diff options
Diffstat (limited to 'indra/newview')
766 files changed, 49428 insertions, 5414 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index b0779bc4cf..4921f2164c 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -17,6 +17,7 @@ include(JsonCpp) include(LLAudio) include(LLCharacter) include(LLCommon) +include(LLConvexDecomposition) include(LLImage) include(LLImageJ2COJ) include(LLInventory) @@ -40,14 +41,17 @@ include(UnixInstall) include(LLKDU) include(ViewerMiscLibs) include(LLLogin) +include(GLOD) include(CMakeCopyIfDifferent) include_directories( ${DBUSGLIB_INCLUDE_DIRS} ${JSONCPP_INCLUDE_DIRS} + ${GLOD_INCLUDE_DIR} ${LLAUDIO_INCLUDE_DIRS} ${LLCHARACTER_INCLUDE_DIRS} ${LLCOMMON_INCLUDE_DIRS} + ${LLCONVEXDECOMP_INCLUDE_DIRS} ${FMOD_INCLUDE_DIR} ${LLIMAGE_INCLUDE_DIRS} ${LLKDU_INCLUDE_DIRS} @@ -66,10 +70,13 @@ include_directories( ${LSCRIPT_INCLUDE_DIRS}/lscript_compile ${LLLOGIN_INCLUDE_DIRS} ${UPDATER_INCLUDE_DIRS} + ${LIBS_PREBUILT_DIR}/include/collada ${OPENAL_LIB_INCLUDE_DIRS} + ${LIBS_PREBUILT_DIR}/include/collada/1.4 ) set(viewer_SOURCE_FILES + groupchatlistener.cpp llagent.cpp llagentaccess.cpp llagentcamera.cpp @@ -112,7 +119,6 @@ set(viewer_SOURCE_FILES llchiclet.cpp llclassifiedinfo.cpp llclassifiedstatsresponder.cpp - llcloud.cpp llcofwearables.cpp llcolorswatch.cpp llcommanddispatcherlistener.cpp @@ -202,6 +208,8 @@ set(viewer_SOURCE_FILES llfloatermediabrowser.cpp llfloatermediasettings.cpp llfloatermemleak.cpp + llfloatermodelpreview.cpp + llfloatermodelwizard.cpp llfloaternamedesc.cpp llfloaternotificationsconsole.cpp llfloateropenobject.cpp @@ -306,6 +314,7 @@ set(viewer_SOURCE_FILES llmediadataclient.cpp llmemoryview.cpp llmenucommands.cpp + llmeshrepository.cpp llmimetypes.cpp llmorphview.cpp llmoveview.cpp @@ -389,6 +398,7 @@ set(viewer_SOURCE_FILES llparticipantlist.cpp llpatchvertexarray.cpp llphysicsmotion.cpp + llphysicsshapebuilderutil.cpp llplacesinventorybridge.cpp llplacesinventorypanel.cpp llpopupview.cpp @@ -408,6 +418,7 @@ set(viewer_SOURCE_FILES llremoteparcelrequest.cpp llsavedsettingsglue.cpp llsaveoutfitcombobtn.cpp + llsceneview.cpp llscreenchannel.cpp llscriptfloater.cpp llscrollingpanelparam.cpp @@ -621,6 +632,7 @@ endif (LINUX) set(viewer_HEADER_FILES CMakeLists.txt ViewerInstall.cmake + groupchatlistener.h llagent.h llagentaccess.h llagentcamera.h @@ -664,7 +676,6 @@ set(viewer_HEADER_FILES llchiclet.h llclassifiedinfo.h llclassifiedstatsresponder.h - llcloud.h llcofwearables.h llcolorswatch.h llcommanddispatcherlistener.h @@ -755,6 +766,8 @@ set(viewer_HEADER_FILES llfloatermediabrowser.h llfloatermediasettings.h llfloatermemleak.h + llfloatermodelpreview.h + llfloatermodelwizard.h llfloaternamedesc.h llfloaternotificationsconsole.h llfloateropenobject.h @@ -859,6 +872,7 @@ set(viewer_HEADER_FILES llmediadataclient.h llmemoryview.h llmenucommands.h + llmeshrepository.h llmimetypes.h llmorphview.h llmoveview.h @@ -936,6 +950,7 @@ set(viewer_HEADER_FILES llparticipantlist.h llpatchvertexarray.h llphysicsmotion.h + llphysicsshapebuilderutil.h llplacesinventorybridge.h llplacesinventorypanel.h llpolymesh.h @@ -957,6 +972,7 @@ set(viewer_HEADER_FILES llrootview.h llsavedsettingsglue.h llsaveoutfitcombobtn.h + llsceneview.h llscreenchannel.h llscriptfloater.h llscrollingpanelparam.h @@ -1457,11 +1473,11 @@ set(PACKAGE ON CACHE BOOL "Add a package target that builds an installer package.") if (WINDOWS) - set_target_properties(${VIEWER_BINARY_NAME} + set_target_properties(${VIEWER_BINARY_NAME} PROPERTIES # *TODO -reenable this once we get server usage sorted out #LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:\"__tcmalloc\"" - LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS" + LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:__tcmalloc" LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO" LINK_FLAGS_RELEASE "" ) @@ -1500,6 +1516,12 @@ if (WINDOWS) ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/libapr-1.dll ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/libaprutil-1.dll ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/libapriconv-1.dll + ${SHARED_LIB_STAGING_DIR}/Release/glod.dll + ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/glod.dll + ${SHARED_LIB_STAGING_DIR}/Debug/glod.dll + ${SHARED_LIB_STAGING_DIR}/Release/libcollada14dom22.dll + ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libcollada14dom22.dll + ${SHARED_LIB_STAGING_DIR}/Debug/libcollada14dom22-d.dll ${SHARED_LIB_STAGING_DIR}/Release/openjpeg.dll ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/openjpeg.dll ${SHARED_LIB_STAGING_DIR}/Debug/openjpegd.dll @@ -1672,6 +1694,7 @@ endif (WINDOWS) # that they depend upon. -brad target_link_libraries(${VIEWER_BINARY_NAME} ${UPDATER_LIBRARIES} + ${GOOGLE_PERFTOOLS_LIBRARIES} ${LLAUDIO_LIBRARIES} ${LLCHARACTER_LIBRARIES} ${LLIMAGE_LIBRARIES} @@ -1696,6 +1719,7 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${DBUSGLIB_LIBRARIES} ${OPENGL_LIBRARIES} ${FMODWRAPPER_LIBRARY} # must come after LLAudio + ${GLOD_LIBRARIES} ${OPENGL_LIBRARIES} ${JSONCPP_LIBRARIES} ${SDL_LIBRARY} @@ -1707,7 +1731,8 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} ${LLLOGIN_LIBRARIES} - ${GOOGLE_PERFTOOLS_LIBRARIES} + ${LLCONVEXDECOMP_LIBRARY} + ${TCMALLOC_LIBRARIES} ) if (USE_KDU) @@ -1763,6 +1788,8 @@ if (LINUX) ${COPY_INPUT_DEPENDENCIES} ) + if (PACKAGE) + endif (PACKAGE) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.copy_touched COMMAND ${PYTHON_EXECUTABLE} diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings index 4bf67b1367..5c7cacedec 100644 --- a/indra/newview/English.lproj/InfoPlist.strings +++ b/indra/newview/English.lproj/InfoPlist.strings @@ -2,6 +2,6 @@ CFBundleName = "Second Life"; -CFBundleShortVersionString = "Second Life version 2.1.1.0"; -CFBundleGetInfoString = "Second Life version 2.1.1.0, Copyright 2004-2010 Linden Research, Inc."; +CFBundleShortVersionString = "Second Life version 2.1.0.13828"; +CFBundleGetInfoString = "Second Life version 2.1.0.13828, Copyright 2004-2009 Linden Research, Inc."; diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist index 3cda7467dd..f7b11b217c 100644 --- a/indra/newview/Info-SecondLife.plist +++ b/indra/newview/Info-SecondLife.plist @@ -60,7 +60,7 @@ </dict> </array> <key>CFBundleVersion</key> - <string>2.1.1.0</string> + <string>2.1.0.13828</string> <key>CSResourcesFileMapped</key> <true/> </dict> diff --git a/indra/newview/app_settings/high_graphics.xml b/indra/newview/app_settings/high_graphics.xml index 4e137d971a..5bc2e1b7e6 100644 --- a/indra/newview/app_settings/high_graphics.xml +++ b/indra/newview/app_settings/high_graphics.xml @@ -4,15 +4,15 @@ <RenderAvatarCloth value="FALSE"/> <!--Default for now--> <RenderAvatarLODFactor value="1.0"/> - <!--Default for now--> - <RenderAvatarPhysicsLODFactor value="0.9"/> + <!--Default for now--> + <RenderAvatarPhysicsLODFactor value="0.9"/> <!--NO SHADERS--> <RenderAvatarVP value="TRUE"/> <!--Short Range--> <RenderFarClip value="128"/> <!--Default for now--> <RenderFlexTimeFactor value="1"/> - <!--256... but they don't use this--> + <!--256... but they do not use this--> <RenderGlowResolutionPow value="9"/> <!--Low number--> <RenderMaxPartCount value="4096"/> @@ -26,8 +26,6 @@ <RenderTerrainLODFactor value="2"/> <!--Default for now--> <RenderTreeLODFactor value="0.5"/> - <!--Default for now--> - <RenderUseFBO value="1"/> <!--Try Impostors--> <RenderUseImpostors value="TRUE"/> <!--Default for now--> @@ -36,11 +34,10 @@ <VertexShaderEnable value="TRUE"/> <!--NO SHADERS--> <WindLightUseAtmosShaders value="TRUE"/> - <!--Deferred Shading--> - <RenderDeferred value="FALSE"/> - <!--SSAO Disabled--> - <RenderDeferredSSAO value="FALSE"/> - <!--Sun Shadows--> - <RenderShadowDetail value="0"/> - + <!--Deferred Shading--> + <RenderDeferred value="FALSE"/> + <!--SSAO Disabled--> + <RenderDeferredSSAO value="FALSE"/> + <!--Sun Shadows--> + <RenderShadowDetail value="0"/> </settings> diff --git a/indra/newview/app_settings/low_graphics.xml b/indra/newview/app_settings/low_graphics.xml index 79463b475c..ca1dae0b86 100644 --- a/indra/newview/app_settings/low_graphics.xml +++ b/indra/newview/app_settings/low_graphics.xml @@ -4,17 +4,17 @@ <RenderAvatarCloth value="FALSE"/> <!--Default for now--> <RenderAvatarLODFactor value="0.5"/> - <!--Default for now--> - <RenderAvatarPhysicsLODFactor value="0.0"/> - <!--Default for now--> - <RenderAvatarMaxVisible value="3"/> + <!--Default for now--> + <RenderAvatarPhysicsLODFactor value="0.0"/> + <!--Default for now--> + <RenderAvatarMaxVisible value="3"/> <!--NO SHADERS--> <RenderAvatarVP value="FALSE"/> <!--Short Range--> <RenderFarClip value="64"/> <!--Default for now--> <RenderFlexTimeFactor value="0.5"/> - <!--256... but they don't use this--> + <!--256... but they do not use this--> <RenderGlowResolutionPow value="8"/> <!--Low number--> <RenderMaxPartCount value="1024"/> @@ -28,8 +28,6 @@ <RenderTerrainLODFactor value="1.0"/> <!--Default for now--> <RenderTreeLODFactor value="0.5"/> - <!--Default for now--> - <RenderUseFBO value="0"/> <!--Try Impostors--> <RenderUseImpostors value="TRUE"/> <!--Default for now--> @@ -38,11 +36,10 @@ <VertexShaderEnable value="FALSE"/> <!--NO SHADERS--> <WindLightUseAtmosShaders value="FALSE"/> - <!--No Deferred Shading--> - <RenderDeferred value="FALSE"/> - <!--SSAO Disabled--> - <RenderDeferredSSAO value="FALSE"/> - <!--No Shadows--> - <RenderShadowDetail value="0"/> - + <!--No Deferred Shading--> + <RenderDeferred value="FALSE"/> + <!--SSAO Disabled--> + <RenderDeferredSSAO value="FALSE"/> + <!--No Shadows--> + <RenderShadowDetail value="0"/> </settings> diff --git a/indra/newview/app_settings/mid_graphics.xml b/indra/newview/app_settings/mid_graphics.xml index ab1e2a2e1c..01822fe64c 100644 --- a/indra/newview/app_settings/mid_graphics.xml +++ b/indra/newview/app_settings/mid_graphics.xml @@ -4,15 +4,15 @@ <RenderAvatarCloth value="FALSE"/> <!--Default for now--> <RenderAvatarLODFactor value="0.5"/> - <!--Default for now--> - <RenderAvatarPhysicsLODFactor value="0.75"/> + <!--Default for now--> + <RenderAvatarPhysicsLODFactor value="0.75"/> <!--NO SHADERS--> <RenderAvatarVP value="TRUE"/> <!--Short Range--> <RenderFarClip value="96"/> <!--Default for now--> <RenderFlexTimeFactor value="1"/> - <!--256... but they don't use this--> + <!--256... but they do not use this--> <RenderGlowResolutionPow value="8"/> <!--Low number--> <RenderMaxPartCount value="2048"/> @@ -26,8 +26,6 @@ <RenderTerrainLODFactor value="1.0"/> <!--Default for now--> <RenderTreeLODFactor value="0.5"/> - <!--Default for now--> - <RenderUseFBO value="0"/> <!--Try Impostors--> <RenderUseImpostors value="TRUE"/> <!--Default for now--> @@ -36,11 +34,10 @@ <VertexShaderEnable value="TRUE"/> <!--NO SHADERS--> <WindLightUseAtmosShaders value="FALSE"/> - <!--No Deferred Shading--> - <RenderDeferred value="FALSE"/> - <!--SSAO Disabled--> - <RenderDeferredSSAO value="FALSE"/> - <!--No Shadows--> - <RenderShadowDetail value="0"/> - + <!--No Deferred Shading--> + <RenderDeferred value="FALSE"/> + <!--SSAO Disabled--> + <RenderDeferredSSAO value="FALSE"/> + <!--No Shadows--> + <RenderShadowDetail value="0"/> </settings> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index bd1e9e63d0..d1d64516f9 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1333,7 +1333,68 @@ <key>Value</key> <integer>0</integer> </map> - <key>CertStore</key> + + <key>CameraFocusTransitionTime</key> + <map> + <key>Comment</key> + <string>How many seconds it takes the camera to transition between focal distances</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.5</real> + </map> + + <key>CameraFNumber</key> + <map> + <key>Comment</key> + <string>Camera f-number value for DoF effect</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>9.0</real> + </map> + + <key>CameraFocalLength</key> + <map> + <key>Comment</key> + <string>Camera focal length for DoF effect (in millimeters)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>50</real> + </map> + + <key>CameraFieldOfView</key> + <map> + <key>Comment</key> + <string>Vertical camera field of view for DoF effect (in degrees)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>60.0</real> + </map> + + <key>CameraAspectRatio</key> + <map> + <key>Comment</key> + <string>Camera aspect ratio for DoF effect</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>1.5</real> + </map> + + <key>CertStore</key> <map> <key>Comment</key> <string>Specifies the Certificate Store for certificate trust verification</string> @@ -1855,7 +1916,7 @@ <key>DebugShowRenderInfo</key> <map> <key>Comment</key> - <string>Show depth buffer contents</string> + <string>Show stats about current scene</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -1863,6 +1924,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>DebugShowUploadCost</key> + <map> + <key>Comment</key> + <string>Show what it would cost to upload assets in current scene</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>DebugShowRenderMatrices</key> <map> <key>Comment</key> @@ -5484,7 +5556,40 @@ <key>Value</key> <real>0</real> </map> - <key>MigrateCacheDirectory</key> + <key>MeshEnabled</key> + <map> + <key>Comment</key> + <string>Expose UI for mesh functionality (may require restart to take effect).</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <real>1</real> + </map> + <key>MeshImportUseSLM</key> + <map> + <key>Comment</key> + <string>Use cached copy of last upload for a dae if available instead of loading dae file from scratch.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <real>0</real> + </map> + <key>MeshUseWholeModelUpload</key> + <map> + <key>Comment</key> + <string>Upload model in its entirety instead of mesh-by-mesh (new caps)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <real>0</real> + </map> + <key>MigrateCacheDirectory</key> <map> <key>Comment</key> <string>Check for old version of disk cache to migrate to current location</string> @@ -6147,6 +6252,66 @@ <key>Value</key> <real>0.0</real> </map> + <key>ObjectCostHighThreshold</key> + <map> + <key>Comment</key> + <string>Threshold at which object cost is considered high (displayed in red).</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>50.0</real> + </map> + <key>ObjectCostLowColor</key> + <map> + <key>Comment</key> + <string>Color for object with a low object cost.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>0.0</real> + <real>0.5</real> + <real>1.0</real> + <real>0.5</real> + </array> + </map> + <key>ObjectCostMidColor</key> + <map> + <key>Comment</key> + <string>Color for object with a medium object cost.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>1.0</real> + <real>0.75</real> + <real>0.0</real> + <real>0.65</real> + </array> + </map> + <key>ObjectCostHighColor</key> + <map> + <key>Comment</key> + <string>Color for object a high object cost.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>1.0</real> + <real>0.0</real> + <real>0.0</real> + <real>0.75</real> + </array> + </map> + <key>ParcelMediaAutoPlayEnable</key> <map> <key>Comment</key> @@ -6382,7 +6547,177 @@ <key>Value</key> <integer>13</integer> </map> - <key>PrimMediaMasterEnabled</key> + + <key>PreviewAmbientColor</key> + <map> + <key>Comment</key> + <string>Ambient color of preview render.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>0.0</real> + <real>0.0</real> + <real>0.0</real> + <real>1.0</real> + </array> + </map> + + + <key>PreviewDiffuse0</key> + <map> + <key>Comment</key> + <string>Diffise color of preview light 0.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>1.0</real> + <real>1.0</real> + <real>1.0</real> + <real>1.0</real> + </array> + </map> + + <key>PreviewDiffuse1</key> + <map> + <key>Comment</key> + <string>Diffise color of preview light 1.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>0.25</real> + <real>0.25</real> + <real>0.25</real> + <real>1.0</real> + </array> + </map> + + <key>PreviewDiffuse2</key> + <map> + <key>Comment</key> + <string>Diffise color of preview light 2.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>1.0</real> + <real>1.0</real> + <real>1.0</real> + <real>1.0</real> + </array> + </map> + + <key>PreviewSpecular0</key> + <map> + <key>Comment</key> + <string>Diffise color of preview light 0.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>1.0</real> + <real>1.0</real> + <real>1.0</real> + <real>1.0</real> + </array> + </map> + + <key>PreviewSpecular1</key> + <map> + <key>Comment</key> + <string>Diffise color of preview light 1.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>1.0</real> + <real>1.0</real> + <real>1.0</real> + <real>1.0</real> + </array> + </map> + + <key>PreviewSpecular2</key> + <map> + <key>Comment</key> + <string>Diffise color of preview light 2.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Color4</string> + <key>Value</key> + <array> + <real>1.0</real> + <real>1.0</real> + <real>1.0</real> + <real>1.0</real> + </array> + </map> + + + <key>PreviewDirection0</key> + <map> + <key>Comment</key> + <string>Direction of light 0 for preview render.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Vector3</string> + <key>Value</key> + <array> + <real>-0.75</real> + <real>1</real> + <real>1.0</real> + </array> + </map> + + <key>PreviewDirection1</key> + <map> + <key>Comment</key> + <string>Direction of light 1 for preview render.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Vector3</string> + <key>Value</key> + <array> + <real>0.5</real> + <real>-0.6</real> + <real>0.4</real> + </array> + </map> + + <key>PreviewDirection2</key> + <map> + <key>Comment</key> + <string>Direction of light 2 for preview render.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Vector3</string> + <key>Value</key> + <array> + <real>0.5</real> + <real>-0.8</real> + <real>0.3</real> + </array> + </map> + + <key>PrimMediaMasterEnabled</key> <map> <key>Comment</key> <string>Whether or not Media on a Prim is enabled.</string> @@ -6866,7 +7201,31 @@ <key>Value</key> <integer>1</integer> </map> - + <key>RenderPerformanceTest</key> + <map> + <key>Comment</key> + <string>Disable rendering of everything but in-world content for + performance testing</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + + <key>RenderLocalLights</key> + <map> + <key>Comment</key> + <string>Whether or not to render local lights.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>RenderShadowNearDist</key> <map> <key>Comment</key> @@ -7003,7 +7362,7 @@ <string>Vector3</string> <key>Value</key> <array> - <real>0.40</real> + <real>0.80</real> <real>1.00</real> <real>0.00</real> </array> @@ -7063,7 +7422,18 @@ <key>Value</key> <integer>0</integer> </map> - <key>RenderDebugPipeline</key> + <key>RenderDebugNormalScale</key> + <map> + <key>Comment</key> + <string>Scale of normals in debug display.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.03</real> + </map> + <key>RenderDebugPipeline</key> <map> <key>Comment</key> <string>Enable strict pipeline debugging.</string> @@ -7096,6 +7466,7 @@ <key>Value</key> <integer>0</integer> </map> + <key>RenderAnimateRes</key> <map> <key>Comment</key> @@ -7107,7 +7478,31 @@ <key>Value</key> <integer>0</integer> </map> - + + <key>RenderBakeSunlight</key> + <map> + <key>Comment</key> + <string>Bake sunlight into vertex buffers for static objects.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + + <key>RenderNoAlpha</key> + <map> + <key>Comment</key> + <string>Disable rendering of alpha objects (render all alpha objects as alpha masks).</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>RenderAnimateTrees</key> <map> <key>Comment</key> @@ -7264,6 +7659,18 @@ <real>16.0</real> </map> + <key>RenderMinimumLODTriangleCount</key> + <map> + <key>Comment</key> + <string>Triangle count threshold at which automatic LOD generation stops</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <real>16</real> + </map> + <key>RenderEdgeDepthCutoff</key> <map> <key>Comment</key> @@ -7354,7 +7761,6 @@ <key>Value</key> <real>0.01</real> </map> - <key>RenderShadowBiasError</key> <map> <key>Comment</key> @@ -7377,6 +7783,18 @@ <key>Value</key> <real>0</real> </map> + + <key>RenderDepthOfField</key> + <map> + <key>Comment</key> + <string>Whether to use depth of field effect when lighting and shadows are enabled</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RenderSpotLightsInNondeferred</key> <map> @@ -7399,7 +7817,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <real>0.0</real> + <real>-0.001</real> </map> <key>RenderSpotShadowOffset</key> <map> @@ -7621,30 +8039,6 @@ <integer>1</integer> </map> - <key>RenderDeferredLocalLights</key> - <map> - <key>Comment</key> - <string>Execute local lighting shader in deferred renderer.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - - <key>RenderDeferredFullscreenLights</key> - <map> - <key>Comment</key> - <string>Execute local lighting shader in deferred renderer.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> - <key>RenderDeferredSunWash</key> <map> <key>Comment</key> @@ -7687,7 +8081,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <real>1.1</real> + <real>0.8</real> </map> <key>RenderShadowGaussian</key> @@ -7737,7 +8131,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <real>0.1</real> + <real>0</real> </map> <key>RenderGIAmbiance</key> @@ -7957,9 +8351,9 @@ <string>Vector3</string> <key>Value</key> <array> - <real>0.299</real> - <real>0.587</real> - <real>0.114</real> + <real>1</real> + <real>0</real> + <real>0</real> </array> </map> <key>RenderGlowMaxExtractAlpha</key> @@ -7971,7 +8365,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <real>0.065</real> + <real>0.25</real> </map> <key>RenderGlowMinLuminance</key> <map> @@ -7982,7 +8376,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <real>2.5</real> + <real>9999</real> </map> <key>RenderGlowResolutionPow</key> <map> @@ -8096,7 +8490,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>1</integer> + <integer>0</integer> </map> <key>RenderHideGroupTitle</key> <map> @@ -8462,17 +8856,17 @@ <key>Value</key> <integer>0</integer> </map> - <key>RenderUseFBO</key> - <map> - <key>Comment</key> - <string>Whether we want to use GL_EXT_framebuffer_objects.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> + <key>RenderUseTriStrips</key> + <map> + <key>Comment</key> + <string>Use triangle strips for rendering prims.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RenderUseTriStrips</key> <map> <key>Comment</key> @@ -8561,7 +8955,18 @@ <key>Value</key> <integer>1</integer> </map> - <key>RenderVolumeLODFactor</key> + <key>RenderPreferStreamDraw</key> + <map> + <key>Comment</key> + <string>Use GL_STREAM_DRAW in place of GL_DYNAMIC_DRAW</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>RenderVolumeLODFactor</key> <map> <key>Comment</key> <string>Controls level of detail of primitives (multiplier for current screen area when calculated level of detail)</string> @@ -8638,7 +9043,51 @@ <key>Value</key> <real>1.0</real> </map> - <key>SafeMode</key> + <key>MeshStreamingCostScaler</key> + <map> + <key>Comment</key> + <string>DEBUG</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>3.0</real> + </map> + <key>MeshThreadCount</key> + <map> + <key>Comment</key> + <string>Number of threads to use for loading meshes.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>8</integer> + </map> + <key>MeshMaxConcurrentRequests</key> + <map> + <key>Comment</key> + <string>Number of threads to use for loading meshes.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>32</integer> + </map> + <key>RunMultipleThreads</key> + <map> + <key>Comment</key> + <string>If TRUE keep background threads active during render</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>SafeMode</key> <map> <key>Comment</key> <string>Reset preferences, run in safe mode.</string> @@ -9738,17 +10187,6 @@ <real>0.1</real> </array> </map> - <key>SkyUseClassicClouds</key> - <map> - <key>Comment</key> - <string>Whether to use the old Second Life particle clouds or not</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>1</integer> - </map> <key>SnapEnabled</key> <map> <key>Comment</key> @@ -9914,6 +10352,17 @@ <key>Value</key> <string>pilot.txt</string> </map> + <key>StatsPilotXMLFile</key> + <map> + <key>Comment</key> + <string>Filename for stats logging extended autopilot path</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>pilot.xml</string> + </map> <key>StatsQuitAfterRuns</key> <map> <key>Comment</key> @@ -11452,7 +11901,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>1</integer> + <integer>0</integer> </map> <key>SpeakerParticipantDefaultOrder</key> <map> diff --git a/indra/newview/app_settings/settings_crash_behavior.xml b/indra/newview/app_settings/settings_crash_behavior.xml index cc7f5ac88b..97651ff4ca 100644 --- a/indra/newview/app_settings/settings_crash_behavior.xml +++ b/indra/newview/app_settings/settings_crash_behavior.xml @@ -9,7 +9,7 @@ <key>Type</key> <string>S32</string> <key>Value</key> - <integer>0</integer> + <integer>1</integer> </map> </map> </llsd> diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl index 5de9cb0790..3f6b8b3323 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/avatarF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 void default_lighting(); diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl index 7e9818e54a..1ad87badfe 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 attribute vec4 weight; //1 diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl index 9f06301cc7..a15846f192 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); mat4 getSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl b/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl index 0feb88535a..05fe100372 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/eyeballF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 void default_lighting(); diff --git a/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl b/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl index 30a2f10f62..4b8a7604a1 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol); void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl new file mode 100644 index 0000000000..ef823c28b1 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl @@ -0,0 +1,30 @@ +/** + * @file objectSkinV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +attribute vec4 object_weight; + +uniform mat4 matrixPalette[32]; + +mat4 getObjectSkinnedTransform() +{ + int i; + + vec4 w = fract(object_weight); + vec4 index = floor(object_weight); + + float scale = 1.0/(w.x+w.y+w.z+w.w); + w *= scale; + + mat4 mat = matrixPalette[int(index.x)]*w.x; + mat += matrixPalette[int(index.y)]*w.y; + mat += matrixPalette[int(index.z)]*w.z; + mat += matrixPalette[int(index.w)]*w.w; + + return mat; +} diff --git a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl index bcd710dc57..27ac59a840 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl index 299def1927..f1aa549a47 100644 --- a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 mat4 getSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index 171a0e76f7..3b12a07a27 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -4,11 +4,12 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable uniform sampler2D diffuseMap; -uniform sampler2D noiseMap; uniform sampler2DRect depthMap; uniform mat4 shadow_matrix[6]; @@ -22,7 +23,7 @@ varying vec3 vary_ambient; varying vec3 vary_directional; varying vec3 vary_fragcoord; varying vec3 vary_position; -varying vec3 vary_light; +varying vec3 vary_pointlight_col; uniform mat4 inv_proj; @@ -44,18 +45,19 @@ void main() vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; frag *= screen_res; - vec3 samp_pos = getPosition(frag).xyz; - vec4 pos = vec4(vary_position, 1.0); + vec4 diff= texture2D(diffuseMap, gl_TexCoord[0].xy); + vec4 col = vec4(vary_ambient + vary_directional.rgb, gl_Color.a); - vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * col; + vec4 color = diff * col; color.rgb = atmosLighting(color.rgb); color.rgb = scaleSoftClip(color.rgb); - //gl_FragColor = gl_Color; + color.rgb += diff.rgb * vary_pointlight_col.rgb; + gl_FragColor = color; //gl_FragColor = vec4(1,0,1,1); //gl_FragColor = vec4(1,0,1,1)*shadow; diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl new file mode 100644 index 0000000000..5addbbb176 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaSkinnedV.glsl @@ -0,0 +1,107 @@ +/** + * @file alphaSkinnedV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); +mat4 getObjectSkinnedTransform(); +void calcAtmospherics(vec3 inPositionEye); + +float calcDirectionalLight(vec3 n, vec3 l); + +vec3 atmosAmbient(vec3 light); +vec3 atmosAffectDirectionalLight(float lightIntensity); +vec3 scaleDownLight(vec3 light); +vec3 scaleUpLight(vec3 light); + +varying vec3 vary_position; +varying vec3 vary_ambient; +varying vec3 vary_directional; +varying vec3 vary_normal; +varying vec3 vary_fragcoord; +varying vec3 vary_pointlight_col; + +uniform float near_clip; + +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +{ + //get light vector + vec3 lv = lp.xyz-v; + + //get distance + float d = length(lv); + + //normalize light vector + lv *= 1.0/d; + + //distance attenuation + float dist2 = d*d/(la*la); + float da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + + // spotlight coefficient. + float spot = max(dot(-ln, lv), is_pointlight); + da *= spot*spot; // GL_SPOT_EXPONENT=2 + + //angular attenuation + da *= calcDirectionalLight(n, lv); + + return da; +} + +void main() +{ + gl_TexCoord[0] = gl_MultiTexCoord0; + + vec4 pos; + vec3 norm; + + mat4 trans = getObjectSkinnedTransform(); + trans = gl_ModelViewMatrix * trans; + + pos = trans * gl_Vertex; + + norm = gl_Vertex.xyz + gl_Normal.xyz; + norm = normalize(( trans*vec4(norm, 1.0) ).xyz-pos.xyz); + + vec4 frag_pos = gl_ProjectionMatrix * pos; + gl_Position = frag_pos; + + vary_position = pos.xyz; + vary_normal = norm; + + calcAtmospherics(pos.xyz); + + vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a); + + // Collect normal lights + col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].quadraticAttenuation, gl_LightSource[2].specular.a); + col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].quadraticAttenuation ,gl_LightSource[3].specular.a); + col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].quadraticAttenuation, gl_LightSource[4].specular.a); + col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].quadraticAttenuation, gl_LightSource[5].specular.a); + col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].quadraticAttenuation, gl_LightSource[6].specular.a); + col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].quadraticAttenuation, gl_LightSource[7].specular.a); + + vary_pointlight_col = col.rgb*gl_Color.rgb; + + col.rgb = vec3(0,0,0); + + // Add windlight lights + col.rgb = atmosAmbient(vec3(0.)); + + vary_ambient = col.rgb*gl_Color.rgb; + vary_directional = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); + + col.rgb = min(col.rgb*gl_Color.rgb, 1.0); + + gl_FrontColor = col; + + gl_FogFragCoord = pos.z; + + vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip); +} + + diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index fabbce0824..525b68c437 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -5,11 +5,12 @@ * $/LicenseInfo$ */ +#version 120 + vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); void calcAtmospherics(vec3 inPositionEye); float calcDirectionalLight(vec3 n, vec3 l); -float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight); vec3 atmosAmbient(vec3 light); vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -21,11 +22,37 @@ varying vec3 vary_directional; varying vec3 vary_fragcoord; varying vec3 vary_position; varying vec3 vary_light; +varying vec3 vary_pointlight_col; uniform float near_clip; uniform float shadow_offset; uniform float shadow_bias; +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +{ + //get light vector + vec3 lv = lp.xyz-v; + + //get distance + float d = length(lv); + + //normalize light vector + lv *= 1.0/d; + + //distance attenuation + float dist2 = d*d/(la*la); + float da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + + // spotlight coefficient. + float spot = max(dot(-ln, lv), is_pointlight); + da *= spot*spot; // GL_SPOT_EXPONENT=2 + + //angular attenuation + da *= calcDirectionalLight(n, lv); + + return da; +} + void main() { //transform vertex @@ -36,33 +63,35 @@ void main() vec4 pos = (gl_ModelViewMatrix * gl_Vertex); vec3 norm = normalize(gl_NormalMatrix * gl_Normal); - vary_position = pos.xyz + norm.xyz * (-pos.z/64.0*shadow_offset+shadow_bias); + float dp_directional_light = max(0.0, dot(norm, gl_LightSource[0].position.xyz)); + vary_position = pos.xyz + gl_LightSource[0].position.xyz * (1.0-dp_directional_light)*shadow_offset; calcAtmospherics(pos.xyz); //vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); - vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a); - // Collect normal lights (need to be divided by two, as we later multiply by 2) - col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); - col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); - col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a); - col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a); - col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a); - col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a); - col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); - col.rgb = scaleDownLight(col.rgb); + // Collect normal lights + col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].quadraticAttenuation, gl_LightSource[2].specular.a); + col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].quadraticAttenuation ,gl_LightSource[3].specular.a); + col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].quadraticAttenuation, gl_LightSource[4].specular.a); + col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].quadraticAttenuation, gl_LightSource[5].specular.a); + col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].quadraticAttenuation, gl_LightSource[6].specular.a); + col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].quadraticAttenuation, gl_LightSource[7].specular.a); + vary_pointlight_col = col.rgb*gl_Color.rgb; + + col.rgb = vec3(0,0,0); + // Add windlight lights - col.rgb += atmosAmbient(vec3(0.)); + col.rgb = atmosAmbient(vec3(0.)); vary_light = gl_LightSource[0].position.xyz; vary_ambient = col.rgb*gl_Color.rgb; vary_directional.rgb = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); - col.rgb = min(col.rgb*gl_Color.rgb, 1.0); + col.rgb = col.rgb*gl_Color.rgb; gl_FrontColor = col; diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl new file mode 100644 index 0000000000..164322c3a7 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl @@ -0,0 +1,18 @@ +/** + * @file avatarShadowF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +uniform sampler2D diffuseMap; + + +void main() +{ + //gl_FragColor = vec4(1,1,1,gl_Color.a * texture2D(diffuseMap, gl_TexCoord[0].xy).a); + gl_FragColor = vec4(1,1,1,1); +} + diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl new file mode 100644 index 0000000000..5ae41cb730 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl @@ -0,0 +1,27 @@ +/** + * @file attachmentShadowV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +mat4 getObjectSkinnedTransform(); + +void main() +{ + //transform vertex + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + + mat4 mat = getObjectSkinnedTransform(); + + mat = gl_ModelViewMatrix * mat; + vec3 pos = (mat*gl_Vertex).xyz; + + gl_FrontColor = gl_Color; + + vec4 p = gl_ProjectionMatrix * vec4(pos, 1.0); + p.z = max(p.z, -p.w+0.01); + gl_Position = p; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl deleted file mode 100644 index 82ce6d7377..0000000000 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file avatarAlphaF.glsl - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * $/LicenseInfo$ - */ - -uniform sampler2D diffuseMap; -uniform sampler2DShadow shadowMap0; -uniform sampler2DShadow shadowMap1; -uniform sampler2DShadow shadowMap2; -uniform sampler2DShadow shadowMap3; -uniform sampler2D noiseMap; - -uniform mat4 shadow_matrix[6]; -uniform vec4 shadow_clip; - -vec3 atmosLighting(vec3 light); -vec3 scaleSoftClip(vec3 light); - -varying vec3 vary_ambient; -varying vec3 vary_directional; -varying vec4 vary_position; -varying vec3 vary_normal; - -void main() -{ - float shadow = 1.0; - vec4 pos = vary_position; - vec3 norm = normalize(vary_normal); - - vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; - - if (pos.z > -shadow_clip.w) - { - - if (pos.z < -shadow_clip.z) - { - vec4 lpos = shadow_matrix[3]*pos; - shadow = shadow2DProj(shadowMap3, lpos).x; - } - else if (pos.z < -shadow_clip.y) - { - vec4 lpos = shadow_matrix[2]*pos; - shadow = shadow2DProj(shadowMap2, lpos).x; - } - else if (pos.z < -shadow_clip.x) - { - vec4 lpos = shadow_matrix[1]*pos; - shadow = shadow2DProj(shadowMap1, lpos).x; - } - else - { - vec4 lpos = shadow_matrix[0]*pos; - shadow = shadow2DProj(shadowMap0, lpos).x; - } - } - - - vec4 col = vec4(vary_ambient + vary_directional*shadow, gl_Color.a); - vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * col; - - color.rgb = atmosLighting(color.rgb); - - color.rgb = scaleSoftClip(color.rgb); - - gl_FragColor = color; -} diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl index 21ddc2fad8..a2a7dea20d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); mat4 getSkinnedTransform(); @@ -17,10 +19,38 @@ vec3 atmosAffectDirectionalLight(float lightIntensity); vec3 scaleDownLight(vec3 light); vec3 scaleUpLight(vec3 light); -varying vec4 vary_position; +varying vec3 vary_position; varying vec3 vary_ambient; varying vec3 vary_directional; -varying vec3 vary_normal; +varying vec3 vary_fragcoord; +varying vec3 vary_pointlight_col; + +uniform float near_clip; + +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +{ + //get light vector + vec3 lv = lp.xyz-v; + + //get distance + float d = length(lv); + + //normalize light vector + lv *= 1.0/d; + + //distance attenuation + float dist2 = d*d/(la*la); + float da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + + // spotlight coefficient. + float spot = max(dot(-ln, lv), is_pointlight); + da *= spot*spot; // GL_SPOT_EXPONENT=2 + + //angular attenuation + da *= calcDirectionalLight(n, lv); + + return da; +} void main() { @@ -40,9 +70,10 @@ void main() norm.z = dot(trans[2].xyz, gl_Normal); norm = normalize(norm); - gl_Position = gl_ProjectionMatrix * pos; - vary_position = pos; - vary_normal = norm; + vec4 frag_pos = gl_ProjectionMatrix * pos; + gl_Position = frag_pos; + + vary_position = pos.xyz; calcAtmospherics(pos.xyz); @@ -50,18 +81,20 @@ void main() vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a); - // Collect normal lights (need to be divided by two, as we later multiply by 2) - col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); - col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); - col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a); - col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a); - col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a); - col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a); - col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); - col.rgb = scaleDownLight(col.rgb); + // Collect normal lights + col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].quadraticAttenuation, gl_LightSource[2].specular.a); + col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].quadraticAttenuation ,gl_LightSource[3].specular.a); + col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].quadraticAttenuation, gl_LightSource[4].specular.a); + col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].quadraticAttenuation, gl_LightSource[5].specular.a); + col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].quadraticAttenuation, gl_LightSource[6].specular.a); + col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].quadraticAttenuation, gl_LightSource[7].specular.a); + vary_pointlight_col = col.rgb*gl_Color.rgb; + + col.rgb = vec3(0,0,0); + // Add windlight lights - col.rgb += atmosAmbient(vec3(0.)); + col.rgb = atmosAmbient(vec3(0.)); vary_ambient = col.rgb*gl_Color.rgb; vary_directional = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); @@ -71,7 +104,8 @@ void main() gl_FrontColor = col; gl_FogFragCoord = pos.z; - + + vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index e376892e0a..9748727147 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl index d88e3ecfd8..1b7ae06888 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl index 2af8c8f5f7..cf6579a40d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 mat4 getSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl index 988226fb7c..69c93799b5 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 mat4 getSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index 258a9b7c40..d9f021b114 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable @@ -37,44 +39,49 @@ vec4 getPosition(vec2 pos_screen) void main() { - vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz; + vec2 tc = vary_fragcoord.xy; + vec3 norm = texture2DRect(normalMap, tc).xyz; norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm - vec3 pos = getPosition(vary_fragcoord.xy).xyz; - vec4 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rgba; + vec3 pos = getPosition(tc).xyz; + vec4 ccol = texture2DRect(lightMap, tc).rgba; vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy); - dlt /= max(-pos.z*dist_factor, 1.0); vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free' vec4 col = defined_weight.xyxx * ccol; - + + // relax tolerance according to distance to avoid speckling artifacts, as angles and distances are a lot more abrupt within a small screen area at larger distances + float pointplanedist_tolerance_pow2 = pos.z*pos.z*0.00005; + + // perturb sampling origin slightly in screen-space to hide edge-ghosting artifacts where smoothing radius is quite large + tc += ( (mod(tc.x+tc.y,2) - 0.5) * kern[1].z * dlt * 0.5 ); + for (int i = 1; i < 4; i++) { - vec2 tc = vary_fragcoord.xy + kern[i].z*dlt; - vec3 samppos = getPosition(tc).xyz; + vec2 samptc = tc + kern[i].z*dlt; + vec3 samppos = getPosition(samptc).xyz; float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane - if (d*d <= 0.003) + if (d*d <= pointplanedist_tolerance_pow2) { - col += texture2DRect(lightMap, tc)*kern[i].xyxx; + col += texture2DRect(lightMap, samptc)*kern[i].xyxx; defined_weight += kern[i].xy; } } for (int i = 1; i < 4; i++) { - vec2 tc = vary_fragcoord.xy - kern[i].z*dlt; - vec3 samppos = getPosition(tc).xyz; + vec2 samptc = tc - kern[i].z*dlt; + vec3 samppos = getPosition(samptc).xyz; float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane - if (d*d <= 0.003) + if (d*d <= pointplanedist_tolerance_pow2) { - col += texture2DRect(lightMap, tc)*kern[i].xyxx; + col += texture2DRect(lightMap, samptc)*kern[i].xyxx; defined_weight += kern[i].xy; } } - - col /= defined_weight.xyxx; + col.y *= col.y; gl_FragColor = col; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl index b1b3f55f00..c2d05c601a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec2 vary_fragcoord; uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl index 35f334d58e..37bfaac32c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; uniform sampler2D bumpMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl new file mode 100644 index 0000000000..d884f2e4a5 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpSkinnedV.glsl @@ -0,0 +1,37 @@ +/** + * @file bumpV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +varying vec3 vary_mat0; +varying vec3 vary_mat1; +varying vec3 vary_mat2; + +mat4 getObjectSkinnedTransform(); + +void main() +{ + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + + mat4 mat = getObjectSkinnedTransform(); + + mat = gl_ModelViewMatrix * mat; + + vec3 pos = (mat*gl_Vertex).xyz; + + + vec3 n = normalize((mat * vec4(gl_Normal.xyz+gl_Vertex.xyz, 1.0)).xyz-pos.xyz); + vec3 b = normalize((mat * vec4(gl_MultiTexCoord2.xyz+gl_Vertex.xyz, 1.0)).xyz-pos.xyz); + vec3 t = cross(b, n); + + 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); + + gl_Position = gl_ProjectionMatrix*vec4(pos, 1.0); + gl_FrontColor = gl_Color; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl index 6c8550cb5b..9b109b2db6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec3 vary_mat0; varying vec3 vary_mat1; diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl index 9bd622a506..35cfb80c93 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl new file mode 100644 index 0000000000..9a45c03237 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseSkinnedV.glsl @@ -0,0 +1,33 @@ +/** + * @file diffuseSkinnedV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +varying vec3 vary_normal; + +mat4 getObjectSkinnedTransform(); + +void main() +{ + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + + mat4 mat = getObjectSkinnedTransform(); + + mat = gl_ModelViewMatrix * mat; + vec3 pos = (mat*gl_Vertex).xyz; + + vec4 norm = gl_Vertex; + norm.xyz += gl_Normal.xyz; + norm.xyz = (mat*norm).xyz; + norm.xyz = normalize(norm.xyz-pos.xyz); + + vary_normal = norm.xyz; + + gl_FrontColor = gl_Color; + + gl_Position = gl_ProjectionMatrix*vec4(pos, 1.0); +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl index bd58096317..03d3322cb6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec3 vary_normal; diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index f53e15c6cc..3429877397 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl index dc8b2c6be4..6c38d220e2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl b/indra/newview/app_settings/shaders/class1/deferred/giF.glsl index e64e29a0d2..75b555e8ae 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/giF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class1/deferred/giV.glsl b/indra/newview/app_settings/shaders/class1/deferred/giV.glsl index 543527612e..8dc1410ea5 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/giV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/giV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec2 vary_fragcoord; diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl index 7f365fedc8..e3c15a2ab2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; uniform sampler2D normalMap; @@ -12,7 +14,7 @@ uniform sampler2D specularMap; void main() { vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy); - gl_FragData[0] = vec4(col.rgb, col.a <= 0.5 ? 0.0 : 0.005); + gl_FragData[0] = vec4(col.rgb, col.a * 0.005); gl_FragData[1] = texture2D(specularMap, gl_TexCoord[0].xy); gl_FragData[2] = vec4(texture2D(normalMap, gl_TexCoord[0].xy).xyz, 0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl index 4fc27d4412..37148b3f1a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 void main() { diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl index acb3014d18..78df54d5dc 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl @@ -5,6 +5,8 @@ * $/LicenseInfo$ */ +#version 120 + uniform sampler2DRect diffuseMap; varying vec2 vary_fragcoord; diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl index 6368def830..0c820bfc6c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl @@ -5,6 +5,9 @@ * $/LicenseInfo$ */ +#version 120 + + varying vec2 vary_fragcoord; uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 6fca08ae6a..c5ddf31ac0 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -5,6 +5,8 @@ * $/LicenseInfo$ */ +#version 120 + #extension GL_ARB_texture_rectangle : enable uniform sampler2DRect depthMap; diff --git a/indra/newview/app_settings/shaders/class2/deferred/blurLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl index b1b3f55f00..2e3e84dd15 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/blurLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl @@ -1,17 +1,20 @@ /** - * @file blurLightF.glsl + * @file multiPointLightV.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ -varying vec2 vary_fragcoord; -uniform vec2 screen_res; +#version 120 + +varying vec4 vary_fragcoord; void main() { //transform vertex - gl_Position = ftransform(); vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; + vary_fragcoord = pos; + + gl_Position = pos; + gl_FrontColor = gl_Color; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index 43da16436b..22ed9dcd40 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + + #version 120 #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl index e056c3e896..8e74feb615 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl @@ -5,6 +5,8 @@ * $/LicenseInfo$ */ +#version 120 + varying vec4 vary_light; varying vec4 vary_fragcoord; diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl index 650e1a91a8..77f1b2224c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl @@ -4,54 +4,134 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable uniform sampler2DRect diffuseRect; -uniform sampler2DRect localLightMap; -uniform sampler2DRect sunLightMap; -uniform sampler2DRect giLightMap; -uniform sampler2D luminanceMap; -uniform sampler2DRect lightMap; +uniform sampler2DRect edgeMap; +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2D bloomMap; -uniform vec3 lum_quad; -uniform float lum_lod; -uniform vec4 ambient; - -uniform vec3 gi_quad; +uniform float depth_cutoff; +uniform float norm_cutoff; +uniform float focal_distance; +uniform float blur_constant; +uniform float tan_pixel_angle; +uniform float magnification; +uniform mat4 inv_proj; uniform vec2 screen_res; + varying vec2 vary_fragcoord; -void main() +float getDepth(vec2 pos_screen) { - vec2 tc = vary_fragcoord.xy; - vec3 lum = texture2DLod(luminanceMap, tc/screen_res, lum_lod).rgb; - float luminance = lum.r; - luminance = luminance*lum_quad.y+lum_quad.z; + float z = texture2DRect(depthMap, pos_screen.xy).a; + z = z*2.0-1.0; + vec4 ndc = vec4(0.0, 0.0, z, 1.0); + vec4 p = inv_proj*ndc; + return p.z/p.w; +} - vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); +float calc_cof(float depth) +{ + float sc = abs(depth-focal_distance)/-depth*blur_constant; + + sc /= magnification; + + // tan_pixel_angle = pixel_length/-depth; + float pixel_length = tan_pixel_angle*-focal_distance; + + sc = sc/pixel_length; + sc *= 1.414; + + return sc; +} - float ambocc = texture2DRect(lightMap, vary_fragcoord.xy).g; - - vec3 gi_col = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; - gi_col = gi_col*gi_col*gi_quad.x + gi_col*gi_quad.y+gi_quad.z*ambocc*ambient.rgb; - gi_col *= diff; +void dofSampleNear(inout vec4 diff, inout float w, float cur_sc, vec2 tc) +{ + float d = getDepth(tc); - vec4 sun_col = texture2DRect(sunLightMap, vary_fragcoord.xy); + float sc = calc_cof(d); - vec3 local_col = texture2DRect(localLightMap, vary_fragcoord.xy).rgb; + float wg = 0.25; + vec4 s = texture2DRect(diffuseRect, tc); + // de-weight dull areas to make highlights 'pop' + wg += s.r+s.g+s.b; + + diff += wg*s; + + w += wg; +} + +void dofSample(inout vec4 diff, inout float w, float min_sc, float cur_depth, vec2 tc) +{ + float d = getDepth(tc); + + float sc = calc_cof(d); + + if (sc > min_sc //sampled pixel is more "out of focus" than current sample radius + || d < cur_depth) //sampled pixel is further away than current pixel + { + float wg = 0.25; - sun_col *= 1.0/min(luminance, 1.0); - gi_col *= 1.0/luminance; + vec4 s = texture2DRect(diffuseRect, tc); + // de-weight dull areas to make highlights 'pop' + wg += s.r+s.g+s.b; + + diff += wg*s; + + w += wg; + } +} + + +void main() +{ + vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz; + norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm - vec3 col = sun_col.rgb+gi_col+local_col; + vec2 tc = vary_fragcoord.xy; - gl_FragColor.rgb = col.rgb; - col.rgb = max(col.rgb-vec3(1.0,1.0,1.0), vec3(0.0, 0.0, 0.0)); + float depth = getDepth(tc); - gl_FragColor.a = 0.0; // max(dot(col.rgb,col.rgb)*lum_quad.x, sun_col.a); + vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); - //gl_FragColor.rgb = vec3(lum_lod); + { + float w = 1.0; + + float sc = calc_cof(depth); + sc = min(abs(sc), 10.0); + + float fd = depth*0.5f; + + float PI = 3.14159265358979323846264; + + // sample quite uniformly spaced points within a circle, for a circular 'bokeh' + //if (depth < focal_distance) + { + while (sc > 0.5) + { + int its = int(max(1.0,(sc*3.7))); + for (int i=0; i<its; ++i) + { + float ang = sc+i*2*PI/its; // sc is added for rotary perturbance + float samp_x = sc*sin(ang); + float samp_y = sc*cos(ang); + // you could test sample coords against an interesting non-circular aperture shape here, if desired. + dofSample(diff, w, sc, depth, vary_fragcoord.xy + vec2(samp_x,samp_y)); + } + sc -= 1.0; + } + } + + diff /= w; + } + + vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res); + gl_FragColor = diff + bloom; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl new file mode 100644 index 0000000000..ab48d08bbb --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl @@ -0,0 +1,24 @@ +/** + * @file postDeferredF.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $/LicenseInfo$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2D bloomMap; + +uniform vec2 screen_res; +varying vec2 vary_fragcoord; + +void main() +{ + vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); + + vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res); + gl_FragColor = diff + bloom; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl index 0ec81dcb02..12983baa94 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec2 vary_fragcoord; uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl index e8e58f50e1..63b3c9f205 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2DRect depthMap; uniform sampler2DRect normalMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl b/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl index e5f6217644..ae57227fe5 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec2 vary_fragcoord; uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl index 378a3295ec..6674c4a5aa 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl index 666f909f01..db3bddc6be 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec4 post_pos; diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 5fbeceba81..29340c7e9f 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable @@ -268,14 +270,10 @@ void main() vec4 diffuse = texture2DRect(diffuseRect, tc); vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); - vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; - float scol = max(scol_ambocc.r, diffuse.a); - float ambocc = scol_ambocc.g; - - calcAtmospherics(pos.xyz, ambocc); + calcAtmospherics(pos.xyz, 1.0); vec3 col = atmosAmbient(vec3(0)); - col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a)); + col += atmosAffectDirectionalLight(max(min(da, 1.0), diffuse.a)); col *= diffuse.rgb; @@ -285,7 +283,7 @@ void main() // vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); float sa = dot(refnormpersp, vary_light.xyz); - vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).a; + vec3 dumbshiny = vary_SunlitColor*texture2D(lightFunc, vec2(sa, spec.a)).a; /* // screen-space cheap fakey reflection map diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl index 9d187b46e2..8f0bcca76b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl index d4d686bbb7..00093836a2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 //class 1, no shadow, no SSAO, should never be called diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl index cdbed4b791..cd91351ad4 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable @@ -13,8 +15,6 @@ uniform sampler2DRect depthMap; uniform sampler2DRect normalMap; uniform sampler2D noiseMap; -uniform sampler2D lightFunc; - // Inputs uniform mat4 shadow_matrix[6]; @@ -51,57 +51,49 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm) { float ret = 1.0; - float dist = dot(pos.xyz,pos.xyz); - - if (dist < 64.0*64.0) - { - vec2 kern[8]; - // exponentially (^2) distant occlusion samples spread around origin - kern[0] = vec2(-1.0, 0.0) * 0.125*0.125; - kern[1] = vec2(1.0, 0.0) * 0.250*0.250; - kern[2] = vec2(0.0, 1.0) * 0.375*0.375; - kern[3] = vec2(0.0, -1.0) * 0.500*0.500; - kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625; - kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750; - kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875; - kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000; + vec2 kern[8]; + // exponentially (^2) distant occlusion samples spread around origin + kern[0] = vec2(-1.0, 0.0) * 0.125*0.125; + kern[1] = vec2(1.0, 0.0) * 0.250*0.250; + kern[2] = vec2(0.0, 1.0) * 0.375*0.375; + kern[3] = vec2(0.0, -1.0) * 0.500*0.500; + kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625; + kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750; + kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875; + kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000; - vec2 pos_screen = vary_fragcoord.xy; - vec3 pos_world = pos.xyz; - vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy; + vec2 pos_screen = vary_fragcoord.xy; + vec3 pos_world = pos.xyz; + vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy; - float angle_hidden = 0.0; - int points = 0; + float angle_hidden = 0.0; + int points = 0; - float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); + float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); - // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?) - for (int i = 0; i < 8; i++) - { - vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect); - vec3 samppos_world = getPosition(samppos_screen).xyz; + // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations unrolling?) + for (int i = 0; i < 8; i++) + { + vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect); + vec3 samppos_world = getPosition(samppos_screen).xyz; - vec3 diff = pos_world - samppos_world; - float dist2 = dot(diff, diff); + vec3 diff = pos_world - samppos_world; + float dist2 = dot(diff, diff); - // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area - // --> solid angle shrinking by the square of distance - //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2 - //(k should vary inversely with # of samples, but this is taken care of later) + // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area + // --> solid angle shrinking by the square of distance + //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2 + //(k should vary inversely with # of samples, but this is taken care of later) - //if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) // -0.05*norm to shift sample point back slightly for flat surfaces - // angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional. max of 1.0 (= ssao_factor_inv * ssao_factor) - angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); + angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); - // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion" - points = points + int(diff.z > -1.0); - } + // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion" + points = points + int(diff.z > -1.0); + } - angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); + angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); - ret = (1.0 - (float(points != 0) * angle_hidden)); - ret += max((dist-32.0*32.0)/(32.0*32.0), 0.0); - } + ret = (1.0 - (float(points != 0) * angle_hidden)); return min(ret, 1.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl index 9d092d9cea..9beb513ad8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec4 vary_light; varying vec2 vary_fragcoord; diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl index 9ba508a30c..0edae47918 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D detail_0; uniform sampler2D detail_1; diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl index 789e53b789..a6163063be 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec3 vary_normal; diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl index 1c1725a95c..c54d9a1e3e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl index 45832e350f..29689ecbaf 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec3 vary_normal; diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index ea531de24a..e76f598d09 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl index e002d75ebe..649e392630 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl index 2d40a19fa6..f2023fa5ea 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl index fe45898ed2..0ca0608b45 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl @@ -5,6 +5,7 @@ * $/LicenseInfo$ */ +#version 120 void main() { diff --git a/indra/newview/app_settings/shaders/class1/effects/glowF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowF.glsl index 5b4e8b3ecc..65fc2e9f99 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowF.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; uniform float glowStrength; diff --git a/indra/newview/app_settings/shaders/class1/effects/glowV.glsl b/indra/newview/app_settings/shaders/class1/effects/glowV.glsl index 97696e4719..0bd44cec90 100644 --- a/indra/newview/app_settings/shaders/class1/effects/glowV.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/glowV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform vec2 glowDelta; diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl index 3a852239fb..ac00f15b35 100644 --- a/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D detail0; uniform sampler2D detail1; diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl index 0d781fd849..1e19ee7699 100644 --- a/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl index 99c340d91a..34f78565a5 100644 --- a/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 // this class1 shader is just a copy of terrainF diff --git a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl index 66458ec66d..0dfac84a6e 100644 --- a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; uniform sampler2D bumpMap; diff --git a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl index 5f1fbee1df..4e9c09b1ea 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 vec3 scaleSoftClip(vec3 inColor); vec3 atmosTransport(vec3 inColor); diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl index e5eb25f3fa..a34cf23790 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 vec4 applyWaterFog(vec4 color) { diff --git a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl index 608a7a5807..161c794c68 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl index 5ac9e96601..6f821f893d 100644 --- a/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl index c5f69c4ad4..d1c98bf70c 100644 --- a/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 void main() { diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl index ad128dae8d..9c59e8c3ad 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl index 1742b9fc1c..1fee99c446 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl index 68b6603b4a..fb5da21c72 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl new file mode 100644 index 0000000000..1bdaccf9b8 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl @@ -0,0 +1,17 @@ +/** + * @file lightFullbrightShinyWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + + +#version 120 + +uniform sampler2D diffuseMap; +uniform samplerCube environmentMap; + +void fullbright_shiny_lighting_water() +{ + gl_FragColor = texture2D(diffuseMap, gl_TexCoord[0].xy); +} diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl index 693ed289f2..2e94d3bbf1 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl @@ -5,6 +5,8 @@ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl index b888e70325..714f9a2551 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFuncSpecularV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 float calcDirectionalLight(vec3 n, vec3 l) { diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl index 4b6d95e177..65b45f8081 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 float calcDirectionalLight(vec3 n, vec3 l) diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl index b127b1f8ea..7f65ea76f7 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl index 05ad3256af..8f13e6dc04 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl index b1a7cb46ff..56f31f6a79 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightSpecularV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 float calcDirectionalLight(vec3 n, vec3 l); diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl index f6afa6a3ae..64d549ff52 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 float calcDirectionalLight(vec3 n, vec3 l); diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl index e5e6ddc2d8..c5d084c132 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl index a0649aea88..732d246471 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/sumLightsSpecularV.glsl @@ -4,6 +4,9 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 + float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da); vec3 atmosAmbient(vec3 light); vec3 atmosAffectDirectionalLight(float lightIntensity); diff --git a/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl index c7d40d853f..73e1a1ec26 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 float calcDirectionalLight(vec3 n, vec3 l); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl index 9da4c2c92b..afc3dc89bf 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 void fullbright_lighting(); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl index 1c8a9a1a30..3dc4294f67 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 void fullbright_shiny_lighting(); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl new file mode 100644 index 0000000000..f0baeeeee5 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinySkinnedV.glsl @@ -0,0 +1,39 @@ +/** + * @file shinySimpleSkinnedV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +void calcAtmospherics(vec3 inPositionEye); +mat4 getObjectSkinnedTransform(); + +attribute vec4 object_weight; + +void main() +{ + mat4 mat = getObjectSkinnedTransform(); + + mat = gl_ModelViewMatrix * mat; + vec3 pos = (mat*gl_Vertex).xyz; + + vec4 norm = gl_Vertex; + norm.xyz += gl_Normal.xyz; + norm.xyz = (mat*norm).xyz; + norm.xyz = normalize(norm.xyz-pos.xyz); + + vec3 ref = reflect(pos.xyz, -norm.xyz); + + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + gl_TexCoord[1] = gl_TextureMatrix[1]*vec4(ref,1.0); + + calcAtmospherics(pos.xyz); + + gl_FrontColor = gl_Color; + + gl_Position = gl_ProjectionMatrix*vec4(pos, 1.0); + + gl_FogFragCoord = pos.z; +} diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl index 032def63b3..02367b9439 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl new file mode 100644 index 0000000000..5daf66fb31 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl @@ -0,0 +1,15 @@ +/** + * @file fullbrightShinyWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +void fullbright_shiny_lighting_water(); + +void main() +{ + fullbright_shiny_lighting_water(); +} diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl new file mode 100644 index 0000000000..02ff3cc2a9 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightSkinnedV.glsl @@ -0,0 +1,37 @@ +/** + * @file fullbrightSkinnedV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +void calcAtmospherics(vec3 inPositionEye); +mat4 getObjectSkinnedTransform(); + +attribute vec4 object_weight; + +void main() +{ + //transform vertex + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + + mat4 mat = getObjectSkinnedTransform(); + + mat = gl_ModelViewMatrix * mat; + vec3 pos = (mat*gl_Vertex).xyz; + + vec4 norm = gl_Vertex; + norm.xyz += gl_Normal.xyz; + norm.xyz = (mat*norm).xyz; + norm.xyz = normalize(norm.xyz-pos.xyz); + + calcAtmospherics(pos.xyz); + + gl_FrontColor = gl_Color; + + gl_Position = gl_ProjectionMatrix*vec4(pos, 1.0); + + gl_FogFragCoord = pos.z; +} diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl index 914e417ca0..38e07dbd80 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl index df76e9e1eb..afaac4f69c 100644 --- a/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 void fullbright_lighting_water(); diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl index 6bcd44506d..2cf7a69baa 100644 --- a/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 void shiny_lighting(); diff --git a/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl new file mode 100644 index 0000000000..4146646058 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/objects/shinySimpleSkinnedV.glsl @@ -0,0 +1,39 @@ +/** + * @file shinySimpleSkinnedV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); +void calcAtmospherics(vec3 inPositionEye); +mat4 getObjectSkinnedTransform(); + +attribute vec4 object_weight; + +void main() +{ + mat4 mat = getObjectSkinnedTransform(); + + mat = gl_ModelViewMatrix * mat; + vec3 pos = (mat*gl_Vertex).xyz; + + vec4 norm = gl_Vertex; + norm.xyz += gl_Normal.xyz; + norm.xyz = (mat*norm).xyz; + norm.xyz = normalize(norm.xyz-pos.xyz); + + vec3 ref = reflect(pos.xyz, -norm.xyz); + + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + gl_TexCoord[1] = gl_TextureMatrix[1]*vec4(ref,1.0); + + calcAtmospherics(pos.xyz); + + vec4 color = calcLighting(pos.xyz, norm.xyz, gl_Color, vec4(0.)); + gl_FrontColor = color; + + gl_Position = gl_ProjectionMatrix*vec4(pos, 1.0); +} diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl index 074892c98e..6ea83b721d 100644 --- a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 void calcAtmospherics(vec3 inPositionEye); @@ -12,7 +14,7 @@ uniform vec4 origin; void main() { //transform vertex - gl_Position = ftransform(); //gl_ModelViewProjectionMatrix * gl_Vertex; + gl_Position = ftransform(); vec4 pos = (gl_ModelViewMatrix * gl_Vertex); vec3 norm = normalize(gl_NormalMatrix * gl_Normal); diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl index 54b30573e7..e3babe2210 100644 --- a/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 void shiny_lighting_water(); diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl index 61c2ce4272..d449d37c0c 100644 --- a/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/simpleF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 void default_lighting(); diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl new file mode 100644 index 0000000000..be38a14d52 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/objects/simpleSkinnedV.glsl @@ -0,0 +1,39 @@ +/** + * @file simpleSkinnedV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); +void calcAtmospherics(vec3 inPositionEye); +mat4 getObjectSkinnedTransform(); + +attribute vec4 object_weight; + +void main() +{ + //transform vertex + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + + mat4 mat = getObjectSkinnedTransform(); + + mat = gl_ModelViewMatrix * mat; + vec3 pos = (mat*gl_Vertex).xyz; + + vec4 norm = gl_Vertex; + norm.xyz += gl_Normal.xyz; + norm.xyz = (mat*norm).xyz; + norm.xyz = normalize(norm.xyz-pos.xyz); + + calcAtmospherics(pos.xyz); + + vec4 color = calcLighting(pos.xyz, norm.xyz, gl_Color, vec4(0.)); + gl_FrontColor = color; + + gl_Position = gl_ProjectionMatrix*vec4(pos, 1.0); + + gl_FogFragCoord = pos.z; +} diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl index ced1a4be01..0d8e14e2e3 100644 --- a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl index 5e44212aed..68bd81e029 100644 --- a/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/simpleWaterF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 void default_lighting_water(); diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl index 7a05b8c8c6..f337bde329 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 vec3 atmosLighting(vec3 light) { diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl index 874f2b4843..4b402a7028 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 vec3 atmosAmbient(vec3 light) { diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl index 7ead9ddf26..20948b1e46 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 void setPositionEye(vec3 v); diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl index f6032f8d41..8a2c2a7186 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec3 vary_PositionEye; diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl index a696ddf607..a1dd4ed5fe 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec3 vary_PositionEye; diff --git a/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl b/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl index 4a1899798a..7aed1fd3b5 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform vec4 gamma; diff --git a/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl index b78b90545e..6780dc4d3e 100644 --- a/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl +++ b/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 vec3 atmosTransport(vec3 light) { diff --git a/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl b/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl index 47300f0b39..172c2ca078 100644 --- a/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl +++ b/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor, vec4 baseCol); void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index e2d7cd94da..6dfc1b952c 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable @@ -12,7 +14,6 @@ uniform sampler2DRectShadow shadowMap0; uniform sampler2DRectShadow shadowMap1; uniform sampler2DRectShadow shadowMap2; uniform sampler2DRectShadow shadowMap3; -uniform sampler2D noiseMap; uniform sampler2DRect depthMap; uniform mat4 shadow_matrix[6]; @@ -27,7 +28,7 @@ varying vec3 vary_ambient; varying vec3 vary_directional; varying vec3 vary_fragcoord; varying vec3 vary_position; -varying vec3 vary_light; +varying vec3 vary_pointlight_col; uniform float shadow_bias; @@ -68,8 +69,6 @@ void main() vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; frag *= screen_res; - vec3 samp_pos = getPosition(frag).xyz; - float shadow = 1.0; vec4 pos = vec4(vary_position, 1.0); @@ -106,16 +105,21 @@ void main() } } + vec4 diff= texture2D(diffuseMap, gl_TexCoord[0].xy); + vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, gl_Color.a); - vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * col; + vec4 color = diff * col; color.rgb = atmosLighting(color.rgb); color.rgb = scaleSoftClip(color.rgb); + color.rgb += diff.rgb * vary_pointlight_col.rgb; + //gl_FragColor = gl_Color; gl_FragColor = color; - //gl_FragColor = vec4(1,0,1,1)*shadow; + //gl_FragColor.r = 0.0; + //gl_FragColor = vec4(1,shadow,1,1); } diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl new file mode 100644 index 0000000000..d227346163 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaSkinnedV.glsl @@ -0,0 +1,110 @@ +/** + * @file alphaSkinnedV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); +void calcAtmospherics(vec3 inPositionEye); + +float calcDirectionalLight(vec3 n, vec3 l); +mat4 getObjectSkinnedTransform(); +vec3 atmosAmbient(vec3 light); +vec3 atmosAffectDirectionalLight(float lightIntensity); +vec3 scaleDownLight(vec3 light); +vec3 scaleUpLight(vec3 light); + +varying vec3 vary_ambient; +varying vec3 vary_directional; +varying vec3 vary_fragcoord; +varying vec3 vary_position; +varying vec3 vary_pointlight_col; + +uniform float near_clip; +uniform float shadow_offset; +uniform float shadow_bias; + +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +{ + //get light vector + vec3 lv = lp.xyz-v; + + //get distance + float d = length(lv); + + //normalize light vector + lv *= 1.0/d; + + //distance attenuation + float dist2 = d*d/(la*la); + float da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + + // spotlight coefficient. + float spot = max(dot(-ln, lv), is_pointlight); + da *= spot*spot; // GL_SPOT_EXPONENT=2 + + //angular attenuation + da *= calcDirectionalLight(n, lv); + + return da; +} + +void main() +{ + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + + mat4 mat = getObjectSkinnedTransform(); + + mat = gl_ModelViewMatrix * mat; + + vec3 pos = (mat*gl_Vertex).xyz; + + gl_Position = gl_ProjectionMatrix * vec4(pos, 1.0); + + vec4 n = gl_Vertex; + n.xyz += gl_Normal.xyz; + n.xyz = (mat*n).xyz; + n.xyz = normalize(n.xyz-pos.xyz); + + vec3 norm = n.xyz; + + float dp_directional_light = max(0.0, dot(norm, gl_LightSource[0].position.xyz)); + vary_position = pos.xyz + gl_LightSource[0].position.xyz * (1.0-dp_directional_light)*shadow_offset; + + calcAtmospherics(pos.xyz); + + //vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); + vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a); + + // Collect normal lights + col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].quadraticAttenuation, gl_LightSource[2].specular.a); + col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].quadraticAttenuation ,gl_LightSource[3].specular.a); + col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].quadraticAttenuation, gl_LightSource[4].specular.a); + col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].quadraticAttenuation, gl_LightSource[5].specular.a); + col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].quadraticAttenuation, gl_LightSource[6].specular.a); + col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].quadraticAttenuation, gl_LightSource[7].specular.a); + + vary_pointlight_col = col.rgb*gl_Color.rgb; + + col.rgb = vec3(0,0,0); + + // Add windlight lights + col.rgb = atmosAmbient(vec3(0.)); + + vary_ambient = col.rgb*gl_Color.rgb; + vary_directional.rgb = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); + + col.rgb = min(col.rgb*gl_Color.rgb, 1.0); + + gl_FrontColor = col; + + gl_FogFragCoord = pos.z; + + pos.xyz = (gl_ModelViewProjectionMatrix * gl_Vertex).xyz; + vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); + +} + diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl index 45f727951e..86f014df35 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl @@ -4,12 +4,13 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); void calcAtmospherics(vec3 inPositionEye); float calcDirectionalLight(vec3 n, vec3 l); -float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight); vec3 atmosAmbient(vec3 light); vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -20,12 +21,37 @@ varying vec3 vary_ambient; varying vec3 vary_directional; varying vec3 vary_fragcoord; varying vec3 vary_position; -varying vec3 vary_light; +varying vec3 vary_pointlight_col; uniform float near_clip; uniform float shadow_offset; uniform float shadow_bias; +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +{ + //get light vector + vec3 lv = lp.xyz-v; + + //get distance + float d = length(lv); + + //normalize light vector + lv *= 1.0/d; + + //distance attenuation + float dist2 = d*d/(la*la); + float da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + + // spotlight coefficient. + float spot = max(dot(-ln, lv), is_pointlight); + da *= spot*spot; // GL_SPOT_EXPONENT=2 + + //angular attenuation + da *= calcDirectionalLight(n, lv); + + return da; +} + void main() { //transform vertex @@ -44,25 +70,25 @@ void main() //vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a); - // Collect normal lights (need to be divided by two, as we later multiply by 2) - col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); - col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); - col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a); - col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a); - col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a); - col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a); - col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); - col.rgb = scaleDownLight(col.rgb); + // Collect normal lights + col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].quadraticAttenuation, gl_LightSource[2].specular.a); + col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].quadraticAttenuation ,gl_LightSource[3].specular.a); + col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].quadraticAttenuation, gl_LightSource[4].specular.a); + col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].quadraticAttenuation, gl_LightSource[5].specular.a); + col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].quadraticAttenuation, gl_LightSource[6].specular.a); + col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].quadraticAttenuation, gl_LightSource[7].specular.a); + vary_pointlight_col = col.rgb*gl_Color.rgb; + + col.rgb = vec3(0,0,0); + // Add windlight lights - col.rgb += atmosAmbient(vec3(0.)); - - vary_light = gl_LightSource[0].position.xyz; + col.rgb = atmosAmbient(vec3(0.)); vary_ambient = col.rgb*gl_Color.rgb; vary_directional.rgb = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); - col.rgb = min(col.rgb*gl_Color.rgb, 1.0); + col.rgb = col.rgb*gl_Color.rgb; gl_FrontColor = col; diff --git a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl deleted file mode 100644 index 5ecbbd2c4f..0000000000 --- a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @file avatarAlphaF.glsl - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * $/LicenseInfo$ - */ - -#extension GL_ARB_texture_rectangle : enable - -uniform sampler2D diffuseMap; -uniform sampler2DRectShadow shadowMap0; -uniform sampler2DRectShadow shadowMap1; -uniform sampler2DRectShadow shadowMap2; -uniform sampler2DRectShadow shadowMap3; -uniform sampler2D noiseMap; - -uniform mat4 shadow_matrix[6]; -uniform vec4 shadow_clip; -uniform vec2 screen_res; -uniform vec2 shadow_res; - -vec3 atmosLighting(vec3 light); -vec3 scaleSoftClip(vec3 light); - -varying vec3 vary_ambient; -varying vec3 vary_directional; -varying vec3 vary_position; -varying vec3 vary_normal; - -uniform float shadow_bias; - -float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) -{ - stc.xyz /= stc.w; - stc.z += shadow_bias; - - float cs = shadow2DRect(shadowMap, stc.xyz).x; - float shadow = cs; - - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(scl, -scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, scl, 0.0)).x, cs); - shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-scl, -scl, 0.0)).x, cs); - - return shadow/5.0; -} - -void main() -{ - float shadow = 1.0; - vec4 pos = vec4(vary_position, 1.0); - vec3 norm = normalize(vary_normal); - - //vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; - - vec4 spos = pos; - - if (spos.z > -shadow_clip.w) - { - vec4 lpos; - - if (spos.z < -shadow_clip.z) - { - lpos = shadow_matrix[3]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap3, lpos, 1.5); - shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); - } - else if (spos.z < -shadow_clip.y) - { - lpos = shadow_matrix[2]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap2, lpos, 1.5); - } - else if (spos.z < -shadow_clip.x) - { - lpos = shadow_matrix[1]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap1, lpos, 1.5); - } - else - { - lpos = shadow_matrix[0]*spos; - lpos.xy *= shadow_res; - shadow = pcfShadow(shadowMap0, lpos, 1.5); - } - } - - - vec4 col = vec4(vary_ambient + vary_directional*shadow, gl_Color.a); - vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * col; - - color.rgb = atmosLighting(color.rgb); - - color.rgb = scaleSoftClip(color.rgb); - - gl_FragColor = color; -} diff --git a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl index d7d1111ba8..495e86c8db 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); mat4 getSkinnedTransform(); @@ -20,12 +22,38 @@ vec3 scaleUpLight(vec3 light); varying vec3 vary_position; varying vec3 vary_ambient; varying vec3 vary_directional; -varying vec3 vary_normal; +varying vec3 vary_fragcoord; +varying vec3 vary_pointlight_col; uniform float near_clip; uniform float shadow_offset; uniform float shadow_bias; +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight) +{ + //get light vector + vec3 lv = lp.xyz-v; + + //get distance + float d = length(lv); + + //normalize light vector + lv *= 1.0/d; + + //distance attenuation + float dist2 = d*d/(la*la); + float da = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + + // spotlight coefficient. + float spot = max(dot(-ln, lv), is_pointlight); + da *= spot*spot; // GL_SPOT_EXPONENT=2 + + //angular attenuation + da *= calcDirectionalLight(n, lv); + + return da; +} + void main() { gl_TexCoord[0] = gl_MultiTexCoord0; @@ -48,7 +76,6 @@ void main() float dp_directional_light = max(0.0, dot(norm, gl_LightSource[0].position.xyz)); vary_position = pos.xyz + gl_LightSource[0].position.xyz * (1.0-dp_directional_light)*shadow_offset; - vary_normal = norm; calcAtmospherics(pos.xyz); @@ -56,18 +83,20 @@ void main() vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a); - // Collect normal lights (need to be divided by two, as we later multiply by 2) - col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); - col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); - col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a); - col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a); - col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a); - col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a); - col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); - col.rgb = scaleDownLight(col.rgb); + // Collect normal lights + col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].quadraticAttenuation, gl_LightSource[2].specular.a); + col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].quadraticAttenuation ,gl_LightSource[3].specular.a); + col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].quadraticAttenuation, gl_LightSource[4].specular.a); + col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].quadraticAttenuation, gl_LightSource[5].specular.a); + col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].quadraticAttenuation, gl_LightSource[6].specular.a); + col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].quadraticAttenuation, gl_LightSource[7].specular.a); + vary_pointlight_col = col.rgb*gl_Color.rgb; + + col.rgb = vec3(0,0,0); + // Add windlight lights - col.rgb += atmosAmbient(vec3(0.)); + col.rgb = atmosAmbient(vec3(0.)); vary_ambient = col.rgb*gl_Color.rgb; vary_directional = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); @@ -77,7 +106,7 @@ void main() gl_FrontColor = col; gl_FogFragCoord = pos.z; - + vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); } diff --git a/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl deleted file mode 100644 index 258a9b7c40..0000000000 --- a/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @file blurLightF.glsl - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * $/LicenseInfo$ - */ - -#extension GL_ARB_texture_rectangle : enable - -uniform sampler2DRect depthMap; -uniform sampler2DRect normalMap; -uniform sampler2DRect lightMap; - -uniform float dist_factor; -uniform float blur_size; -uniform vec2 delta; -uniform vec3 kern[4]; -uniform float kern_scale; - -varying vec2 vary_fragcoord; - -uniform mat4 inv_proj; -uniform vec2 screen_res; - -vec4 getPosition(vec2 pos_screen) -{ - float depth = texture2DRect(depthMap, pos_screen.xy).a; - vec2 sc = pos_screen.xy*2.0; - sc /= screen_res; - sc -= vec2(1.0,1.0); - vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); - vec4 pos = inv_proj * ndc; - pos /= pos.w; - pos.w = 1.0; - return pos; -} - -void main() -{ - vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz; - norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm - vec3 pos = getPosition(vary_fragcoord.xy).xyz; - vec4 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rgba; - - vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy); - - dlt /= max(-pos.z*dist_factor, 1.0); - - vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free' - vec4 col = defined_weight.xyxx * ccol; - - for (int i = 1; i < 4; i++) - { - vec2 tc = vary_fragcoord.xy + kern[i].z*dlt; - vec3 samppos = getPosition(tc).xyz; - float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane - if (d*d <= 0.003) - { - col += texture2DRect(lightMap, tc)*kern[i].xyxx; - defined_weight += kern[i].xy; - } - } - for (int i = 1; i < 4; i++) - { - vec2 tc = vary_fragcoord.xy - kern[i].z*dlt; - vec3 samppos = getPosition(tc).xyz; - float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane - if (d*d <= 0.003) - { - col += texture2DRect(lightMap, tc)*kern[i].xyxx; - defined_weight += kern[i].xy; - } - } - - - - col /= defined_weight.xyxx; - - gl_FragColor = col; -} - diff --git a/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl b/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl index ff32a15c54..3155f3f929 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl @@ -4,14 +4,14 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable uniform sampler2DRect depthMap; uniform sampler2DRect normalMap; -uniform float gi_dist_cutoff; - varying vec2 vary_fragcoord; uniform float depth_cutoff; diff --git a/indra/newview/app_settings/shaders/class2/deferred/edgeV.glsl b/indra/newview/app_settings/shaders/class2/deferred/edgeV.glsl index 74f2bd9818..b3413c301f 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/edgeV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/edgeV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec2 vary_fragcoord; uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl deleted file mode 100644 index 757e3e7aab..0000000000 --- a/indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl +++ /dev/null @@ -1,59 +0,0 @@ -/** - * @file postDeferredF.glsl - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * $/LicenseInfo$ - */ - -uniform sampler2DRect diffuseRect; -uniform sampler2DRect localLightMap; -uniform sampler2DRect sunLightMap; -uniform sampler2DRect giLightMap; -uniform sampler2D luminanceMap; -uniform sampler2DRect lightMap; - -uniform vec3 gi_lum_quad; -uniform vec3 sun_lum_quad; -uniform vec3 lum_quad; -uniform float lum_lod; -uniform vec4 ambient; - -uniform vec3 gi_quad; - -uniform vec2 screen_res; -varying vec2 vary_fragcoord; - -void main() -{ - vec2 tc = vary_fragcoord.xy; - vec3 lcol = texture2DLod(luminanceMap, tc/screen_res, lum_lod).rgb; - - float lum = sqrt(lcol.r)*lum_quad.x+lcol.r*lcol.r*lum_quad.y+lcol.r*lum_quad.z; - - vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); - - float ambocc = texture2DRect(lightMap, vary_fragcoord.xy).g; - - vec3 gi_col = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; - gi_col = gi_col*gi_col*gi_quad.x + gi_col*gi_quad.y+gi_quad.z*ambocc*ambient.rgb; - gi_col *= diff; - - vec4 sun_col = texture2DRect(sunLightMap, vary_fragcoord.xy); - - vec3 local_col = texture2DRect(localLightMap, vary_fragcoord.xy).rgb; - - - float sun_lum = 1.0-lum; - sun_lum = sun_lum*sun_lum*sun_lum_quad.x + sun_lum*sun_lum_quad.y+sun_lum_quad.z; - - float gi_lum = lum; - gi_lum = gi_lum*gi_lum*gi_lum_quad.x+gi_lum*gi_lum_quad.y+gi_lum_quad.z; - gi_col *= 1.0/gi_lum; - - vec3 col = sun_col.rgb*(1.0+max(sun_lum,0.0))+gi_col+local_col; - - gl_FragColor.rgb = col.rgb; - gl_FragColor.a = max(sun_lum*min(sun_col.r+sun_col.g+sun_col.b, 1.0), sun_col.a); - - //gl_FragColor.rgb = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; -} diff --git a/indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl b/indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl deleted file mode 100644 index 0ec81dcb02..0000000000 --- a/indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @file postDeferredV.glsl - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * $/LicenseInfo$ - */ - -varying vec2 vary_fragcoord; -uniform vec2 screen_res; - -void main() -{ - //transform vertex - gl_Position = ftransform(); - vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; -} diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index 1067be1e6e..0160e84278 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl index 9d187b46e2..8f0bcca76b 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index d0e242c2d4..50b9ef276e 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -4,7 +4,7 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ - + #version 120 #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl index f565d3bdb9..4369b3b34f 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable @@ -17,9 +19,6 @@ uniform sampler2DRectShadow shadowMap2; uniform sampler2DRectShadow shadowMap3; uniform sampler2DShadow shadowMap4; uniform sampler2DShadow shadowMap5; -uniform sampler2D noiseMap; - -uniform sampler2D lightFunc; // Inputs diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 4e33a1af45..847b36b1ac 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -4,6 +4,8 @@ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. * $License$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable @@ -19,8 +21,6 @@ uniform sampler2DShadow shadowMap4; uniform sampler2DShadow shadowMap5; uniform sampler2D noiseMap; -uniform sampler2D lightFunc; - // Inputs uniform mat4 shadow_matrix[6]; uniform vec4 shadow_clip; @@ -60,58 +60,50 @@ vec4 getPosition(vec2 pos_screen) float calcAmbientOcclusion(vec4 pos, vec3 norm) { float ret = 1.0; - - float dist = dot(pos.xyz,pos.xyz); - - if (dist < 64.0*64.0) - { - vec2 kern[8]; - // exponentially (^2) distant occlusion samples spread around origin - kern[0] = vec2(-1.0, 0.0) * 0.125*0.125; - kern[1] = vec2(1.0, 0.0) * 0.250*0.250; - kern[2] = vec2(0.0, 1.0) * 0.375*0.375; - kern[3] = vec2(0.0, -1.0) * 0.500*0.500; - kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625; - kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750; - kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875; - kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000; - vec2 pos_screen = vary_fragcoord.xy; - vec3 pos_world = pos.xyz; - vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy; + vec2 kern[8]; + // exponentially (^2) distant occlusion samples spread around origin + kern[0] = vec2(-1.0, 0.0) * 0.125*0.125; + kern[1] = vec2(1.0, 0.0) * 0.250*0.250; + kern[2] = vec2(0.0, 1.0) * 0.375*0.375; + kern[3] = vec2(0.0, -1.0) * 0.500*0.500; + kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625; + kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750; + kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875; + kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000; + + vec2 pos_screen = vary_fragcoord.xy; + vec3 pos_world = pos.xyz; + vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy; - float angle_hidden = 0.0; - int points = 0; + float angle_hidden = 0.0; + int points = 0; - float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); + float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); - // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?) - for (int i = 0; i < 8; i++) - { - vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect); - vec3 samppos_world = getPosition(samppos_screen).xyz; + // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?) + for (int i = 0; i < 8; i++) + { + vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect); + vec3 samppos_world = getPosition(samppos_screen).xyz; - vec3 diff = pos_world - samppos_world; - float dist2 = dot(diff, diff); + vec3 diff = pos_world - samppos_world; + float dist2 = dot(diff, diff); - // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area - // --> solid angle shrinking by the square of distance - //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2 - //(k should vary inversely with # of samples, but this is taken care of later) + // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area + // --> solid angle shrinking by the square of distance + //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2 + //(k should vary inversely with # of samples, but this is taken care of later) - //if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) // -0.05*norm to shift sample point back slightly for flat surfaces - // angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional. max of 1.0 (= ssao_factor_inv * ssao_factor) - angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); + angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); - // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion" - points = points + int(diff.z > -1.0); - } + // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion" + points = points + int(diff.z > -1.0); + } - angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); + angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); - ret = (1.0 - (float(points != 0) * angle_hidden)); - ret += max((dist-32.0*32.0)/(32.0*32.0), 0.0); - } + ret = (1.0 - (float(points != 0) * angle_hidden)); return min(ret, 1.0); } diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl index 9d092d9cea..9beb513ad8 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec4 vary_light; varying vec2 vary_fragcoord; diff --git a/indra/newview/app_settings/shaders/class2/effects/blurF.glsl b/indra/newview/app_settings/shaders/class2/effects/blurF.glsl index 4173709298..a4ad0bfa15 100644 --- a/indra/newview/app_settings/shaders/class2/effects/blurF.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/blurF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2DRect RenderTexture; uniform float bloomStrength; diff --git a/indra/newview/app_settings/shaders/class2/effects/blurV.glsl b/indra/newview/app_settings/shaders/class2/effects/blurV.glsl index f66609527d..d471a6c5e5 100644 --- a/indra/newview/app_settings/shaders/class2/effects/blurV.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/blurV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform vec2 texelSize; uniform vec2 blurDirection; diff --git a/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl b/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl index df41dae757..66880b958e 100644 --- a/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/colorFilterF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2DRect RenderTexture; uniform float brightness; diff --git a/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl b/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl index e836caf93f..c35c500d62 100644 --- a/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/drawQuadV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 void main(void) { diff --git a/indra/newview/app_settings/shaders/class2/effects/extractF.glsl b/indra/newview/app_settings/shaders/class2/effects/extractF.glsl index 06d5fc9797..e77baa5bee 100644 --- a/indra/newview/app_settings/shaders/class2/effects/extractF.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/extractF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2DRect RenderTexture; uniform float extractLow; diff --git a/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl b/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl index 0a2767ad02..8e0eec6f5e 100644 --- a/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/nightVisionF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2DRect RenderTexture; uniform sampler2D NoiseTexture; diff --git a/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl b/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl index 29ad9a995b..98a50e22fc 100644 --- a/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl +++ b/indra/newview/app_settings/shaders/class2/effects/simpleF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2DRect RenderTexture; diff --git a/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl b/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl index 32259acf1b..bbb8951f3a 100644 --- a/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/terrainF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D detail_0; uniform sampler2D detail_1; diff --git a/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl b/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl index 2234f0bd89..84906c16bf 100644 --- a/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/terrainV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 void calcAtmospherics(vec3 inPositionEye); diff --git a/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl b/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl index 1650912fc8..7590c542ef 100644 --- a/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/terrainWaterF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D detail_0; uniform sampler2D detail_1; diff --git a/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl index 9e936a3790..900f1a6cb8 100644 --- a/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/underWaterF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; uniform sampler2D bumpMap; diff --git a/indra/newview/app_settings/shaders/class2/environment/waterF.glsl b/indra/newview/app_settings/shaders/class2/environment/waterF.glsl index e477107c0b..f4f6b6e90f 100644 --- a/indra/newview/app_settings/shaders/class2/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/waterF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 vec3 scaleSoftClip(vec3 inColor); vec3 atmosTransport(vec3 inColor); diff --git a/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl index 7bcdcf5d5b..9f3328cbf0 100644 --- a/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl +++ b/indra/newview/app_settings/shaders/class2/environment/waterFogF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform vec4 lightnorm; uniform vec4 waterPlane; diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl index 269d11a085..342bc2ab66 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl index 9ffe3c6f4a..dad18b5883 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl index b7181dec3a..73ff81e03a 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; uniform samplerCube environmentMap; diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl new file mode 100644 index 0000000000..9b4b584369 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightShinyWaterF.glsl @@ -0,0 +1,31 @@ +/** + * @file lightFullbrightShinyWaterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +uniform sampler2D diffuseMap; +uniform samplerCube environmentMap; + +vec3 fullbrightShinyAtmosTransport(vec3 light); +vec3 fullbrightScaleSoftClip(vec3 light); +vec4 applyWaterFog(vec4 color); + +void fullbright_shiny_lighting_water() +{ + vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy); + color.rgb *= gl_Color.rgb; + + vec3 envColor = textureCube(environmentMap, gl_TexCoord[1].xyz).rgb; + color.rgb = mix(color.rgb, envColor.rgb, gl_Color.a); + + color.rgb = fullbrightShinyAtmosTransport(color.rgb); + color.rgb = fullbrightScaleSoftClip(color.rgb); + color.a = max(color.a, gl_Color.a); + + gl_FragColor = applyWaterFog(color); +} + diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl index ee38790cc4..3d46c8d874 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightFullbrightWaterF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl index b96b5d75bc..ebe21320b4 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightShinyF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; uniform samplerCube environmentMap; diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl index 0f5b2d6fcf..7f48e2cf1d 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightShinyWaterF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl index 6400b45d9e..ad1dc4da77 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightSpecularV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 // All lights, no specular highlights diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl index 89ef510d7c..a0f6e019ef 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 // All lights, no specular highlights diff --git a/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl b/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl index 016258bd18..97eba92d7b 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/lightWaterF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl index 8cfeeb1cf9..fde32ed035 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da); vec3 calcPointLightSpecular(inout vec4 specular, vec3 view, vec3 v, vec3 n, vec3 l, float r, float pw, vec3 lightCol); diff --git a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl index a512b9d6fb..8fe49e3be0 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 float calcDirectionalLight(vec3 n, vec3 l); float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight); diff --git a/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl b/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl index c428bbb28e..4cebb06df0 100644 --- a/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl +++ b/indra/newview/app_settings/shaders/class2/objects/shinyV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl index 8baff24dbd..77d15fba9a 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 ////////////////////////////////////////////////////////// // The fragment shader for the terrain atmospherics diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl index 6883edc1f1..8c5b864cbe 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 // Output variables vec3 getSunlitColor(); diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl index f5c513bbdd..8d365c15ca 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 // varying param funcs void setSunlitColor(vec3 v); diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl index d0b60e918e..cf9ef30632 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec3 vary_PositionEye; diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl index 4b4baf50d0..398f1556a0 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec3 vary_PositionEye; diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl index 2a559440fc..13207997b2 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 ///////////////////////////////////////////////////////////////////////// // The fragment shader for the sky diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl index 865c0e9da8..267ef36d4d 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 ////////////////////////////////////////////////////////////////////////// // The vertex shader for creating the atmospheric sky diff --git a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl index ce4bd2358f..a658edd21f 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform vec4 gamma; diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl index b69a88a45f..77ca4868a6 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 ///////////////////////////////////////////////////////////////////////// // The fragment shader for the sky diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl index 397db01378..03bca8f27e 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 // SKY //////////////////////////////////////////////////////////////////////// // The vertex shader for creating the atmospheric sky diff --git a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl index b30313bdc8..7f1ad4d5b4 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 ////////////////////////////////////////////////////////// // The fragment shader for the terrain atmospherics diff --git a/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl b/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl index c85ba0c734..a003e2a1f1 100644 --- a/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl +++ b/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); mat4 getSkinnedTransform(); diff --git a/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl b/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl index d26b244fa3..fc370ef367 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2DRect giLightMap; diff --git a/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl b/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl index e5f6217644..ae57227fe5 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec2 vary_fragcoord; uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class3/deferred/giF.glsl b/indra/newview/app_settings/shaders/class3/deferred/giF.glsl index 735150a78c..951e3e97ae 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/giF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/giF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class3/deferred/giFinalF.glsl b/indra/newview/app_settings/shaders/class3/deferred/giFinalF.glsl index e0f4a3e4f5..b2f8b2c633 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/giFinalF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/giFinalF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class3/deferred/giFinalV.glsl b/indra/newview/app_settings/shaders/class3/deferred/giFinalV.glsl index fbf2c17370..19c4e07b8b 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/giFinalV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/giFinalV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec2 vary_fragcoord; uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class3/deferred/giV.glsl b/indra/newview/app_settings/shaders/class3/deferred/giV.glsl index 543527612e..8dc1410ea5 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/giV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/giV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec2 vary_fragcoord; diff --git a/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl index d9483bc6e4..5f3bf68b24 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl b/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl index 6368def830..a24eda35dc 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec2 vary_fragcoord; diff --git a/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl index 51ab579e3c..ab99a88971 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl @@ -4,7 +4,9 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ - + +#version 120 + #extension GL_ARB_texture_rectangle : enable uniform sampler2DRect diffuseRect; diff --git a/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl b/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl index 0ec81dcb02..12983baa94 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec2 vary_fragcoord; uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl b/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl index 24fa07f251..f037754708 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl b/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl index e5f6217644..ae57227fe5 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 varying vec2 vary_fragcoord; uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index a2db247331..ce32f66000 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 #extension GL_ARB_texture_rectangle : enable diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl index 9d187b46e2..8f0bcca76b 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform vec2 screen_res; diff --git a/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl index 1c1725a95c..c54d9a1e3e 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 uniform sampler2D diffuseMap; diff --git a/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl index 2b44aedd5a..04533fdce1 100644 --- a/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl +++ b/indra/newview/app_settings/shaders/class3/lighting/sumLightsSpecularV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 float calcDirectionalLightSpecular(inout vec4 specular, vec3 view, vec3 n, vec3 l, vec3 lightCol, float da); vec3 calcPointLightSpecular(inout vec4 specular, vec3 view, vec3 v, vec3 n, vec3 l, float r, float pw, vec3 lightCol); diff --git a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl index 329b0c4305..73bc18b866 100644 --- a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl +++ b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl @@ -4,6 +4,8 @@ * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * $/LicenseInfo$ */ + +#version 120 float calcDirectionalLight(vec3 n, vec3 l); float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight); diff --git a/indra/newview/app_settings/ultra_graphics.xml b/indra/newview/app_settings/ultra_graphics.xml index e1f3ca5769..71459e5470 100644 --- a/indra/newview/app_settings/ultra_graphics.xml +++ b/indra/newview/app_settings/ultra_graphics.xml @@ -4,15 +4,15 @@ <RenderAvatarCloth value="TRUE"/> <!--Default for now--> <RenderAvatarLODFactor value="1.0"/> - <!--Default for now--> - <RenderAvatarPhysicsLODFactor value="1.0"/> + <!--Default for now--> + <RenderAvatarPhysicsLODFactor value="1.0"/> <!--NO SHADERS--> <RenderAvatarVP value="TRUE"/> <!--Short Range--> <RenderFarClip value="256"/> <!--Default for now--> <RenderFlexTimeFactor value="1"/> - <!--256... but they don't use this--> + <!--256... but they do not use this--> <RenderGlowResolutionPow value="9"/> <!--Low number--> <RenderMaxPartCount value="4096"/> @@ -26,8 +26,6 @@ <RenderTerrainLODFactor value="2.0"/> <!--Default for now--> <RenderTreeLODFactor value="1.0"/> - <!--Default for now--> - <RenderUseFBO value="1"/> <!--Try Impostors--> <RenderUseImpostors value="TRUE"/> <!--Default for now--> @@ -36,11 +34,10 @@ <VertexShaderEnable value="TRUE"/> <!--NO SHADERS--> <WindLightUseAtmosShaders value="TRUE"/> - <!--Deferred Shading--> - <RenderDeferred value="TRUE"/> - <!--SSAO Enabled--> - <RenderDeferredSSAO value="TRUE"/> - <!--Full Shadows--> - <RenderShadowDetail value="2"/> - + <!--Deferred Shading--> + <RenderDeferred value="TRUE"/> + <!--SSAO Enabled--> + <RenderDeferredSSAO value="TRUE"/> + <!--Full Shadows--> + <RenderShadowDetail value="2"/> </settings> diff --git a/indra/newview/app_settings/windlight/postprocesseffects.xml b/indra/newview/app_settings/windlight/postprocesseffects.xml index 4645215a47..60fbfd3483 100644 --- a/indra/newview/app_settings/windlight/postprocesseffects.xml +++ b/indra/newview/app_settings/windlight/postprocesseffects.xml @@ -1,2 +1 @@ <llsd><map><key>Asi Weird</key><map><key>bloom_strength</key><real>4.5799999237060547</real><key>bloom_width</key><real>12.539999961853027</real><key>brightness</key><real>0.89999997615814209</real><key>brightness_multiplier</key><real>3</real><key>contrast</key><real>0.22999998927116394</real><key>contrast_base</key><array><real>1</real><real>1</real><real>1</real><real>0.5</real></array><key>enable_bloom</key><integer>1</integer><key>enable_color_filter</key><integer>1</integer><key>enable_night_vision</key><boolean>0</boolean><key>extract_high</key><real>1</real><key>extract_low</key><real>0.47999998927116394</real><key>noise_size</key><real>25</real><key>noise_strength</key><real>0.40000000000000002</real><key>saturation</key><real>-1</real></map><key>NegativeSaturation</key><map><key>bloom_strength</key><real>1.5</real><key>bloom_width</key><real>2.25</real><key>brightness</key><real>1</real><key>brightness_multiplier</key><real>3</real><key>contrast</key><real>1</real><key>contrast_base</key><array><real>1</real><real>1</real><real>1</real><real>0.5</real></array><key>enable_bloom</key><boolean>0</boolean><key>enable_color_filter</key><integer>1</integer><key>enable_night_vision</key><boolean>0</boolean><key>extract_high</key><real>1</real><key>extract_low</key><real>0.94999999999999996</real><key>noise_size</key><real>25</real><key>noise_strength</key><real>0.40000000000000002</real><key>saturation</key><real>-1</real></map><key>NightVision</key><map><key>bloom_strength</key><real>1.5</real><key>bloom_width</key><real>2.25</real><key>brightness</key><real>1</real><key>brightness_multiplier</key><real>3</real><key>contrast</key><real>1</real><key>contrast_base</key><array><real>1</real><real>1</real><real>1</real><real>0.5</real></array><key>enable_bloom</key><boolean>0</boolean><key>enable_color_filter</key><boolean>0</boolean><key>enable_night_vision</key><integer>1</integer><key>extract_high</key><real>1</real><key>extract_low</key><real>0.94999999999999996</real><key>noise_size</key><real>25</real><key>noise_strength</key><real>0.40000000000000002</real><key>saturation</key><real>1</real></map><key>WGhost</key><map><key>bloom_strength</key><real>2.0399999618530273</real><key>bloom_width</key><real>2.25</real><key>brightness</key><real>1</real><key>brightness_multiplier</key><real>3</real><key>contrast</key><real>1</real><key>contrast_base</key><array><real>1</real><real>1</real><real>1</real><real>0.5</real></array><key>enable_bloom</key><integer>1</integer><key>enable_color_filter</key><boolean>0</boolean><key>enable_night_vision</key><boolean>0</boolean><key>extract_high</key><real>1</real><key>extract_low</key><real>0.22999998927116394</real><key>noise_size</key><real>25</real><key>noise_strength</key><real>0.40000000000000002</real><key>saturation</key><real>1</real></map><key>default</key><map><key>bloom_strength</key><real>1.5</real><key>bloom_width</key><real>2.25</real><key>brightness</key><real>1</real><key>brightness_multiplier</key><real>3</real><key>contrast</key><real>1</real><key>contrast_base</key><array><real>1</real><real>1</real><real>1</real><real>0.5</real></array><key>enable_bloom</key><boolean>0</boolean><key>enable_color_filter</key><boolean>0</boolean><key>enable_night_vision</key><boolean>0</boolean><key>extract_high</key><real>1</real><key>extract_low</key><real>0.94999999999999996</real><key>noise_size</key><real>25</real><key>noise_strength</key><real>0.40000000000000002</real><key>saturation</key><real>1</real></map></map></llsd> -><map><key>bloom_strength</key><real>1.5</real><key>bloom_width</key><real>2.25</real><key>brightness</key><real>1</real><key>brightness_multiplier</key><real>3</real><key>contrast</key><real>1</real><key>contrast_base</key><array><real>1</real><real>1</real><real>1</real><real>0.5</real></array><key>enable_bloom</key><boolean>0</boolean><key>enable_color_filter</key><boolean>0</boolean><key>enable_night_vision</key><boolean>0</boolean><key>extract_high</key><real>1</real><key>extract_low</key><real>0.94999999999999996</real><key>noise_size</key><real>25</real><key>noise_strength</key><real>0.40000000000000002</real><key>saturation</key><real>1</real></map></map></llsd> diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index af2d951bf7..9cc6893b15 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 25 +version 27 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table @@ -40,6 +40,7 @@ RenderGround 1 1 RenderMaxPartCount 1 8192 RenderNightBrightness 1 1.0 RenderObjectBump 1 1 +RenderLocalLights 1 1 RenderReflectionDetail 1 4 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 @@ -57,13 +58,11 @@ Disregard128DefaultDrawDistance 1 1 Disregard96DefaultDrawDistance 1 1 RenderTextureMemoryMultiple 1 1.0 RenderShaderLightingMaxLevel 1 3 -SkyUseClassicClouds 1 1 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 +RenderShadowDetail 1 2 WatchdogDisabled 1 1 RenderUseStreamVBO 1 1 -RenderUseFBO 1 1 // // Low Graphics Settings @@ -80,6 +79,7 @@ RenderFlexTimeFactor 1 0 RenderGlowResolutionPow 1 8 RenderMaxPartCount 1 0 RenderObjectBump 1 0 +RenderLocalLights 1 0 RenderReflectionDetail 1 0 RenderTerrainDetail 1 0 RenderTerrainLODFactor 1 1 @@ -90,11 +90,9 @@ RenderVolumeLODFactor 1 0.5 VertexShaderEnable 1 0 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -SkyUseClassicClouds 1 0 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 -RenderUseFBO 1 0 // // Mid Graphics Settings @@ -110,6 +108,7 @@ RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 8 RenderMaxPartCount 1 2048 RenderObjectBump 1 1 +RenderLocalLights 1 1 RenderReflectionDetail 1 0 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 1.0 @@ -123,7 +122,6 @@ WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 -RenderUseFBO 1 0 // // High Graphics Settings (purty) @@ -139,6 +137,7 @@ RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 RenderMaxPartCount 1 4096 RenderObjectBump 1 1 +RenderLocalLights 1 1 RenderReflectionDetail 1 0 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 @@ -152,7 +151,6 @@ WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 -RenderUseFBO 1 0 // // Ultra graphics (REALLY PURTY!) @@ -167,6 +165,7 @@ RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 RenderMaxPartCount 1 8192 RenderObjectBump 1 1 +RenderLocalLights 1 1 RenderReflectionDetail 1 4 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 @@ -177,10 +176,9 @@ RenderVolumeLODFactor 1 2.0 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 1 WLSkyDetail 1 128 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 -RenderUseFBO 1 0 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 +RenderShadowDetail 1 2 // // Class Unknown Hardware (unknown) @@ -238,6 +236,7 @@ RenderDeferred 0 0 RenderDeferredSSAO 0 0 RenderShadowDetail 0 0 + // // "Default" setups for safe, low, medium, high // @@ -246,6 +245,7 @@ RenderAnisotropic 1 0 RenderAvatarCloth 0 0 RenderAvatarVP 0 0 RenderObjectBump 0 0 +RenderLocalLights 1 0 RenderMaxPartCount 1 1024 RenderTerrainDetail 1 0 RenderUseImpostors 0 0 @@ -255,8 +255,8 @@ WindLightUseAtmosShaders 0 0 RenderDeferred 0 0 RenderDeferredSSAO 0 0 RenderShadowDetail 0 0 -RenderUseFBO 1 0 + // // CPU based feature masks // @@ -277,6 +277,9 @@ RenderObjectBump 0 0 list OpenGLPre15 RenderVBOEnable 1 0 +list OpenGLPre30 +RenderDeferred 0 0 + list Intel RenderAnisotropic 1 0 @@ -462,6 +465,11 @@ RenderAvatarCloth 0 0 list ATI RenderUseStreamVBO 1 0 +RenderAvatarVP 1 0 + +// Disable vertex buffer objects by default for ATI cards with little video memory +list ATIVramLT256 +RenderVBOEnable 1 0 /// Tweaked NVIDIA @@ -562,3 +570,4 @@ list NVIDIA_GeForce_Go_7800 RenderShaderLightingMaxLevel 1 2 list NVIDIA_GeForce_Go_7900 RenderShaderLightingMaxLevel 1 2 + diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index 5da1495da9..1aa6314246 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -1,4 +1,4 @@ -version 22 +version 23 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table @@ -37,6 +37,7 @@ RenderFogRatio 1 4.0 RenderGamma 1 0 RenderGlowResolutionPow 1 9 RenderGround 1 1 +RenderLocalLights 1 1 RenderMaxPartCount 1 8192 RenderNightBrightness 1 1.0 RenderObjectBump 1 1 @@ -56,13 +57,10 @@ WLSkyDetail 1 128 Disregard128DefaultDrawDistance 1 1 Disregard96DefaultDrawDistance 1 1 RenderTextureMemoryMultiple 1 1.0 -SkyUseClassicClouds 1 1 RenderShaderLightingMaxLevel 1 3 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 -WatchdogDisabled 1 1 -RenderUseFBO 1 1 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 +RenderShadowDetail 1 2 // // Low Graphics Settings @@ -77,6 +75,7 @@ RenderAvatarVP 1 0 RenderFarClip 1 64 RenderFlexTimeFactor 1 0 RenderGlowResolutionPow 1 8 +RenderLocalLights 1 0 RenderMaxPartCount 1 0 RenderObjectBump 1 0 RenderReflectionDetail 1 0 @@ -89,11 +88,9 @@ RenderVolumeLODFactor 1 0.5 VertexShaderEnable 1 0 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -SkyUseClassicClouds 1 0 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 -RenderUseFBO 1 0 // // Mid Graphics Settings @@ -107,6 +104,7 @@ RenderAvatarVP 1 1 RenderFarClip 1 96 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 8 +RenderLocalLights 1 1 RenderMaxPartCount 1 2048 RenderObjectBump 1 1 RenderReflectionDetail 1 0 @@ -122,7 +120,6 @@ WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 -RenderUseFBO 1 0 // // High Graphics Settings (purty) @@ -136,6 +133,7 @@ RenderAvatarVP 1 1 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 +RenderLocalLights 1 1 RenderMaxPartCount 1 4096 RenderObjectBump 1 1 RenderReflectionDetail 1 0 @@ -151,7 +149,6 @@ WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 -RenderUseFBO 1 0 // // Ultra graphics (REALLY PURTY!) @@ -165,6 +162,7 @@ RenderAvatarVP 1 1 RenderFarClip 1 256 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 +RenderLocalLights 1 1 RenderMaxPartCount 1 8192 RenderObjectBump 1 1 RenderReflectionDetail 1 4 @@ -177,10 +175,9 @@ RenderVolumeLODFactor 1 2.0 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 1 WLSkyDetail 1 128 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 -RenderUseFBO 1 0 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 +RenderShadowDetail 1 2 // // Class Unknown Hardware (unknown) @@ -255,7 +252,6 @@ WindLightUseAtmosShaders 0 0 RenderDeferred 0 0 RenderDeferredSSAO 0 0 RenderShadowDetail 0 0 -RenderUseFBO 1 0 // diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 421f9c0973..9a8e4d04be 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 22 +version 23 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table @@ -24,11 +24,11 @@ version 22 // list all RenderAnisotropic 1 0 -RenderAvatarCloth 0 0 +RenderAvatarCloth 1 1 RenderAvatarLODFactor 1 1.0 RenderAvatarPhysicsLODFactor 1 1.0 RenderAvatarMaxVisible 1 12 -RenderAvatarVP 1 0 +RenderAvatarVP 1 1 RenderCubeMap 1 1 RenderDelayVBUpdate 1 0 RenderFarClip 1 256 @@ -37,11 +37,11 @@ RenderFogRatio 1 4.0 RenderGamma 1 0 RenderGlowResolutionPow 1 9 RenderGround 1 1 -RenderLightingDetail 1 1 +RenderLocalLights 1 1 RenderMaxPartCount 1 8192 RenderNightBrightness 1 1.0 RenderObjectBump 1 1 -RenderReflectionDetail 1 3 +RenderReflectionDetail 1 4 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 RenderTransparentWater 1 1 @@ -49,20 +49,20 @@ RenderTreeLODFactor 1 1.0 RenderUseImpostors 1 1 RenderVBOEnable 1 1 RenderVolumeLODFactor 1 2.0 -RenderWaterReflections 1 1 +UseStartScreen 1 1 UseOcclusion 1 1 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 1 WLSkyDetail 1 128 -RenderUseCleverUI 1 1 Disregard128DefaultDrawDistance 1 1 Disregard96DefaultDrawDistance 1 1 RenderTextureMemoryMultiple 1 0.5 -Disregard128DefaultDrawDistance 1 1 -Disregard96DefaultDrawDistance 1 1 -SkyUseClassicClouds 1 1 +RenderShaderLightingMaxLevel 1 3 +RenderDeferred 1 1 +RenderDeferredSSAO 1 1 +RenderShadowDetail 1 2 WatchdogDisabled 1 1 -RenderUseFBO 1 1 +RenderUseStreamVBO 1 1 // // Low Graphics Settings @@ -77,7 +77,7 @@ RenderAvatarVP 1 0 RenderFarClip 1 64 RenderFlexTimeFactor 1 0 RenderGlowResolutionPow 1 8 -RenderLightingDetail 1 0 +RenderLocalLights 1 0 RenderMaxPartCount 1 0 RenderObjectBump 1 0 RenderReflectionDetail 1 0 @@ -87,12 +87,12 @@ RenderTransparentWater 1 0 RenderTreeLODFactor 1 0 RenderUseImpostors 1 1 RenderVolumeLODFactor 1 0.5 -RenderWaterReflections 1 0 VertexShaderEnable 1 0 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -SkyUseClassicClouds 1 0 -RenderUseFBO 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 +RenderShadowDetail 1 0 // // Mid Graphics Settings @@ -106,7 +106,7 @@ RenderAvatarVP 1 1 RenderFarClip 1 96 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 8 -RenderLightingDetail 1 1 +RenderLocalLights 1 1 RenderMaxPartCount 1 2048 RenderObjectBump 1 1 RenderReflectionDetail 1 0 @@ -116,11 +116,12 @@ RenderTransparentWater 1 1 RenderTreeLODFactor 1 0.5 RenderUseImpostors 1 1 RenderVolumeLODFactor 1 1.125 -RenderWaterReflections 1 0 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -RenderUseFBO 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 +RenderShadowDetail 1 0 // // High Graphics Settings (purty) @@ -134,7 +135,7 @@ RenderAvatarVP 1 1 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 -RenderLightingDetail 1 1 +RenderLocalLights 1 1 RenderMaxPartCount 1 4096 RenderObjectBump 1 1 RenderReflectionDetail 1 0 @@ -144,11 +145,12 @@ RenderTransparentWater 1 1 RenderTreeLODFactor 1 0.5 RenderUseImpostors 1 1 RenderVolumeLODFactor 1 1.125 -RenderWaterReflections 1 0 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 1 WLSkyDetail 1 48 -RenderUseFBO 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 +RenderShadowDetail 1 2 // // Ultra graphics (REALLY PURTY!) @@ -162,21 +164,22 @@ RenderAvatarVP 1 1 RenderFarClip 1 256 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 -RenderLightingDetail 1 1 +RenderLocalLights 1 1 RenderMaxPartCount 1 8192 RenderObjectBump 1 1 -RenderReflectionDetail 1 3 +RenderReflectionDetail 1 4 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 RenderTransparentWater 1 1 RenderTreeLODFactor 1 1.0 RenderUseImpostors 1 1 RenderVolumeLODFactor 1 2.0 -RenderWaterReflections 1 1 VertexShaderEnable 1 1 WindLightUseAtmosShaders 1 1 WLSkyDetail 1 128 -RenderUseFBO 1 0 +RenderDeferred 1 0 +RenderDeferredSSAO 1 0 +RenderShadowDetail 1 2 // // Class Unknown Hardware (unknown) @@ -214,9 +217,12 @@ RenderVBOEnable 1 1 list NoPixelShaders RenderAvatarVP 0 0 RenderAvatarCloth 0 0 -RenderWaterReflections 0 0 +RenderReflectionDetail 0 0 VertexShaderEnable 0 0 WindLightUseAtmosShaders 0 0 +RenderDeferred 0 0 +RenderDeferredSSAO 0 0 +RenderShadowDetail 0 0 // // No Vertex Shaders available @@ -224,25 +230,31 @@ WindLightUseAtmosShaders 0 0 list NoVertexShaders RenderAvatarVP 0 0 RenderAvatarCloth 0 0 -RenderWaterReflections 0 0 +RenderReflectionDetail 0 0 VertexShaderEnable 0 0 WindLightUseAtmosShaders 0 0 +RenderDeferred 0 0 +RenderDeferredSSAO 0 0 +RenderShadowDetail 0 0 +// // "Default" setups for safe, low, medium, high // list safe RenderAnisotropic 1 0 RenderAvatarCloth 0 0 RenderAvatarVP 0 0 -RenderLightingDetail 1 0 +RenderLocalLights 1 0 RenderObjectBump 0 0 RenderMaxPartCount 1 1024 RenderTerrainDetail 1 0 RenderUseImpostors 0 0 RenderVBOEnable 1 0 -RenderWaterReflections 0 0 +RenderReflectionDetail 0 0 WindLightUseAtmosShaders 0 0 -RenderUseFBO 1 0 +RenderDeferred 0 0 +RenderDeferredSSAO 0 0 +RenderShadowDetail 0 0 // // CPU based feature masks @@ -264,13 +276,16 @@ RenderObjectBump 0 0 list OpenGLPre15 RenderVBOEnable 1 0 +list TexUnit8orLess +RenderDeferredSSAO 0 0 + list Intel RenderAnisotropic 1 0 -RenderLightingDetail 1 0 +RenderLocalLights 1 0 list GeForce2 RenderAnisotropic 1 0 -RenderLightingDetail 1 0 +RenderLocalLights 1 0 RenderMaxPartCount 1 2048 RenderTerrainDetail 1 0 RenderVBOEnable 1 1 @@ -387,7 +402,6 @@ list ATI_Radeon_X1500 Disregard128DefaultDrawDistance 1 0 list ATI_Radeon_X1600 Disregard128DefaultDrawDistance 1 0 -RenderUseFBO 0 0 list ATI_Radeon_X1700 Disregard128DefaultDrawDistance 1 0 list ATI_Mobility_Radeon_X1xxx diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt index c2e5dfff9f..9b9e1f6ead 100644 --- a/indra/newview/featuretable_xp.txt +++ b/indra/newview/featuretable_xp.txt @@ -1,4 +1,4 @@ -version 25 +version 27 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table @@ -37,6 +37,7 @@ RenderFogRatio 1 4.0 RenderGamma 1 0 RenderGlowResolutionPow 1 9 RenderGround 1 1 +RenderLocalLights 1 1 RenderMaxPartCount 1 8192 RenderNightBrightness 1 1.0 RenderObjectBump 1 1 @@ -57,11 +58,9 @@ Disregard128DefaultDrawDistance 1 1 Disregard96DefaultDrawDistance 1 1 RenderTextureMemoryMultiple 1 1.0 RenderShaderLightingMaxLevel 1 3 -SkyUseClassicClouds 1 1 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 -RenderUseFBO 1 1 WatchdogDisabled 1 1 RenderUseStreamVBO 1 1 @@ -78,6 +77,7 @@ RenderAvatarVP 1 0 RenderFarClip 1 64 RenderFlexTimeFactor 1 0 RenderGlowResolutionPow 1 8 +RenderLocalLights 1 0 RenderMaxPartCount 1 0 RenderObjectBump 1 0 RenderReflectionDetail 1 0 @@ -90,11 +90,9 @@ RenderVolumeLODFactor 1 0.5 VertexShaderEnable 1 0 WindLightUseAtmosShaders 1 0 WLSkyDetail 1 48 -SkyUseClassicClouds 1 0 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 -RenderUseFBO 1 0 // // Mid Graphics Settings @@ -108,6 +106,7 @@ RenderAvatarVP 1 1 RenderFarClip 1 96 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 8 +RenderLocalLights 1 1 RenderMaxPartCount 1 2048 RenderObjectBump 1 1 RenderReflectionDetail 1 0 @@ -123,7 +122,6 @@ WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 -RenderUseFBO 1 0 // // High Graphics Settings (purty) @@ -137,6 +135,7 @@ RenderAvatarVP 1 1 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 +RenderLocalLights 1 1 RenderMaxPartCount 1 4096 RenderObjectBump 1 1 RenderReflectionDetail 1 0 @@ -151,8 +150,7 @@ WindLightUseAtmosShaders 1 1 WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 -RenderUseFBO 1 0 +RenderShadowDetail 1 2 // // Ultra graphics (REALLY PURTY!) @@ -166,6 +164,7 @@ RenderAvatarVP 1 1 RenderFarClip 1 256 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 +RenderLocalLights 1 1 RenderMaxPartCount 1 8192 RenderObjectBump 1 1 RenderReflectionDetail 1 4 @@ -180,8 +179,7 @@ WindLightUseAtmosShaders 1 1 WLSkyDetail 1 128 RenderDeferred 1 0 RenderDeferredSSAO 1 0 -RenderShadowDetail 1 0 -RenderUseFBO 1 0 +RenderShadowDetail 1 2 // // Class Unknown Hardware (unknown) @@ -256,7 +254,6 @@ WindLightUseAtmosShaders 0 0 RenderDeferred 0 0 RenderDeferredSSAO 0 0 RenderShadowDetail 0 0 -RenderUseFBO 1 0 // // CPU based feature masks @@ -278,6 +275,9 @@ RenderObjectBump 0 0 list OpenGLPre15 RenderVBOEnable 1 0 +list OpenGLPre30 +RenderDeferred 0 0 + list Intel RenderAnisotropic 1 0 @@ -464,6 +464,11 @@ RenderAvatarCloth 0 0 list ATI RenderUseStreamVBO 1 0 +RenderAvatarVP 1 0 + +// Disable vertex buffer objects by default for ATI cards with little video memory +list ATIVramLT256 +RenderVBOEnable 1 0 /// Tweaked NVIDIA diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt index da888bc64d..6ed4e3b7f7 100644 --- a/indra/newview/gpu_table.txt +++ b/indra/newview/gpu_table.txt @@ -1,10 +1,20 @@ -// +// // Categorizes graphics chips into various classes by name // -// The table contains chip names regular expressions to match +// The table contains regular expressions to match // against driver strings, a class number, and whether we claim // to support them or not. // +// If you modify this table, use the (perl) gpu_table_tester +// to compare the results of recognizing known cards (it is easy +// to mess this up by putting things in the wrong order): +// +// perl ../../scripts/gpu_table_tester -g gpu_table.txt tests/gpus_seen.txt | diff - tests/gpus_results.txt +// +// Format: +// Fields are separated by one or more tab (not space) characters +// <recognizer name> <regular expression> <class> <supported> +// // Class Numbers: // 0 - Defaults to low graphics settings. No shaders on by default // 1 - Defaults to mid graphics settings. Basic shaders on by default @@ -15,304 +25,495 @@ // 0 - We claim to not support this card. // 1 - We claim to support this card. // -// Format: -// <chip name> <regexp> <class> <supported> -// -3Dfx .*3Dfx.* 0 0 -3Dlabs .*3Dlabs.* 0 0 -ATI 3D-Analyze .*ATI.*3D-Analyze.* 0 0 -ATI All-in-Wonder 7500 .*ATI.*All-in-Wonder 75.* 0 1 -ATI All-in-Wonder 8500 .*ATI.*All-in-Wonder 85.* 0 1 -ATI All-in-Wonder 9200 .*ATI.*All-in-Wonder 92.* 0 1 -ATI All-in-Wonder 9xxx .*ATI.*All-in-Wonder 9.* 1 1 -ATI All-in-Wonder HD .*ATI.*All-in-Wonder HD.* 1 1 -ATI All-in-Wonder X600 .*ATI.*All-in-Wonder X6.* 1 1 -ATI All-in-Wonder X800 .*ATI.*All-in-Wonder X8.* 2 1 -ATI All-in-Wonder X1800 .*ATI.*All-in-Wonder X18.* 3 1 -ATI All-in-Wonder X1900 .*ATI.*All-in-Wonder X19.* 3 1 -ATI All-in-Wonder PCI-E .*ATI.*All-in-Wonder.*PCI-E.* 1 1 -ATI All-in-Wonder Radeon .*ATI.*All-in-Wonder Radeon.* 0 1 -ATI ASUS A9xxx .*ATI.*ASUS.*A9.* 1 1 -ATI ASUS AH24xx .*ATI.*ASUS.*AH24.* 1 1 -ATI ASUS AH26xx .*ATI.*ASUS.*AH26.* 3 1 -ATI ASUS AH34xx .*ATI.*ASUS.*AH34.* 1 1 -ATI ASUS AH36xx .*ATI.*ASUS.*AH36.* 3 1 -ATI ASUS AH46xx .*ATI.*ASUS.*AH46.* 3 1 -ATI ASUS AX3xx .*ATI.*ASUS.*AX3.* 1 1 -ATI ASUS AX5xx .*ATI.*ASUS.*AX5.* 1 1 -ATI ASUS AX8xx .*ATI.*ASUS.*AX8.* 2 1 -ATI ASUS EAH24xx .*ATI.*ASUS.*EAH24.* 2 1 -ATI ASUS EAH26xx .*ATI.*ASUS.*EAH26.* 3 1 -ATI ASUS EAH34xx .*ATI.*ASUS.*EAH34.* 1 1 -ATI ASUS EAH36xx .*ATI.*ASUS.*EAH36.* 3 1 -ATI ASUS EAH38xx .*ATI.*ASUS.*EAH38.* 3 1 -ATI ASUS EAH43xx .*ATI.*ASUS.*EAH43.* 1 1 -ATI ASUS EAH45xx .*ATI.*ASUS.*EAH45.* 1 1 -ATI ASUS EAH48xx .*ATI.*ASUS.*EAH48.* 3 1 -ATI ASUS EAH57xx .*ATI.*ASUS.*EAH57.* 3 1 -ATI ASUS EAH58xx .*ATI.*ASUS.*EAH58.* 3 1 -ATI Radeon X1xxx .*ATI.*ASUS.*X1.* 3 1 -ATI Radeon X7xx .*ATI.*ASUS.*X7.* 1 1 -ATI Radeon X500 .*ATI.*Diamond X5.* 1 1 -ATI Radeon X13xx .*ATI.*Diamond X13.* 1 1 -ATI Radeon X16xx .*ATI.*Diamond X16.* 1 1 -ATI Radeon X19xx .*ATI.*Diamond X19.* 1 1 -ATI Display Adapter .*ATI.*display adapter.* 0 1 -ATI FireGL 5200 .*ATI.*FireGL V52.* 0 1 -ATI FireGL 5xxx .*ATI.*FireGL V5.* 1 1 -ATI FireGL .*ATI.*Fire.*GL.* 0 1 -ATI FireMV .*ATI.*FireMV.* 0 0 -ATI Generic .*ATI.*Generic.* 0 0 -ATI Hercules 9800 .*ATI.*Hercules.*9800.* 1 1 -ATI IGP 340M .*ATI.*IGP.*340M.* 0 0 -ATI M52 .*ATI.*M52.* 1 1 -ATI M54 .*ATI.*M54.* 1 1 -ATI M56 .*ATI.*M56.* 1 1 -ATI M71 .*ATI.*M71.* 1 1 -ATI M72 .*ATI.*M72.* 1 1 -ATI M76 .*ATI.*M76.* 3 1 -ATI Mobility Radeon 4100 .*ATI.*Mobility *41.* 0 1 -ATI Mobility Radeon 7xxx .*ATI.*Mobility *Radeon 7.* 0 1 -ATI Mobility Radeon 8xxx .*ATI.*Mobility *Radeon 8.* 0 1 -ATI Mobility Radeon 9800 .*ATI.*Mobility *98.* 0 1 -ATI Mobility Radeon 9700 .*ATI.*Mobility *97.* 0 1 -ATI Mobility Radeon 9600 .*ATI.*Mobility *96.* 0 1 -ATI Mobility Radeon HD 2300 .*ATI.*Mobility *HD *23.* 1 1 -ATI Mobility Radeon HD 2400 .*ATI.*Mobility *HD *24.* 1 1 -ATI Mobility Radeon HD 2600 .*ATI.*Mobility *HD *26.* 3 1 -ATI Mobility Radeon HD 3400 .*ATI.*Mobility *HD *34.* 1 1 -ATI Mobility Radeon HD 3600 .*ATI.*Mobility *HD *36.* 3 1 -ATI Mobility Radeon HD 3800 .*ATI.*Mobility *HD *38.* 3 1 -ATI Mobility Radeon HD 5400 .*ATI.*Mobility *HD *54.* 1 1 -ATI Mobility Radeon HD 5500 .*ATI.*Mobility *HD *55.* 1 1 -ATI Mobility Radeon X1xxx .*ATI.*Mobility *X1.* 0 1 -ATI Mobility Radeon X2xxx .*ATI.*Mobility *X2.* 0 1 -ATI Mobility Radeon X3xx .*ATI.*Mobility *X3.* 1 1 -ATI Mobility Radeon X6xx .*ATI.*Mobility *X6.* 1 1 -ATI Mobility Radeon X7xx .*ATI.*Mobility *X7.* 1 1 -ATI Mobility Radeon Xxxx .*ATI.*Mobility *X.* 0 1 -ATI Radeon HD 2300 .*ATI.*Radeon HD *23.* 0 1 -ATI Radeon HD 2400 .*ATI.*Radeon HD *24.* 1 1 -ATI Radeon HD 2600 .*ATI.*Radeon HD *26.* 2 1 -ATI Radeon HD 2900 .*ATI.*Radeon HD *29.* 3 1 -ATI Radeon HD 3200 .*ATI.*Radeon *HD *32.* 0 1 -ATI Radeon HD 3300 .*ATI.*Radeon HD *33.* 1 1 -ATI Radeon HD 3400 .*ATI.*Radeon HD *34.* 1 1 -ATI Radeon HD 3600 .*ATI.*Radeon HD *36.* 3 1 -ATI Radeon HD 3800 .*ATI.*Radeon HD *38.* 3 1 -ATI Radeon HD 4200 .*ATI.*Radeon HD *42.* 1 1 -ATI Radeon HD 4300 .*ATI.*Radeon HD *43.* 1 1 -ATI Radeon HD 4500 .*ATI.*Radeon HD *45.* 3 1 -ATI Radeon HD 4600 .*ATI.*Radeon HD *46.* 3 1 -ATI Radeon HD 4700 .*ATI.*Radeon HD *47.* 3 1 -ATI Radeon HD 4800 .*ATI.*Radeon.*HD *48.* 3 1 -ATI Radeon HD 5400 .*ATI.*Radeon.*HD *54.* 3 1 -ATI Radeon HD 5500 .*ATI.*Radeon.*HD *55.* 3 1 -ATI Radeon HD 5600 .*ATI.*Radeon.*HD *56.* 3 1 -ATI Radeon HD 5700 .*ATI.*Radeon.*HD *57.* 3 1 -ATI Radeon HD 5800 .*ATI.*Radeon.*HD *58.* 3 1 -ATI Radeon HD 5900 .*ATI.*Radeon.*HD *59.* 3 1 -ATI Radeon OpenGL .*ATI.*Radeon OpenGL.* 0 0 -ATI Radeon 2100 .*ATI.*Radeon 21.* 0 1 -ATI Radeon 3000 .*ATI.*Radeon 30.* 0 1 -ATI Radeon 3100 .*ATI.*Radeon 31.* 0 1 -ATI Radeon 7xxx .*ATI.*Radeon 7.* 0 1 -ATI Radeon 8xxx .*ATI.*Radeon 8.* 0 1 -ATI Radeon 9000 .*ATI.*Radeon 90.* 0 1 -ATI Radeon 9100 .*ATI.*Radeon 91.* 0 1 -ATI Radeon 9200 .*ATI.*Radeon 92.* 0 1 -ATI Radeon 9500 .*ATI.*Radeon 95.* 0 1 -ATI Radeon 9600 .*ATI.*Radeon 96.* 0 1 -ATI Radeon 9700 .*ATI.*Radeon 97.* 1 1 -ATI Radeon 9800 .*ATI.*Radeon 98.* 1 1 -ATI Radeon RV250 .*ATI.*RV250.* 0 1 -ATI Radeon RV600 .*ATI.*RV6.* 1 1 -ATI Radeon RX700 .*ATI.*RX70.* 1 1 -ATI Radeon RX800 .*ATI.*Radeon *RX80.* 2 1 -ATI Radeon RX9550 .*ATI.*RX9550.* 1 1 -ATI Radeon VE .*ATI.*Radeon.*VE.* 0 0 -ATI Radeon X1000 .*ATI.*Radeon *X10.* 0 1 -ATI Radeon X1200 .*ATI.*Radeon *X12.* 0 1 -ATI Radeon X1300 .*ATI.*Radeon *X13.* 1 1 -ATI Radeon X1400 .*ATI.*Radeon *X14.* 1 1 -ATI Radeon X1500 .*ATI.*Radeon *X15.* 1 1 -ATI Radeon X1600 .*ATI.*Radeon *X16.* 1 1 -ATI Radeon X1700 .*ATI.*Radeon *X17.* 1 1 -ATI Radeon X1800 .*ATI.*Radeon *X18.* 3 1 -ATI Radeon X1900 .*ATI.*Radeon *X19.* 3 1 -ATI Radeon X300 .*ATI.*Radeon *X3.* 0 1 -ATI Radeon X400 .*ATI.*Radeon X4.* 0 1 -ATI Radeon X500 .*ATI.*Radeon X5.* 0 1 -ATI Radeon X600 .*ATI.*Radeon X6.* 1 1 -ATI Radeon X700 .*ATI.*Radeon X7.* 1 1 -ATI Radeon X800 .*ATI.*Radeon X8.* 2 1 -ATI Radeon X900 .*ATI.*Radeon X9.* 2 1 -ATI Radeon Xpress .*ATI.*Radeon Xpress.* 0 0 -ATI Rage 128 .*ATI.*Rage 128.* 0 1 -ATI RV250 .*ATI.*RV250.* 0 1 -ATI RV380 .*ATI.*RV380.* 0 1 -ATI RV530 .*ATI.*RV530.* 1 1 -ATI RX700 .*ATI.*RX700.* 1 1 -Intel X3100 .*Intel.*X3100.* 0 1 -Intel 830M .*Intel.*830M 0 0 -Intel 845G .*Intel.*845G 0 0 -Intel 855GM .*Intel.*855GM 0 0 -Intel 865G .*Intel.*865G 0 0 -Intel 900 .*Intel.*900.*900 0 0 -Intel 915GM .*Intel.*915GM 0 0 -Intel 915G .*Intel.*915G 0 0 -Intel 945GM .*Intel.*945GM.* 0 1 -Intel 945G .*Intel.*945G.* 0 1 -Intel 950 .*Intel.*950.* 0 1 -Intel 965 .*Intel.*965.* 0 1 -Intel G33 .*Intel.*G33.* 0 0 -Intel G41 .*Intel.*G41.* 0 1 -Intel G45 .*Intel.*G45.* 0 1 -Intel Bear Lake .*Intel.*Bear Lake.* 0 0 -Intel Broadwater .*Intel.*Broadwater.* 0 0 -Intel Brookdale .*Intel.*Brookdale.* 0 0 -Intel Cantiga .*Intel.*Cantiga.* 0 0 -Intel Eaglelake .*Intel.*Eaglelake.* 0 1 -Intel Graphics Media HD .*Intel(R) Graphics Media.*HD.* 0 1 -Intel HD Graphics .*Intel(R) HD Graphics.* 0 1 -Intel Mobile 4 Series .*Intel.*Mobile.*4 Series.* 0 1 -Intel Media Graphics HD .*Intel Media Graphics HD.* 0 1 -Intel Montara .*Intel.*Montara.* 0 0 -Intel Pineview .*Intel.*Pineview.* 0 1 -Intel Springdale .*Intel.*Springdale.* 0 0 -Matrox .*Matrox.* 0 0 -Mesa .*Mesa.* 0 0 -NVIDIA 310M .*NVIDIA.*GeForce 310M.* 0 1 -NVIDIA 310 .*NVIDIA.*GeForce 310.* 0 1 -NVIDIA 320M .*NVIDIA.*GeForce 320M.* 0 1 -NVIDIA G100M .*NVIDIA.*GeForce G *100M.* 0 1 -NVIDIA G102M .*NVIDIA.*GeForce G *102M.* 0 1 -NVIDIA G103M .*NVIDIA.*GeForce G *103M.* 0 1 -NVIDIA G105M .*NVIDIA.*GeForce G *105M.* 0 1 -NVIDIA G210M .*NVIDIA.*GeForce G210M.* 0 1 -NVIDIA GT 120 .*NVIDIA.*GeForce GT 12.* 1 1 -NVIDIA GT 130 .*NVIDIA.*GeForce GT 13.* 1 1 -NVIDIA GT 220 .*NVIDIA.*GeForce GT 22.* 1 1 -NVIDIA GT 230 .*NVIDIA.*GeForce GT 23.* 1 1 -NVIDIA GT 240 .*NVIDIA.*GeForce GT 24.* 1 1 -NVIDIA GT 320 .*NVIDIA.*GeForce GT 32.* 0 1 -NVIDIA GT 330M .*NVIDIA.*GeForce GT 330M.* 1 1 -NVIDIA GTS 240 .*NVIDIA.*GeForce GTS 24.* 1 1 -NVIDIA GTS 250 .*NVIDIA.*GeForce GTS 25.* 3 1 -NVIDIA GTS 360M .*NVIDIA.*GeForce GTS 360M.* 3 1 -NVIDIA GTX 260 .*NVIDIA.*GeForce GTX 26.* 3 1 -NVIDIA GTX 270 .*NVIDIA.*GeForce GTX 27.* 3 1 -NVIDIA GTX 280 .*NVIDIA.*GeForce GTX 28.* 3 1 -NVIDIA GTX 290 .*NVIDIA.*GeForce GTX 29.* 3 1 -NVIDIA GTX 470 .*NVIDIA.*GeForce GTX 47.* 3 1 -NVIDIA GTX 480 .*NVIDIA.*GeForce GTX 48.* 3 1 -NVIDIA C51 .*NVIDIA.*C51.* 0 1 -NVIDIA G72 .*NVIDIA.*G72.* 1 1 -NVIDIA G73 .*NVIDIA.*G73.* 1 1 -NVIDIA G84 .*NVIDIA.*G84.* 3 1 -NVIDIA G86 .*NVIDIA.*G86.* 3 1 -NVIDIA G92 .*NVIDIA.*G92.* 3 1 -NVIDIA GeForce .*GeForce 256.* 0 0 -NVIDIA GeForce 2 .*GeForce2.* 0 1 -NVIDIA GeForce 3 .*GeForce3.* 0 1 -NVIDIA GeForce 4 Go .*NVIDIA.*GeForce4.*Go.* 0 1 -NVIDIA GeForce 4 MX .*NVIDIA.*GeForce4 MX.* 0 1 -NVIDIA GeForce 4 Ti .*NVIDIA.*GeForce4 Ti.* 0 1 -NVIDIA GeForce 6100 .*NVIDIA.*GeForce 61.* 0 1 -NVIDIA GeForce 6200 .*NVIDIA.*GeForce 62.* 0 1 -NVIDIA GeForce 6500 .*NVIDIA.*GeForce 65.* 0 1 -NVIDIA GeForce 6600 .*NVIDIA.*GeForce 66.* 1 1 -NVIDIA GeForce 6700 .*NVIDIA.*GeForce 67.* 2 1 -NVIDIA GeForce 6800 .*NVIDIA.*GeForce 68.* 2 1 -NVIDIA GeForce 7000 .*NVIDIA.*GeForce 70.* 0 1 -NVIDIA GeForce 7100 .*NVIDIA.*GeForce 71.* 0 1 -NVIDIA GeForce 7200 .*NVIDIA.*GeForce 72.* 1 1 -NVIDIA GeForce 7300 .*NVIDIA.*GeForce 73.* 1 1 -NVIDIA GeForce 7500 .*NVIDIA.*GeForce 75.* 1 1 -NVIDIA GeForce 7600 .*NVIDIA.*GeForce 76.* 1 1 -NVIDIA GeForce 7800 .*NVIDIA.*GeForce 78.* 1 1 -NVIDIA GeForce 7900 .*NVIDIA.*GeForce 79.* 1 1 -NVIDIA GeForce 8100 .*NVIDIA.*GeForce 81.* 1 1 -NVIDIA GeForce 8200 .*NVIDIA.*GeForce 82.* 1 1 -NVIDIA GeForce 8300 .*NVIDIA.*GeForce 83.* 1 1 -NVIDIA GeForce 8400 .*NVIDIA.*GeForce 84.* 1 1 -NVIDIA GeForce 8500 .*GeForce 85.* 1 1 -NVIDIA GeForce 8600M .*NVIDIA.*GeForce.*8600M.* 1 1 -NVIDIA GeForce 8600 .*NVIDIA.*GeForce 86.* 3 1 -NVIDIA GeForce 8700 .*NVIDIA.*GeForce 87.* 3 1 -NVIDIA GeForce 8800 .*NVIDIA.*GeForce 88.* 3 1 -NVIDIA GeForce 9100 .*NVIDIA.*GeForce 9100.* 0 1 -NVIDIA GeForce 9200 .*NVIDIA.*GeForce 9200.* 0 1 -NVIDIA GeForce 9300M .*NVIDIA.*GeForce 9300M.* 1 1 -NVIDIA GeForce 9400M .*NVIDIA.*GeForce 9400M.* 1 1 -NVIDIA GeForce 9500M .*NVIDIA.*GeForce 9500M.* 2 1 -NVIDIA GeForce 9600M .*NVIDIA.*GeForce 9600M.* 3 1 -NVIDIA GeForce 9700M .*NVIDIA.*GeForce 9700M.* 3 1 -NVIDIA GeForce 9300 .*NVIDIA.*GeForce 93.* 1 1 -NVIDIA GeForce 9400 .*GeForce 94.* 1 1 -NVIDIA GeForce 9500 .*NVIDIA.*GeForce 95.* 2 1 -NVIDIA GeForce 9600 .*NVIDIA.*GeForce.*96.* 3 1 -NVIDIA GeForce 9800 .*NVIDIA.*GeForce.*98.* 3 1 -NVIDIA GeForce FX 5100 .*NVIDIA.*GeForce FX 51.* 0 1 -NVIDIA GeForce FX 5200 .*NVIDIA.*GeForce FX 52.* 0 1 -NVIDIA GeForce FX 5500 .*NVIDIA.*GeForce FX 55.* 0 1 -NVIDIA GeForce FX 5600 .*NVIDIA.*GeForce FX 56.* 0 1 -NVIDIA GeForce FX 5700 .*NVIDIA.*GeForce FX 57.* 1 1 -NVIDIA GeForce FX 5800 .*NVIDIA.*GeForce FX 58.* 1 1 -NVIDIA GeForce FX 5900 .*NVIDIA.*GeForce FX 59.* 1 1 -NVIDIA GeForce FX Go5100 .*NVIDIA.*GeForce FX Go51.* 0 1 -NVIDIA GeForce FX Go5200 .*NVIDIA.*GeForce FX Go52.* 0 1 -NVIDIA GeForce FX Go5300 .*NVIDIA.*GeForce FX Go53.* 0 1 -NVIDIA GeForce FX Go5500 .*NVIDIA.*GeForce FX Go55.* 0 1 -NVIDIA GeForce FX Go5600 .*NVIDIA.*GeForce FX Go56.* 0 1 -NVIDIA GeForce FX Go5700 .*NVIDIA.*GeForce FX Go57.* 1 1 -NVIDIA GeForce FX Go5800 .*NVIDIA.*GeForce FX Go58.* 1 1 -NVIDIA GeForce FX Go5900 .*NVIDIA.*GeForce FX Go59.* 1 1 -NVIDIA GeForce Go 6100 .*NVIDIA.*GeForce Go 61.* 0 1 -NVIDIA GeForce Go 6200 .*NVIDIA.*GeForce Go 62.* 0 1 -NVIDIA GeForce Go 6500 .*NVIDIA.*GeForce Go 65.* 1 1 -NVIDIA GeForce Go 6600 .*NVIDIA.*GeForce Go 66.* 1 1 -NVIDIA GeForce Go 6700 .*NVIDIA.*GeForce Go 67.* 1 1 -NVIDIA GeForce Go 6800 .*NVIDIA.*GeForce Go 68.* 1 1 -NVIDIA GeForce Go 7200 .*NVIDIA.*GeForce Go 72.* 1 1 -NVIDIA GeForce Go 7300 .*NVIDIA.*GeForce Go 73.* 1 1 -NVIDIA GeForce Go 7300 LE .*NVIDIA.*GeForce Go 73.*LE.* 0 1 -NVIDIA GeForce Go 7400 .*NVIDIA.*GeForce Go 74.* 1 1 -NVIDIA GeForce Go 7600 .*NVIDIA.*GeForce Go 76.* 2 1 -NVIDIA GeForce Go 7700 .*NVIDIA.*GeForce Go 77.* 2 1 -NVIDIA GeForce Go 7800 .*NVIDIA.*GeForce Go 78.* 2 1 -NVIDIA GeForce Go 7900 .*NVIDIA.*GeForce Go 79.* 2 1 -NVIDIA D9M .*D9M.* 1 1 -NVIDIA G84 .*G84.* 1 1 -NVIDIA G92 .*G92.* 3 1 -NVIDIA G94 .*G94.* 3 1 -NVIDIA GeForce Go 6 .*GeForce Go 6.* 1 1 -NVIDIA ION .*NVIDIA ION.* 1 1 -NVIDIA NB9M .*GeForce NB9M.* 1 1 -NVIDIA NB9P .*GeForce NB9P.* 1 1 -NVIDIA GeForce PCX .*GeForce PCX.* 0 1 -NVIDIA Generic .*NVIDIA.*Unknown.* 0 0 -NVIDIA NV17 .*GeForce NV17.* 0 1 -NVIDIA NV34 .*NVIDIA.*NV34.* 0 1 -NVIDIA NV35 .*NVIDIA.*NV35.* 0 1 -NVIDIA NV36 .*GeForce NV36.* 1 1 -NVIDIA NV43 .*NVIDIA.*NV43.* 1 1 -NVIDIA NV44 .*NVIDIA.*NV44.* 1 1 -NVIDIA nForce .*NVIDIA.*nForce.* 0 0 -NVIDIA MCP78 .*NVIDIA.*MCP78.* 1 1 -NVIDIA Quadro2 .*Quadro2.* 0 1 -NVIDIA Quadro4 .*Quadro4.* 0 1 -NVIDIA Quadro DCC .*Quadro DCC.* 0 1 -NVIDIA Quadro FX 4500 .*Quadro.*FX.*4500.* 3 1 -NVIDIA Quadro FX .*Quadro FX.* 1 1 -NVIDIA Quadro NVS .*Quadro NVS.* 0 1 -NVIDIA RIVA TNT .*RIVA TNT.* 0 0 -S3 .*S3 Graphics.* 0 0 -SiS SiS.* 0 0 -Trident Trident.* 0 0 -Tungsten Graphics Tungsten.* 0 0 -XGI XGI.* 0 0 -VIA VIA.* 0 0 -Apple Generic Apple.*Generic.* 0 0 -Apple Software Renderer Apple.*Software Renderer.* 0 0 +3Dfx .*3Dfx.* 0 0 +3Dlabs .*3Dlabs.* 0 0 +ATI 3D-Analyze .*ATI.*3D-Analyze.* 0 0 +ATI All-in-Wonder 7500 .*ATI.*All-in-Wonder 75.* 0 1 +ATI All-in-Wonder 8500 .*ATI.*All-in-Wonder 85.* 0 1 +ATI All-in-Wonder 9200 .*ATI.*All-in-Wonder 92.* 0 1 +ATI All-in-Wonder 9xxx .*ATI.*All-in-Wonder 9.* 1 1 +ATI All-in-Wonder HD .*ATI.*All-in-Wonder HD.* 1 1 +ATI All-in-Wonder X600 .*ATI.*All-in-Wonder X6.* 1 1 +ATI All-in-Wonder X800 .*ATI.*All-in-Wonder X8.* 2 1 +ATI All-in-Wonder X1800 .*ATI.*All-in-Wonder X18.* 3 1 +ATI All-in-Wonder X1900 .*ATI.*All-in-Wonder X19.* 3 1 +ATI All-in-Wonder PCI-E .*ATI.*All-in-Wonder.*PCI-E.* 1 1 +ATI All-in-Wonder Radeon .*ATI.*All-in-Wonder Radeon.* 0 1 +ATI ASUS A9xxx .*ATI.*ASUS.*A9.* 1 1 +ATI ASUS AH24xx .*ATI.*ASUS.*AH24.* 1 1 +ATI ASUS AH26xx .*ATI.*ASUS.*AH26.* 3 1 +ATI ASUS AH34xx .*ATI.*ASUS.*AH34.* 1 1 +ATI ASUS AH36xx .*ATI.*ASUS.*AH36.* 3 1 +ATI ASUS AH46xx .*ATI.*ASUS.*AH46.* 3 1 +ATI ASUS AX3xx .*ATI.*ASUS.*AX3.* 1 1 +ATI ASUS AX5xx .*ATI.*ASUS.*AX5.* 1 1 +ATI ASUS AX8xx .*ATI.*ASUS.*AX8.* 2 1 +ATI ASUS EAH24xx .*ATI.*ASUS.*EAH24.* 2 1 +ATI ASUS EAH26xx .*ATI.*ASUS.*EAH26.* 3 1 +ATI ASUS EAH34xx .*ATI.*ASUS.*EAH34.* 1 1 +ATI ASUS EAH36xx .*ATI.*ASUS.*EAH36.* 3 1 +ATI ASUS EAH38xx .*ATI.*ASUS.*EAH38.* 3 1 +ATI ASUS EAH43xx .*ATI.*ASUS.*EAH43.* 1 1 +ATI ASUS EAH45xx .*ATI.*ASUS.*EAH45.* 1 1 +ATI ASUS EAH48xx .*ATI.*ASUS.*EAH48.* 3 1 +ATI ASUS EAH57xx .*ATI.*ASUS.*EAH57.* 3 1 +ATI ASUS EAH58xx .*ATI.*ASUS.*EAH58.* 3 1 +ATI ASUS Radeon X1xxx .*ATI.*ASUS.*X1.* 3 1 +ATI Radeon X7xx .*ATI.*ASUS.*X7.* 1 1 +ATI Radeon X1xxx .*ATI.*X1.* 0 1 +ATI Radeon X13xx .*ATI.*Diamond X13.* 1 1 +ATI Radeon X16xx .*ATI.*Diamond X16.* 1 1 +ATI Radeon X19xx .*ATI.*Diamond X19.* 1 1 +ATI Display Adapter .*ATI.*display adapter.* 0 1 +ATI FireGL 5200 .*ATI.*FireGL V52.* 0 1 +ATI FireGL 5xxx .*ATI.*FireGL V5.* 1 1 +ATI FireGL .*ATI.*Fire.*GL.* 0 1 +ATI FirePro M3900 .*ATI.*FirePro.*M39.* 2 1 +ATI FirePro M5800 .*ATI.*FirePro.*M58.* 3 1 +ATI FirePro M7740 .*ATI.*FirePro.*M77.* 3 1 +ATI FirePro M7820 .*ATI.*FirePro.*M78.* 3 1 +ATI FireMV .*ATI.*FireMV.* 0 1 +ATI Geforce 9500 GT .*ATI.*Geforce 9500 *GT 2 1 +ATI Geforce 9800 GT .*ATI.*Geforce 9800 *GT 2 1 +ATI Generic .*ATI.*Generic.* 0 0 +ATI Hercules 9800 .*ATI.*Hercules.*9800.* 1 1 +ATI IGP 340M .*ATI.*IGP.*340M.* 0 0 +ATI M52 .*ATI.*M52.* 1 1 +ATI M54 .*ATI.*M54.* 1 1 +ATI M56 .*ATI.*M56.* 1 1 +ATI M71 .*ATI.*M71.* 1 1 +ATI M72 .*ATI.*M72.* 1 1 +ATI M76 .*ATI.*M76.* 3 1 +ATI Mobility Radeon 4100 .*ATI.*(Mobility|MOBILITY).*41.* 0 1 +ATI Mobility Radeon 7xxx .*ATI.*(Mobility|MOBILITY).*Radeon 7.* 0 1 +ATI Mobility Radeon 8xxx .*ATI.*(Mobility|MOBILITY).*Radeon 8.* 0 1 +ATI Mobility Radeon 9800 .*ATI.*(Mobility|MOBILITY).*98.* 1 1 +ATI Mobility Radeon 9700 .*ATI.*(Mobility|MOBILITY).*97.* 1 1 +ATI Mobility Radeon 9600 .*ATI.*(Mobility|MOBILITY).*96.* 0 1 +ATI Mobility Radeon HD 530v .*ATI.*(Mobility|MOBILITY).*HD *530v.* 1 1 +ATI Mobility Radeon HD 540v .*ATI.*(Mobility|MOBILITY).*HD *540v.* 2 1 +ATI Mobility Radeon HD 545v .*ATI.*(Mobility|MOBILITY).*HD *545v.* 2 1 +ATI Mobility Radeon HD 550v .*ATI.*(Mobility|MOBILITY).*HD *550v.* 2 1 +ATI Mobility Radeon HD 560v .*ATI.*(Mobility|MOBILITY).*HD *560v.* 2 1 +ATI Mobility Radeon HD 565v .*ATI.*(Mobility|MOBILITY).*HD *565v.* 2 1 +ATI Mobility Radeon HD 2300 .*ATI.*(Mobility|MOBILITY).*HD *23.* 1 1 +ATI Mobility Radeon HD 2400 .*ATI.*(Mobility|MOBILITY).*HD *24.* 1 1 +ATI Mobility Radeon HD 2600 .*ATI.*(Mobility|MOBILITY).*HD *26.* 3 1 +ATI Mobility Radeon HD 2700 .*ATI.*(Mobility|MOBILITY).*HD *27.* 3 1 +ATI Mobility Radeon HD 3100 .*ATI.*(Mobility|MOBILITY).*HD *31.* 0 1 +ATI Mobility Radeon HD 3200 .*ATI.*(Mobility|MOBILITY).*HD *32.* 0 1 +ATI Mobility Radeon HD 3400 .*ATI.*(Mobility|MOBILITY).*HD *34.* 2 1 +ATI Mobility Radeon HD 3600 .*ATI.*(Mobility|MOBILITY).*HD *36.* 3 1 +ATI Mobility Radeon HD 3800 .*ATI.*(Mobility|MOBILITY).*HD *38.* 3 1 +ATI Mobility Radeon HD 4200 .*ATI.*(Mobility|MOBILITY).*HD *42.* 2 1 +ATI Mobility Radeon HD 4300 .*ATI.*(Mobility|MOBILITY).*HD *43.* 2 1 +ATI Mobility Radeon HD 4500 .*ATI.*(Mobility|MOBILITY).*HD *45.* 3 1 +ATI Mobility Radeon HD 4600 .*ATI.*(Mobility|MOBILITY).*HD *46.* 3 1 +ATI Mobility Radeon HD 4800 .*ATI.*(Mobility|MOBILITY).*HD *48.* 3 1 +ATI Mobility Radeon HD 5100 .*ATI.*(Mobility|MOBILITY).*HD *51.* 2 1 +ATI Mobility Radeon HD 5300 .*ATI.*(Mobility|MOBILITY).*HD *53.* 2 1 +ATI Mobility Radeon HD 5400 .*ATI.*(Mobility|MOBILITY).*HD *54.* 2 1 +ATI Mobility Radeon HD 5500 .*ATI.*(Mobility|MOBILITY).*HD *55.* 2 1 +ATI Mobility Radeon HD 5600 .*ATI.*(Mobility|MOBILITY).*HD *56.* 2 1 +ATI Mobility Radeon HD 5700 .*ATI.*(Mobility|MOBILITY).*HD *57.* 3 1 +ATI Mobility Radeon HD 6200 .*ATI.*(Mobility|MOBILITY).*HD *62.* 2 1 +ATI Mobility Radeon HD 6300 .*ATI.*(Mobility|MOBILITY).*HD *63.* 2 1 +ATI Mobility Radeon HD 6400M .*ATI.*(Mobility|MOBILITY).*HD *64.* 3 1 +ATI Mobility Radeon HD 6500M .*ATI.*(Mobility|MOBILITY).*HD *65.* 3 1 +ATI Mobility Radeon HD 6600M .*ATI.*(Mobility|MOBILITY).*HD *66.* 3 1 +ATI Mobility Radeon HD 6700M .*ATI.*(Mobility|MOBILITY).*HD *67.* 3 1 +ATI Mobility Radeon HD 6800M .*ATI.*(Mobility|MOBILITY).*HD *68.* 3 1 +ATI Mobility Radeon HD 6900M .*ATI.*(Mobility|MOBILITY).*HD *69.* 3 1 +ATI Mobility Radeon X1xxx .*ATI.*(Mobility|MOBILITY).*X1.* 0 1 +ATI Mobility Radeon X2xxx .*ATI.*(Mobility|MOBILITY).*X2.* 0 1 +ATI Mobility Radeon X3xx .*ATI.*(Mobility|MOBILITY).*X3.* 1 1 +ATI Mobility Radeon X6xx .*ATI.*(Mobility|MOBILITY).*X6.* 1 1 +ATI Mobility Radeon X7xx .*ATI.*(Mobility|MOBILITY).*X7.* 1 1 +ATI Mobility Radeon Xxxx .*ATI.*(Mobility|MOBILITY).*X.* 0 1 +ATI Mobility Radeon .*ATI.*(Mobility|MOBILITY).* 0 1 +ATI Radeon HD 2300 .*ATI.*(Radeon|RADEON) HD *23.* 0 1 +ATI Radeon HD 2400 .*ATI.*(Radeon|RADEON) HD *24.* 1 1 +ATI Radeon HD 2600 .*ATI.*(Radeon|RADEON) HD *26.* 2 1 +ATI Radeon HD 2900 .*ATI.*(Radeon|RADEON) HD *29.* 3 1 +ATI Radeon HD 3000 .*ATI.*(Radeon|RADEON) HD *30.* 0 1 +ATI Radeon HD 3100 .*ATI.*(Radeon|RADEON) HD *31.* 1 1 +ATI Radeon HD 3200 .*ATI.*(Radeon|RADEON) HD *32.* 0 1 +ATI Radeon HD 3300 .*ATI.*(Radeon|RADEON) HD *33.* 1 1 +ATI Radeon HD 3400 .*ATI.*(Radeon|RADEON) HD *34.* 1 1 +ATI Radeon HD 3500 .*ATI.*(Radeon|RADEON) HD *35.* 1 1 +ATI Radeon HD 3600 .*ATI.*(Radeon|RADEON) HD *36.* 3 1 +ATI Radeon HD 3700 .*ATI.*(Radeon|RADEON) HD *37.* 3 1 +ATI Radeon HD 3800 .*ATI.*(Radeon|RADEON) HD *38.* 3 1 +ATI Radeon HD 4200 .*ATI.*(Radeon|RADEON) HD *42.* 1 1 +ATI Radeon HD 4300 .*ATI.*(Radeon|RADEON) HD *43.* 1 1 +ATI Radeon HD 4400 .*ATI.*(Radeon|RADEON) HD *44.* 1 1 +ATI Radeon HD 4500 .*ATI.*(Radeon|RADEON) HD *45.* 3 1 +ATI Radeon HD 4600 .*ATI.*(Radeon|RADEON) HD *46.* 3 1 +ATI Radeon HD 4700 .*ATI.*(Radeon|RADEON) HD *47.* 3 1 +ATI Radeon HD 4800 .*ATI.*(Radeon|RADEON) HD *48.* 3 1 +ATI Radeon HD 5400 .*ATI.*(Radeon|RADEON) HD *54.* 3 1 +ATI Radeon HD 5500 .*ATI.*(Radeon|RADEON) HD *55.* 3 1 +ATI Radeon HD 5600 .*ATI.*(Radeon|RADEON) HD *56.* 3 1 +ATI Radeon HD 5700 .*ATI.*(Radeon|RADEON) HD *57.* 3 1 +ATI Radeon HD 5800 .*ATI.*(Radeon|RADEON) HD *58.* 3 1 +ATI Radeon HD 5900 .*ATI.*(Radeon|RADEON) HD *59.* 3 1 +ATI Radeon HD 6200 .*ATI.*(Radeon|RADEON) HD *62.* 2 1 +ATI Radeon HD 6300 .*ATI.*(Radeon|RADEON) HD *63.* 2 1 +ATI Radeon HD 6400 .*ATI.*(Radeon|RADEON) HD *64.* 3 1 +ATI Radeon HD 6500 .*ATI.*(Radeon|RADEON) HD *65.* 3 1 +ATI Radeon HD 66xx .*ATI.*(Radeon|RADEON) HD *66.* 3 1 +ATI Radeon HD 6700 .*ATI.*(Radeon|RADEON) HD *67.* 3 1 +ATI Radeon HD 6800 .*ATI.*(Radeon|RADEON) HD *68.* 3 1 +ATI Radeon HD 6900 .*ATI.*(Radeon|RADEON) HD *69.* 3 1 +ATI Radeon OpenGL .*ATI.*(Radeon|RADEON) OpenGL.* 0 0 +ATI Radeon 2100 .*ATI.*(Radeon|RADEON) 21.* 0 1 +ATI Radeon 3000 .*ATI.*(Radeon|RADEON) 30.* 0 1 +ATI Radeon 3100 .*ATI.*(Radeon|RADEON) 31.* 1 1 +ATI Radeon 5xxx .*ATI.*(Radeon|RADEON) 5.* 3 1 +ATI Radeon 7xxx .*ATI.*(Radeon|RADEON) 7.* 0 1 +ATI Radeon 8xxx .*ATI.*(Radeon|RADEON) 8.* 0 1 +ATI Radeon 9000 .*ATI.*(Radeon|RADEON) 90.* 0 1 +ATI Radeon 9100 .*ATI.*(Radeon|RADEON) 91.* 0 1 +ATI Radeon 9200 .*ATI.*(Radeon|RADEON) 92.* 0 1 +ATI Radeon 9500 .*ATI.*(Radeon|RADEON) 95.* 0 1 +ATI Radeon 9600 .*ATI.*(Radeon|RADEON) 96.* 0 1 +ATI Radeon 9700 .*ATI.*(Radeon|RADEON) 97.* 1 1 +ATI Radeon 9800 .*ATI.*(Radeon|RADEON) 98.* 1 1 +ATI Radeon RV250 .*ATI.*RV250.* 0 1 +ATI Radeon RV600 .*ATI.*RV6.* 1 1 +ATI Radeon RX700 .*ATI.*RX70.* 1 1 +ATI Radeon RX800 .*ATI.*(Radeon|RADEON) *RX80.* 2 1 +ATI RS880M .*ATI.*RS880M 1 1 +ATI Radeon RX9550 .*ATI.*RX9550.* 1 1 +ATI Radeon VE .*ATI.*(Radeon|RADEON).*VE.* 0 0 +ATI Radeon X1000 .*ATI.*(Radeon|RADEON) *X10.* 0 1 +ATI Radeon X1200 .*ATI.*(Radeon|RADEON) *X12.* 0 1 +ATI Radeon X1300 .*ATI.*(Radeon|RADEON) *X13.* 1 1 +ATI Radeon X1400 .*ATI.*(Radeon|RADEON) *X14.* 1 1 +ATI Radeon X1500 .*ATI.*(Radeon|RADEON) *X15.* 1 1 +ATI Radeon X1600 .*ATI.*(Radeon|RADEON) *X16.* 1 1 +ATI Radeon X1700 .*ATI.*(Radeon|RADEON) *X17.* 1 1 +ATI Radeon X1800 .*ATI.*(Radeon|RADEON) *X18.* 3 1 +ATI Radeon X1900 .*ATI.*(Radeon|RADEON) *X19.* 3 1 +ATI Radeon X300 .*ATI.*(Radeon|RADEON) *X3.* 0 1 +ATI Radeon X400 .*ATI.*(Radeon|RADEON) X4.* 0 1 +ATI Radeon X500 .*ATI.*(Radeon|RADEON) X5.* 0 1 +ATI Radeon X600 .*ATI.*(Radeon|RADEON) X6.* 1 1 +ATI Radeon X700 .*ATI.*(Radeon|RADEON) X7.* 1 1 +ATI Radeon X800 .*ATI.*(Radeon|RADEON) X8.* 2 1 +ATI Radeon X900 .*ATI.*(Radeon|RADEON) X9.* 2 1 +ATI Radeon Xpress .*ATI.*(Radeon|RADEON) (Xpress|XPRESS).* 0 1 +ATI Rage 128 .*ATI.*Rage 128.* 0 1 +ATI R350 (9800) .*(ATI)?.*R350.* 1 1 +ATI R580 (X1900) .*(ATI)?.*R580.* 3 1 +ATI RC410 (Xpress 200) .*(ATI)?.*RC410.* 0 0 +ATI RS48x (Xpress 200x) .*(ATI)?.*RS48.* 0 0 +ATI RS600 (Xpress 3200) .*(ATI)?.*RS600.* 0 0 +ATI RV350 (9600) .*(ATI)?.*RV350.* 0 1 +ATI RV370 (X300) .*(ATI)?.*RV370.* 0 1 +ATI RV410 (X700) .*(ATI)?.*RV410.* 1 1 +ATI RV515 .*(ATI)?.*RV515.* 1 1 +ATI RV570 (X1900 GT/PRO) .*(ATI)?.*RV570.* 3 1 +ATI RV380 .*(ATI)?.*RV380.* 0 1 +ATI RV530 .*(ATI)?.*RV530.* 1 1 +ATI RX480 (Xpress 200P) .*(ATI)?.*RX480.* 0 1 +ATI RX700 .*(ATI)?.*RX700.* 1 1 +AMD ANTILLES (HD 6990) .*(AMD|ATI).*(Antilles|ANTILLES).* 3 1 +AMD BARTS (HD 6800) .*(AMD|ATI).*(Barts|BARTS).* 3 1 +AMD CAICOS (HD 6400) .*(AMD|ATI).*(Caicos|CAICOS).* 3 1 +AMD CAYMAN (HD 6900) .*(AMD|ATI).*(Cayman|CAYMAM).* 3 1 +AMD CEDAR (HD 5450) .*(AMD|ATI).*(Cedar|CEDAR).* 2 1 +AMD CYPRESS (HD 5800) .*(AMD|ATI).*(Cypress|CYPRESS).* 3 1 +AMD HEMLOCK (HD 5970) .*(AMD|ATI).*(Hemlock|HEMLOCK).* 3 1 +AMD JUNIPER (HD 5700) .*(AMD|ATI).*(Juniper|JUNIPER).* 3 1 +AMD PARK .*(AMD|ATI).*(Park|PARK).* 3 1 +AMD REDWOOD (HD 5500/5600) .*(AMD|ATI).*(Redwood|REDWOOD).* 3 1 +AMD TURKS (HD 6500/6600) .*(AMD|ATI).*(Turks|TURKS).* 3 1 +AMD RS780 (HD 3200) .*(AMD|ATI)?.*RS780.* 0 1 +AMD RS880 (HD 4200) .*(AMD|ATI)?.*RS880.* 1 1 +AMD RV610 (HD 2400) .*(AMD|ATI)?.*RV610.* 1 1 +AMD RV620 (HD 3400) .*(AMD|ATI)?.*RV620.* 1 1 +AMD RV630 (HD 2600) .*(AMD|ATI)?.*RV630.* 2 1 +AMD RV635 (HD 3600) .*(AMD|ATI)?.*RV635.* 3 1 +AMD RV670 (HD 3800) .*(AMD|ATI)?.*RV670.* 3 1 +AMD R680 (HD 3870 X2) .*(AMD|ATI)?.*R680.* 3 1 +AMD R700 (HD 4800 X2) .*(AMD|ATI)?.*R700.* 3 1 +AMD RV710 (HD 4300) .*(AMD|ATI)?.*RV710.* 1 1 +AMD RV730 (HD 4600) .*(AMD|ATI)?.*RV730.* 3 1 +AMD RV740 (HD 4700) .*(AMD|ATI)?.*RV740.* 3 1 +AMD RV770 (HD 4800) .*(AMD|ATI)?.*RV770.* 3 1 +AMD RV790 (HD 4800) .*(AMD|ATI)?.*RV790.* 3 1 +ATI 760G/Radeon 3000 .*ATI.*AMD 760G.* 1 1 +ATI 780L/Radeon 3000 .*ATI.*AMD 780L.* 1 1 +ATI Radeon DDR .*ATI.*(Radeon|RADEON) ?DDR.* 0 1 +ATI FirePro 2000 .*ATI.*FirePro 2.* 1 1 +ATI FirePro 3000 .*ATI.*FirePro V3.* 1 1 +ATI FirePro 4000 .*ATI.*FirePro V4.* 2 1 +ATI FirePro 5000 .*ATI.*FirePro V5.* 3 1 +ATI FirePro 7000 .*ATI.*FirePro V7.* 3 1 +ATI FirePro M .*ATI.*FirePro M.* 3 1 +ATI Technologies .*ATI *Technologies.* 0 1 +// This entry is last to work around the "R300" driver problem. +ATI R300 (9700) .*(ATI)?.*R300.* 1 1 +ATI Radeon .*ATI.*Radeon.* 0 1 +Intel X3100 .*Intel.*X3100.* 0 1 +Intel 830M .*Intel.*830M 0 0 +Intel 845G .*Intel.*845G 0 0 +Intel 855GM .*Intel.*855GM 0 0 +Intel 865G .*Intel.*865G 0 0 +Intel 900 .*Intel.*900.*900 0 0 +Intel 915GM .*Intel.*915GM 0 0 +Intel 915G .*Intel.*915G 0 0 +Intel 945GM .*Intel.*945GM.* 0 1 +Intel 945G .*Intel.*945G.* 0 1 +Intel 950 .*Intel.*950.* 0 1 +Intel 965 .*Intel.*965.* 0 1 +Intel G33 .*Intel.*G33.* 0 0 +Intel G41 .*Intel.*G41.* 0 1 +Intel G45 .*Intel.*G45.* 0 1 +Intel Bear Lake .*Intel.*Bear Lake.* 0 0 +Intel Broadwater .*Intel.*Broadwater.* 0 0 +Intel Brookdale .*Intel.*Brookdale.* 0 0 +Intel Cantiga .*Intel.*Cantiga.* 0 0 +Intel Eaglelake .*Intel.*Eaglelake.* 0 1 +Intel Graphics Media HD .*Intel.*Graphics Media.*HD.* 0 1 +Intel HD Graphics .*Intel.*HD Graphics.* 2 1 +Intel Mobile 4 Series .*Intel.*Mobile *4 Series.* 0 1 +Intel Media Graphics HD .*Intel.*Media Graphics HD.* 0 1 +Intel Montara .*Intel.*Montara.* 0 0 +Intel Pineview .*Intel.*Pineview.* 0 1 +Intel Springdale .*Intel.*Springdale.* 0 0 +Intel HD Graphics 2000 .*Intel.*HD2000.* 1 1 +Intel HD Graphics 3000 .*Intel.*HD3000.* 2 1 +Matrox .*Matrox.* 0 0 +Mesa .*Mesa.* 0 0 +NVIDIA 205 .*NVIDIA.*GeForce 205.* 2 1 +NVIDIA 210 .*NVIDIA.*GeForce 210.* 2 1 +NVIDIA 310M .*NVIDIA.*GeForce 310M.* 1 1 +NVIDIA 310 .*NVIDIA.*GeForce 310.* 3 1 +NVIDIA 315M .*NVIDIA.*GeForce 315M.* 2 1 +NVIDIA 315 .*NVIDIA.*GeForce 315.* 3 1 +NVIDIA 320M .*NVIDIA.*GeForce 320M.* 2 1 +NVIDIA G100M .*NVIDIA *(GeForce)? *(G)? ?100M.* 0 1 +NVIDIA G100 .*NVIDIA *(GeForce)? *(G)? ?100.* 0 1 +NVIDIA G102M .*NVIDIA *(GeForce)? *(G)? ?102M.* 0 1 +NVIDIA G103M .*NVIDIA *(GeForce)? *(G)? ?103M.* 0 1 +NVIDIA G105M .*NVIDIA *(GeForce)? *(G)? ?105M.* 0 1 +NVIDIA G 110M .*NVIDIA *(GeForce)? *(G)? ?110M.* 0 1 +NVIDIA G 120M .*NVIDIA *(GeForce)? *(G)? ?120M.* 1 1 +NVIDIA G 200 .*NVIDIA *(GeForce)? *(G)? ?200(M)?.* 0 1 +NVIDIA G 205M .*NVIDIA *(GeForce)? *(G)? ?205(M)?.* 0 1 +NVIDIA G 210 .*NVIDIA *(GeForce)? *(G)? ?210(M)?.* 1 1 +NVIDIA 305M .*NVIDIA *(GeForce)? *(G)? ?305(M)?.* 1 1 +NVIDIA G 310M .*NVIDIA *(GeForce)? *(G)? ?310(M)?.* 2 1 +NVIDIA G 315 .*NVIDIA *(GeForce)? *(G)? ?315(M)?.* 2 1 +NVIDIA G 320M .*NVIDIA *(GeForce)? *(G)? ?320(M)?.* 2 1 +NVIDIA G 405 .*NVIDIA *(GeForce)? *(G)? ?405(M)?.* 1 1 +NVIDIA G 410M .*NVIDIA *(GeForce)? *(G)? ?410(M)?.* 1 1 +NVIDIA GT 120M .*NVIDIA.*(GeForce)? *GT *120(M)?.* 2 1 +NVIDIA GT 120 .*NVIDIA.*GT.*120 2 1 +NVIDIA GT 130M .*NVIDIA.*(GeForce)? *GT *130(M)?.* 2 1 +NVIDIA GT 140M .*NVIDIA.*(GeForce)? *GT *140(M)?.* 2 1 +NVIDIA GT 150M .*NVIDIA.*(GeForce)? *GT(S)? *150(M)?.* 2 1 +NVIDIA GT 160M .*NVIDIA.*(GeForce)? *GT *160(M)?.* 2 1 +NVIDIA GT 220M .*NVIDIA.*(GeForce)? *GT *220(M)?.* 2 1 +NVIDIA GT 230M .*NVIDIA.*(GeForce)? *GT *230(M)?.* 2 1 +NVIDIA GT 240M .*NVIDIA.*(GeForce)? *GT *240(M)?.* 2 1 +NVIDIA GT 250M .*NVIDIA.*(GeForce)? *GT *250(M)?.* 2 1 +NVIDIA GT 260M .*NVIDIA.*(GeForce)? *GT *260(M)?.* 2 1 +NVIDIA GT 320M .*NVIDIA.*(GeForce)? *GT *320(M)?.* 2 1 +NVIDIA GT 325M .*NVIDIA.*(GeForce)? *GT *325(M)?.* 0 1 +NVIDIA GT 330M .*NVIDIA.*(GeForce)? *GT *330(M)?.* 3 1 +NVIDIA GT 335M .*NVIDIA.*(GeForce)? *GT *335(M)?.* 1 1 +NVIDIA GT 340M .*NVIDIA.*(GeForce)? *GT *340(M)?.* 2 1 +NVIDIA GT 415M .*NVIDIA.*(GeForce)? *GT *415(M)?.* 2 1 +NVIDIA GT 420M .*NVIDIA.*(GeForce)? *GT *420(M)?.* 2 1 +NVIDIA GT 425M .*NVIDIA.*(GeForce)? *GT *425(M)?.* 3 1 +NVIDIA GT 430M .*NVIDIA.*(GeForce)? *GT *430(M)?.* 3 1 +NVIDIA GT 435M .*NVIDIA.*(GeForce)? *GT *435(M)?.* 3 1 +NVIDIA GT 440M .*NVIDIA.*(GeForce)? *GT *440(M)?.* 3 1 +NVIDIA GT 445M .*NVIDIA.*(GeForce)? *GT *445(M)?.* 3 1 +NVIDIA GT 450M .*NVIDIA.*(GeForce)? *GT *450(M)?.* 3 1 +NVIDIA GT 520M .*NVIDIA.*(GeForce)? *GT *520(M)?.* 3 1 +NVIDIA GT 525M .*NVIDIA.*(GeForce)? *GT *525(M)?.* 3 1 +NVIDIA GT 540M .*NVIDIA.*(GeForce)? *GT *540(M)?.* 3 1 +NVIDIA GT 550M .*NVIDIA.*(GeForce)? *GT *550(M)?.* 3 1 +NVIDIA GT 555M .*NVIDIA.*(GeForce)? *GT *555(M)?.* 3 1 +NVIDIA GTS 160M .*NVIDIA.*(GeForce)? *GT(S)? *160(M)?.* 2 1 +NVIDIA GTS 240 .*NVIDIA.*(GeForce)? *GTS *24.* 3 1 +NVIDIA GTS 250 .*NVIDIA.*(GeForce)? *GTS *25.* 3 1 +NVIDIA GTS 350M .*NVIDIA.*(GeForce)? *GTS *350M.* 3 1 +NVIDIA GTS 360M .*NVIDIA.*(GeForce)? *GTS *360M.* 3 1 +NVIDIA GTS 360 .*NVIDIA.*(GeForce)? *GTS *360.* 3 1 +NVIDIA GTS 450 .*NVIDIA.*(GeForce)? *GTS *45.* 3 1 +NVIDIA GTX 260 .*NVIDIA.*(GeForce)? *GTX *26.* 3 1 +NVIDIA GTX 275 .*NVIDIA.*(GeForce)? *GTX *275.* 3 1 +NVIDIA GTX 270 .*NVIDIA.*(GeForce)? *GTX *27.* 3 1 +NVIDIA GTX 285 .*NVIDIA.*(GeForce)? *GTX *285.* 3 1 +NVIDIA GTX 280 .*NVIDIA.*(GeForce)? *GTX *280.* 3 1 +NVIDIA GTX 290 .*NVIDIA.*(GeForce)? *GTX *290.* 3 1 +NVIDIA GTX 295 .*NVIDIA.*(GeForce)? *GTX *295.* 3 1 +NVIDIA GTX 460M .*NVIDIA.*(GeForce)? *GTX *460M.* 3 1 +NVIDIA GTX 465 .*NVIDIA.*(GeForce)? *GTX *465.* 3 1 +NVIDIA GTX 460 .*NVIDIA.*(GeForce)? *GTX *46.* 3 1 +NVIDIA GTX 470M .*NVIDIA.*(GeForce)? *GTX *470M.* 3 1 +NVIDIA GTX 470 .*NVIDIA.*(GeForce)? *GTX *47.* 3 1 +NVIDIA GTX 480M .*NVIDIA.*(GeForce)? *GTX *480M.* 3 1 +NVIDIA GTX 485M .*NVIDIA.*(GeForce)? *GTX *485M.* 3 1 +NVIDIA GTX 480 .*NVIDIA.*(GeForce)? *GTX *48.* 3 1 +NVIDIA GTX 530 .*NVIDIA.*(GeForce)? *GTX *53.* 3 1 +NVIDIA GTX 550 .*NVIDIA.*(GeForce)? *GTX *55.* 3 1 +NVIDIA GTX 560 .*NVIDIA.*(GeForce)? *GTX *56.* 3 1 +NVIDIA GTX 570 .*NVIDIA.*(GeForce)? *GTX *57.* 3 1 +NVIDIA GTX 580M .*NVIDIA.*(GeForce)? *GTX *580M.* 3 1 +NVIDIA GTX 580 .*NVIDIA.*(GeForce)? *GTX *58.* 3 1 +NVIDIA GTX 590 .*NVIDIA.*(GeForce)? *GTX *59.* 3 1 +NVIDIA C51 .*NVIDIA.*(GeForce)? *C51.* 0 1 +NVIDIA G72 .*NVIDIA.*(GeForce)? *G72.* 1 1 +NVIDIA G73 .*NVIDIA.*(GeForce)? *G73.* 1 1 +NVIDIA G84 .*NVIDIA.*(GeForce)? *G84.* 2 1 +NVIDIA G86 .*NVIDIA.*(GeForce)? *G86.* 3 1 +NVIDIA G92 .*NVIDIA.*(GeForce)? *G92.* 3 1 +NVIDIA GeForce .*GeForce 256.* 0 0 +NVIDIA GeForce 2 .*GeForce ?2 ?.* 0 1 +NVIDIA GeForce 3 .*GeForce ?3 ?.* 0 1 +NVIDIA GeForce 3 Ti .*GeForce ?3 Ti.* 0 1 +NVIDIA GeForce 4 .*NVIDIA.*GeForce ?4.* 0 1 +NVIDIA GeForce 4 Go .*NVIDIA.*GeForce ?4.*Go.* 0 1 +NVIDIA GeForce 4 MX .*NVIDIA.*GeForce ?4 MX.* 0 1 +NVIDIA GeForce 4 PCX .*NVIDIA.*GeForce ?4 PCX.* 0 1 +NVIDIA GeForce 4 Ti .*NVIDIA.*GeForce ?4 Ti.* 0 1 +NVIDIA GeForce 6100 .*NVIDIA.*GeForce 61.* 0 1 +NVIDIA GeForce 6200 .*NVIDIA.*GeForce 62.* 0 1 +NVIDIA GeForce 6500 .*NVIDIA.*GeForce 65.* 0 1 +NVIDIA GeForce 6600 .*NVIDIA.*GeForce 66.* 1 1 +NVIDIA GeForce 6700 .*NVIDIA.*GeForce 67.* 2 1 +NVIDIA GeForce 6800 .*NVIDIA.*GeForce 68.* 2 1 +NVIDIA GeForce 7000 .*NVIDIA.*GeForce 70.* 0 1 +NVIDIA GeForce 7100 .*NVIDIA.*GeForce 71.* 0 1 +NVIDIA GeForce 7200 .*NVIDIA.*GeForce 72.* 1 1 +NVIDIA GeForce 7300 .*NVIDIA.*GeForce 73.* 1 1 +NVIDIA GeForce 7500 .*NVIDIA.*GeForce 75.* 1 1 +NVIDIA GeForce 7600 .*NVIDIA.*GeForce 76.* 2 1 +NVIDIA GeForce 7800 .*NVIDIA.*GeForce 78.* 2 1 +NVIDIA GeForce 7900 .*NVIDIA.*GeForce 79.* 2 1 +NVIDIA GeForce 8100 .*NVIDIA.*GeForce 81.* 1 1 +NVIDIA GeForce 8200M .*NVIDIA.*GeForce 8200M.* 1 1 +NVIDIA GeForce 8200 .*NVIDIA.*GeForce 82.* 1 1 +NVIDIA GeForce 8300 .*NVIDIA.*GeForce 83.* 1 1 +NVIDIA GeForce 8400M .*NVIDIA.*GeForce 8400M.* 1 1 +NVIDIA GeForce 8400 .*NVIDIA.*GeForce 84.* 1 1 +NVIDIA GeForce 8500 .*NVIDIA.*GeForce 85.* 3 1 +NVIDIA GeForce 8600M .*NVIDIA.*GeForce 8600M.* 1 1 +NVIDIA GeForce 8600 .*NVIDIA.*GeForce 86.* 3 1 +NVIDIA GeForce 8700M .*NVIDIA.*GeForce 8700M.* 3 1 +NVIDIA GeForce 8700 .*NVIDIA.*GeForce 87.* 3 1 +NVIDIA GeForce 8800M .*NVIDIA.*GeForce 8800M.* 3 1 +NVIDIA GeForce 8800 .*NVIDIA.*GeForce 88.* 3 1 +NVIDIA GeForce 9100M .*NVIDIA.*GeForce 9100M.* 0 1 +NVIDIA GeForce 9100 .*NVIDIA.*GeForce 91.* 0 1 +NVIDIA GeForce 9200M .*NVIDIA.*GeForce 9200M.* 1 1 +NVIDIA GeForce 9200 .*NVIDIA.*GeForce 92.* 1 1 +NVIDIA GeForce 9300M .*NVIDIA.*GeForce 9300M.* 1 1 +NVIDIA GeForce 9300 .*NVIDIA.*GeForce 93.* 1 1 +NVIDIA GeForce 9400M .*NVIDIA.*GeForce 9400M.* 1 1 +NVIDIA GeForce 9400 .*NVIDIA.*GeForce 94.* 1 1 +NVIDIA GeForce 9500M .*NVIDIA.*GeForce 9500M.* 2 1 +NVIDIA GeForce 9500 .*NVIDIA.*GeForce 95.* 2 1 +NVIDIA GeForce 9600M .*NVIDIA.*GeForce 9600M.* 3 1 +NVIDIA GeForce 9600 .*NVIDIA.*GeForce 96.* 2 1 +NVIDIA GeForce 9700M .*NVIDIA.*GeForce 9700M.* 2 1 +NVIDIA GeForce 9800M .*NVIDIA.*GeForce 9800M.* 3 1 +NVIDIA GeForce 9800 .*NVIDIA.*GeForce 98.* 3 1 +NVIDIA GeForce FX 5100 .*NVIDIA.*GeForce FX 51.* 0 1 +NVIDIA GeForce FX 5200 .*NVIDIA.*GeForce FX 52.* 0 1 +NVIDIA GeForce FX 5300 .*NVIDIA.*GeForce FX 53.* 0 1 +NVIDIA GeForce FX 5500 .*NVIDIA.*GeForce FX 55.* 0 1 +NVIDIA GeForce FX 5600 .*NVIDIA.*GeForce FX 56.* 0 1 +NVIDIA GeForce FX 5700 .*NVIDIA.*GeForce FX 57.* 1 1 +NVIDIA GeForce FX 5800 .*NVIDIA.*GeForce FX 58.* 1 1 +NVIDIA GeForce FX 5900 .*NVIDIA.*GeForce FX 59.* 1 1 +NVIDIA GeForce FX Go5100 .*NVIDIA.*GeForce FX Go51.* 0 1 +NVIDIA GeForce FX Go5200 .*NVIDIA.*GeForce FX Go52.* 0 1 +NVIDIA GeForce FX Go5300 .*NVIDIA.*GeForce FX Go53.* 0 1 +NVIDIA GeForce FX Go5500 .*NVIDIA.*GeForce FX Go55.* 0 1 +NVIDIA GeForce FX Go5600 .*NVIDIA.*GeForce FX Go56.* 0 1 +NVIDIA GeForce FX Go5700 .*NVIDIA.*GeForce FX Go57.* 1 1 +NVIDIA GeForce FX Go5800 .*NVIDIA.*GeForce FX Go58.* 1 1 +NVIDIA GeForce FX Go5900 .*NVIDIA.*GeForce FX Go59.* 1 1 +NVIDIA GeForce FX Go5xxx .*NVIDIA.*GeForce FX Go.* 0 1 +NVIDIA GeForce Go 6100 .*NVIDIA.*GeForce Go 61.* 0 1 +NVIDIA GeForce Go 6200 .*NVIDIA.*GeForce Go 62.* 0 1 +NVIDIA GeForce Go 6400 .*NVIDIA.*GeForce Go 64.* 1 1 +NVIDIA GeForce Go 6500 .*NVIDIA.*GeForce Go 65.* 1 1 +NVIDIA GeForce Go 6600 .*NVIDIA.*GeForce Go 66.* 1 1 +NVIDIA GeForce Go 6700 .*NVIDIA.*GeForce Go 67.* 1 1 +NVIDIA GeForce Go 6800 .*NVIDIA.*GeForce Go 68.* 1 1 +NVIDIA GeForce Go 7200 .*NVIDIA.*GeForce Go 72.* 1 1 +NVIDIA GeForce Go 7300 LE .*NVIDIA.*GeForce Go 73.*LE.* 0 1 +NVIDIA GeForce Go 7300 .*NVIDIA.*GeForce Go 73.* 1 1 +NVIDIA GeForce Go 7400 .*NVIDIA.*GeForce Go 74.* 1 1 +NVIDIA GeForce Go 7600 .*NVIDIA.*GeForce Go 76.* 2 1 +NVIDIA GeForce Go 7700 .*NVIDIA.*GeForce Go 77.* 2 1 +NVIDIA GeForce Go 7800 .*NVIDIA.*GeForce Go 78.* 2 1 +NVIDIA GeForce Go 7900 .*NVIDIA.*GeForce Go 79.* 2 1 +NVIDIA D9M .*NVIDIA.*D9M.* 1 1 +NVIDIA G94 .*NVIDIA.*G94.* 3 1 +NVIDIA GeForce Go 6 .*GeForce Go 6.* 1 1 +NVIDIA ION 2 .*NVIDIA ION 2.* 2 1 +NVIDIA ION .*NVIDIA ION.* 2 1 +NVIDIA NB9M .*GeForce NB9M.* 1 1 +NVIDIA NB9P .*GeForce NB9P.* 1 1 +NVIDIA GeForce PCX .*GeForce PCX.* 0 1 +NVIDIA Generic .*NVIDIA.*Unknown.* 0 0 +NVIDIA NV17 .*GeForce NV17.* 0 1 +NVIDIA NV34 .*NVIDIA.*NV34.* 0 1 +NVIDIA NV35 .*NVIDIA.*NV35.* 0 1 +NVIDIA NV36 .*GeForce NV36.* 1 1 +NVIDIA NV43 .*NVIDIA *NV43.* 1 1 +NVIDIA NV44 .*NVIDIA *NV44.* 1 1 +NVIDIA nForce .*NVIDIA *nForce.* 0 0 +NVIDIA MCP78 .*NVIDIA *MCP78.* 1 1 +NVIDIA Quadro2 .*Quadro2.* 0 1 +NVIDIA Quadro 1000M .*Quadro.*1000M.* 2 1 +NVIDIA Quadro 2000 M/D .*Quadro.*2000(M|D)?.* 3 1 +NVIDIA Quadro 4000M .*Quadro.*4000M.* 3 1 +NVIDIA Quadro 4000 .*Quadro *4000.* 3 1 +NVIDIA Quadro 50x0 M .*Quadro.*50.0(M)?.* 3 1 +NVIDIA Quadro 6000 .*Quadro.*6000.* 3 1 +NVIDIA Quadro 400 .*Quadro.*400.* 2 1 +NVIDIA Quadro 600 .*Quadro.*600.* 2 1 +NVIDIA Quadro4 .*Quadro4.* 0 1 +NVIDIA Quadro DCC .*Quadro DCC.* 0 1 +NVIDIA Quadro FX 770M .*Quadro.*FX *770M.* 2 1 +NVIDIA Quadro FX 1500M .*Quadro.*FX *1500M.* 1 1 +NVIDIA Quadro FX 1600M .*Quadro.*FX *1600M.* 2 1 +NVIDIA Quadro FX 2500M .*Quadro.*FX *2500M.* 2 1 +NVIDIA Quadro FX 2700M .*Quadro.*FX *2700M.* 3 1 +NVIDIA Quadro FX 2800M .*Quadro.*FX *2800M.* 3 1 +NVIDIA Quadro FX 3500 .*Quadro.*FX *3500.* 2 1 +NVIDIA Quadro FX 3600 .*Quadro.*FX *3600.* 3 1 +NVIDIA Quadro FX 3700 .*Quadro.*FX *3700.* 3 1 +NVIDIA Quadro FX 3800 .*Quadro.*FX *3800.* 3 1 +NVIDIA Quadro FX 4500 .*Quadro.*FX *45.* 3 1 +NVIDIA Quadro FX 880M .*Quadro.*FX *880M.* 3 1 +NVIDIA Quadro FX 4800 .*NVIDIA.*Quadro *FX *4800.* 3 1 +NVIDIA Quadro FX .*Quadro FX.* 1 1 +NVIDIA Quadro NVS 1xxM .*Quadro NVS *1.[05]M.* 0 1 +NVIDIA Quadro NVS 300M .*NVIDIA.*NVS *300M.* 2 1 +NVIDIA Quadro NVS 320M .*NVIDIA.*NVS *320M.* 2 1 +NVIDIA Quadro NVS 2100M .*NVIDIA.*NVS *2100M.* 2 1 +NVIDIA Quadro NVS 3100M .*NVIDIA.*NVS *3100M.* 2 1 +NVIDIA Quadro NVS 4200M .*NVIDIA.*NVS *4200M.* 2 1 +NVIDIA Quadro NVS 5100M .*NVIDIA.*NVS *5100M.* 2 1 +NVIDIA Quadro NVS .*NVIDIA.*NVS 0 1 +NVIDIA RIVA TNT .*RIVA TNT.* 0 0 +S3 .*S3 Graphics.* 0 0 +SiS SiS.* 0 0 +Trident Trident.* 0 0 +Tungsten Graphics Tungsten.* 0 0 +XGI XGI.* 0 0 +VIA VIA.* 0 0 +Apple Generic Apple.*Generic.* 0 0 +Apple Software Renderer Apple.*Software Renderer.* 0 0 diff --git a/indra/newview/groupchatlistener.cpp b/indra/newview/groupchatlistener.cpp new file mode 100644 index 0000000000..ef015a950d --- /dev/null +++ b/indra/newview/groupchatlistener.cpp @@ -0,0 +1,76 @@ +/** + * @file groupchatlistener.cpp + * @author Nat Goodspeed + * @date 2011-04-11 + * @brief Implementation for groupchatlistener. + * + * $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$ + */ + +// Precompiled header +#include "llviewerprecompiledheaders.h" +// associated header +#include "groupchatlistener.h" +// STL headers +// std headers +// external library headers +// other Linden headers +#include "llgroupactions.h" +#include "llimview.h" + + +namespace { + void startIm_wrapper(LLSD const & event) + { + LLUUID session_id = LLGroupActions::startIM(event["id"].asUUID()); + sendReply(LLSDMap("session_id", LLSD(session_id)), event); + } + + void send_message_wrapper(const std::string& text, const LLUUID& session_id, const LLUUID& group_id) + { + LLIMModel::sendMessage(text, session_id, group_id, IM_SESSION_GROUP_START); + } +} + + +GroupChatListener::GroupChatListener(): + LLEventAPI("GroupChat", + "API to enter, leave, send and intercept group chat messages") +{ + add("startIM", + "Enter a group chat in group with UUID [\"id\"]\n" + "Assumes the logged-in agent is already a member of this group.", + &startIm_wrapper); + add("endIM", + "Leave a group chat in group with UUID [\"id\"]\n" + "Assumes a prior successful startIM request.", + &LLGroupActions::endIM, + LLSDArray("id")); + add("sendIM", + "send a groupchat IM", + &send_message_wrapper, + LLSDArray("text")("session_id")("group_id")); +} +/* + static void sendMessage(const std::string& utf8_text, const LLUUID& im_session_id, + const LLUUID& other_participant_id, EInstantMessage dialog); +*/ diff --git a/indra/newview/groupchatlistener.h b/indra/newview/groupchatlistener.h new file mode 100644 index 0000000000..0c76db305e --- /dev/null +++ b/indra/newview/groupchatlistener.h @@ -0,0 +1,40 @@ +/** + * @file groupchatlistener.h + * @author Nat Goodspeed + * @date 2011-04-11 + * @brief + * + * $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$ + */ + +#if ! defined(LL_GROUPCHATLISTENER_H) +#define LL_GROUPCHATLISTENER_H + +#include "lleventapi.h" + +class GroupChatListener: public LLEventAPI +{ +public: + GroupChatListener(); +}; + +#endif /* ! defined(LL_GROUPCHATLISTENER_H) */ diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 4e8ed807ee..b5d43021ec 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -211,6 +211,25 @@ continue_install: FunctionEnd ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Checks for CPU valid (must have SSE2 support) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function CheckCPUFlags + Call GetWindowsVersion + Pop $R0 + StrCmp $R0 "2000" OK_SSE ; sse check not available on win2k. + + Push $1 + System::Call 'kernel32::IsProcessorFeaturePresent(i) i(10) .r1' + IntCmp $1 1 OK_SSE + MessageBox MB_OKCANCEL $(MissingSSE2) /SD IDOK IDOK OK_SSE + Quit + + OK_SSE: + Pop $1 + Return +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Close the program, if running. Modifies no variables. ; Allows user to bail out of install process. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -744,6 +763,7 @@ StrCpy $INSTEXE "${INSTEXE}" StrCpy $INSTSHORTCUT "${SHORTCUT}" Call CheckWindowsVersion ; warn if on Windows 98/ME +Call CheckCPUFlags ; Make sure we have SSE2 support Call CheckIfAdministrator ; Make sure the user can install/uninstall Call CheckIfAlreadyCurrent ; Make sure that we haven't already installed this version Call CloseSecondLife ; Make sure we're not running diff --git a/indra/newview/installers/windows/lang_en-us.nsi b/indra/newview/installers/windows/lang_en-us.nsi Binary files differindex a01541377d..da0d7f54d2 100644 --- a/indra/newview/installers/windows/lang_en-us.nsi +++ b/indra/newview/installers/windows/lang_en-us.nsi diff --git a/indra/newview/licenses-win32.txt b/indra/newview/licenses-win32.txt index 7e6d4b4561..8736626907 100644 --- a/indra/newview/licenses-win32.txt +++ b/indra/newview/licenses-win32.txt @@ -769,3 +769,72 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +============= +GLOD license +============= +The GLOD Open-Source License Version 1.0 June 16, 2004 + +Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns +Hopkins University and David Luebke, Brenden Schubert, University of +Virginia. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, is permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer and + request. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer and + request in the documentation and/or other materials provided with + the distribution. + +3. The name "GLOD" must not be used to endorse or promote products + derived from this software without prior written permission. + +4. Redistributions of any modified version of this source, whether in + source or binary form , must include a form of the following + acknowledgment: "This product is derived from the GLOD library, + which is available from http://www.cs.jhu.edu/~graphics/GLOD." + +5. Redistributions of any modified version of this source in binary + form must provide, free of charge, access to the modified version + of the code. + +6. This license shall be governed by and construed and enforced in + accordance with the laws of the State of Maryland, without + reference to its conflicts of law provisions. The exclusive + jurisdiction and venue for all legal actions relating to this + license shall be in courts of competent subject matter jurisdiction + located in the State of Maryland. + +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, GLOD IS PROVIDED +UNDER THIS LICENSE ON AN AS IS BASIS, WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES +THAT GLOD IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR +PURPOSE OR NON-INFRINGING. ALL WARRANTIES ARE DISCLAIMED AND THE +ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE CODE IS WITH +YOU. SHOULD ANY CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE +COPYRIGHT HOLDER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY +NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY +CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY CODE IS +AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL +THE COPYRIGHT HOLDER OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY +SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES FOR LOSS OF +PROFITS, REVENUE, OR FOR LOSS OF INFORMATION OR ANY OTHER LOSS. + +YOU EXPRESSLY AGREE TO FOREVER INDEMNIFY, DEFEND AND HOLD HARMLESS THE +COPYRIGHT HOLDERS AND CONTRIBUTORS OF GLOD AGAINST ALL CLAIMS, +DEMANDS, SUITS OR OTHER ACTIONS ARISING DIRECTLY OR INDIRECTLY FROM +YOUR ACCEPTANCE AND USE OF GLOD. + +Although NOT REQUIRED, we would appreciate it if active users of GLOD +put a link on their web site to the GLOD web site when possible. + + diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index d2df968544..283a28a0aa 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -92,23 +92,23 @@ cd "${RUN_PATH}" ## subprocesses that care. export SAVED_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" -if [ -n "$LL_TCMALLOC" ]; then - tcmalloc_libs='/usr/lib/libtcmalloc.so.0 /usr/lib/libstacktrace.so.0 /lib/libpthread.so.0' - all=1 - for f in $tcmalloc_libs; do - if [ ! -f $f ]; then - all=0 - fi - done - if [ $all != 1 ]; then - echo 'Cannot use tcmalloc libraries: components missing' 1>&2 - else - export LD_PRELOAD=$(echo $tcmalloc_libs | tr ' ' :) - if [ -z "$HEAPCHECK" -a -z "$HEAPPROFILE" ]; then - export HEAPCHECK=${HEAPCHECK:-normal} - fi - fi -fi +# if [ -n "$LL_TCMALLOC" ]; then +# tcmalloc_libs='/usr/lib/libtcmalloc.so.0 /usr/lib/libstacktrace.so.0 /lib/libpthread.so.0' +# all=1 +# for f in $tcmalloc_libs; do +# if [ ! -f $f ]; then +# all=0 +# fi +# done +# if [ $all != 1 ]; then +# echo 'Cannot use tcmalloc libraries: components missing' 1>&2 +# else +# export LD_PRELOAD=$(echo $tcmalloc_libs | tr ' ' :) +# if [ -z "$HEAPCHECK" -a -z "$HEAPPROFILE" ]; then +# export HEAPCHECK=${HEAPCHECK:-normal} +# fi +# fi +#fi export SL_ENV='LD_LIBRARY_PATH="`pwd`"/lib:"${LD_LIBRARY_PATH}"' export SL_CMD='$LL_WRAPPER bin/do-not-directly-run-secondlife-bin' diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index d9c82363b4..343f5b17ec 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -1239,7 +1239,13 @@ BOOL LLAgent::getBusy() const //----------------------------------------------------------------------------- // startAutoPilotGlobal() //----------------------------------------------------------------------------- -void LLAgent::startAutoPilotGlobal(const LLVector3d &target_global, const std::string& behavior_name, const LLQuaternion *target_rotation, void (*finish_callback)(BOOL, void *), void *callback_data, F32 stop_distance, F32 rot_threshold) +void LLAgent::startAutoPilotGlobal( + const LLVector3d &target_global, + const std::string& behavior_name, + const LLQuaternion *target_rotation, + void (*finish_callback)(BOOL, void *), + void *callback_data, + F32 stop_distance, F32 rot_threshold) { if (!isAgentAvatarValid()) { @@ -1270,7 +1276,7 @@ void LLAgent::startAutoPilotGlobal(const LLVector3d &target_global, const std::s else { // Guess at a reasonable stop distance. - mAutoPilotStopDistance = fsqrtf( distance ); + mAutoPilotStopDistance = (F32) sqrt( distance ); if (mAutoPilotStopDistance < 0.5f) { mAutoPilotStopDistance = 0.5f; diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 6c5c3bcdab..c6b5a0113f 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -390,10 +390,12 @@ LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 origi { return original_focus_point - obj_pos; } - LLQuaternion inv_obj_rot = ~obj_rot; // get inverse of rotation - LLVector3 object_extents = object->getScale(); + LLVector3 object_extents; + const LLVector4a* oe4 = object->mDrawable->getSpatialExtents(); + object_extents.set( oe4[1][0], oe4[1][1], oe4[1][2] ); + // make sure they object extents are non-zero object_extents.clamp(0.001f, F32_MAX); @@ -551,7 +553,9 @@ 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) - if (!mFocusObject || mFocusObject->isDead()) + if (!mFocusObject || mFocusObject->isDead() || + mFocusObject->isMesh() || + gSavedSettings.getBOOL("DisableCameraConstraints")) { obj_min_distance = 0.f; return TRUE; diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index ed24febf41..9cea33c7c6 100644 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -64,6 +64,12 @@ LLAgentListener::LLAgentListener(LLAgent &agent) "[\"quat\"]: array of [x, y, z, w] quaternion values", &LLAgentListener::getAxes, LLSDMap("reply", LLSD())); + add("getGroups", + "Send on [\"reply\"], in [\"groups\"], an array describing agent's groups:\n" + "[\"id\"]: UUID of group\n" + "[\"name\"]: name of group", + &LLAgentListener::getGroups, + LLSDMap("reply", LLSD())); } void LLAgentListener::requestTeleport(LLSD const & event_data) const @@ -140,3 +146,21 @@ void LLAgentListener::getAxes(const LLSD& event) const ("euler", LLSDMap("roll", roll)("pitch", pitch)("yaw", yaw)), event); } + +void LLAgentListener::getGroups(const LLSD& event) const +{ + LLSD reply(LLSD::emptyArray()); + for (LLDynamicArray<LLGroupData>::const_iterator + gi(mAgent.mGroups.begin()), gend(mAgent.mGroups.end()); + gi != gend; ++gi) + { + reply.append(LLSDMap + ("id", gi->mID) + ("name", gi->mName) + ("insignia", gi->mInsigniaID) + ("notices", bool(gi->mAcceptNotices)) + ("display", bool(gi->mListInProfile)) + ("contrib", gi->mContribution)); + } + sendReply(LLSDMap("groups", reply), event); +} diff --git a/indra/newview/llagentlistener.h b/indra/newview/llagentlistener.h index 0aa58d0b16..5a89a99f6a 100644 --- a/indra/newview/llagentlistener.h +++ b/indra/newview/llagentlistener.h @@ -46,6 +46,7 @@ private: void requestStand(LLSD const & event_data) const; void resetAxes(const LLSD& event) const; void getAxes(const LLSD& event) const; + void getGroups(const LLSD& event) const; private: LLAgent & mAgent; diff --git a/indra/newview/llagentpilot.cpp b/indra/newview/llagentpilot.cpp index 13e1023185..734c502fcf 100644 --- a/indra/newview/llagentpilot.cpp +++ b/indra/newview/llagentpilot.cpp @@ -34,12 +34,12 @@ #include "llagent.h" #include "llappviewer.h" #include "llviewercontrol.h" +#include "llviewercamera.h" +#include "llsdserialize.h" +#include "llsdutil_math.h" LLAgentPilot gAgentPilot; -BOOL LLAgentPilot::sLoop = TRUE; -BOOL LLAgentPilot::sReplaySession = FALSE; - LLAgentPilot::LLAgentPilot() : mNumRuns(-1), mQuitAfterRuns(FALSE), @@ -47,7 +47,10 @@ LLAgentPilot::LLAgentPilot() : mLastRecordTime(0.f), mStarted(FALSE), mPlaying(FALSE), - mCurrentAction(0) + mCurrentAction(0), + mOverrideCamera(FALSE), + mLoop(TRUE), + mReplaySession(FALSE) { } @@ -55,7 +58,26 @@ LLAgentPilot::~LLAgentPilot() { } -void LLAgentPilot::load(const std::string& filename) +void LLAgentPilot::load() +{ + std::string txt_filename = gSavedSettings.getString("StatsPilotFile"); + std::string xml_filename = gSavedSettings.getString("StatsPilotXMLFile"); + if (LLFile::isfile(xml_filename)) + { + loadXML(xml_filename); + } + else if (LLFile::isfile(txt_filename)) + { + loadTxt(txt_filename); + } + else + { + lldebugs << "no autopilot file found" << llendl; + return; + } +} + +void LLAgentPilot::loadTxt(const std::string& filename) { if(filename.empty()) { @@ -75,6 +97,7 @@ void LLAgentPilot::load(const std::string& filename) llinfos << "Opening pilot file " << filename << llendl; } + mActions.reset(); S32 num_actions; file >> num_actions; @@ -89,10 +112,59 @@ void LLAgentPilot::load(const std::string& filename) mActions.put(new_action); } + mOverrideCamera = false; + + file.close(); +} + +void LLAgentPilot::loadXML(const std::string& filename) +{ + if(filename.empty()) + { + return; + } + + llifstream file(filename); + + if (!file) + { + lldebugs << "Couldn't open " << filename + << ", aborting agentpilot load!" << llendl; + return; + } + else + { + llinfos << "Opening pilot file " << filename << llendl; + } + + mActions.reset(); + LLSD record; + while (!file.eof() && LLSDSerialize::fromXML(record, file)) + { + Action action; + action.mTime = record["time"].asReal(); + action.mType = (EActionType)record["type"].asInteger(); + action.mCameraView = record["camera_view"].asReal(); + action.mTarget = ll_vector3d_from_sd(record["target"]); + action.mCameraOrigin = ll_vector3_from_sd(record["camera_origin"]); + action.mCameraXAxis = ll_vector3_from_sd(record["camera_xaxis"]); + action.mCameraYAxis = ll_vector3_from_sd(record["camera_yaxis"]); + action.mCameraZAxis = ll_vector3_from_sd(record["camera_zaxis"]); + mActions.put(action); + } + mOverrideCamera = true; file.close(); } -void LLAgentPilot::save(const std::string& filename) +void LLAgentPilot::save() +{ + std::string txt_filename = gSavedSettings.getString("StatsPilotFile"); + std::string xml_filename = gSavedSettings.getString("StatsPilotXMLFile"); + saveTxt(txt_filename); + saveXML(xml_filename); +} + +void LLAgentPilot::saveTxt(const std::string& filename) { llofstream file; file.open(filename); @@ -108,12 +180,41 @@ void LLAgentPilot::save(const std::string& filename) for (i = 0; i < mActions.count(); i++) { file << mActions[i].mTime << "\t" << mActions[i].mType << "\t"; - file << std::setprecision(32) << mActions[i].mTarget.mdV[VX] << "\t" << mActions[i].mTarget.mdV[VY] << "\t" << mActions[i].mTarget.mdV[VZ] << '\n'; + file << std::setprecision(32) << mActions[i].mTarget.mdV[VX] << "\t" << mActions[i].mTarget.mdV[VY] << "\t" << mActions[i].mTarget.mdV[VZ]; + file << '\n'; } file.close(); } +void LLAgentPilot::saveXML(const std::string& filename) +{ + llofstream file; + file.open(filename); + + if (!file) + { + llinfos << "Couldn't open " << filename << ", aborting agentpilot save!" << llendl; + } + + S32 i; + for (i = 0; i < mActions.count(); i++) + { + Action& action = mActions[i]; + LLSD record; + record["time"] = (LLSD::Real)action.mTime; + record["type"] = (LLSD::Integer)action.mType; + record["camera_view"] = (LLSD::Real)action.mCameraView; + record["target"] = ll_sd_from_vector3d(action.mTarget); + record["camera_origin"] = ll_sd_from_vector3(action.mCameraOrigin); + record["camera_xaxis"] = ll_sd_from_vector3(action.mCameraXAxis); + record["camera_yaxis"] = ll_sd_from_vector3(action.mCameraYAxis); + record["camera_zaxis"] = ll_sd_from_vector3(action.mCameraZAxis); + LLSDSerialize::toXML(record, file); + } + file.close(); +} + void LLAgentPilot::startRecord() { mActions.reset(); @@ -125,7 +226,7 @@ void LLAgentPilot::startRecord() void LLAgentPilot::stopRecord() { gAgentPilot.addAction(STRAIGHT); - gAgentPilot.save(gSavedSettings.getString("StatsPilotFile")); + gAgentPilot.save(); mRecording = FALSE; } @@ -136,6 +237,12 @@ void LLAgentPilot::addAction(enum EActionType action_type) action.mType = action_type; action.mTarget = gAgent.getPositionGlobal(); action.mTime = mTimer.getElapsedTimeF32(); + LLViewerCamera *cam = LLViewerCamera::getInstance(); + action.mCameraView = cam->getView(); + action.mCameraOrigin = cam->getOrigin(); + action.mCameraXAxis = cam->getXAxis(); + action.mCameraYAxis = cam->getYAxis(); + action.mCameraZAxis = cam->getZAxis(); mLastRecordTime = (F32)action.mTime; mActions.put(action); } @@ -152,6 +259,7 @@ void LLAgentPilot::startPlayback() { llinfos << "Starting playback, moving to waypoint 0" << llendl; gAgent.startAutoPilotGlobal(mActions[0].mTarget); + moveCamera(); mStarted = FALSE; } else @@ -172,12 +280,53 @@ void LLAgentPilot::stopPlayback() gAgent.stopAutoPilot(); } - if (sReplaySession) + if (mReplaySession) { LLAppViewer::instance()->forceQuit(); } } +void LLAgentPilot::moveCamera() +{ + if (!getOverrideCamera()) + return; + + if (mCurrentAction<mActions.count()) + { + S32 start_index = llmax(mCurrentAction-1,0); + S32 end_index = mCurrentAction; + F32 t = 0.0; + F32 timedelta = mActions[end_index].mTime - mActions[start_index].mTime; + F32 tickelapsed = mTimer.getElapsedTimeF32()-mActions[start_index].mTime; + if (timedelta > 0.0) + { + t = tickelapsed/timedelta; + } + + if ((t<0.0)||(t>1.0)) + { + llwarns << "mCurrentAction is invalid, t = " << t << llendl; + return; + } + + Action& start = mActions[start_index]; + Action& end = mActions[end_index]; + + F32 view = lerp(start.mCameraView, end.mCameraView, t); + LLVector3 origin = lerp(start.mCameraOrigin, end.mCameraOrigin, t); + LLQuaternion start_quat(start.mCameraXAxis, start.mCameraYAxis, start.mCameraZAxis); + LLQuaternion end_quat(end.mCameraXAxis, end.mCameraYAxis, end.mCameraZAxis); + LLQuaternion quat = nlerp(t, start_quat, end_quat); + LLMatrix3 mat(quat); + + LLViewerCamera::getInstance()->setView(view); + LLViewerCamera::getInstance()->setOrigin(origin); + LLViewerCamera::getInstance()->mXAxis = LLVector3(mat.mMatrix[0]); + LLViewerCamera::getInstance()->mYAxis = LLVector3(mat.mMatrix[1]); + LLViewerCamera::getInstance()->mZAxis = LLVector3(mat.mMatrix[2]); + } +} + void LLAgentPilot::updateTarget() { if (mPlaying) @@ -209,12 +358,13 @@ void LLAgentPilot::updateTarget() if (mCurrentAction < mActions.count()) { gAgent.startAutoPilotGlobal(mActions[mCurrentAction].mTarget); + moveCamera(); } else { stopPlayback(); mNumRuns--; - if (sLoop) + if (mLoop) { if ((mNumRuns < 0) || (mNumRuns > 0)) { @@ -249,29 +399,8 @@ void LLAgentPilot::updateTarget() } } -// static -void LLAgentPilot::startRecord(void *) -{ - gAgentPilot.startRecord(); -} - -void LLAgentPilot::saveRecord(void *) +void LLAgentPilot::addWaypoint() { - gAgentPilot.stopRecord(); -} - -void LLAgentPilot::addWaypoint(void *) -{ - gAgentPilot.addAction(STRAIGHT); -} - -void LLAgentPilot::startPlayback(void *) -{ - gAgentPilot.mNumRuns = -1; - gAgentPilot.startPlayback(); + addAction(STRAIGHT); } -void LLAgentPilot::stopPlayback(void *) -{ - gAgentPilot.stopPlayback(); -} diff --git a/indra/newview/llagentpilot.h b/indra/newview/llagentpilot.h index f3d34246ae..dd1709ec0c 100644 --- a/indra/newview/llagentpilot.h +++ b/indra/newview/llagentpilot.h @@ -46,8 +46,12 @@ public: LLAgentPilot(); virtual ~LLAgentPilot(); - void load(const std::string& filename); - void save(const std::string& filename); + void load(); + void loadTxt(const std::string& filename); + void loadXML(const std::string& filename); + void save(); + void saveTxt(const std::string& filename); + void saveXML(const std::string& filename); void startRecord(); void stopRecord(); @@ -56,19 +60,34 @@ public: void startPlayback(); void stopPlayback(); + bool isRecording() { return mRecording; } + bool isPlaying() { return mPlaying; } + bool getOverrideCamera() { return mOverrideCamera; } + void updateTarget(); - static void startRecord(void *); - static void addWaypoint(void *); - static void saveRecord(void *); - static void startPlayback(void *); - static void stopPlayback(void *); - static BOOL sLoop; - static BOOL sReplaySession; + void addWaypoint(); + void moveCamera(); + + void setReplaySession(BOOL new_val) { mReplaySession = new_val; } + BOOL getReplaySession() { return mReplaySession; } + + void setLoop(BOOL new_val) { mLoop = new_val; } + BOOL getLoop() { return mLoop; } + + void setQuitAfterRuns(BOOL quit_val) { mQuitAfterRuns = quit_val; } + void setNumRuns(S32 num_runs) { mNumRuns = num_runs; } + +private: + + + + BOOL mLoop; + BOOL mReplaySession; S32 mNumRuns; BOOL mQuitAfterRuns; -private: + void setAutopilotTarget(const S32 id); BOOL mRecording; @@ -78,6 +97,8 @@ private: BOOL mPlaying; S32 mCurrentAction; + BOOL mOverrideCamera; + class Action { public: @@ -85,10 +106,16 @@ private: EActionType mType; LLVector3d mTarget; F64 mTime; + F32 mCameraView; + LLVector3 mCameraOrigin; + LLVector3 mCameraXAxis; + LLVector3 mCameraYAxis; + LLVector3 mCameraZAxis; }; LLDynamicArray<Action> mActions; LLTimer mTimer; + }; extern LLAgentPilot gAgentPilot; diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index f9e850899a..1388d9aee0 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -2773,75 +2773,6 @@ BOOL LLAppearanceMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const */ } -// Shim class to allow arbitrary boost::bind -// expressions to be run as one-time idle callbacks. -// -// TODO: rework idle function spec to take a boost::function in the first place. -class OnIdleCallbackOneTime -{ -public: - OnIdleCallbackOneTime(nullary_func_t callable): - mCallable(callable) - { - } - static void onIdle(void *data) - { - gIdleCallbacks.deleteFunction(onIdle, data); - OnIdleCallbackOneTime* self = reinterpret_cast<OnIdleCallbackOneTime*>(data); - self->call(); - delete self; - } - void call() - { - mCallable(); - } -private: - nullary_func_t mCallable; -}; - -void doOnIdleOneTime(nullary_func_t callable) -{ - OnIdleCallbackOneTime* cb_functor = new OnIdleCallbackOneTime(callable); - gIdleCallbacks.addFunction(&OnIdleCallbackOneTime::onIdle,cb_functor); -} - -// Shim class to allow generic boost functions to be run as -// recurring idle callbacks. Callable should return true when done, -// false to continue getting called. -// -// TODO: rework idle function spec to take a boost::function in the first place. -class OnIdleCallbackRepeating -{ -public: - OnIdleCallbackRepeating(bool_func_t callable): - mCallable(callable) - { - } - // Will keep getting called until the callable returns true. - static void onIdle(void *data) - { - OnIdleCallbackRepeating* self = reinterpret_cast<OnIdleCallbackRepeating*>(data); - bool done = self->call(); - if (done) - { - gIdleCallbacks.deleteFunction(onIdle, data); - delete self; - } - } - bool call() - { - return mCallable(); - } -private: - bool_func_t mCallable; -}; - -void doOnIdleRepeating(bool_func_t callable) -{ - OnIdleCallbackRepeating* cb_functor = new OnIdleCallbackRepeating(callable); - gIdleCallbacks.addFunction(&OnIdleCallbackRepeating::onIdle,cb_functor); -} - class CallAfterCategoryFetchStage2: public LLInventoryFetchItemsObserver { public: diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index c65d9dc9ee..4b1d95cf25 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -248,15 +248,6 @@ private: LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id,const std::string& name); -typedef boost::function<void ()> nullary_func_t; -typedef boost::function<bool ()> bool_func_t; - -// Call a given callable once in idle loop. -void doOnIdleOneTime(nullary_func_t callable); - -// Repeatedly call a callable in idle loop until it returns true. -void doOnIdleRepeating(bool_func_t callable); - // Invoke a given callable after category contents are fully fetched. void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 3bff57ab07..572a5a4683 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1,4 +1,4 @@ - /** +/** * @file llappviewer.cpp * @brief The LLAppViewer class definitions * @@ -46,6 +46,7 @@ #include "llviewerstats.h" #include "llviewerstatsrecorder.h" #include "llmd5.h" +#include "llmeshrepository.h" #include "llpumpio.h" #include "llmimetypes.h" #include "llslurl.h" @@ -75,6 +76,8 @@ #include "llteleporthistory.h" #include "lllocationhistory.h" #include "llfasttimerview.h" +#include "llvector4a.h" +#include "llviewermenufile.h" #include "llvoicechannel.h" #include "llvoavatarself.h" #include "llsidetray.h" @@ -200,7 +203,6 @@ // Include for security api initialization #include "llsecapi.h" #include "llmachineid.h" - #include "llmainlooprepeater.h" // *FIX: These extern globals should be cleaned up. @@ -506,8 +508,8 @@ static void settings_to_globals() LLSelectMgr::sRenderHiddenSelections = gSavedSettings.getBOOL("RenderHiddenSelections"); LLSelectMgr::sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius"); - gAgentPilot.mNumRuns = gSavedSettings.getS32("StatsNumRuns"); - gAgentPilot.mQuitAfterRuns = gSavedSettings.getBOOL("StatsQuitAfterRuns"); + gAgentPilot.setNumRuns(gSavedSettings.getS32("StatsNumRuns")); + gAgentPilot.setQuitAfterRuns(gSavedSettings.getBOOL("StatsQuitAfterRuns")); gAgent.setHideGroupTitle(gSavedSettings.getBOOL("RenderHideGroupTitle")); gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc"); @@ -517,7 +519,8 @@ static void settings_to_globals() static void settings_modify() { - LLRenderTarget::sUseFBO = gSavedSettings.getBOOL("RenderUseFBO"); + LLRenderTarget::sUseFBO = gSavedSettings.getBOOL("RenderDeferred"); + LLPipeline::sRenderDeferred = gSavedSettings.getBOOL("RenderDeferred"); LLVOAvatar::sUseImpostors = gSavedSettings.getBOOL("RenderUseImpostors"); LLVOSurfacePatch::sLODFactor = gSavedSettings.getF32("RenderTerrainLODFactor"); LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4] @@ -568,7 +571,7 @@ 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); } @@ -586,7 +589,6 @@ public: os.close(); } - }; //virtual @@ -672,6 +674,9 @@ bool LLAppViewer::init() // LLFastTimer::reset(); + // initialize SSE options + LLVector4a::initClass(); + // 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"); @@ -888,7 +893,7 @@ bool LLAppViewer::init() // Initialize the repeater service. LLMainLoopRepeater::instance().start(); - + // // Initialize the window // @@ -935,6 +940,18 @@ bool LLAppViewer::init() 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")) { @@ -994,7 +1011,7 @@ bool LLAppViewer::init() gDebugInfo["GraphicsCard"] = LLFeatureManager::getInstance()->getGPUString(); // Save the current version to the prefs file - gSavedSettings.setString("LastRunVersion", + gSavedSettings.setString("LastRunVersion", LLVersionInfo::getChannelAndVersion()); gSimLastTime = gRenderStartTime.getElapsedTimeF32(); @@ -1072,7 +1089,7 @@ bool LLAppViewer::mainLoop() gServicePump = new LLPumpIO(gAPRPoolp); LLHTTPClient::setPump(*gServicePump); LLCurl::setCAFile(gDirUtilp->getCAFile()); - + // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated. LLVoiceChannel::initClass(); @@ -1316,6 +1333,7 @@ bool LLAppViewer::mainLoop() break; } } + gMeshRepo.update() ; if(!total_work_pending) //pause texture fetching threads if nothing to process. { @@ -1421,6 +1439,20 @@ bool LLAppViewer::cleanup() // workaround for DEV-35406 crash on shutdown LLEventPumps::instance().reset(); + if (LLFastTimerView::sAnalyzePerformance) + { + llinfos << "Analyzing performance" << llendl; + std::string baseline_name = LLFastTimer::sLogName + "_baseline.slp"; + std::string current_name = LLFastTimer::sLogName + ".slp"; + std::string report_name = LLFastTimer::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)); + } + LLMetricPerformanceTesterBasic::cleanClass(); + // remove any old breakpad minidump files from the log directory if (! isError()) { @@ -1459,6 +1491,9 @@ bool LLAppViewer::cleanup() llinfos << "Cleaning Up" << llendflush; + // shut down mesh streamer + gMeshRepo.shutdown(); + // Must clean up texture references before viewer window is destroyed. if(LLHUDManager::instanceExists()) { @@ -1725,6 +1760,8 @@ bool LLAppViewer::cleanup() sTextureFetch->shutDownTextureCacheThread() ; sTextureFetch->shutDownImageDecodeThread() ; + LLFilePickerThread::cleanupClass(); + delete sTextureCache; sTextureCache = NULL; delete sTextureFetch; @@ -1746,7 +1783,8 @@ bool LLAppViewer::cleanup() gDirUtilp->getExpandedFilename(LL_PATH_LOGS, baseline_name), gDirUtilp->getExpandedFilename(LL_PATH_LOGS, current_name), gDirUtilp->getExpandedFilename(LL_PATH_LOGS, report_name)); - } + } + LLMetricPerformanceTesterBasic::cleanClass() ; #if LL_RECORD_VIEWER_STATS @@ -1874,6 +1912,11 @@ bool LLAppViewer::initThreads() mFastTimerLogThread->start(); } + // Mesh streaming and caching + gMeshRepo.init(); + + LLFilePickerThread::initClass(); + // *FIX: no error handling here! return true; } @@ -2086,6 +2129,8 @@ bool LLAppViewer::initConfiguration() gSavedSettings.setString("ClientSettingsFile", gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Global"))); + gSavedSettings.setString("VersionChannelName", LLVersionInfo::getChannel()); + #ifndef LL_RELEASE_FOR_DOWNLOAD // provide developer build only overrides for these control variables that are not // persisted to settings.xml @@ -2256,7 +2301,6 @@ bool LLAppViewer::initConfiguration() { LLVersionInfo::resetChannel(clp.getOption("channel")[0]); } - // If we have specified crash on startup, set the global so we'll trigger the crash at the right time if(clp.hasOption("crashonstartup")) @@ -2267,12 +2311,12 @@ bool LLAppViewer::initConfiguration() if (clp.hasOption("logperformance")) { LLFastTimer::sLog = TRUE; - LLFastTimer::sLogName = std::string("performance"); + LLFastTimer::sLogName = std::string("performance"); } if (clp.hasOption("logmetrics")) - { - LLFastTimer::sMetricLog = TRUE ; + { + LLFastTimer::sMetricLog = TRUE ; // '--logmetrics' can be specified with a named test metric argument so the data gathering is done only on that test // In the absence of argument, every metric is gathered (makes for a rather slow run and hard to decipher report...) std::string test_name = clp.getOption("logmetrics")[0]; @@ -2286,7 +2330,7 @@ bool LLAppViewer::initConfiguration() { LLFastTimer::sLogName = test_name; } - } + } if (clp.hasOption("graphicslevel")) { @@ -2329,7 +2373,7 @@ bool LLAppViewer::initConfiguration() if (clp.hasOption("replaysession")) { - LLAgentPilot::sReplaySession = TRUE; + gAgentPilot.setReplaySession(TRUE); } if (clp.hasOption("nonotifications")) @@ -2536,7 +2580,7 @@ bool LLAppViewer::initConfiguration() namespace { // *TODO - decide if there's a better place for these functions. - // do we need a file llupdaterui.cpp or something? -brad + // do we need a file llupdaterui.cpp or something? -brad void apply_update_callback(LLSD const & notification, LLSD const & response) { @@ -2629,8 +2673,8 @@ namespace { LLAppViewer::instance()->forceQuit(); } - bool notify_update(LLSD const & evt) - { + bool notify_update(LLSD const & evt) + { std::string notification_name; switch (evt["type"].asInteger()) { @@ -2649,8 +2693,8 @@ namespace { } // let others also handle this event by default - return false; - } + return false; + } bool on_bandwidth_throttle(LLUpdaterService * updater, LLSD const & evt) { @@ -2807,6 +2851,7 @@ bool LLAppViewer::initWindow() gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); gPipeline.init(); + stop_glerror(); gViewerWindow->initGLDefaults(); @@ -2881,7 +2926,7 @@ void LLAppViewer::cleanupSavedSettings() if (!maximized) { LLCoordScreen window_pos; - + if (gViewerWindow->mWindow->getPosition(&window_pos)) { gSavedSettings.setS32("WindowX", window_pos.mX); @@ -2971,6 +3016,8 @@ void LLAppViewer::writeSystemInfo() LL_INFOS("SystemInfo") << "OS: " << getOSInfo().getOSStringSimple() << LL_ENDL; LL_INFOS("SystemInfo") << "OS info: " << getOSInfo() << LL_ENDL; + LL_INFOS("SystemInfo") << "Timers: " << LLFastTimer::sClockType << LL_ENDL; + writeDebugInfo(); // Save out debug_info.log early, in case of crash. } @@ -3943,6 +3990,8 @@ static LLFastTimer::DeclareTimer FTM_OBJECTLIST_UPDATE("Update Objectlist"); static LLFastTimer::DeclareTimer FTM_REGION_UPDATE("Update Region"); static LLFastTimer::DeclareTimer FTM_WORLD_UPDATE("Update World"); static LLFastTimer::DeclareTimer FTM_NETWORK("Network"); +static LLFastTimer::DeclareTimer FTM_AGENT_NETWORK("Agent Network"); +static LLFastTimer::DeclareTimer FTM_VLMANAGER("VL Manager"); /////////////////////////////////////////////////////// // idle() @@ -3963,6 +4012,8 @@ void LLAppViewer::idle() LLEventTimer::updateClass(); LLCriticalDamp::updateInterpolants(); LLMortician::updateClass(); + LLFilePickerThread::clearDead(); //calls LLFilePickerThread::notify() + F32 dt_raw = idle_timer.getElapsedTimeAndResetF32(); // Cap out-of-control frame times @@ -4260,7 +4311,6 @@ void LLAppViewer::idle() // // Update weather effects // - LLWorld::getInstance()->updateClouds(gFrameDTClamped); gSky.propagateHeavenlyBodies(gFrameDTClamped); // moves sun, moon, and planets // Update wind vector @@ -4298,8 +4348,12 @@ void LLAppViewer::idle() LLWorld::getInstance()->updateParticles(); - if (LLViewerJoystick::getInstance()->getOverrideCamera()) + if (gAgentPilot.isPlaying() && gAgentPilot.getOverrideCamera()) { + gAgentPilot.moveCamera(); + } + else if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { LLViewerJoystick::getInstance()->moveFlycam(); } else @@ -4537,6 +4591,11 @@ static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME; #endif static LLFastTimer::DeclareTimer FTM_IDLE_NETWORK("Idle Network"); +static LLFastTimer::DeclareTimer FTM_MESSAGE_ACKS("Message Acks"); +static LLFastTimer::DeclareTimer FTM_RETRANSMIT("Retransmit"); +static LLFastTimer::DeclareTimer FTM_TIMEOUT_CHECK("Timeout Check"); +static LLFastTimer::DeclareTimer FTM_DYNAMIC_THROTTLE("Dynamic Throttle"); +static LLFastTimer::DeclareTimer FTM_CHECK_REGION_CIRCUIT("Check Region Circuit"); void LLAppViewer::idleNetwork() { diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index d328567a0e..6396ca91ff 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -26,12 +26,6 @@ #include "llviewerprecompiledheaders.h" -#if defined(_DEBUG) -# if _MSC_VER >= 1400 // Visual C++ 2005 or later -# define WINDOWS_CRT_MEM_CHECKS 1 -# endif -#endif - #include "llappviewerwin32.h" #include "llmemtype.h" @@ -440,7 +434,11 @@ bool LLAppViewerWin32::initHardwareTest() LL_WARNS("AppInit") << " Someone took over my exception handler (post hardware probe)!" << LL_ENDL; } - gGLManager.mVRAM = gDXHardware.getVRAM(); + if (gGLManager.mVRAM == 0) + { + gGLManager.mVRAM = gDXHardware.getVRAM(); + } + LL_INFOS("AppInit") << "Detected VRAM: " << gGLManager.mVRAM << LL_ENDL; return true; diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index dd5bc74b2a..c08771c5e7 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -60,6 +60,7 @@ #include "llnotificationsutil.h" #include "llscrolllistctrl.h" #include "llsdserialize.h" +#include "llsdutil.h" #include "llvfs.h" // When uploading multiple files, don't display any of them when uploading more than this number. @@ -67,6 +68,106 @@ static const S32 FILE_COUNT_DISPLAY_THRESHOLD = 5; void dialog_refresh_all(); +void on_new_single_inventory_upload_complete( + LLAssetType::EType asset_type, + LLInventoryType::EType inventory_type, + const std::string inventory_type_string, + const LLUUID& item_folder_id, + const std::string& item_name, + const std::string& item_description, + const LLSD& server_response, + S32 upload_price) +{ + if ( upload_price > 0 ) + { + // this upload costed us L$, update our balance + // and display something saying that it cost L$ + LLStatusBar::sendMoneyBalanceRequest(); + + LLSD args; + args["AMOUNT"] = llformat("%d", upload_price); + LLNotificationsUtil::add("UploadPayment", args); + } + + if( item_folder_id.notNull() ) + { + U32 everyone_perms = PERM_NONE; + U32 group_perms = PERM_NONE; + U32 next_owner_perms = PERM_ALL; + if( server_response.has("new_next_owner_mask") ) + { + // The server provided creation perms so use them. + // Do not assume we got the perms we asked for in + // since the server may not have granted them all. + everyone_perms = server_response["new_everyone_mask"].asInteger(); + group_perms = server_response["new_group_mask"].asInteger(); + next_owner_perms = server_response["new_next_owner_mask"].asInteger(); + } + else + { + // The server doesn't provide creation perms + // so use old assumption-based perms. + if( inventory_type_string != "snapshot") + { + next_owner_perms = PERM_MOVE | PERM_TRANSFER; + } + } + + LLPermissions new_perms; + new_perms.init( + gAgent.getID(), + gAgent.getID(), + LLUUID::null, + LLUUID::null); + + new_perms.initMasks( + PERM_ALL, + PERM_ALL, + everyone_perms, + group_perms, + next_owner_perms); + + S32 creation_date_now = time_corrected(); + LLPointer<LLViewerInventoryItem> item = new LLViewerInventoryItem( + server_response["new_inventory_item"].asUUID(), + item_folder_id, + new_perms, + server_response["new_asset"].asUUID(), + asset_type, + inventory_type, + item_name, + item_description, + LLSaleInfo::DEFAULT, + LLInventoryItemFlags::II_FLAGS_NONE, + creation_date_now); + + gInventory.updateItem(item); + gInventory.notifyObservers(); + + // Show the preview panel for textures and sounds to let + // user know that the image (or snapshot) arrived intact. + LLInventoryPanel* panel = LLInventoryPanel::getActiveInventoryPanel(); + if ( panel ) + { + LLFocusableElement* focus = gFocusMgr.getKeyboardFocus(); + + panel->setSelection( + server_response["new_inventory_item"].asUUID(), + TAKE_FOCUS_NO); + + // restore keyboard focus + gFocusMgr.setKeyboardFocus(focus); + } + } + else + { + llwarns << "Can't find a folder to put it in" << llendl; + } + + // remove the "Uploading..." message + LLUploadDialog::modalUploadFinished(); +} + LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data, const LLUUID& vfile_id, LLAssetType::EType asset_type) @@ -84,9 +185,10 @@ LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data, } } -LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data, - const std::string& file_name, - LLAssetType::EType asset_type) +LLAssetUploadResponder::LLAssetUploadResponder( + const LLSD &post_data, + const std::string& file_name, + LLAssetType::EType asset_type) : LLHTTPClient::Responder(), mPostData(post_data), mFileName(file_name), @@ -135,6 +237,7 @@ void LLAssetUploadResponder::result(const LLSD& content) lldebugs << "LLAssetUploadResponder::result from capabilities" << llendl; std::string state = content["state"]; + if (state == "upload") { uploadUpload(content); @@ -196,16 +299,36 @@ void LLAssetUploadResponder::uploadComplete(const LLSD& content) { } -LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data, - const LLUUID& vfile_id, - LLAssetType::EType asset_type) -: LLAssetUploadResponder(post_data, vfile_id, asset_type) +LLNewAgentInventoryResponder::LLNewAgentInventoryResponder( + const LLSD& post_data, + const LLUUID& vfile_id, + LLAssetType::EType asset_type) + : LLAssetUploadResponder(post_data, vfile_id, asset_type) { } -LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data, const std::string& file_name, LLAssetType::EType asset_type) -: LLAssetUploadResponder(post_data, file_name, asset_type) +LLNewAgentInventoryResponder::LLNewAgentInventoryResponder( + const LLSD& post_data, + const std::string& file_name, + LLAssetType::EType asset_type) + : LLAssetUploadResponder(post_data, file_name, asset_type) +{ +} + +// virtual +void LLNewAgentInventoryResponder::error(U32 statusNum, const std::string& reason) { + LLAssetUploadResponder::error(statusNum, reason); + //LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, LLUUID(), FALSE); +} + + +//virtual +void LLNewAgentInventoryResponder::uploadFailure(const LLSD& content) +{ + LLAssetUploadResponder::uploadFailure(content); + + //LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, content["new_asset"], FALSE); } //virtual @@ -219,95 +342,31 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) LLAssetType::EType asset_type = LLAssetType::lookup(mPostData["asset_type"].asString()); LLInventoryType::EType inventory_type = LLInventoryType::lookup(mPostData["inventory_type"].asString()); - S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); + S32 expected_upload_cost = 0; // Update L$ and ownership credit information // since it probably changed on the server if (asset_type == LLAssetType::AT_TEXTURE || asset_type == LLAssetType::AT_SOUND || - asset_type == LLAssetType::AT_ANIMATION) + asset_type == LLAssetType::AT_ANIMATION || + asset_type == LLAssetType::AT_MESH) { - LLStatusBar::sendMoneyBalanceRequest(); - - LLSD args; - args["AMOUNT"] = llformat("%d", expected_upload_cost); - LLNotificationsUtil::add("UploadPayment", args); + expected_upload_cost = + LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); } - // Actually add the upload to viewer inventory - llinfos << "Adding " << content["new_inventory_item"].asUUID() << " " - << content["new_asset"].asUUID() << " to inventory." << llendl; - if(mPostData["folder_id"].asUUID().notNull()) - { - //std::ostringstream out; - //LLSDXMLFormatter *formatter = new LLSDXMLFormatter; - //formatter->format(mPostData, out, LLSDFormatter::OPTIONS_PRETTY); - //llinfos << "Post Data: " << out.str() << llendl; + on_new_single_inventory_upload_complete( + asset_type, + inventory_type, + mPostData["asset_type"].asString(), + mPostData["folder_id"].asUUID(), + mPostData["name"], + mPostData["description"], + content, + expected_upload_cost); - U32 everyone_perms = PERM_NONE; - U32 group_perms = PERM_NONE; - U32 next_owner_perms = PERM_ALL; - if(content.has("new_next_owner_mask")) - { - // This is a new sim that provides creation perms so use them. - // Do not assume we got the perms we asked for in mPostData - // since the sim may not have granted them all. - everyone_perms = content["new_everyone_mask"].asInteger(); - group_perms = content["new_group_mask"].asInteger(); - next_owner_perms = content["new_next_owner_mask"].asInteger(); - } - else - { - // This old sim doesn't provide creation perms so use old assumption-based perms. - if(mPostData["inventory_type"].asString() != "snapshot") - { - next_owner_perms = PERM_MOVE | PERM_TRANSFER; - } - } - LLPermissions new_perms; - new_perms.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null); - new_perms.initMasks(PERM_ALL, PERM_ALL, everyone_perms, group_perms, next_owner_perms); - S32 creation_date_now = time_corrected(); - LLPointer<LLViewerInventoryItem> item - = new LLViewerInventoryItem(content["new_inventory_item"].asUUID(), - mPostData["folder_id"].asUUID(), - new_perms, - content["new_asset"].asUUID(), - asset_type, - inventory_type, - mPostData["name"].asString(), - mPostData["description"].asString(), - LLSaleInfo::DEFAULT, - LLInventoryItemFlags::II_FLAGS_NONE, - creation_date_now); - gInventory.updateItem(item); - gInventory.notifyObservers(); - - // Show the preview panel for textures and sounds to let - // user know that the image (or snapshot) arrived intact. - LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(); - if (active_panel) - { - active_panel->setSelection(content["new_inventory_item"].asUUID(), TAKE_FOCUS_NO); - if((LLAssetType::AT_TEXTURE == asset_type || LLAssetType::AT_SOUND == asset_type) - && LLFilePicker::instance().getFileCount() <= FILE_COUNT_DISPLAY_THRESHOLD) - { - active_panel->openSelected(); - } - //LLFloaterInventory::dumpSelectionInformation((void*)view); - // restore keyboard focus - LLFocusableElement* focus = gFocusMgr.getKeyboardFocus(); - gFocusMgr.setKeyboardFocus(focus); - } - } - else - { - llwarns << "Can't find a folder to put it in" << llendl; - } + // continue uploading for bulk uploads - // remove the "Uploading..." message - LLUploadDialog::modalUploadFinished(); - // *FIX: 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. @@ -324,19 +383,42 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content) // Continuing the horrible hack above, we need to extract the originally requested permissions data, if any, // and use them for each next file to be uploaded. Note the requested perms are not the same as the - // granted ones found in the given "content" structure but can still be found in mPostData. -MG - U32 everyone_perms = mPostData.has("everyone_mask") ? mPostData.get("everyone_mask" ).asInteger() : PERM_NONE; - U32 group_perms = mPostData.has("group_mask") ? mPostData.get("group_mask" ).asInteger() : PERM_NONE; - U32 next_owner_perms = mPostData.has("next_owner_mask") ? mPostData.get("next_owner_mask").asInteger() : PERM_NONE; + U32 everyone_perms = + content.has("everyone_mask") ? + content["everyone_mask"].asInteger() : + PERM_NONE; + + U32 group_perms = + content.has("group_mask") ? + content["group_mask"].asInteger() : + PERM_NONE; + + U32 next_owner_perms = + content.has("next_owner_mask") ? + content["next_owner_mask"].asInteger() : + PERM_NONE; + std::string display_name = LLStringUtil::null; LLAssetStorage::LLStoreAssetCallback callback = NULL; void *userdata = NULL; - upload_new_resource(next_file, asset_name, asset_name, - 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE, - next_owner_perms, group_perms, - everyone_perms, display_name, - callback, expected_upload_cost, userdata); + + upload_new_resource( + next_file, + asset_name, + asset_name, + 0, + LLFolderType::FT_NONE, + LLInventoryType::IT_NONE, + next_owner_perms, + group_perms, + everyone_perms, + display_name, + callback, + LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(), + userdata); } + + //LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, content["new_asset"], TRUE); } LLSendTexLayerResponder::LLSendTexLayerResponder(const LLSD& post_data, @@ -390,17 +472,19 @@ void LLSendTexLayerResponder::error(U32 statusNum, const std::string& reason) mBakedUploadData = NULL; // deleted in onTextureUploadComplete() } -LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& post_data, - const LLUUID& vfile_id, - LLAssetType::EType asset_type) -: LLAssetUploadResponder(post_data, vfile_id, asset_type) +LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder( + const LLSD& post_data, + const LLUUID& vfile_id, + LLAssetType::EType asset_type) + : LLAssetUploadResponder(post_data, vfile_id, asset_type) { } -LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& post_data, - const std::string& file_name, - LLAssetType::EType asset_type) -: LLAssetUploadResponder(post_data, file_name, asset_type) +LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder( + const LLSD& post_data, + const std::string& file_name, + LLAssetType::EType asset_type) + : LLAssetUploadResponder(post_data, file_name, asset_type) { } @@ -583,3 +667,474 @@ void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content) break; } } + + +///////////////////////////////////////////////////// +// LLNewAgentInventoryVariablePriceResponder::Impl // +///////////////////////////////////////////////////// +class LLNewAgentInventoryVariablePriceResponder::Impl +{ +public: + Impl( + const LLUUID& vfile_id, + LLAssetType::EType asset_type, + const LLSD& inventory_data) : + mVFileID(vfile_id), + mAssetType(asset_type), + mInventoryData(inventory_data), + mFileName("") + { + if (!gVFS->getExists(vfile_id, asset_type)) + { + llwarns + << "LLAssetUploadResponder called with nonexistant " + << "vfile_id " << vfile_id << llendl; + mVFileID.setNull(); + mAssetType = LLAssetType::AT_NONE; + } + } + + Impl( + const std::string& file_name, + LLAssetType::EType asset_type, + const LLSD& inventory_data) : + mFileName(file_name), + mAssetType(asset_type), + mInventoryData(inventory_data) + { + mVFileID.setNull(); + } + + std::string getFilenameOrIDString() const + { + return (mFileName.empty() ? mVFileID.asString() : mFileName); + } + + LLUUID getVFileID() const + { + return mVFileID; + } + + std::string getFilename() const + { + return mFileName; + } + + LLAssetType::EType getAssetType() const + { + return mAssetType; + } + + LLInventoryType::EType getInventoryType() const + { + return LLInventoryType::lookup( + mInventoryData["inventory_type"].asString()); + } + + std::string getInventoryTypeString() const + { + return mInventoryData["inventory_type"].asString(); + } + + LLUUID getFolderID() const + { + return mInventoryData["folder_id"].asUUID(); + } + + std::string getItemName() const + { + return mInventoryData["name"].asString(); + } + + std::string getItemDescription() const + { + return mInventoryData["description"].asString(); + } + + void displayCannotUploadReason(const std::string& reason) + { + LLSD args; + args["FILE"] = getFilenameOrIDString(); + args["REASON"] = reason; + + + LLNotificationsUtil::add("CannotUploadReason", args); + LLUploadDialog::modalUploadFinished(); + } + + void onApplicationLevelError(const LLSD& error) + { + static const std::string _IDENTIFIER = "identifier"; + + static const std::string _INSUFFICIENT_FUNDS = + "NewAgentInventory_InsufficientLindenDollarBalance"; + static const std::string _MISSING_REQUIRED_PARAMETER = + "NewAgentInventory_MissingRequiredParamater"; + static const std::string _INVALID_REQUEST_BODY = + "NewAgentInventory_InvalidRequestBody"; + static const std::string _RESOURCE_COST_DIFFERS = + "NewAgentInventory_ResourceCostDiffers"; + + static const std::string _MISSING_PARAMETER = "missing_parameter"; + static const std::string _INVALID_PARAMETER = "invalid_parameter"; + static const std::string _MISSING_RESOURCE = "missing_resource"; + static const std::string _INVALID_RESOURCE = "invalid_resource"; + + // TODO* Add the other error_identifiers + + std::string error_identifier = error[_IDENTIFIER].asString(); + + // TODO*: Pull these user visible strings from an xml file + // to be localized + if ( _INSUFFICIENT_FUNDS == error_identifier ) + { + displayCannotUploadReason("You do not have a sufficient L$ balance to complete this upload."); + } + else if ( _MISSING_REQUIRED_PARAMETER == error_identifier ) + { + // Missing parameters + if (error.has(_MISSING_PARAMETER) ) + { + std::string message = + "Upload request was missing required parameter '[P]'"; + LLStringUtil::replaceString( + message, + "[P]", + error[_MISSING_PARAMETER].asString()); + + displayCannotUploadReason(message); + } + else + { + std::string message = + "Upload request was missing a required parameter"; + displayCannotUploadReason(message); + } + } + else if ( _INVALID_REQUEST_BODY == error_identifier ) + { + // Invalid request body, check to see if + // a particular parameter was invalid + if ( error.has(_INVALID_PARAMETER) ) + { + std::string message = "Upload parameter '[P]' is invalid."; + LLStringUtil::replaceString( + message, + "[P]", + error[_INVALID_PARAMETER].asString()); + + // See if the server also responds with what resource + // is missing. + if ( error.has(_MISSING_RESOURCE) ) + { + message += "\nMissing resource '[R]'."; + + LLStringUtil::replaceString( + message, + "[R]", + error[_MISSING_RESOURCE].asString()); + } + else if ( error.has(_INVALID_RESOURCE) ) + { + message += "\nInvalid resource '[R]'."; + + LLStringUtil::replaceString( + message, + "[R]", + error[_INVALID_RESOURCE].asString()); + } + + displayCannotUploadReason(message); + } + else + { + std::string message = "Upload request was malformed"; + displayCannotUploadReason(message); + } + } + else if ( _RESOURCE_COST_DIFFERS == error_identifier ) + { + displayCannotUploadReason("The resource cost associated with this upload is not consistent with the server."); + } + else + { + displayCannotUploadReason("Unknown Error"); + } + } + + void onTransportError() + { + displayCannotUploadReason( + "The server is experiencing unexpected difficulties."); + } + + void onTransportError(const LLSD& error) + { + static const std::string _IDENTIFIER = "identifier"; + + static const std::string _SERVER_ERROR_AFTER_CHARGE = + "NewAgentInventory_ServerErrorAfterCharge"; + + std::string error_identifier = error[_IDENTIFIER].asString(); + + // TODO*: Pull the user visible strings from an xml file + // to be localized + + if ( _SERVER_ERROR_AFTER_CHARGE == error_identifier ) + { + displayCannotUploadReason( + "The server is experiencing unexpected difficulties. You may have been charged for the upload."); + } + else + { + displayCannotUploadReason( + "The server is experiencing unexpected difficulties."); + } + } + + bool uploadConfirmationCallback( + const LLSD& notification, + const LLSD& response, + boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder> responder) + { + S32 option; + std::string confirmation_url; + + option = LLNotificationsUtil::getSelectedOption( + notification, + response); + + confirmation_url = + notification["payload"]["confirmation_url"].asString(); + + // Yay! We are confirming or cancelling our upload + switch(option) + { + case 0: + { + confirmUpload(confirmation_url, responder); + } + break; + case 1: + default: + break; + } + + return false; + } + + void confirmUpload( + const std::string& confirmation_url, + boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder> responder) + { + if ( getFilename().empty() ) + { + // we have no filename, use virtual file ID instead + LLHTTPClient::postFile( + confirmation_url, + getVFileID(), + getAssetType(), + responder); + } + else + { + LLHTTPClient::postFile( + confirmation_url, + getFilename(), + responder); + } + } + + +private: + std::string mFileName; + + LLSD mInventoryData; + LLAssetType::EType mAssetType; + LLUUID mVFileID; +}; + +/////////////////////////////////////////////// +// LLNewAgentInventoryVariablePriceResponder // +/////////////////////////////////////////////// +LLNewAgentInventoryVariablePriceResponder::LLNewAgentInventoryVariablePriceResponder( + const LLUUID& vfile_id, + LLAssetType::EType asset_type, + const LLSD& inventory_info) +{ + mImpl = new Impl( + vfile_id, + asset_type, + inventory_info); +} + +LLNewAgentInventoryVariablePriceResponder::LLNewAgentInventoryVariablePriceResponder( + const std::string& file_name, + LLAssetType::EType asset_type, + const LLSD& inventory_info) +{ + mImpl = new Impl( + file_name, + asset_type, + inventory_info); +} + +LLNewAgentInventoryVariablePriceResponder::~LLNewAgentInventoryVariablePriceResponder() +{ + delete mImpl; +} + +void LLNewAgentInventoryVariablePriceResponder::errorWithContent( + U32 statusNum, + const std::string& reason, + const LLSD& content) +{ + lldebugs + << "LLNewAgentInventoryVariablePrice::error " << statusNum + << " reason: " << reason << llendl; + + if ( content.has("error") ) + { + static const std::string _ERROR = "error"; + + mImpl->onTransportError(content[_ERROR]); + } + else + { + mImpl->onTransportError(); + } +} + +void LLNewAgentInventoryVariablePriceResponder::result(const LLSD& content) +{ + // Parse out application level errors and the appropriate + // responses for them + static const std::string _ERROR = "error"; + static const std::string _STATE = "state"; + + static const std::string _COMPLETE = "complete"; + static const std::string _CONFIRM_UPLOAD = "confirm_upload"; + + static const std::string _UPLOAD_PRICE = "upload_price"; + static const std::string _RESOURCE_COST = "resource_cost"; + static const std::string _RSVP = "rsvp"; + + // Check for application level errors + if ( content.has(_ERROR) ) + { + onApplicationLevelError(content[_ERROR]); + return; + } + + std::string state = content[_STATE]; + LLAssetType::EType asset_type = mImpl->getAssetType(); + + if ( _COMPLETE == state ) + { + // rename file in VFS with new asset id + if (mImpl->getFilename().empty()) + { + // rename the file in the VFS to the actual asset id + // llinfos << "Changing uploaded asset UUID to " << content["new_asset"].asUUID() << llendl; + gVFS->renameFile( + mImpl->getVFileID(), + asset_type, + content["new_asset"].asUUID(), + asset_type); + } + + on_new_single_inventory_upload_complete( + asset_type, + mImpl->getInventoryType(), + mImpl->getInventoryTypeString(), + mImpl->getFolderID(), + mImpl->getItemName(), + mImpl->getItemDescription(), + content, + content[_UPLOAD_PRICE].asInteger()); + + // TODO* Add bulk (serial) uploading or add + // a super class of this that does so + } + else if ( _CONFIRM_UPLOAD == state ) + { + showConfirmationDialog( + content[_UPLOAD_PRICE].asInteger(), + content[_RESOURCE_COST].asInteger(), + content[_RSVP].asString()); + } + else + { + onApplicationLevelError(""); + } +} + +void LLNewAgentInventoryVariablePriceResponder::onApplicationLevelError( + const LLSD& error) +{ + mImpl->onApplicationLevelError(error); +} + +void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog( + S32 upload_price, + S32 resource_cost, + const std::string& confirmation_url) +{ + if ( 0 == upload_price ) + { + // don't show confirmation dialog for free uploads, I mean, + // they're free! + + // The creating of a new instrusive_ptr(this) + // creates a new boost::intrusive_ptr + // which is a copy of this. This code is required because + // 'this' is always of type Class* and not the intrusive_ptr, + // and thus, a reference to 'this' is not registered + // by using just plain 'this'. + + // Since LLNewAgentInventoryVariablePriceResponder is a + // reference counted class, it is possible (since the + // reference to a plain 'this' would be missed here) that, + // when using plain ol' 'this', that this object + // would be deleted before the callback is triggered + // and cause sadness. + mImpl->confirmUpload( + confirmation_url, + boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder>(this)); + } + else + { + LLSD substitutions; + LLSD payload; + + substitutions["PRICE"] = upload_price; + + payload["confirmation_url"] = confirmation_url; + + // The creating of a new instrusive_ptr(this) + // creates a new boost::intrusive_ptr + // which is a copy of this. This code is required because + // 'this' is always of type Class* and not the intrusive_ptr, + // and thus, a reference to 'this' is not registered + // by using just plain 'this'. + + // Since LLNewAgentInventoryVariablePriceResponder is a + // reference counted class, it is possible (since the + // reference to a plain 'this' would be missed here) that, + // when using plain ol' 'this', that this object + // would be deleted before the callback is triggered + // and cause sadness. + LLNotificationsUtil::add( + "UploadCostConfirmation", + substitutions, + payload, + boost::bind( + &LLNewAgentInventoryVariablePriceResponder::Impl::uploadConfirmationCallback, + mImpl, + _1, + _2, + boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder>(this))); + } +} + + diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h index 752c0dfe45..70871b62e2 100644 --- a/indra/newview/llassetuploadresponders.h +++ b/indra/newview/llassetuploadresponders.h @@ -55,15 +55,58 @@ protected: std::string mFileName; }; +// TODO*: Remove this once deprecated class LLNewAgentInventoryResponder : public LLAssetUploadResponder { public: - LLNewAgentInventoryResponder(const LLSD& post_data, - const LLUUID& vfile_id, - LLAssetType::EType asset_type); - LLNewAgentInventoryResponder(const LLSD& post_data, const std::string& file_name, - LLAssetType::EType asset_type); + LLNewAgentInventoryResponder( + const LLSD& post_data, + const LLUUID& vfile_id, + LLAssetType::EType asset_type); + LLNewAgentInventoryResponder( + const LLSD& post_data, + const std::string& file_name, + LLAssetType::EType asset_type); + virtual void error(U32 statusNum, const std::string& reason); virtual void uploadComplete(const LLSD& content); + virtual void uploadFailure(const LLSD& content); +}; + +// A base class which goes through and performs some default +// actions for variable price uploads. If more specific actions +// are needed (such as different confirmation messages, etc.) +// the functions onApplicationLevelError and showConfirmationDialog. +class LLNewAgentInventoryVariablePriceResponder : + public LLHTTPClient::Responder +{ +public: + LLNewAgentInventoryVariablePriceResponder( + const LLUUID& vfile_id, + LLAssetType::EType asset_type, + const LLSD& inventory_info); + + LLNewAgentInventoryVariablePriceResponder( + const std::string& file_name, + LLAssetType::EType asset_type, + const LLSD& inventory_info); + virtual ~LLNewAgentInventoryVariablePriceResponder(); + + void errorWithContent( + U32 statusNum, + const std::string& reason, + const LLSD& content); + void result(const LLSD& content); + + virtual void onApplicationLevelError( + const LLSD& error); + virtual void showConfirmationDialog( + S32 upload_price, + S32 resource_cost, + const std::string& confirmation_url); + +private: + class Impl; + Impl* mImpl; }; struct LLBakedUploadData; diff --git a/indra/newview/llcallbacklist.cpp b/indra/newview/llcallbacklist.cpp index a54c77b4a0..357a6582d1 100644 --- a/indra/newview/llcallbacklist.cpp +++ b/indra/newview/llcallbacklist.cpp @@ -115,6 +115,71 @@ void LLCallbackList::callFunctions() } } +// Shim class to allow arbitrary boost::bind +// expressions to be run as one-time idle callbacks. +class OnIdleCallbackOneTime +{ +public: + OnIdleCallbackOneTime(nullary_func_t callable): + mCallable(callable) + { + } + static void onIdle(void *data) + { + gIdleCallbacks.deleteFunction(onIdle, data); + OnIdleCallbackOneTime* self = reinterpret_cast<OnIdleCallbackOneTime*>(data); + self->call(); + delete self; + } + void call() + { + mCallable(); + } +private: + nullary_func_t mCallable; +}; + +void doOnIdleOneTime(nullary_func_t callable) +{ + OnIdleCallbackOneTime* cb_functor = new OnIdleCallbackOneTime(callable); + gIdleCallbacks.addFunction(&OnIdleCallbackOneTime::onIdle,cb_functor); +} + +// Shim class to allow generic boost functions to be run as +// recurring idle callbacks. Callable should return true when done, +// false to continue getting called. +class OnIdleCallbackRepeating +{ +public: + OnIdleCallbackRepeating(bool_func_t callable): + mCallable(callable) + { + } + // Will keep getting called until the callable returns true. + static void onIdle(void *data) + { + OnIdleCallbackRepeating* self = reinterpret_cast<OnIdleCallbackRepeating*>(data); + bool done = self->call(); + if (done) + { + gIdleCallbacks.deleteFunction(onIdle, data); + delete self; + } + } + bool call() + { + return mCallable(); + } +private: + bool_func_t mCallable; +}; + +void doOnIdleRepeating(bool_func_t callable) +{ + OnIdleCallbackRepeating* cb_functor = new OnIdleCallbackRepeating(callable); + gIdleCallbacks.addFunction(&OnIdleCallbackRepeating::onIdle,cb_functor); +} + #ifdef _DEBUG void test1(void *data) diff --git a/indra/newview/llcallbacklist.h b/indra/newview/llcallbacklist.h index 07ac21f5e9..97f3bfd9ee 100644 --- a/indra/newview/llcallbacklist.h +++ b/indra/newview/llcallbacklist.h @@ -52,6 +52,15 @@ protected: callback_list_t mCallbackList; }; +typedef boost::function<void ()> nullary_func_t; +typedef boost::function<bool ()> bool_func_t; + +// Call a given callable once in idle loop. +void doOnIdleOneTime(nullary_func_t callable); + +// Repeatedly call a callable in idle loop until it returns true. +void doOnIdleRepeating(bool_func_t callable); + extern LLCallbackList gIdleCallbacks; #endif diff --git a/indra/newview/lldebugview.cpp b/indra/newview/lldebugview.cpp index 0876c3fd99..b6d67899f8 100644 --- a/indra/newview/lldebugview.cpp +++ b/indra/newview/lldebugview.cpp @@ -39,7 +39,9 @@ #include "llviewerwindow.h" #include "llappviewer.h" #include "llmemoryview.h" +#include "llsceneview.h" #include "llviewertexture.h" + // // Globals // @@ -83,6 +85,13 @@ void LLDebugView::init() addChild(mFastTimerView); mFastTimerView->setRect(rect); + gSceneView = new LLSceneView(r); + gSceneView->setFollowsTop(); + gSceneView->setFollowsLeft(); + gSceneView->setVisible(FALSE); + addChild(gSceneView); + gSceneView->setRect(rect); + r.setLeftTopAndSize(25, rect.getHeight() - 50, (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f), (S32) (gViewerWindow->getWindowRectScaled().getHeight() * 0.75f)); LLMemoryView::Params mp; @@ -103,6 +112,9 @@ void LLDebugView::init() addChild(gTextureView); //gTextureView->reshape(r.getWidth(), r.getHeight(), TRUE); + + + if(gAuditTexture) { r.set(150, rect.getHeight() - 50, 900 + LLImageGL::sTextureLoadedCounter.size() * 30, 100); @@ -133,6 +145,7 @@ LLDebugView::~LLDebugView() // These have already been deleted. Fix the globals appropriately. gDebugView = NULL; gTextureView = NULL; + gSceneView = NULL; gTextureSizeView = NULL; gTextureCategoryView = NULL; } diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 8106fada11..bdc12ec0e3 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -35,6 +35,7 @@ #include "llcriticaldamp.h" #include "llface.h" #include "lllightconstants.h" +#include "llmatrix4a.h" #include "llsky.h" #include "llsurfacepatch.h" #include "llviewercamera.h" @@ -85,6 +86,7 @@ void LLDrawable::incrementVisible() sCurVisible++; sCurPixelAngle = (F32) gViewerWindow->getWindowHeightRaw()/LLViewerCamera::getInstance()->getView(); } + void LLDrawable::init() { // mXform @@ -115,6 +117,11 @@ void LLDrawable::initClass() void LLDrawable::destroy() { + if (gDebugGL) + { + gPipeline.checkReferences(this); + } + if (isDead()) { sNumZombieDrawables--; @@ -133,6 +140,7 @@ void LLDrawable::destroy() { llinfos << "- Zombie drawables: " << sNumZombieDrawables << llendl; }*/ + } void LLDrawable::markDead() @@ -170,6 +178,11 @@ LLVOVolume* LLDrawable::getVOVolume() const } } +const LLMatrix4& LLDrawable::getRenderMatrix() const +{ + return isRoot() ? getWorldMatrix() : getParent()->getWorldMatrix(); +} + BOOL LLDrawable::isLight() const { LLViewerObject* objectp = mVObjp; @@ -183,20 +196,30 @@ BOOL LLDrawable::isLight() const } } +static LLFastTimer::DeclareTimer FTM_CLEANUP_DRAWABLE("Cleanup Drawable"); +static LLFastTimer::DeclareTimer FTM_DEREF_DRAWABLE("Deref"); +static LLFastTimer::DeclareTimer FTM_DELETE_FACES("Faces"); + void LLDrawable::cleanupReferences() { - LLFastTimer t(FTM_PIPELINE); + LLFastTimer t(FTM_CLEANUP_DRAWABLE); - std::for_each(mFaces.begin(), mFaces.end(), DeletePointer()); - mFaces.clear(); + { + LLFastTimer t(FTM_DELETE_FACES); + std::for_each(mFaces.begin(), mFaces.end(), DeletePointer()); + mFaces.clear(); + } gObjectList.removeDrawable(this); gPipeline.unlinkDrawable(this); - // Cleanup references to other objects - mVObjp = NULL; - mParent = NULL; + { + LLFastTimer t(FTM_DEREF_DRAWABLE); + // Cleanup references to other objects + mVObjp = NULL; + mParent = NULL; + } } void LLDrawable::cleanupDeadDrawables() @@ -685,13 +708,15 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) LLVOVolume* volume = getVOVolume(); if (volume) { - volume->updateRelativeXform(); - pos = volume->getRelativeXform().getTranslation(); - if (isStatic()) + if (getSpatialGroup()) { - pos += volume->getRegion()->getOriginAgent(); + pos.set(getPositionGroup().getF32ptr()); } - + else + { + pos = getPositionAgent(); + } + if (isState(LLDrawable::HAS_ALPHA)) { for (S32 i = 0; i < getNumFaces(); i++) @@ -699,21 +724,23 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) LLFace* facep = getFace(i); if (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA) { - LLVector3 box = (facep->mExtents[1] - facep->mExtents[0]) * 0.25f; + LLVector4a box; + box.setSub(facep->mExtents[1], facep->mExtents[0]); + box.mul(0.25f); LLVector3 v = (facep->mCenterLocal-camera.getOrigin()); const LLVector3& at = camera.getAtAxis(); for (U32 j = 0; j < 3; j++) { - v.mV[j] -= box.mV[j] * at.mV[j]; + v.mV[j] -= box[j] * at.mV[j]; } facep->mDistance = v * camera.getAtAxis(); } } - } + } } else { - pos = LLVector3(getPositionGroup()); + pos = LLVector3(getPositionGroup().getF32ptr()); } pos -= camera.getOrigin(); @@ -739,7 +766,7 @@ void LLDrawable::updateTexture() if (getVOVolume()) { - if (isActive()) + /*if (isActive()) { if (isRoot()) { @@ -749,7 +776,7 @@ void LLDrawable::updateTexture() { getParent()->mQuietCount = 0; } - } + }*/ gPipeline.markRebuild(this, LLDrawable::REBUILD_MATERIAL, TRUE); } @@ -762,7 +789,7 @@ BOOL LLDrawable::updateGeometry(BOOL priority) return res; } -void LLDrawable::shiftPos(const LLVector3 &shift_vector) +void LLDrawable::shiftPos(const LLVector4a &shift_vector) { if (isDead()) { @@ -794,20 +821,19 @@ void LLDrawable::shiftPos(const LLVector3 &shift_vector) for (S32 i = 0; i < getNumFaces(); i++) { LLFace *facep = getFace(i); - facep->mCenterAgent += shift_vector; - facep->mExtents[0] += shift_vector; - facep->mExtents[1] += shift_vector; + facep->mCenterAgent += LLVector3(shift_vector.getF32ptr()); + facep->mExtents[0].add(shift_vector); + facep->mExtents[1].add(shift_vector); if (!volume && facep->hasGeometry()) { - facep->mVertexBuffer = NULL; - facep->mLastVertexBuffer = NULL; + facep->clearVertexBuffer(); } } - mExtents[0] += shift_vector; - mExtents[1] += shift_vector; - mPositionGroup += LLVector3d(shift_vector); + mExtents[0].add(shift_vector); + mExtents[1].add(shift_vector); + mPositionGroup.add(shift_vector); } else if (mSpatialBridge) { @@ -815,9 +841,9 @@ void LLDrawable::shiftPos(const LLVector3 &shift_vector) } else if (isAvatar()) { - mExtents[0] += shift_vector; - mExtents[1] += shift_vector; - mPositionGroup += LLVector3d(shift_vector); + mExtents[0].add(shift_vector); + mExtents[1].add(shift_vector); + mPositionGroup.add(shift_vector); } mVObjp->onShift(shift_vector); @@ -829,21 +855,26 @@ const LLVector3& LLDrawable::getBounds(LLVector3& min, LLVector3& max) const return mXform.getPositionW(); } -const LLVector3* LLDrawable::getSpatialExtents() const +const LLVector4a* LLDrawable::getSpatialExtents() const { return mExtents; } -void LLDrawable::setSpatialExtents(LLVector3 min, LLVector3 max) +void LLDrawable::setSpatialExtents(const LLVector3& min, const LLVector3& max) +{ + mExtents[0].load3(min.mV); + mExtents[1].load3(max.mV); +} + +void LLDrawable::setSpatialExtents(const LLVector4a& min, const LLVector4a& max) { - LLVector3 size = max - min; mExtents[0] = min; - mExtents[1] = max; + mExtents[1] = max; } -void LLDrawable::setPositionGroup(const LLVector3d& pos) +void LLDrawable::setPositionGroup(const LLVector4a& pos) { - mPositionGroup.setVec(pos); + mPositionGroup = pos; } void LLDrawable::updateSpatialExtents() @@ -857,7 +888,7 @@ void LLDrawable::updateSpatialExtents() if (mSpatialBridge.notNull()) { - mPositionGroup.setVec(0,0,0); + mPositionGroup.splat(0.f); } } @@ -910,6 +941,18 @@ void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp) { mSpatialGroupp->setState(LLSpatialGroup::GEOM_DIRTY); }*/ + + if (mSpatialGroupp != groupp && getVOVolume()) + { //NULL out vertex buffer references for volumes on spatial group change to maintain + //requirement that every face vertex buffer is either NULL or points to a vertex buffer + //contained by its drawable's spatial group + for (S32 i = 0; i < getNumFaces(); ++i) + { + LLFace* facep = getFace(i); + facep->clearVertexBuffer(); + } + } + mSpatialGroupp = groupp; } @@ -1027,7 +1070,7 @@ BOOL LLDrawable::isVisible() const //======================================= LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask) -: LLSpatialPartition(data_mask, render_by_group, FALSE) +: LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB) { mDrawable = root; root->setSpatialBridge(this); @@ -1068,59 +1111,72 @@ void LLSpatialBridge::updateSpatialExtents() root->rebound(); } - LLXformMatrix* mat = mDrawable->getXform(); - - LLVector3 offset = root->mBounds[0]; - LLVector3 size = root->mBounds[1]; + LLVector4a offset; + LLVector4a size = root->mBounds[1]; - LLVector3 center = LLVector3(0,0,0) * mat->getWorldMatrix(); - LLQuaternion rotation = LLQuaternion(mat->getWorldMatrix()); + //VECTORIZE THIS + LLMatrix4a mat; + mat.loadu(mDrawable->getXform()->getWorldMatrix()); + + LLVector4a t; + t.splat(0.f); + + LLVector4a center; + mat.affineTransform(t, center); - offset *= rotation; - center += offset; + mat.rotate(root->mBounds[0], offset); + center.add(offset); - LLVector3 v[4]; + LLVector4a v[4]; + //get 4 corners of bounding box - v[0] = (size * rotation); - v[1] = (LLVector3(-size.mV[0], -size.mV[1], size.mV[2]) * rotation); - v[2] = (LLVector3(size.mV[0], -size.mV[1], -size.mV[2]) * rotation); - v[3] = (LLVector3(-size.mV[0], size.mV[1], -size.mV[2]) * rotation); + mat.rotate(size,v[0]); - LLVector3& newMin = mExtents[0]; - LLVector3& newMax = mExtents[1]; + LLVector4a scale; + + scale.set(-1.f, -1.f, 1.f); + scale.mul(size); + mat.rotate(scale, v[1]); + + scale.set(1.f, -1.f, -1.f); + scale.mul(size); + mat.rotate(scale, v[2]); + + scale.set(-1.f, 1.f, -1.f); + scale.mul(size); + mat.rotate(scale, v[3]); + + + LLVector4a& newMin = mExtents[0]; + LLVector4a& newMax = mExtents[1]; newMin = newMax = center; for (U32 i = 0; i < 4; i++) { - for (U32 j = 0; j < 3; j++) - { - F32 delta = fabsf(v[i].mV[j]); - F32 min = center.mV[j] - delta; - F32 max = center.mV[j] + delta; - - if (min < newMin.mV[j]) - { - newMin.mV[j] = min; - } - - if (max > newMax.mV[j]) - { - newMax.mV[j] = max; - } - } - } + LLVector4a delta; + delta.setAbs(v[i]); + LLVector4a min; + min.setSub(center, delta); + LLVector4a max; + max.setAdd(center, delta); - LLVector3 diagonal = newMax - newMin; - mRadius = diagonal.magVec() * 0.5f; + newMin.setMin(newMin, min); + newMax.setMax(newMax, max); + } + + LLVector4a diagonal; + diagonal.setSub(newMax, newMin); + mRadius = diagonal.getLength3().getF32() * 0.5f; - mPositionGroup.setVec((newMin + newMax) * 0.5f); + mPositionGroup.setAdd(newMin,newMax); + mPositionGroup.mul(0.5f); updateBinRadius(); } void LLSpatialBridge::updateBinRadius() { - mBinRadius = llmin((F32) mOctree->getSize().mdV[0]*0.5f, 256.f); + mBinRadius = llmin( mOctree->getSize()[0]*0.5f, 256.f); } LLCamera LLSpatialBridge::transformCamera(LLCamera& camera) @@ -1261,8 +1317,12 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); group->rebound(); - LLVector3 center = (mExtents[0] + mExtents[1]) * 0.5f; - LLVector3 size = (mExtents[1]-mExtents[0]) * 0.5f; + LLVector4a center; + center.setAdd(mExtents[0], mExtents[1]); + center.mul(0.5f); + LLVector4a size; + size.setSub(mExtents[1], mExtents[0]); + size.mul(0.5f); if ((LLPipeline::sShadowRender && camera_in.AABBInFrustum(center, size)) || LLPipeline::sImpostorRender || @@ -1375,11 +1435,11 @@ BOOL LLSpatialBridge::updateMove() return TRUE; } -void LLSpatialBridge::shiftPos(const LLVector3& vec) +void LLSpatialBridge::shiftPos(const LLVector4a& vec) { - mExtents[0] += vec; - mExtents[1] += vec; - mPositionGroup += LLVector3d(vec); + mExtents[0].add(vec); + mExtents[1].add(vec); + mPositionGroup.add(vec); } void LLSpatialBridge::cleanupReferences() @@ -1497,7 +1557,7 @@ F32 LLHUDBridge::calcPixelArea(LLSpatialGroup* group, LLCamera& camera) } -void LLHUDBridge::shiftPos(const LLVector3& vec) +void LLHUDBridge::shiftPos(const LLVector4a& vec) { //don't shift hud bridges on region crossing } diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 2cea41df0a..9ebe1a45b4 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -35,6 +35,7 @@ #include "v4math.h" #include "m4math.h" #include "v4coloru.h" +#include "llvector4a.h" #include "llquaternion.h" #include "xform.h" #include "llmemtype.h" @@ -61,6 +62,17 @@ const U32 SILHOUETTE_HIGHLIGHT = 0; class LLDrawable : public LLRefCount { public: + LLDrawable(const LLDrawable& rhs) + { + *this = rhs; + } + + const LLDrawable& operator=(const LLDrawable& rhs) + { + llerrs << "Illegal operation!" << llendl; + return *this; + } + static void initClass(); LLDrawable() { init(); } @@ -84,19 +96,19 @@ public: LLVOVolume* getVOVolume() const; // cast mVObjp tp LLVOVolume if OK const LLMatrix4& getWorldMatrix() const { return mXform.getWorldMatrix(); } - const LLMatrix4& getRenderMatrix() const { return isRoot() ? getWorldMatrix() : getParent()->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 LLVector3d& getPositionGroup() const { return mPositionGroup; } + const LLVector4a& getPositionGroup() const { return mPositionGroup; } 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; } - F64 getBinRadius() const { return mBinRadius; } + F32 getBinRadius() const { return mBinRadius; } void getMinMax(LLVector3& min,LLVector3& max) const { mXform.getMinMax(min,max); } LLXformMatrix* getXform() { return &mXform; } @@ -150,7 +162,7 @@ public: void updateSpecialHoverCursor(BOOL enabled); - virtual void shiftPos(const LLVector3 &shift_vector); + virtual void shiftPos(const LLVector4a &shift_vector); S32 getGeneration() const { return mGeneration; } @@ -168,11 +180,12 @@ public: const LLVector3& getBounds(LLVector3& min, LLVector3& max) const; virtual void updateSpatialExtents(); virtual void updateBinRadius(); - const LLVector3* getSpatialExtents() const; - void setSpatialExtents(LLVector3 min, LLVector3 max); - void setPositionGroup(const LLVector3d& pos); - void setPositionGroup(const LLVector3& pos) { setPositionGroup(LLVector3d(pos)); } + const LLVector4a* getSpatialExtents() const; + void setSpatialExtents(const LLVector3& min, const LLVector3& max); + void setSpatialExtents(const LLVector4a& min, const LLVector4a& max); + void setPositionGroup(const LLVector4a& pos); + void setRenderType(S32 type) { mRenderType = type; } BOOL isRenderType(S32 type) { return mRenderType == type; } S32 getRenderType() { return mRenderType; } @@ -232,37 +245,44 @@ public: typedef enum e_drawable_flags { - IN_REBUILD_Q1 = 0x00000002, - IN_REBUILD_Q2 = 0x00000004, - IN_LIGHT_Q = 0x00000008, - EARLY_MOVE = 0x00000010, - MOVE_UNDAMPED = 0x00000020, - ON_MOVE_LIST = 0x00000040, - USE_BACKLIGHT = 0x00000080, - UV = 0x00000100, - UNLIT = 0x00000200, - LIGHT = 0x00000400, - LIGHTING_BUILT = 0x00000800, - REBUILD_VOLUME = 0x00001000, //volume changed LOD or parameters, or vertex buffer changed - REBUILD_TCOORD = 0x00002000, //texture coordinates changed - REBUILD_COLOR = 0x00004000, //color changed - REBUILD_POSITION= 0x00010000, //vertex positions/normals changed + IN_REBUILD_Q1 = 0x00000001, + IN_REBUILD_Q2 = 0x00000002, + IN_LIGHT_Q = 0x00000004, + EARLY_MOVE = 0x00000008, + MOVE_UNDAMPED = 0x00000010, + ON_MOVE_LIST = 0x00000020, + USE_BACKLIGHT = 0x00000040, + UV = 0x00000080, + UNLIT = 0x00000100, + LIGHT = 0x00000200, + LIGHTING_BUILT = 0x00000400, + REBUILD_VOLUME = 0x00000800, //volume changed LOD or parameters, or vertex buffer changed + REBUILD_TCOORD = 0x00001000, //texture coordinates changed + REBUILD_COLOR = 0x00002000, //color changed + REBUILD_POSITION= 0x00004000, //vertex positions/normals changed REBUILD_GEOMETRY= REBUILD_POSITION|REBUILD_TCOORD|REBUILD_COLOR, REBUILD_MATERIAL= REBUILD_TCOORD|REBUILD_COLOR, REBUILD_ALL = REBUILD_GEOMETRY|REBUILD_VOLUME, - ON_SHIFT_LIST = 0x00100000, - BLOCKER = 0x00400000, - ACTIVE = 0x00800000, - DEAD = 0x01000000, - INVISIBLE = 0x02000000, // stay invisible until flag is cleared - NEARBY_LIGHT = 0x04000000, // In gPipeline.mNearbyLightSet - BUILT = 0x08000000, - FORCE_INVISIBLE = 0x10000000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned) - CLEAR_INVISIBLE = 0x20000000, // clear FORCE_INVISIBLE next draw frame - REBUILD_SHADOW = 0x40000000, - HAS_ALPHA = 0x80000000, + REBUILD_RIGGED = 0x00008000, + ON_SHIFT_LIST = 0x00010000, + BLOCKER = 0x00020000, + ACTIVE = 0x00040000, + DEAD = 0x00080000, + INVISIBLE = 0x00100000, // stay invisible until flag is cleared + NEARBY_LIGHT = 0x00200000, // In gPipeline.mNearbyLightSet + BUILT = 0x00400000, + FORCE_INVISIBLE = 0x00800000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned) + CLEAR_INVISIBLE = 0x01000000, // clear FORCE_INVISIBLE next draw frame + REBUILD_SHADOW = 0x02000000, + HAS_ALPHA = 0x04000000, + RIGGED = 0x08000000, } EDrawableFlags; +private: //aligned members + LLVector4a mExtents[2]; + LLVector4a mPositionGroup; + +public: LLXformMatrix mXform; // vis data @@ -292,9 +312,7 @@ private: mutable U32 mVisible; F32 mRadius; - LLVector3 mExtents[2]; - LLVector3d mPositionGroup; - F64 mBinRadius; + F32 mBinRadius; S32 mGeneration; LLVector3 mCurrentScale; diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index ba576ff97f..25e4bc847c 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -243,11 +243,6 @@ void LLFacePool::dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures { } -BOOL LLFacePool::moveFace(LLFace *face, LLDrawPool *poolp, BOOL copy_data) -{ - return TRUE; -} - // static S32 LLFacePool::drawLoop(face_array_t& face_list) { diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index 1d6f99d346..d3fd9ead0d 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -47,14 +47,14 @@ public: { // Correspond to LLPipeline render type POOL_SIMPLE = 1, + POOL_GROUND, + POOL_FULLBRIGHT, + POOL_BUMP, POOL_TERRAIN, - POOL_TREE, POOL_SKY, POOL_WL_SKY, - POOL_GROUND, + POOL_TREE, POOL_GRASS, - POOL_FULLBRIGHT, - POOL_BUMP, POOL_INVISIBLE, // see below * POOL_AVATAR, POOL_VOIDWATER, @@ -182,8 +182,6 @@ public: virtual void resetDrawOrders(); void resetAll(); - BOOL moveFace(LLFace *face, LLDrawPool *poolp, BOOL copy_data = FALSE); - void destroy(); void buildEdges(); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index a2428d2de0..8b5a2ce781 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -103,16 +103,40 @@ void LLDrawPoolAlpha::renderDeferred(S32 pass) S32 LLDrawPoolAlpha::getNumPostDeferredPasses() { - return 1; + if (LLPipeline::sImpostorRender) + { //skip depth buffer filling pass when rendering impostors + return 1; + } + else if (gSavedSettings.getBOOL("RenderDepthOfField")) + { + return 2; + } + else + { + return 1; + } } void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass) { LLFastTimer t(FTM_RENDER_ALPHA); - simple_shader = &gDeferredAlphaProgram; - fullbright_shader = &gDeferredFullbrightProgram; - + if (pass == 0) + { + simple_shader = &gDeferredAlphaProgram; + fullbright_shader = &gDeferredFullbrightProgram; + } + else + { + //update depth buffer sampler + gPipeline.mScreen.flush(); + gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(), + 0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); + gPipeline.mDeferredDepth.bindTarget(); + simple_shader = NULL; + fullbright_shader = NULL; + } + deferred_render = TRUE; if (mVertexShaderLevel > 0) { @@ -124,6 +148,13 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass) void LLDrawPoolAlpha::endPostDeferredPass(S32 pass) { + + if (pass == 1) + { + gPipeline.mDeferredDepth.flush(); + gPipeline.mScreen.bindTarget(); + } + deferred_render = FALSE; endRenderPass(pass); } @@ -174,9 +205,16 @@ void LLDrawPoolAlpha::render(S32 pass) LLGLSPipelineAlpha gls_pipeline_alpha; - gGL.setColorMask(true, true); + if (deferred_render && pass == 1) + { //depth only + gGL.setColorMask(false, false); + } + else + { + gGL.setColorMask(true, true); + } - if (LLPipeline::sAutoMaskAlphaNonDeferred && !deferred_render) + if (LLPipeline::sAutoMaskAlphaNonDeferred) { mColorSFactor = LLRender::BF_ONE; // } mColorDFactor = LLRender::BF_ZERO; // } these are like disabling blend on the color channels, but we're still blending on the alpha channel so that we can suppress glow @@ -192,7 +230,10 @@ void LLDrawPoolAlpha::render(S32 pass) simple_shader->bind(); pushBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask()); } - fullbright_shader->bind(); + if (fullbright_shader) + { + fullbright_shader->bind(); + } pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask()); LLGLSLShader::bindNoShader(); } @@ -206,18 +247,42 @@ void LLDrawPoolAlpha::render(S32 pass) gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } - LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ? GL_TRUE : GL_FALSE); + LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy || + (deferred_render && pass == 1) ? GL_TRUE : GL_FALSE); - mColorSFactor = LLRender::BF_SOURCE_ALPHA; // } regular alpha blend - mColorDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // } - mAlphaSFactor = LLRender::BF_ZERO; // } glow suppression - mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // } - gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); + if (deferred_render && pass == 1) + { + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.33f); + gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); + } + else + { + mColorSFactor = LLRender::BF_SOURCE_ALPHA; // } regular alpha blend + mColorDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // } + mAlphaSFactor = LLRender::BF_ZERO; // } glow suppression + mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // } + gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); + + if (LLPipeline::sImpostorRender) + { + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); + } + else + { + gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + } + } renderAlpha(getVertexDataMask()); gGL.setColorMask(true, false); + if (deferred_render && pass == 1) + { + gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + } + if (deferred_render && current_shader != NULL) { gPipeline.unbindDeferredShader(*current_shader); @@ -276,22 +341,10 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) BOOL light_enabled = TRUE; S32 diffuse_channel = 0; - //BOOL is_particle = FALSE; BOOL use_shaders = (LLPipeline::sUnderWaterRender && gPipeline.canUseVertexShaders()) || gPipeline.canUseWindLightShadersOnObjects(); - // check to see if it's a particle and if it's "close" - { - if (LLPipeline::sImpostorRender) - { - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); - } - else - { - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); - } - } - + for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { LLSpatialGroup* group = *i; diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index dbd5da31a6..645c7ebcae 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -31,15 +31,21 @@ #include "llvoavatar.h" #include "m3math.h" +#include "llmatrix4a.h" +#include "llagent.h" //for gAgent.needsRenderAvatar() #include "lldrawable.h" +#include "lldrawpoolbump.h" #include "llface.h" +#include "llmeshrepository.h" #include "llsky.h" #include "llviewercamera.h" #include "llviewerregion.h" #include "noise.h" #include "pipeline.h" #include "llviewershadermgr.h" +#include "llvovolume.h" +#include "llvolume.h" #include "llappviewer.h" #include "llrendersphere.h" #include "llviewerpartsim.h" @@ -47,10 +53,15 @@ static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK; static U32 sBufferUsage = GL_STREAM_DRAW_ARB; static U32 sShaderLevel = 0; -static LLGLSLShader* sVertexProgram = NULL; + +LLGLSLShader* LLDrawPoolAvatar::sVertexProgram = NULL; BOOL LLDrawPoolAvatar::sSkipOpaque = FALSE; BOOL LLDrawPoolAvatar::sSkipTransparent = FALSE; +S32 LLDrawPoolAvatar::sDiffuseChannel = 0; + + +static bool is_deferred_render = false; extern BOOL gUseGLPick; @@ -86,7 +97,7 @@ BOOL gAvatarEmbossBumpMap = FALSE; static BOOL sRenderingSkinned = FALSE; S32 normal_channel = -1; S32 specular_channel = -1; -S32 diffuse_channel = -1; +S32 cube_channel = -1; static LLFastTimer::DeclareTimer FTM_SHADOW_AVATAR("Avatar Shadow"); @@ -142,21 +153,17 @@ LLMatrix4& LLDrawPoolAvatar::getModelView() //----------------------------------------------------------------------------- -S32 LLDrawPoolAvatar::getNumDeferredPasses() -{ - return getNumPasses(); -} void LLDrawPoolAvatar::beginDeferredPass(S32 pass) { LLFastTimer t(FTM_RENDER_CHARACTERS); sSkipTransparent = TRUE; - + is_deferred_render = true; + if (LLPipeline::sImpostorRender) - { - beginDeferredSkinned(); - return; + { //impostor pass does not have rigid or impostor rendering + pass += 2; } switch (pass) @@ -170,6 +177,12 @@ void LLDrawPoolAvatar::beginDeferredPass(S32 pass) case 2: beginDeferredSkinned(); break; + case 3: + beginDeferredRiggedSimple(); + break; + case 4: + beginDeferredRiggedBump(); + break; } } @@ -178,11 +191,11 @@ void LLDrawPoolAvatar::endDeferredPass(S32 pass) LLFastTimer t(FTM_RENDER_CHARACTERS); sSkipTransparent = FALSE; + is_deferred_render = false; if (LLPipeline::sImpostorRender) { - endDeferredSkinned(); - return; + pass += 2; } switch (pass) @@ -196,6 +209,12 @@ void LLDrawPoolAvatar::endDeferredPass(S32 pass) case 2: endDeferredSkinned(); break; + case 3: + endDeferredRiggedSimple(); + break; + case 4: + endDeferredRiggedBump(); + break; } } @@ -206,11 +225,36 @@ void LLDrawPoolAvatar::renderDeferred(S32 pass) S32 LLDrawPoolAvatar::getNumPostDeferredPasses() { - return 1; + return 6; } void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass) { + switch (pass) + { + case 0: + beginPostDeferredAlpha(); + break; + case 1: + beginRiggedFullbright(); + break; + case 2: + beginRiggedFullbrightShiny(); + break; + case 3: + beginDeferredRiggedAlpha(); + break; + case 4: + beginRiggedFullbrightAlpha(); + break; + case 5: + beginRiggedGlow(); + break; + } +} + +void LLDrawPoolAvatar::beginPostDeferredAlpha() +{ sSkipOpaque = TRUE; sShaderLevel = mVertexShaderLevel; sVertexProgram = &gDeferredAvatarAlphaProgram; @@ -219,64 +263,143 @@ void LLDrawPoolAvatar::beginPostDeferredPass(S32 pass) gPipeline.bindDeferredShader(*sVertexProgram); + sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); enable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]); } +void LLDrawPoolAvatar::beginDeferredRiggedAlpha() +{ + sVertexProgram = &gDeferredSkinnedAlphaProgram; + gPipeline.bindDeferredShader(*sVertexProgram); + sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + LLVertexBuffer::sWeight4Loc = sVertexProgram->getAttribLocation(LLViewerShaderMgr::OBJECT_WEIGHT); + gPipeline.enableLightsDynamic(); +} + +void LLDrawPoolAvatar::endDeferredRiggedAlpha() +{ + LLVertexBuffer::unbind(); + gPipeline.unbindDeferredShader(*sVertexProgram); + sDiffuseChannel = 0; + LLVertexBuffer::sWeight4Loc = -1; + sVertexProgram = NULL; +} + void LLDrawPoolAvatar::endPostDeferredPass(S32 pass) { + switch (pass) + { + case 0: + endPostDeferredAlpha(); + break; + case 1: + endRiggedFullbright(); + break; + case 2: + endRiggedFullbrightShiny(); + break; + case 3: + endDeferredRiggedAlpha(); + break; + case 4: + endRiggedFullbrightAlpha(); + break; + case 5: + endRiggedGlow(); + break; + } +} + +void LLDrawPoolAvatar::endPostDeferredAlpha() +{ // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done sRenderingSkinned = FALSE; sSkipOpaque = FALSE; disable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]); gPipeline.unbindDeferredShader(*sVertexProgram); - + sDiffuseChannel = 0; sShaderLevel = mVertexShaderLevel; } void LLDrawPoolAvatar::renderPostDeferred(S32 pass) { - render(2); //pass 2 = skinned + const S32 actual_pass[] = + { //map post deferred pass numbers to what render() expects + 2, //skinned + 4, // rigged fullbright + 6, //rigged fullbright shiny + 7, //rigged alpha + 8, //rigged fullbright alpha + 9, //rigged glow + }; + + pass = actual_pass[pass]; + + if (LLPipeline::sImpostorRender) + { //HACK for impostors so actual pass ends up being proper pass + pass -= 2; + } + + render(pass); } S32 LLDrawPoolAvatar::getNumShadowPasses() { - return 1; + return 2; } void LLDrawPoolAvatar::beginShadowPass(S32 pass) { LLFastTimer t(FTM_SHADOW_AVATAR); - sVertexProgram = &gDeferredAvatarShadowProgram; - if (sShaderLevel > 0) + + if (pass == 0) { - gAvatarMatrixParam = sVertexProgram->mUniform[LLViewerShaderMgr::AVATAR_MATRIX]; - } - gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.2f); - - glColor4f(1,1,1,1); + sVertexProgram = &gDeferredAvatarShadowProgram; + if (sShaderLevel > 0) + { + gAvatarMatrixParam = sVertexProgram->mUniform[LLViewerShaderMgr::AVATAR_MATRIX]; + } + gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.2f); + + glColor4f(1,1,1,1); - if ((sShaderLevel > 0)) // for hardware blending + if ((sShaderLevel > 0)) // for hardware blending + { + sRenderingSkinned = TRUE; + sVertexProgram->bind(); + enable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]); + } + } + else { - sRenderingSkinned = TRUE; + sVertexProgram = &gDeferredAttachmentShadowProgram; + sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); sVertexProgram->bind(); - enable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]); + LLVertexBuffer::sWeight4Loc = sVertexProgram->getAttribLocation(LLViewerShaderMgr::OBJECT_WEIGHT); } - } void LLDrawPoolAvatar::endShadowPass(S32 pass) { LLFastTimer t(FTM_SHADOW_AVATAR); - if (sShaderLevel > 0) + if (pass == 0) { - sRenderingSkinned = FALSE; + if (sShaderLevel > 0) + { + sRenderingSkinned = FALSE; + sVertexProgram->unbind(); + disable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]); + } + } + else + { + LLVertexBuffer::unbind(); sVertexProgram->unbind(); - disable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]); + LLVertexBuffer::sWeight4Loc = -1; + sVertexProgram = NULL; } - - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } void LLDrawPoolAvatar::renderShadow(S32 pass) @@ -306,26 +429,66 @@ void LLDrawPoolAvatar::renderShadow(S32 pass) return; } - if (sShaderLevel > 0) + if (pass == 0) { - gAvatarMatrixParam = sVertexProgram->mUniform[LLViewerShaderMgr::AVATAR_MATRIX]; - } - - avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); + if (sShaderLevel > 0) + { + gAvatarMatrixParam = sVertexProgram->mUniform[LLViewerShaderMgr::AVATAR_MATRIX]; + } + avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); + } + else + { + renderRigged(avatarp, RIGGED_SIMPLE); + renderRigged(avatarp, RIGGED_ALPHA); + renderRigged(avatarp, RIGGED_FULLBRIGHT); + renderRigged(avatarp, RIGGED_FULLBRIGHT_SHINY); + renderRigged(avatarp, RIGGED_SHINY); + renderRigged(avatarp, RIGGED_FULLBRIGHT_ALPHA); + } } S32 LLDrawPoolAvatar::getNumPasses() { - return LLPipeline::sImpostorRender ? 1 : 3; + if (LLPipeline::sImpostorRender) + { + return 8; + } + else + { + return 10; + } + if (LLPipeline::sImpostorRender) + { + return 1; + } + else + { + return 3; + } +} + + +S32 LLDrawPoolAvatar::getNumDeferredPasses() +{ + if (LLPipeline::sImpostorRender) + { + return 3; + } + else + { + return 5; + } } + void LLDrawPoolAvatar::render(S32 pass) { LLFastTimer t(FTM_RENDER_CHARACTERS); if (LLPipeline::sImpostorRender) { - renderAvatars(NULL, 2); + renderAvatars(NULL, pass+2); return; } @@ -338,10 +501,14 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass) //reset vertex buffer mappings LLVertexBuffer::unbind(); + if (pass == 0) + { //make sure no stale colors are left over from a previous render + glColor4f(1,1,1,1); + } + if (LLPipeline::sImpostorRender) - { - beginSkinned(); - return; + { //impostor render does not have impostors or rigid rendering + pass += 2; } switch (pass) @@ -355,6 +522,27 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass) case 2: beginSkinned(); break; + case 3: + beginRiggedSimple(); + break; + case 4: + beginRiggedFullbright(); + break; + case 5: + beginRiggedShinySimple(); + break; + case 6: + beginRiggedFullbrightShiny(); + break; + case 7: + beginRiggedAlpha(); + break; + case 8: + beginRiggedFullbrightAlpha(); + break; + case 9: + beginRiggedGlow(); + break; } } @@ -364,8 +552,7 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass) if (LLPipeline::sImpostorRender) { - endSkinned(); - return; + pass += 2; } switch (pass) @@ -378,6 +565,28 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass) break; case 2: endSkinned(); + break; + case 3: + endRiggedSimple(); + break; + case 4: + endRiggedFullbright(); + break; + case 5: + endRiggedShinySimple(); + break; + case 6: + endRiggedFullbrightShiny(); + break; + case 7: + endRiggedAlpha(); + break; + case 8: + endRiggedFullbrightAlpha(); + break; + case 9: + endRiggedGlow(); + break; } } @@ -390,7 +599,7 @@ void LLDrawPoolAvatar::beginImpostor() } gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); - diffuse_channel = 0; + sDiffuseChannel = 0; } void LLDrawPoolAvatar::endImpostor() @@ -441,9 +650,9 @@ void LLDrawPoolAvatar::beginDeferredImpostor() sVertexProgram = &gDeferredImpostorProgram; - normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL); specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP); - diffuse_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL); + sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); sVertexProgram->bind(); } @@ -563,6 +772,254 @@ void LLDrawPoolAvatar::endSkinned() gGL.getTexUnit(0)->activate(); } +void LLDrawPoolAvatar::beginRiggedSimple() +{ + if (sShaderLevel > 0) + { + if (LLPipeline::sUnderWaterRender) + { + sVertexProgram = &gSkinnedObjectSimpleWaterProgram; + } + else + { + sVertexProgram = &gSkinnedObjectSimpleProgram; + } + } + else + { + if (LLPipeline::sUnderWaterRender) + { + sVertexProgram = &gObjectSimpleWaterProgram; + } + else + { + sVertexProgram = &gObjectSimpleProgram; + } + } + + if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) + { + sDiffuseChannel = 0; + sVertexProgram->bind(); + LLVertexBuffer::sWeight4Loc = sVertexProgram->getAttribLocation(LLViewerShaderMgr::OBJECT_WEIGHT); + } +} + +void LLDrawPoolAvatar::endRiggedSimple() +{ + LLVertexBuffer::unbind(); + if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) + { + sVertexProgram->unbind(); + sVertexProgram = NULL; + LLVertexBuffer::sWeight4Loc = -1; + } +} + +void LLDrawPoolAvatar::beginRiggedAlpha() +{ + beginRiggedSimple(); +} + +void LLDrawPoolAvatar::endRiggedAlpha() +{ + endRiggedSimple(); +} + + +void LLDrawPoolAvatar::beginRiggedFullbrightAlpha() +{ + beginRiggedFullbright(); +} + +void LLDrawPoolAvatar::endRiggedFullbrightAlpha() +{ + endRiggedFullbright(); +} + +void LLDrawPoolAvatar::beginRiggedGlow() +{ + beginRiggedFullbright(); +} + +void LLDrawPoolAvatar::endRiggedGlow() +{ + endRiggedFullbright(); +} + +void LLDrawPoolAvatar::beginRiggedFullbright() +{ + if (sShaderLevel > 0) + { + if (LLPipeline::sUnderWaterRender) + { + sVertexProgram = &gSkinnedObjectFullbrightWaterProgram; + } + else + { + sVertexProgram = &gSkinnedObjectFullbrightProgram; + } + } + else + { + if (LLPipeline::sUnderWaterRender) + { + sVertexProgram = &gObjectFullbrightWaterProgram; + } + else + { + sVertexProgram = &gObjectFullbrightProgram; + } + } + + if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) + { + sDiffuseChannel = 0; + sVertexProgram->bind(); + LLVertexBuffer::sWeight4Loc = sVertexProgram->getAttribLocation(LLViewerShaderMgr::OBJECT_WEIGHT); + } +} + +void LLDrawPoolAvatar::endRiggedFullbright() +{ + LLVertexBuffer::unbind(); + if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) + { + sVertexProgram->unbind(); + sVertexProgram = NULL; + LLVertexBuffer::sWeight4Loc = -1; + } +} + +void LLDrawPoolAvatar::beginRiggedShinySimple() +{ + if (sShaderLevel > 0) + { + if (LLPipeline::sUnderWaterRender) + { + sVertexProgram = &gSkinnedObjectShinySimpleWaterProgram; + } + else + { + sVertexProgram = &gSkinnedObjectShinySimpleProgram; + } + } + else + { + if (LLPipeline::sUnderWaterRender) + { + sVertexProgram = &gObjectShinyWaterProgram; + } + else + { + sVertexProgram = &gObjectShinyProgram; + } + } + + if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) + { + sVertexProgram->bind(); + LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false); + LLVertexBuffer::sWeight4Loc = sVertexProgram->getAttribLocation(LLViewerShaderMgr::OBJECT_WEIGHT); + } +} + +void LLDrawPoolAvatar::endRiggedShinySimple() +{ + LLVertexBuffer::unbind(); + if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) + { + LLDrawPoolBump::unbindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false); + sVertexProgram->unbind(); + sVertexProgram = NULL; + LLVertexBuffer::sWeight4Loc = -1; + } +} + +void LLDrawPoolAvatar::beginRiggedFullbrightShiny() +{ + if (sShaderLevel > 0) + { + if (LLPipeline::sUnderWaterRender) + { + sVertexProgram = &gSkinnedObjectFullbrightShinyWaterProgram; + } + else + { + sVertexProgram = &gSkinnedObjectFullbrightShinyProgram; + } + } + else + { + if (LLPipeline::sUnderWaterRender) + { + sVertexProgram = &gObjectFullbrightShinyWaterProgram; + } + else + { + sVertexProgram = &gObjectFullbrightShinyProgram; + } + } + + + if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) + { + sVertexProgram->bind(); + LLDrawPoolBump::bindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false); + LLVertexBuffer::sWeight4Loc = sVertexProgram->getAttribLocation(LLViewerShaderMgr::OBJECT_WEIGHT); + } +} + +void LLDrawPoolAvatar::endRiggedFullbrightShiny() +{ + LLVertexBuffer::unbind(); + if (sShaderLevel > 0 || gPipeline.canUseVertexShaders()) + { + LLDrawPoolBump::unbindCubeMap(sVertexProgram, 2, sDiffuseChannel, cube_channel, false); + sVertexProgram->unbind(); + sVertexProgram = NULL; + LLVertexBuffer::sWeight4Loc = -1; + } +} + + +void LLDrawPoolAvatar::beginDeferredRiggedSimple() +{ + sVertexProgram = &gDeferredSkinnedDiffuseProgram; + sDiffuseChannel = 0; + sVertexProgram->bind(); + LLVertexBuffer::sWeight4Loc = sVertexProgram->getAttribLocation(LLViewerShaderMgr::OBJECT_WEIGHT); +} + +void LLDrawPoolAvatar::endDeferredRiggedSimple() +{ + LLVertexBuffer::unbind(); + sVertexProgram->unbind(); + LLVertexBuffer::sWeight4Loc = -1; + sVertexProgram = NULL; +} + +void LLDrawPoolAvatar::beginDeferredRiggedBump() +{ + sVertexProgram = &gDeferredSkinnedBumpProgram; + sVertexProgram->bind(); + normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP); + sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + LLVertexBuffer::sWeight4Loc = sVertexProgram->getAttribLocation(LLViewerShaderMgr::OBJECT_WEIGHT); +} + +void LLDrawPoolAvatar::endDeferredRiggedBump() +{ + LLVertexBuffer::unbind(); + sVertexProgram->disableTexture(LLViewerShaderMgr::BUMP_MAP); + sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + sVertexProgram->unbind(); + LLVertexBuffer::sWeight4Loc = -1; + normal_channel = -1; + sDiffuseChannel = 0; + sVertexProgram = NULL; +} + void LLDrawPoolAvatar::beginDeferredSkinned() { sShaderLevel = mVertexShaderLevel; @@ -572,6 +1029,7 @@ void LLDrawPoolAvatar::beginDeferredSkinned() sVertexProgram->bind(); + sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); enable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]); gGL.getTexUnit(0)->activate(); @@ -584,6 +1042,8 @@ void LLDrawPoolAvatar::endDeferredSkinned() disable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]); sVertexProgram->unbind(); + sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + sShaderLevel = mVertexShaderLevel; gGL.getTexUnit(0)->activate(); @@ -668,8 +1128,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) return; } - LLOverrideFaceColor color(this, 1.0f, 1.0f, 1.0f, 1.0f); - if (pass == 0) { if (!LLPipeline::sReflectionRender) @@ -679,7 +1137,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) if (impostor) { - if (LLPipeline::sRenderDeferred && avatarp->mImpostor.isComplete()) + if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && avatarp->mImpostor.isComplete()) { if (normal_channel > -1) { @@ -690,7 +1148,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) avatarp->mImpostor.bindTexture(1, specular_channel); } } - avatarp->renderImpostor(LLColor4U(255,255,255,255), diffuse_channel); + avatarp->renderImpostor(LLColor4U(255,255,255,255), sDiffuseChannel); } return; } @@ -706,6 +1164,88 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) avatarp->renderRigid(); return; } + + if (pass == 3) + { + if (is_deferred_render) + { + renderDeferredRiggedSimple(avatarp); + } + else + { + renderRiggedSimple(avatarp); + } + return; + } + + if (pass == 4) + { + if (is_deferred_render) + { + renderDeferredRiggedBump(avatarp); + } + else + { + renderRiggedFullbright(avatarp); + } + + return; + } + + if (pass == 5) + { + renderRiggedShinySimple(avatarp); + return; + } + + if (pass == 6) + { + renderRiggedFullbrightShiny(avatarp); + return; + } + + if (pass >= 7 && pass < 9) + { + LLGLEnable blend(GL_BLEND); + + gGL.setColorMask(true, true); + gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, + LLRender::BF_ONE_MINUS_SOURCE_ALPHA, + LLRender::BF_ZERO, + LLRender::BF_ONE_MINUS_SOURCE_ALPHA); + + + if (pass == 7) + { + renderRiggedAlpha(avatarp); + return; + } + + if (pass == 8) + { + renderRiggedFullbrightAlpha(avatarp); + return; + } + } + + if (pass == 9) + { + LLGLEnable blend(GL_BLEND); + LLGLDisable test(GL_ALPHA_TEST); + gGL.flush(); + + LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(-1.0f, -1.0f); + gGL.setSceneBlendType(LLRender::BT_ADD); + + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + gGL.setColorMask(false, true); + + renderRiggedGlow(avatarp); + gGL.setColorMask(true, false); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + return; + } if (sShaderLevel > 0) { @@ -743,6 +1283,307 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) } } +void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face) +{ + LLVector4a* weight = vol_face.mWeights; + if (!weight) + { + return; + } + + LLVertexBuffer* buffer = face->getVertexBuffer(); + + U32 data_mask = face->getRiggedVertexBufferDataMask(); + + if (!buffer || + buffer->getTypeMask() != data_mask || + buffer->getRequestedVerts() != vol_face.mNumVertices) + { + face->setGeomIndex(0); + face->setIndicesIndex(0); + face->setSize(vol_face.mNumVertices, vol_face.mNumIndices, true); + + + if (sShaderLevel > 0) + { + buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB); + } + else + { + buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB); + } + + buffer->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), true); + + face->setVertexBuffer(buffer); + + U16 offset = 0; + + LLMatrix4 mat_vert = skin->mBindShapeMatrix; + glh::matrix4f m((F32*) mat_vert.mMatrix); + m = m.inverse().transpose(); + + F32 mat3[] = + { m.m[0], m.m[1], m.m[2], + m.m[4], m.m[5], m.m[6], + m.m[8], m.m[9], m.m[10] }; + + LLMatrix3 mat_normal(mat3); + + face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true); + } + + if (sShaderLevel <= 0 && face->mLastSkinTime < avatar->getLastSkinTime()) + { //perform software vertex skinning for this face + LLStrider<LLVector3> position; + LLStrider<LLVector3> normal; + + bool has_normal = buffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); + buffer->getVertexStrider(position); + + if (has_normal) + { + buffer->getNormalStrider(normal); + } + + LLVector4a* pos = (LLVector4a*) position.get(); + + LLVector4a* norm = has_normal ? (LLVector4a*) normal.get() : NULL; + + //build matrix palette + LLMatrix4a mp[64]; + LLMatrix4* mat = (LLMatrix4*) mp; + + for (U32 j = 0; j < skin->mJointNames.size(); ++j) + { + LLJoint* joint = avatar->getJoint(skin->mJointNames[j]); + if (joint) + { + mat[j] = skin->mInvBindMatrix[j]; + mat[j] *= joint->getWorldMatrix(); + } + } + + LLMatrix4a bind_shape_matrix; + bind_shape_matrix.loadu(skin->mBindShapeMatrix); + + for (U32 j = 0; j < buffer->getRequestedVerts(); ++j) + { + LLMatrix4a final_mat; + final_mat.clear(); + + S32 idx[4]; + + LLVector4 wght; + + F32 scale = 0.f; + for (U32 k = 0; k < 4; k++) + { + F32 w = weight[j][k]; + + idx[k] = llclamp((S32) floorf(w), 0, 63); + wght[k] = w - floorf(w); + scale += wght[k]; + } + + wght *= 1.f/scale; + + for (U32 k = 0; k < 4; k++) + { + F32 w = wght[k]; + + LLMatrix4a src; + src.setMul(mp[idx[k]], w); + + final_mat.add(src); + } + + + LLVector4a& v = vol_face.mPositions[j]; + LLVector4a t; + LLVector4a dst; + bind_shape_matrix.affineTransform(v, t); + final_mat.affineTransform(t, dst); + pos[j] = dst; + + if (norm) + { + LLVector4a& n = vol_face.mNormals[j]; + bind_shape_matrix.rotate(n, t); + final_mat.rotate(t, dst); + norm[j] = dst; + } + } + } +} + +void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) +{ + if (avatar->isSelf() && !gAgent.needsRenderAvatar()) + { + return; + } + + stop_glerror(); + + for (U32 i = 0; i < mRiggedFace[type].size(); ++i) + { + LLFace* face = mRiggedFace[type][i]; + LLDrawable* drawable = face->getDrawable(); + if (!drawable) + { + continue; + } + + LLVOVolume* vobj = drawable->getVOVolume(); + + if (!vobj) + { + continue; + } + + LLVolume* volume = vobj->getVolume(); + S32 te = face->getTEOffset(); + + if (!volume || volume->getNumVolumeFaces() <= te) + { + continue; + } + + LLUUID mesh_id = volume->getParams().getSculptID(); + if (mesh_id.isNull()) + { + continue; + } + + const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(mesh_id); + if (!skin) + { + continue; + } + + stop_glerror(); + + const LLVolumeFace& vol_face = volume->getVolumeFace(te); + updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face); + + stop_glerror(); + + U32 data_mask = LLFace::getRiggedDataMask(type); + + LLVertexBuffer* buff = face->getVertexBuffer(); + + if (buff) + { + if (sShaderLevel > 0) + { //upload matrix palette to shader + LLMatrix4 mat[64]; + + for (U32 i = 0; i < skin->mJointNames.size(); ++i) + { + LLJoint* joint = avatar->getJoint(skin->mJointNames[i]); + if (joint) + { + mat[i] = skin->mInvBindMatrix[i]; + mat[i] *= joint->getWorldMatrix(); + } + } + + stop_glerror(); + + LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv("matrixPalette", + skin->mJointNames.size(), + FALSE, + (GLfloat*) mat[0].mMatrix); + + stop_glerror(); + } + else + { + data_mask &= ~LLVertexBuffer::MAP_WEIGHT4; + } + + buff->setBuffer(data_mask); + + U16 start = face->getGeomStart(); + U16 end = start + face->getGeomCount()-1; + S32 offset = face->getIndicesStart(); + U32 count = face->getIndicesCount(); + + if (glow) + { + glColor4f(0,0,0,face->getTextureEntry()->getGlow()); + } + + gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture()); + if (normal_channel > -1) + { + LLDrawPoolBump::bindBumpMap(face, normal_channel); + } + + if (face->mTextureMatrix) + { + glMatrixMode(GL_TEXTURE); + glLoadMatrixf((F32*) face->mTextureMatrix->mMatrix); + buff->drawRange(LLRender::TRIANGLES, start, end, count, offset); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + } + else + { + buff->drawRange(LLRender::TRIANGLES, start, end, count, offset); + } + } + } +} + +void LLDrawPoolAvatar::renderDeferredRiggedSimple(LLVOAvatar* avatar) +{ + renderRigged(avatar, RIGGED_DEFERRED_SIMPLE); +} + +void LLDrawPoolAvatar::renderDeferredRiggedBump(LLVOAvatar* avatar) +{ + renderRigged(avatar, RIGGED_DEFERRED_BUMP); +} + +void LLDrawPoolAvatar::renderRiggedSimple(LLVOAvatar* avatar) +{ + renderRigged(avatar, RIGGED_SIMPLE); +} + +void LLDrawPoolAvatar::renderRiggedFullbright(LLVOAvatar* avatar) +{ + renderRigged(avatar, RIGGED_FULLBRIGHT); +} + + +void LLDrawPoolAvatar::renderRiggedShinySimple(LLVOAvatar* avatar) +{ + renderRigged(avatar, RIGGED_SHINY); +} + +void LLDrawPoolAvatar::renderRiggedFullbrightShiny(LLVOAvatar* avatar) +{ + renderRigged(avatar, RIGGED_FULLBRIGHT_SHINY); +} + +void LLDrawPoolAvatar::renderRiggedAlpha(LLVOAvatar* avatar) +{ + renderRigged(avatar, RIGGED_ALPHA); +} + +void LLDrawPoolAvatar::renderRiggedFullbrightAlpha(LLVOAvatar* avatar) +{ + renderRigged(avatar, RIGGED_FULLBRIGHT_ALPHA); +} + +void LLDrawPoolAvatar::renderRiggedGlow(LLVOAvatar* avatar) +{ + renderRigged(avatar, RIGGED_GLOW, true); +} + + //----------------------------------------------------------------------------- // getDebugTexture() @@ -770,6 +1611,50 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const return LLColor3(0.f, 1.f, 0.f); } +void LLDrawPoolAvatar::addRiggedFace(LLFace* facep, U32 type) +{ + if (type >= NUM_RIGGED_PASSES) + { + llerrs << "Invalid rigged face type." << llendl; + } + + if (facep->getRiggedIndex(type) != -1) + { + llerrs << "Tried to add a rigged face that's referenced elsewhere." << llendl; + } + + facep->setRiggedIndex(type, mRiggedFace[type].size()); + facep->setPool(this); + mRiggedFace[type].push_back(facep); +} + +void LLDrawPoolAvatar::removeRiggedFace(LLFace* facep) +{ + facep->setPool(NULL); + + for (U32 i = 0; i < NUM_RIGGED_PASSES; ++i) + { + S32 index = facep->getRiggedIndex(i); + + if (index > -1) + { + if (mRiggedFace[i].size() > index && mRiggedFace[i][index] == facep) + { + facep->setRiggedIndex(i,-1); + mRiggedFace[i].erase(mRiggedFace[i].begin()+index); + for (U32 j = index; j < mRiggedFace[i].size(); ++j) + { //bump indexes down for faces referenced after erased face + mRiggedFace[i][j]->setRiggedIndex(i, j); + } + } + else + { + llerrs << "Face reference data corrupt for rigged type " << i << llendl; + } + } + } +} + LLVertexBufferAvatar::LLVertexBufferAvatar() : LLVertexBuffer(sDataMask, GL_STREAM_DRAW_ARB) //avatars are always stream draw due to morph targets @@ -782,22 +1667,25 @@ void LLVertexBufferAvatar::setupVertexBuffer(U32 data_mask) const { if (sRenderingSkinned) { - U8* base = useVBOs() ? NULL : mMappedData; + U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData; - glVertexPointer(3,GL_FLOAT, mStride, (void*)(base + 0)); - glNormalPointer(GL_FLOAT, mStride, (void*)(base + mOffsets[TYPE_NORMAL])); - glTexCoordPointer(2,GL_FLOAT, mStride, (void*)(base + mOffsets[TYPE_TEXCOORD0])); + glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_VERTEX], (void*)(base + 0)); + glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL])); + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0])); - set_vertex_weights(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT], mStride, (F32*)(base + mOffsets[TYPE_WEIGHT])); + set_vertex_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT], + LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_WEIGHT], (F32*)(base + mOffsets[TYPE_WEIGHT])); if (sShaderLevel >= LLDrawPoolAvatar::SHADER_LEVEL_BUMP) { - set_binormals(sVertexProgram->mAttribute[LLViewerShaderMgr::BINORMAL], mStride, (LLVector3*)(base + mOffsets[TYPE_BINORMAL])); + set_binormals(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::BINORMAL], + LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_BINORMAL], (LLVector3*)(base + mOffsets[TYPE_BINORMAL])); } if (sShaderLevel >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH) { - set_vertex_clothing_weights(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_CLOTHING], mStride, (LLVector4*)(base + mOffsets[TYPE_CLOTHWEIGHT])); + set_vertex_clothing_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_CLOTHING], + LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_CLOTHWEIGHT], (LLVector4*)(base + mOffsets[TYPE_CLOTHWEIGHT])); } } else diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index f536d3c911..fcd8294af5 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -1,4 +1,4 @@ -/** + /** * @file lldrawpoolavatar.h * @brief LLDrawPoolAvatar class definition * @@ -30,6 +30,12 @@ #include "lldrawpool.h" class LLVOAvatar; +class LLGLSLShader; +class LLFace; +class LLMeshSkinInfo; +class LLVolume; +class LLVolumeFace; + class LLDrawPoolAvatar : public LLFacePool { @@ -83,7 +89,7 @@ public: void beginRigid(); void beginImpostor(); void beginSkinned(); - + void endRigid(); void endImpostor(); void endSkinned(); @@ -95,14 +101,113 @@ public: void endDeferredImpostor(); void endDeferredRigid(); void endDeferredSkinned(); + + void beginPostDeferredAlpha(); + void endPostDeferredAlpha(); + + void beginRiggedSimple(); + void beginRiggedFullbright(); + void beginRiggedFullbrightShiny(); + void beginRiggedShinySimple(); + void beginRiggedAlpha(); + void beginRiggedFullbrightAlpha(); + void beginRiggedGlow(); + void beginDeferredRiggedAlpha(); + + void endRiggedSimple(); + void endRiggedFullbright(); + void endRiggedFullbrightShiny(); + void endRiggedShinySimple(); + void endRiggedAlpha(); + void endRiggedFullbrightAlpha(); + void endRiggedGlow(); + void endDeferredRiggedAlpha(); + + void beginDeferredRiggedSimple(); + void beginDeferredRiggedBump(); + + void endDeferredRiggedSimple(); + void endDeferredRiggedBump(); + void updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, + LLFace* facep, + const LLMeshSkinInfo* skin, + LLVolume* volume, + const LLVolumeFace& vol_face); + + void renderRigged(LLVOAvatar* avatar, U32 type, bool glow = false); + void renderRiggedSimple(LLVOAvatar* avatar); + void renderRiggedAlpha(LLVOAvatar* avatar); + void renderRiggedFullbrightAlpha(LLVOAvatar* avatar); + void renderRiggedFullbright(LLVOAvatar* avatar); + void renderRiggedShinySimple(LLVOAvatar* avatar); + void renderRiggedFullbrightShiny(LLVOAvatar* avatar); + void renderRiggedGlow(LLVOAvatar* avatar); + void renderDeferredRiggedSimple(LLVOAvatar* avatar); + void renderDeferredRiggedBump(LLVOAvatar* avatar); + + typedef enum + { + RIGGED_SIMPLE = 0, + RIGGED_FULLBRIGHT, + RIGGED_SHINY, + RIGGED_FULLBRIGHT_SHINY, + RIGGED_GLOW, + RIGGED_ALPHA, + RIGGED_FULLBRIGHT_ALPHA, + RIGGED_DEFERRED_BUMP, + RIGGED_DEFERRED_SIMPLE, + NUM_RIGGED_PASSES, + RIGGED_UNKNOWN, + } eRiggedPass; + + typedef enum + { + RIGGED_SIMPLE_MASK = LLVertexBuffer::MAP_VERTEX | + LLVertexBuffer::MAP_NORMAL | + LLVertexBuffer::MAP_TEXCOORD0 | + LLVertexBuffer::MAP_COLOR | + LLVertexBuffer::MAP_WEIGHT4, + RIGGED_FULLBRIGHT_MASK = LLVertexBuffer::MAP_VERTEX | + LLVertexBuffer::MAP_TEXCOORD0 | + LLVertexBuffer::MAP_COLOR | + LLVertexBuffer::MAP_WEIGHT4, + RIGGED_SHINY_MASK = RIGGED_SIMPLE_MASK, + RIGGED_FULLBRIGHT_SHINY_MASK = RIGGED_SIMPLE_MASK, + RIGGED_GLOW_MASK = LLVertexBuffer::MAP_VERTEX | + LLVertexBuffer::MAP_TEXCOORD0 | + LLVertexBuffer::MAP_WEIGHT4, + RIGGED_ALPHA_MASK = RIGGED_SIMPLE_MASK, + RIGGED_FULLBRIGHT_ALPHA_MASK = RIGGED_FULLBRIGHT_MASK, + RIGGED_DEFERRED_BUMP_MASK = LLVertexBuffer::MAP_VERTEX | + LLVertexBuffer::MAP_NORMAL | + LLVertexBuffer::MAP_TEXCOORD0 | + LLVertexBuffer::MAP_BINORMAL | + LLVertexBuffer::MAP_COLOR | + LLVertexBuffer::MAP_WEIGHT4, + RIGGED_DEFERRED_SIMPLE_MASK = LLVertexBuffer::MAP_VERTEX | + LLVertexBuffer::MAP_NORMAL | + LLVertexBuffer::MAP_TEXCOORD0 | + LLVertexBuffer::MAP_COLOR | + LLVertexBuffer::MAP_WEIGHT4, + } eRiggedDataMask; + + void addRiggedFace(LLFace* facep, U32 type); + void removeRiggedFace(LLFace* facep); + + std::vector<LLFace*> mRiggedFace[NUM_RIGGED_PASSES]; + /*virtual*/ LLViewerTexture *getDebugTexture(); /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display void renderAvatars(LLVOAvatar *single_avatar, S32 pass = -1); // renders only one avatar if single_avatar is not null. + static BOOL sSkipOpaque; static BOOL sSkipTransparent; + static S32 sDiffuseChannel; + + static LLGLSLShader* sVertexProgram; }; class LLVertexBufferAvatar : public LLVertexBuffer diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index c987847c66..5f89d11391 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -145,12 +145,7 @@ void LLStandardBumpmap::addstandard() // llinfos << "Loading bumpmap: " << bump_image_id << " from viewerart" << llendl; gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label; gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage = - LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id), - TRUE, - LLViewerTexture::BOOST_NONE, - LLViewerTexture::LOD_TEXTURE, - 0, - 0); + LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id)); gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLViewerTexture::BOOST_BUMP) ; gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL ); LLStandardBumpmap::sStandardBumpmapCount++; @@ -334,30 +329,43 @@ void LLDrawPoolBump::beginShiny(bool invisible) sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0; } - if (LLPipeline::sUnderWaterRender) + if (getVertexShaderLevel() > 0) { - shader = &gObjectShinyWaterProgram; + if (LLPipeline::sUnderWaterRender) + { + shader = &gObjectShinyWaterProgram; + } + else + { + shader = &gObjectShinyProgram; + } + shader->bind(); } else { - shader = &gObjectShinyProgram; + shader = NULL; } + bindCubeMap(shader, mVertexShaderLevel, diffuse_channel, cube_channel, invisible); +} + +//static +void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible) +{ LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; if( cube_map ) { - if (!invisible && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0 ) + if (!invisible && shader ) { 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 (mVertexShaderLevel > 1) + 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 @@ -419,22 +427,16 @@ void LLDrawPoolBump::renderShiny(bool invisible) } } -void LLDrawPoolBump::endShiny(bool invisible) +//static +void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible) { - LLFastTimer t(FTM_RENDER_SHINY); - if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))|| - (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))) - { - return; - } - LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; if( cube_map ) { cube_map->disable(); cube_map->restoreMatrix(); - if (!invisible && mVertexShaderLevel > 1) + if (!invisible && shader_level > 1) { shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); @@ -445,7 +447,6 @@ void LLDrawPoolBump::endShiny(bool invisible) shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); } } - shader->unbind(); } } gGL.getTexUnit(diffuse_channel)->disable(); @@ -453,6 +454,22 @@ void LLDrawPoolBump::endShiny(bool invisible) gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +} + +void LLDrawPoolBump::endShiny(bool invisible) +{ + LLFastTimer t(FTM_RENDER_SHINY); + if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))|| + (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))) + { + return; + } + + unbindCubeMap(shader, mVertexShaderLevel, diffuse_channel, cube_channel, invisible); + if (shader) + { + shader->unbind(); + } diffuse_channel = -1; cube_channel = 0; @@ -473,7 +490,7 @@ void LLDrawPoolBump::beginFullbrightShiny() if (LLPipeline::sUnderWaterRender) { - shader = &gObjectShinyWaterProgram; + shader = &gObjectFullbrightShinyWaterProgram; } else { @@ -580,18 +597,37 @@ void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL // static BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel) { - LLViewerTexture* bump = NULL; - U8 bump_code = params.mBump; + return bindBumpMap(bump_code, params.mTexture, params.mVSize, 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(), face->getVirtualSize(), channel); + } + + return FALSE; +} + +//static +BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsize, S32 channel) +{ //Note: texture atlas does not support bump texture now. - LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(params.mTexture) ; + 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: @@ -605,7 +641,7 @@ BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel) if( bump_code < LLStandardBumpmap::sStandardBumpmapCount ) { bump = gStandardBumpmapList[bump_code].mImage; - gBumpImageList.addTextureStats(bump_code, tex->getID(), params.mVSize); + gBumpImageList.addTextureStats(bump_code, tex->getID(), vsize); } break; } @@ -624,7 +660,7 @@ BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel) return TRUE; } - + return FALSE; } @@ -853,9 +889,9 @@ void LLBumpImageList::destroyGL() void LLBumpImageList::restoreGL() { - if(!gTextureList.isInitialized())
- {
- return ;
+ if(!gTextureList.isInitialized()) + { + return ; } LLStandardBumpmap::restoreGL(); @@ -969,25 +1005,28 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText } bump_image_map_t::iterator iter = entries_list->find(src_image->getID()); - if (iter != entries_list->end()) + if (iter != entries_list->end() && iter->second.notNull()) { bump = iter->second; } else { LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,1); - raw->clear(0x77, 0x77, 0x77, 0xFF); + raw->clear(0x77, 0x77, 0xFF, 0xFF); (*entries_list)[src_image->getID()] = LLViewerTextureManager::getLocalTexture( raw.get(), TRUE); - (*entries_list)[src_image->getID()]->setExplicitFormat(GL_ALPHA8, GL_ALPHA); - - // Note: this may create an LLImageGL immediately - src_image->setBoostLevel(LLViewerTexture::BOOST_BUMP) ; - src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL ); bump = (*entries_list)[src_image->getID()]; // In case callback was called immediately and replaced the image + } -// bump_total++; -// llinfos << "*** Creating " << (void*)bump << " " << bump_total << llendl; + 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(LLViewerTexture::BOOST_BUMP) ; + src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL ); + } } } @@ -1090,7 +1129,21 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI { 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()) // bump not cached yet + + 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 + LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,1); + raw->clear(0x77, 0x77, 0xFF, 0xFF); + + entries_list[src_vi->getID()] = LLViewerTextureManager::getLocalTexture( raw.get(), 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<LLImageRaw> dst_image = new LLImageRaw(src->getWidth(), src->getHeight(), 1); U8* dst_data = dst_image->getData(); @@ -1216,18 +1269,10 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI bump->setExplicitFormat(GL_RGBA, GL_RGBA); bump->createGLTexture(0, nrm_image); } - - + iter->second = bump; // derefs (and deletes) old image //--------------------------------------------------- } - else - { - // entry should have been added in LLBumpImageList::getImage(). - - // Not a legit assertion - the bump texture could have been flushed by the bump image manager - //llassert(0); - } } } diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h index 65a813ab94..f4702bf61d 100644 --- a/indra/newview/lldrawpoolbump.h +++ b/indra/newview/lldrawpoolbump.h @@ -35,6 +35,7 @@ class LLImageRaw; class LLSpatialGroup; class LLDrawInfo; +class LLGLSLShader; class LLViewerFetchedTexture; class LLDrawPoolBump : public LLRenderPass @@ -73,6 +74,9 @@ public: void renderBump(U32 pass = LLRenderPass::PASS_BUMP); void endBump(U32 pass = LLRenderPass::PASS_BUMP); + static void bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible); + static void unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel, bool invisible); + virtual S32 getNumDeferredPasses(); /*virtual*/ void beginDeferredPass(S32 pass); /*virtual*/ void endDeferredPass(S32 pass); @@ -83,7 +87,12 @@ public: /*virtual*/ void endPostDeferredPass(S32 pass); /*virtual*/ void renderPostDeferred(S32 pass); - BOOL bindBumpMap(LLDrawInfo& params, S32 channel = -2); + static BOOL bindBumpMap(LLDrawInfo& params, S32 channel = -2); + static BOOL bindBumpMap(LLFace* face, S32 channel = -2); + +private: + static BOOL bindBumpMap(U8 bump_code, LLViewerTexture* tex, F32 vsize, S32 channel); + }; enum EBumpEffect diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp index 6b45c5abb0..030d6e1110 100644 --- a/indra/newview/lldrawpoolsky.cpp +++ b/indra/newview/lldrawpoolsky.cpp @@ -63,6 +63,8 @@ void LLDrawPoolSky::prerender() void LLDrawPoolSky::render(S32 pass) { + gGL.flush(); + if (mDrawFace.empty()) { return; @@ -111,13 +113,14 @@ void LLDrawPoolSky::render(S32 pass) S32 face_count = (S32)mDrawFace.size(); + LLVertexBuffer::unbind(); + glColor4f(1,1,1,1); + for (S32 i = 0; i < llmin(6, face_count); ++i) { renderSkyCubeFace(i); } - LLGLEnable blend(GL_BLEND); - glPopMatrix(); } diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index f1198c9a8d..195ee60a2e 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -107,11 +107,12 @@ void LLDrawPoolTree::render(S32 pass) iter != mDrawFace.end(); iter++) { LLFace *face = *iter; - if(face->mVertexBuffer.notNull()) + LLVertexBuffer* buff = face->getVertexBuffer(); + if(buff) { - face->mVertexBuffer->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); - face->mVertexBuffer->drawRange(LLRender::TRIANGLES, 0, face->mVertexBuffer->getRequestedVerts()-1, face->mVertexBuffer->getRequestedIndices(), 0); - gPipeline.addTrianglesDrawn(face->mVertexBuffer->getRequestedIndices()); + buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); + buff->drawRange(LLRender::TRIANGLES, 0, buff->getRequestedVerts()-1, buff->getRequestedIndices(), 0); + gPipeline.addTrianglesDrawn(buff->getRequestedIndices()); } } } @@ -200,13 +201,13 @@ void LLDrawPoolTree::renderTree(BOOL selecting) LLFace *face = *iter; LLDrawable *drawablep = face->getDrawable(); - if (drawablep->isDead() || face->mVertexBuffer.isNull()) + if (drawablep->isDead() || !face->getVertexBuffer()) { continue; } - face->mVertexBuffer->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); - U16* indicesp = (U16*) face->mVertexBuffer->getIndicesPointer(); + face->getVertexBuffer()->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); + U16* indicesp = (U16*) face->getVertexBuffer()->getIndicesPointer(); // Render each of the trees LLVOTree *treep = (LLVOTree *)drawablep->getVObj().get(); diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index 92ad404ca0..9231e6ef88 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -194,7 +194,7 @@ void LLDrawPoolWLSky::renderSkyClouds(F32 camHeightLocal) const &gWLCloudProgram; LLGLEnable blend(GL_BLEND); - LLGLSBlendFunc blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.setSceneBlendType(LLRender::BT_ALPHA); gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); gGL.getTexUnit(0)->bind(sCloudNoiseTexture); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index fe201a6773..5398c13c44 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -33,8 +33,10 @@ #include "llviewercontrol.h" #include "llvolume.h" #include "m3math.h" +#include "llmatrix4a.h" #include "v3color.h" +#include "lldrawpoolavatar.h" #include "lldrawpoolbump.h" #include "llgl.h" #include "llrender.h" @@ -67,35 +69,43 @@ The resulting texture coordinate <u,v> is: u = 2(B dot P) v = 2(T dot P) */ -void planarProjection(LLVector2 &tc, const LLVector3& normal, - const LLVector3 &mCenter, const LLVector3& vec) -{ //DONE! - LLVector3 binormal; - float d = normal * LLVector3(1,0,0); +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) { - binormal = LLVector3(0,1,0); - if (normal.mV[0] < 0) + if (d < 0) + { + binormal.set(0,-1,0); + } + else { - binormal = -binormal; + binormal.set(0, 1, 0); } } else { - binormal = LLVector3(1,0,0); - if (normal.mV[1] > 0) + if (normal[1] > 0) { - binormal = -binormal; + binormal.set(-1,0,0); + } + else + { + binormal.set(1,0,0); } } - LLVector3 tangent = binormal % normal; + LLVector4a tangent; + tangent.setCross3(binormal,normal); - tc.mV[1] = -((tangent*vec)*2 - 0.5f); - tc.mV[0] = 1.0f+((binormal*vec)*2 - 0.5f); + tc.mV[1] = -((tangent.dot3(vec).getF32())*2 - 0.5f); + tc.mV[0] = 1.0f+((binormal.dot3(vec).getF32())*2 - 0.5f); } -void sphericalProjection(LLVector2 &tc, const LLVector3& normal, - const LLVector3 &mCenter, const LLVector3& vec) +void sphericalProjection(LLVector2 &tc, const LLVector4a& normal, + const LLVector4a &mCenter, const LLVector4a& vec) { //BROKEN /*tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/3.14159f; @@ -106,7 +116,7 @@ void sphericalProjection(LLVector2 &tc, const LLVector3& normal, }*/ } -void cylindricalProjection(LLVector2 &tc, const LLVector3& normal, const LLVector3 &mCenter, const LLVector3& vec) +void cylindricalProjection(LLVector2 &tc, const LLVector4a& normal, const LLVector4a &mCenter, const LLVector4a& vec) { //BROKEN /*LLVector3 binormal; float d = vd.mNormal * LLVector3(1,0,0); @@ -138,6 +148,7 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp) { mLastUpdateTime = gFrameTimeSeconds; mLastMoveTime = 0.f; + mLastSkinTime = gFrameTimeSeconds; mVSize = 0.f; mPixelArea = 16.f; mState = GLOBAL; @@ -179,9 +190,13 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp) mHasMedia = FALSE ; } - void LLFace::destroy() { + if (gDebugGL) + { + gPipeline.checkReferences(this); + } + if(mTexture.notNull()) { mTexture->removeFace(this) ; @@ -189,7 +204,15 @@ void LLFace::destroy() if (mDrawPoolp) { - mDrawPoolp->removeFace(this); + if (this->isState(LLFace::RIGGED) && mDrawPoolp->getType() == LLDrawPool::POOL_AVATAR) + { + ((LLDrawPoolAvatar*) mDrawPoolp)->removeRiggedFace(this); + } + else + { + mDrawPoolp->removeFace(this); + } + mDrawPoolp = NULL; } @@ -210,8 +233,8 @@ void LLFace::destroy() } setDrawInfo(NULL); - removeAtlas(); + mDrawablep = NULL; mVObjp = NULL; } @@ -227,6 +250,11 @@ void LLFace::setWorldMatrix(const LLMatrix4 &mat) llerrs << "Faces on this drawable are not independently modifiable\n" << llendl; } +void LLFace::setPool(LLFacePool* pool) +{ + mDrawPoolp = pool; +} + void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep) { LLMemType mt1(LLMemType::MTYPE_DRAWABLE); @@ -329,8 +357,21 @@ void LLFace::setDrawable(LLDrawable *drawable) mXform = &drawable->mXform; } -void LLFace::setSize(const S32 num_vertices, const S32 num_indices) +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; + } + else + { + if (mDrawablep->getVOVolume()) + { + llerrs << "WTF?" << llendl; + } + } + if (mGeomCount != num_vertices || mIndicesCount != num_indices) { @@ -339,8 +380,28 @@ void LLFace::setSize(const S32 num_vertices, const S32 num_indices) mVertexBuffer = NULL; mLastVertexBuffer = NULL; } + + llassert(verify()); +} + +void LLFace::setGeomIndex(U16 idx) +{ + if (mGeomIndex != idx) + { + mGeomIndex = idx; + mVertexBuffer = NULL; + } } +void LLFace::setIndicesIndex(S32 idx) +{ + if (mIndicesIndex != idx) + { + mIndicesIndex = idx; + mVertexBuffer = NULL; + } +} + //============================================================================ U16 LLFace::getGeometryAvatar( @@ -429,8 +490,36 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) } glColor4fv(color.mV); - mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); - mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex); + + if (mDrawablep->isState(LLDrawable::RIGGED)) + { + LLVOVolume* volume = mDrawablep->getVOVolume(); + if (volume) + { + LLRiggedVolume* rigged = volume->getRiggedVolume(); + if (rigged) + { + LLGLEnable offset(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(-1.f, -1.f); + glMultMatrixf((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); + } + glDrawElements(GL_TRIANGLES, vol_face.mNumIndices, GL_UNSIGNED_SHORT, vol_face.mIndices); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + } + } + else + { + mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); + mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex); + } gGL.popMatrix(); } @@ -515,23 +604,26 @@ void LLFace::printDebugInfo() const llinfos << "II: " << mIndicesIndex << " Count:" << mIndicesCount << llendl; llinfos << llendl; - poolp->printDebugInfo(); - - S32 pool_references = 0; - for (std::vector<LLFace*>::iterator iter = poolp->mReferences.begin(); - iter != poolp->mReferences.end(); iter++) + if (poolp) { - LLFace *facep = *iter; - if (facep == this) + poolp->printDebugInfo(); + + S32 pool_references = 0; + for (std::vector<LLFace*>::iterator iter = poolp->mReferences.begin(); + iter != poolp->mReferences.end(); iter++) { - llinfos << "Pool reference: " << pool_references << llendl; - pool_references++; + LLFace *facep = *iter; + if (facep == this) + { + llinfos << "Pool reference: " << pool_references << llendl; + pool_references++; + } } - } - if (pool_references != 1) - { - llinfos << "Incorrect number of pool references!" << llendl; + if (pool_references != 1) + { + llinfos << "Incorrect number of pool references!" << llendl; + } } #if 0 @@ -588,95 +680,116 @@ static void xform(LLVector2 &tex_coord, F32 cosAng, F32 sinAng, F32 offS, F32 of BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, - const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, BOOL global_volume) + const LLMatrix4& mat_vert_in, const LLMatrix3& mat_normal_in, BOOL global_volume) { LLMemType mt1(LLMemType::MTYPE_DRAWABLE); //get bounding box - if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION)) + if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED)) { + //VECTORIZE THIS + LLMatrix4a mat_vert; + mat_vert.loadu(mat_vert_in); + + LLMatrix4a mat_normal; + mat_normal.loadu(mat_normal_in); + //if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME)) //{ //vertex buffer no longer valid // mVertexBuffer = NULL; // mLastVertexBuffer = NULL; //} - LLVector3 min,max; + //VECTORIZE THIS + LLVector4a min,max; if (f >= volume.getNumVolumeFaces()) { - min = LLVector3(-1,-1,-1); - max = LLVector3(1,1,1); - } - else - { - const LLVolumeFace &face = volume.getVolumeFace(f); - min = face.mExtents[0]; - max = face.mExtents[1]; + llwarns << "Generating bounding box for invalid face index!" << llendl; + f = 0; } + const LLVolumeFace &face = volume.getVolumeFace(f); + min = face.mExtents[0]; + max = face.mExtents[1]; + + //min, max are in volume space, convert to drawable render space - LLVector3 center = ((min + max) * 0.5f)*mat_vert; - LLVector3 size = ((max-min) * 0.5f); + LLVector4a center; + LLVector4a t; + t.setAdd(min, max); + t.mul(0.5f); + mat_vert.affineTransform(t, center); + LLVector4a size; + size.setSub(max, min); + size.mul(0.5f); + if (!global_volume) { - size.scaleVec(mDrawablep->getVObj()->getScale()); + //VECTORIZE THIS + LLVector4a scale; + scale.load3(mDrawablep->getVObj()->getScale().mV); + size.mul(scale); } - LLMatrix3 mat = mat_normal; - LLVector3 x = mat.getFwdRow(); - LLVector3 y = mat.getLeftRow(); - LLVector3 z = mat.getUpRow(); - x.normVec(); - y.normVec(); - z.normVec(); + mat_normal.mMatrix[0].normalize3fast(); + mat_normal.mMatrix[1].normalize3fast(); + mat_normal.mMatrix[2].normalize3fast(); + + LLVector4a v[4]; - mat.setRows(x,y,z); + //get 4 corners of bounding box + mat_normal.rotate(size,v[0]); - LLQuaternion rotation = LLQuaternion(mat); + //VECTORIZE THIS + LLVector4a scale; - LLVector3 v[4]; - //get 4 corners of bounding box - v[0] = (size * rotation); - v[1] = (LLVector3(-size.mV[0], -size.mV[1], size.mV[2]) * rotation); - v[2] = (LLVector3(size.mV[0], -size.mV[1], -size.mV[2]) * rotation); - v[3] = (LLVector3(-size.mV[0], size.mV[1], -size.mV[2]) * rotation); + scale.set(-1.f, -1.f, 1.f); + scale.mul(size); + mat_normal.rotate(scale, v[1]); + + scale.set(1.f, -1.f, -1.f); + scale.mul(size); + mat_normal.rotate(scale, v[2]); + + scale.set(-1.f, 1.f, -1.f); + scale.mul(size); + mat_normal.rotate(scale, v[3]); - LLVector3& newMin = mExtents[0]; - LLVector3& newMax = mExtents[1]; + LLVector4a& newMin = mExtents[0]; + LLVector4a& newMax = mExtents[1]; newMin = newMax = center; for (U32 i = 0; i < 4; i++) { - for (U32 j = 0; j < 3; j++) - { - F32 delta = fabsf(v[i].mV[j]); - F32 min = center.mV[j] - delta; - F32 max = center.mV[j] + delta; - - if (min < newMin.mV[j]) - { - newMin.mV[j] = min; - } - - if (max > newMax.mV[j]) - { - newMax.mV[j] = max; - } - } + LLVector4a delta; + delta.setAbs(v[i]); + LLVector4a min; + min.setSub(center, delta); + LLVector4a max; + max.setAdd(center, delta); + + newMin.setMin(newMin,min); + newMax.setMax(newMax,max); } if (!mDrawablep->isActive()) { - LLVector3 offset = mDrawablep->getRegion()->getOriginAgent(); - newMin += offset; - newMax += offset; + LLVector4a offset; + offset.load3(mDrawablep->getRegion()->getOriginAgent().mV); + newMin.add(offset); + newMax.add(offset); } - mCenterLocal = (newMin+newMax)*0.5f; - LLVector3 tmp = (newMin - newMax) ; - mBoundingSphereRadius = tmp.length() * 0.5f ; + t.setAdd(newMin, newMax); + t.mul(0.5f); + + //VECTORIZE THIS + mCenterLocal.set(t.getF32ptr()); + + t.setSub(newMax,newMin); + mBoundingSphereRadius = t.getLength3().getF32()*0.5f; updateCenterAgent(); } @@ -703,18 +816,26 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position, return surface_coord; } + //VECTORIZE THIS // see if we have a non-default mapping U8 texgen = getTextureEntry()->getTexGen(); if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) { - LLVector3 center = mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter; + LLVector4a& center = *(mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter); + + LLVector4a volume_position; + volume_position.load3(mDrawablep->getVOVolume()->agentPositionToVolume(position).mV); - LLVector3 scale = (mDrawablep->getVOVolume()->isVolumeGlobal()) ? LLVector3(1,1,1) : mVObjp->getScale(); - LLVector3 volume_position = mDrawablep->getVOVolume()->agentPositionToVolume(position); - volume_position.scaleVec(scale); + if (!mDrawablep->getVOVolume()->isVolumeGlobal()) + { + LLVector4a scale; + scale.load3(mVObjp->getScale().mV); + volume_position.mul(scale); + } - LLVector3 volume_normal = mDrawablep->getVOVolume()->agentDirectionToVolume(normal); - volume_normal.normalize(); + LLVector4a volume_normal; + volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(normal).mV); + volume_normal.normalize3fast(); switch (texgen) { @@ -755,10 +876,10 @@ void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_po { const LLMatrix4& vol_mat = getWorldMatrix(); const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset); - LLVector3 normal = vf.mVertices[0].mNormal; - LLVector3 binormal = vf.mVertices[0].mBinormal; + const LLVector4a& normal4a = vf.mNormals[0]; + const LLVector4a& binormal4a = vf.mBinormals[0]; LLVector2 projected_binormal; - planarProjection(projected_binormal, normal, vf.mCenter, 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, @@ -766,6 +887,10 @@ void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_po 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(); @@ -848,20 +973,35 @@ void LLFace::updateRebuildFlags() bool LLFace::canRenderAsMask() { + if (LLPipeline::sNoAlpha) + { + return true; + } + const LLTextureEntry* te = getTextureEntry(); - return ( - ( - (LLPipeline::sRenderDeferred && LLPipeline::sAutoMaskAlphaDeferred) || - - (!LLPipeline::sRenderDeferred && LLPipeline::sAutoMaskAlphaNonDeferred) - ) // do we want masks at all? - && - (te->getColor().mV[3] == 1.0f) && // can't treat as mask if we have face alpha - !(LLPipeline::sRenderDeferred && te->getFullbright()) && // hack: alpha masking renders fullbright faces invisible in deferred rendering mode, need to figure out why - for now, avoid + + 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 (LLPipeline::sRenderDeferred) + { + 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; + } + } + else + { + return LLPipeline::sAutoMaskAlphaNonDeferred; + } + } - getTexture()->getIsAlphaMask() // texture actually qualifies for masking (lazily recalculated but expensive) - ); + return false; } @@ -869,13 +1009,15 @@ static LLFastTimer::DeclareTimer FTM_FACE_GET_GEOM("Face Geom"); BOOL LLFace::getGeometryVolume(const LLVolume& volume, const S32 &f, - const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, - const U16 &index_offset) + const LLMatrix4& mat_vert_in, const LLMatrix3& mat_norm_in, + const U16 &index_offset, + bool force_rebuild) { LLFastTimer t(FTM_FACE_GET_GEOM); + llassert(verify()); const LLVolumeFace &vf = volume.getVolumeFace(f); - S32 num_vertices = (S32)vf.mVertices.size(); - S32 num_indices = LLPipeline::sUseTriStrips ? (S32)vf.mTriStrip.size() : (S32) vf.mIndices.size(); + S32 num_vertices = (S32)vf.mNumVertices; + S32 num_indices = (S32) vf.mNumIndices; if (mVertexBuffer.notNull()) { @@ -900,15 +1042,20 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } } - LLStrider<LLVector3> vertices; + LLStrider<LLVector3> vert; + LLVector4a* vertices = NULL; LLStrider<LLVector2> tex_coords; LLStrider<LLVector2> tex_coords2; - LLStrider<LLVector3> normals; + LLVector4a* normals = NULL; + LLStrider<LLVector3> norm; LLStrider<LLColor4U> colors; - LLStrider<LLVector3> binormals; + LLVector4a* binormals = NULL; + LLStrider<LLVector3> binorm; LLStrider<U16> indicesp; + LLVector4a* weights = NULL; + LLStrider<LLVector4> wght; - BOOL full_rebuild = mDrawablep->isState(LLDrawable::REBUILD_VOLUME); + BOOL full_rebuild = force_rebuild || mDrawablep->isState(LLDrawable::REBUILD_VOLUME); BOOL global_volume = mDrawablep->getVOVolume()->isVolumeGlobal(); LLVector3 scale; @@ -921,28 +1068,37 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, 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_tcoord = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_TCOORD); - BOOL rebuild_normal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); - BOOL rebuild_binormal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_BINORMAL); + bool rebuild_pos = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_POSITION); + bool rebuild_color = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_COLOR); + bool rebuild_tcoord = full_rebuild || mDrawablep->isState(LLDrawable::REBUILD_TCOORD); + bool rebuild_normal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL); + bool rebuild_binormal = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_BINORMAL); + bool rebuild_weights = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_WEIGHT4); const LLTextureEntry *tep = mVObjp->getTE(f); - U8 bump_code = tep ? tep->getBumpmap() : 0; + const U8 bump_code = tep ? tep->getBumpmap() : 0; if (rebuild_pos) { - mVertexBuffer->getVertexStrider(vertices, mGeomIndex); + mVertexBuffer->getVertexStrider(vert, mGeomIndex); + vertices = (LLVector4a*) vert.get(); } if (rebuild_normal) { - mVertexBuffer->getNormalStrider(normals, mGeomIndex); + mVertexBuffer->getNormalStrider(norm, mGeomIndex); + normals = (LLVector4a*) norm.get(); } if (rebuild_binormal) { - mVertexBuffer->getBinormalStrider(binormals, mGeomIndex); + mVertexBuffer->getBinormalStrider(binorm, mGeomIndex); + binormals = (LLVector4a*) binorm.get(); } - + if (rebuild_weights) + { + mVertexBuffer->getWeight4Strider(wght, mGeomIndex); + weights = (LLVector4a*) wght.get(); + } + F32 tcoord_xoffset = 0.f ; F32 tcoord_yoffset = 0.f ; F32 tcoord_xscale = 1.f ; @@ -974,8 +1130,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, mVertexBuffer->getColorStrider(colors, mGeomIndex); } - F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0; - BOOL is_static = mDrawablep->isStatic(); BOOL is_global = is_static; @@ -990,59 +1144,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, clearState(GLOBAL); } - LLVector2 tmin, tmax; - - - - if (rebuild_tcoord) - { - if (tep) - { - r = tep->getRotation(); - os = tep->mOffsetS; - ot = tep->mOffsetT; - ms = tep->mScaleS; - mt = tep->mScaleT; - cos_ang = cos(r); - sin_ang = sin(r); - } - else - { - cos_ang = 1.0f; - sin_ang = 0.0f; - os = 0.0f; - ot = 0.0f; - ms = 1.0f; - mt = 1.0f; - } - } - - U8 tex_mode = 0; - - if (isState(TEXTURE_ANIM)) - { - LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp; - tex_mode = vobj->mTexAnimMode; - - 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; - } - - if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) - { //don't override texture transform during tc bake - tex_mode = 0; - } - } - LLColor4U color = tep->getColor(); if (rebuild_color) @@ -1064,265 +1165,469 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } } - // INDICES + // INDICES if (full_rebuild) { mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex); - if (LLPipeline::sUseTriStrips) + __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++) { - for (U32 i = 0; i < (U32) num_indices; i++) - { - *indicesp++ = vf.mTriStrip[i] + index_offset; - } + __m128i res = _mm_add_epi16(src[i], offset); + _mm_storeu_si128(dst+i, res); } - else + + for (S32 i = end*8; i < num_indices; ++i) { - for (U32 i = 0; i < (U32) num_indices; i++) - { - *indicesp++ = vf.mIndices[i] + index_offset; - } + indicesp[i] = vf.mIndices[i]+index_offset; } } + LLMatrix4a mat_normal; + mat_normal.loadu(mat_norm_in); - //bump setup - LLVector3 binormal_dir( -sin_ang, cos_ang, 0 ); - LLVector3 bump_s_primary_light_ray; - LLVector3 bump_t_primary_light_ray; + //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); - LLQuaternion bump_quat; - if (mDrawablep->isActive()) - { - bump_quat = LLQuaternion(mDrawablep->getRenderMatrix()); - } - - if (bump_code) + F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0; + + if (rebuild_tcoord) { - mVObjp->getVolume()->genBinormals(f); - F32 offset_multiple; - switch( bump_code ) + bool do_xform; + + if (tep) { - case BE_NO_BUMP: - offset_multiple = 0.f; - break; - case BE_BRIGHTNESS: - case BE_DARKNESS: - if( mTexture.notNull() && mTexture->hasGLTexture()) + r = tep->getRotation(); + os = tep->mOffsetS; + ot = tep->mOffsetT; + ms = tep->mScaleS; + mt = tep->mScaleT; + cos_ang = cos(r); + sin_ang = sin(r); + + if (cos_ang != 1.f || + sin_ang != 0.f || + os != 0.f || + ot != 0.f || + ms != 1.f || + mt != 1.f) { - // Offset by approximately one texel - S32 cur_discard = mTexture->getDiscardLevel(); - S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() ); - max_size <<= cur_discard; - const F32 ARTIFICIAL_OFFSET = 2.f; - offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size; + do_xform = true; } else { - offset_multiple = 1.f/256; - } - break; - - default: // Standard bumpmap textures. Assumed to be 256x256 - offset_multiple = 1.f / 256; - break; + do_xform = false; + } } - - F32 s_scale = 1.f; - F32 t_scale = 1.f; - if( tep ) + else { - tep->getScale( &s_scale, &t_scale ); + do_xform = false; } - // 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.getMoonDirection(); - LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray; + + //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); - bump_s_primary_light_ray = offset_multiple * s_scale * primary_light_ray; - bump_t_primary_light_ray = offset_multiple * t_scale * primary_light_ray; - } + LLQuaternion bump_quat; + if (mDrawablep->isActive()) + { + bump_quat = LLQuaternion(mDrawablep->getRenderMatrix()); + } - U8 texgen = getTextureEntry()->getTexGen(); - if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT) - { //planar texgen needs binormals - mVObjp->getVolume()->genBinormals(f); - } - - for (S32 i = 0; i < num_vertices; i++) - { - if (rebuild_tcoord) + if (bump_code) { - LLVector2 tc = vf.mVertices[i].mTexCoord; - - if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) + mVObjp->getVolume()->genBinormals(f); + F32 offset_multiple; + switch( bump_code ) { - LLVector3 vec = vf.mVertices[i].mPosition; - - vec.scaleVec(scale); - - switch (texgen) + case BE_NO_BUMP: + offset_multiple = 0.f; + break; + case BE_BRIGHTNESS: + case BE_DARKNESS: + if( mTexture.notNull() && mTexture->hasGLTexture()) { - case LLTextureEntry::TEX_GEN_PLANAR: - planarProjection(tc, vf.mVertices[i].mNormal, vf.mCenter, vec); - break; - case LLTextureEntry::TEX_GEN_SPHERICAL: - sphericalProjection(tc, vf.mVertices[i].mNormal, vf.mCenter, vec); - break; - case LLTextureEntry::TEX_GEN_CYLINDRICAL: - cylindricalProjection(tc, vf.mVertices[i].mNormal, vf.mCenter, vec); - break; - default: - break; - } + // Offset by approximately one texel + S32 cur_discard = mTexture->getDiscardLevel(); + S32 max_size = llmax( mTexture->getWidth(), mTexture->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; } - if (tex_mode && mTextureMatrix) + F32 s_scale = 1.f; + F32 t_scale = 1.f; + if( tep ) { - 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]; + 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.getMoonDirection(); + 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()->genBinormals(f); + } + + U8 tex_mode = 0; + + if (isState(TEXTURE_ANIM)) + { + LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp; + tex_mode = vobj->mTexAnimMode; + + if (!tex_mode) + { + clearState(TEXTURE_ANIM); } else { - xform(tc, cos_ang, sin_ang, os, ot, ms, mt); + os = ot = 0.f; + r = 0.f; + cos_ang = 1.f; + sin_ang = 0.f; + ms = mt = 1.f; + + do_xform = false; } - if(in_atlas) - { - // - //manually calculate tex-coord per vertex for varying address modes. - //should be removed if shader can handle this. - // + if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) + { //don't override texture transform during tc bake + tex_mode = 0; + } + } - S32 int_part = 0 ; - switch(mTexture->getAddressMode()) - { - case LLTexUnit::TAM_CLAMP: - if(tc.mV[0] < 0.f) - { - tc.mV[0] = 0.f ; - } - else if(tc.mV[0] > 1.f) - { - tc.mV[0] = 1.f; - } + LLVector4a scalea; + scalea.load3(scale.mV); - if(tc.mV[1] < 0.f) - { - tc.mV[1] = 0.f ; - } - else if(tc.mV[1] > 1.f) - { - tc.mV[1] = 1.f; - } - break; - case LLTexUnit::TAM_MIRROR: - if(tc.mV[0] < 0.f) - { - tc.mV[0] = -tc.mV[0] ; - } - int_part = (S32)tc.mV[0] ; - if(int_part & 1) //odd number - { - tc.mV[0] = int_part + 1 - tc.mV[0] ; - } - else //even number - { - tc.mV[0] -= int_part ; - } + bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1); + bool do_tex_mat = tex_mode && mTextureMatrix; - if(tc.mV[1] < 0.f) + if (!in_atlas && !do_bump) + { //not in atlas or not bump mapped, might be able to do a cheap update + if (texgen != LLTextureEntry::TEX_GEN_PLANAR) + { + if (!do_tex_mat) + { + if (!do_xform) { - tc.mV[1] = -tc.mV[1] ; + LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32)); } - int_part = (S32)tc.mV[1] ; - if(int_part & 1) //odd number + else { - tc.mV[1] = int_part + 1 - tc.mV[1] ; + for (S32 i = 0; i < num_vertices; i++) + { + LLVector2 tc(vf.mTexCoords[i]); + xform(tc, cos_ang, sin_ang, os, ot, ms, mt); + *tex_coords++ = tc; + } } - else //even number - { - tc.mV[1] -= int_part ; + } + else + { //do tex mat, no texgen, no atlas, no bump + for (S32 i = 0; i < num_vertices; i++) + { + LLVector2 tc(vf.mTexCoords[i]); + //LLVector4a& norm = vf.mNormals[i]; + //LLVector4a& center = *(vf.mCenter); + + 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_coords++ = tc; } - break; - case LLTexUnit::TAM_WRAP: - if(tc.mV[0] > 1.f) - tc.mV[0] -= (S32)(tc.mV[0] - 0.00001f) ; - else if(tc.mV[0] < -1.f) - tc.mV[0] -= (S32)(tc.mV[0] + 0.00001f) ; - - if(tc.mV[1] > 1.f) - tc.mV[1] -= (S32)(tc.mV[1] - 0.00001f) ; - else if(tc.mV[1] < -1.f) - tc.mV[1] -= (S32)(tc.mV[1] + 0.00001f) ; - - if(tc.mV[0] < 0.f) - { - tc.mV[0] = 1.0f + tc.mV[0] ; + } + } + else + { //no bump, no atlas, tex gen 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_coords++ = tc; } - if(tc.mV[1] < 0.f) - { - tc.mV[1] = 1.0f + tc.mV[1] ; + } + 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); + + xform(tc, cos_ang, sin_ang, os, ot, ms, mt); + + *tex_coords++ = tc; } - break; - default: - break; } - - tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ; - tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ; } + } + else + { //either bump mapped or in atlas, just do the whole expensive loop + 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); - *tex_coords++ = tc; - - if (bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)) - { - LLVector3 tangent = vf.mVertices[i].mBinormal % vf.mVertices[i].mNormal; + switch (texgen) + { + case LLTextureEntry::TEX_GEN_PLANAR: + planarProjection(tc, norm, center, vec); + break; + case LLTextureEntry::TEX_GEN_SPHERICAL: + sphericalProjection(tc, norm, center, vec); + break; + case LLTextureEntry::TEX_GEN_CYLINDRICAL: + cylindricalProjection(tc, norm, center, vec); + break; + default: + break; + } + } - LLMatrix3 tangent_to_object; - tangent_to_object.setRows(tangent, vf.mVertices[i].mBinormal, vf.mVertices[i].mNormal); - LLVector3 binormal = binormal_dir * tangent_to_object; - binormal = binormal * mat_normal; - - if (mDrawablep->isActive()) + if (tex_mode && mTextureMatrix) { - binormal *= bump_quat; + 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]; } + else + { + xform(tc, cos_ang, sin_ang, os, ot, ms, mt); + } + + if(in_atlas) + { + // + //manually calculate tex-coord per vertex for varying address modes. + //should be removed if shader can handle this. + // - binormal.normVec(); - tc += LLVector2( bump_s_primary_light_ray * tangent, bump_t_primary_light_ray * binormal ); + S32 int_part = 0 ; + switch(mTexture->getAddressMode()) + { + case LLTexUnit::TAM_CLAMP: + if(tc.mV[0] < 0.f) + { + tc.mV[0] = 0.f ; + } + else if(tc.mV[0] > 1.f) + { + tc.mV[0] = 1.f; + } + + if(tc.mV[1] < 0.f) + { + tc.mV[1] = 0.f ; + } + else if(tc.mV[1] > 1.f) + { + tc.mV[1] = 1.f; + } + break; + case LLTexUnit::TAM_MIRROR: + if(tc.mV[0] < 0.f) + { + tc.mV[0] = -tc.mV[0] ; + } + int_part = (S32)tc.mV[0] ; + if(int_part & 1) //odd number + { + tc.mV[0] = int_part + 1 - tc.mV[0] ; + } + else //even number + { + tc.mV[0] -= int_part ; + } + + if(tc.mV[1] < 0.f) + { + tc.mV[1] = -tc.mV[1] ; + } + int_part = (S32)tc.mV[1] ; + if(int_part & 1) //odd number + { + tc.mV[1] = int_part + 1 - tc.mV[1] ; + } + else //even number + { + tc.mV[1] -= int_part ; + } + break; + case LLTexUnit::TAM_WRAP: + if(tc.mV[0] > 1.f) + tc.mV[0] -= (S32)(tc.mV[0] - 0.00001f) ; + else if(tc.mV[0] < -1.f) + tc.mV[0] -= (S32)(tc.mV[0] + 0.00001f) ; + + if(tc.mV[1] > 1.f) + tc.mV[1] -= (S32)(tc.mV[1] - 0.00001f) ; + else if(tc.mV[1] < -1.f) + tc.mV[1] -= (S32)(tc.mV[1] + 0.00001f) ; + + if(tc.mV[0] < 0.f) + { + tc.mV[0] = 1.0f + tc.mV[0] ; + } + if(tc.mV[1] < 0.f) + { + tc.mV[1] = 1.0f + tc.mV[1] ; + } + break; + default: + break; + } - *tex_coords2++ = tc; - } + tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ; + tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ; + } + + + *tex_coords++ = tc; + + if (bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)) + { + LLVector4a tangent; + tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]); + + LLMatrix4a tangent_to_object; + tangent_to_object.setRows(tangent, vf.mBinormals[i], 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(); + tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() ); + + *tex_coords2++ = tc; + } + } } - - if (rebuild_pos) - { - *vertices++ = vf.mVertices[i].mPosition * mat_vert; + } + + if (rebuild_pos) + { + LLMatrix4a mat_vert; + mat_vert.loadu(mat_vert_in); + + LLVector4a* src = vf.mPositions; + LLVector4a* dst = vertices; + + LLVector4a* end = dst+num_vertices; + do + { + mat_vert.affineTransform(*src++, *dst++); } + while(dst < end); + } - if (rebuild_normal) - { - LLVector3 normal = vf.mVertices[i].mNormal * mat_normal; - normal.normVec(); - - *normals++ = normal; + if (rebuild_normal) + { + for (S32 i = 0; i < num_vertices; i++) + { + LLVector4a normal; + mat_normal.rotate(vf.mNormals[i], normal); + normal.normalize3fast(); + normals[i] = normal; } + } - if (rebuild_binormal) - { - LLVector3 binormal = vf.mVertices[i].mBinormal * mat_normal; - binormal.normVec(); - *binormals++ = binormal; + if (rebuild_binormal) + { + for (S32 i = 0; i < num_vertices; i++) + { + LLVector4a binormal; + mat_normal.rotate(vf.mBinormals[i], binormal); + binormal.normalize3fast(); + binormals[i] = binormal; } + } + + if (rebuild_weights && vf.mWeights) + { + LLVector4a::memcpyNonAliased16((F32*) weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32)); + } + + if (rebuild_color) + { + LLVector4a src; + + U32 vec[4]; + vec[0] = vec[1] = vec[2] = vec[3] = color.mAll; - if (rebuild_color) + src.loadua((F32*) vec); + + LLVector4a* dst = (LLVector4a*) colors.get(); + S32 num_vecs = num_vertices/4; + if (num_vertices%4 > 0) { - *colors++ = color; + ++num_vecs; + } + + for (S32 i = 0; i < num_vecs; i++) + { + dst[i] = src; } } @@ -1418,20 +1723,32 @@ F32 LLFace::getTextureVirtualSize() BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) { + //VECTORIZE THIS //get area of circle around face - LLVector3 center = getPositionAgent(); - LLVector3 size = (mExtents[1] - mExtents[0]) * 0.5f; + LLVector4a center; + center.load3(getPositionAgent().mV); + LLVector4a size; + size.setSub(mExtents[1], mExtents[0]); + size.mul(0.5f); + LLViewerCamera* camera = LLViewerCamera::getInstance(); - F32 size_squared = size.lengthSquared() ; - LLVector3 lookAt = center - camera->getOrigin(); - F32 dist = lookAt.normVec() ; + 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.f); + lookAt.normalize3fast() ; //get area of circle around node - F32 app_angle = atanf(fsqrtf(size_squared) / dist); + F32 app_angle = atanf((F32) sqrt(size_squared) / dist); radius = app_angle*LLDrawable::sCurPixelAngle; mPixelArea = radius*radius * 3.14159f; - cos_angle_to_view_dir = lookAt * camera->getXAxis() ; + 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()) @@ -1447,7 +1764,10 @@ BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) } else { - if(dist * dist * (lookAt - camera->getXAxis()).lengthSquared() < size_squared) + LLVector4a d; + d.setSub(lookAt, x_axis); + + if(dist * dist * d.dot3(d) < size_squared) { cos_angle_to_view_dir = 1.0f ; } @@ -1562,24 +1882,15 @@ BOOL LLFace::verify(const U32* indices_array) const BOOL ok = TRUE; if( mVertexBuffer.isNull() ) - { - if( mGeomCount ) - { - // This happens before teleports as faces are torn down. - // Stop the crash in DEV-31893 with a null pointer check, - // but present this info. - // To clean up the log, the geometry could be cleared, or the - // face could otherwise be marked for no ::verify. - llinfos << "Face with no vertex buffer and " << mGeomCount << " mGeomCount" << llendl; - } + { //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()) + if ((mGeomIndex + mGeomCount) > mVertexBuffer->getRequestedVerts()) { ok = FALSE; - llinfos << "Face not within pool range!" << llendl; + llinfos << "Face references invalid vertices!" << llendl; } S32 indices_count = (S32)getIndicesCount(); @@ -1595,6 +1906,12 @@ BOOL LLFace::verify(const U32* indices_array) const llinfos << "Face has bogus indices count" << llendl; } + if (mIndicesIndex + mIndicesCount > mVertexBuffer->getRequestedIndices()) + { + ok = FALSE; + llinfos << "Face references invalid indices!" << llendl; + } + #if 0 S32 geom_start = getGeomStart(); S32 geom_count = mGeomCount; @@ -1903,3 +2220,78 @@ BOOL LLFace::switchTexture() return mUsingAtlas ; } + +void LLFace::setVertexBuffer(LLVertexBuffer* buffer) +{ + mVertexBuffer = buffer; + llassert(verify()); +} + +void LLFace::clearVertexBuffer() +{ + mVertexBuffer = NULL; + mLastVertexBuffer = NULL; +} + +//static +U32 LLFace::getRiggedDataMask(U32 type) +{ + static const U32 rigged_data_mask[] = { + LLDrawPoolAvatar::RIGGED_SIMPLE_MASK, + LLDrawPoolAvatar::RIGGED_FULLBRIGHT_MASK, + LLDrawPoolAvatar::RIGGED_SHINY_MASK, + LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY_MASK, + LLDrawPoolAvatar::RIGGED_GLOW_MASK, + LLDrawPoolAvatar::RIGGED_ALPHA_MASK, + LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA_MASK, + LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP_MASK, + LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE_MASK, + }; + + llassert(type < sizeof(rigged_data_mask)/sizeof(U32)); + + return rigged_data_mask[type]; +} + +U32 LLFace::getRiggedVertexBufferDataMask() const +{ + U32 data_mask = 0; + for (U32 i = 0; i < mRiggedIndex.size(); ++i) + { + if (mRiggedIndex[i] > -1) + { + data_mask |= LLFace::getRiggedDataMask(i); + } + } + + return data_mask; +} + +S32 LLFace::getRiggedIndex(U32 type) const +{ + if (mRiggedIndex.empty()) + { + return -1; + } + + llassert(type < mRiggedIndex.size()); + + return mRiggedIndex[type]; +} + +void LLFace::setRiggedIndex(U32 type, S32 index) +{ + if (mRiggedIndex.empty()) + { + mRiggedIndex.resize(LLDrawPoolAvatar::NUM_RIGGED_PASSES); + for (U32 i = 0; i < mRiggedIndex.size(); ++i) + { + mRiggedIndex[i] = -1; + } + } + + llassert(type < mRiggedIndex.size()); + + mRiggedIndex[type] = index; +} + diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 6c941bd092..b2170c4cf3 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -59,6 +59,17 @@ class LLFace { public: + LLFace(const LLFace& rhs) + { + *this = rhs; + } + + const LLFace& operator=(const LLFace& rhs) + { + llerrs << "Illegal operation!" << llendl; + return *this; + } + enum EMasks { LIGHT = 0x0001, @@ -67,6 +78,7 @@ public: HUD_RENDER = 0x0008, USE_FACE_COLOR = 0x0010, TEXTURE_ANIM = 0x0020, + RIGGED = 0x0040, }; static void initClass(); @@ -119,14 +131,14 @@ public: LLDrawable* getDrawable() const { return mDrawablep; } LLViewerObject* getViewerObject() const { return mVObjp; } S32 getLOD() const { return mVObjp.notNull() ? mVObjp->getLOD() : 0; } - LLVertexBuffer* getVertexBuffer() const { return mVertexBuffer; } void setPoolType(U32 type) { mPoolType = type; } S32 getTEOffset() { return mTEOffset; } LLViewerTexture* getTexture() const; void setViewerObject(LLViewerObject* object); void setPool(LLFacePool *pool, LLViewerTexture *texturep); - + void setPool(LLFacePool* pool); + void setDrawable(LLDrawable *drawable); void setTEOffset(const S32 te_offset); @@ -142,7 +154,8 @@ public: BOOL getGeometryVolume(const LLVolume& volume, const S32 &f, const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, - const U16 &index_offset); + const U16 &index_offset, + bool force_rebuild = false); // For avatar U16 getGeometryAvatar( @@ -161,7 +174,7 @@ public: S32 getColors(LLStrider<LLColor4U> &colors); S32 getIndices(LLStrider<U16> &indices); - void setSize(const S32 numVertices, const S32 num_indices = 0); + void setSize(S32 numVertices, S32 num_indices = 0, bool align = false); BOOL genVolumeBBoxes(const LLVolume &volume, S32 f, const LLMatrix4& mat, const LLMatrix3& inv_trans_mat, BOOL global_volume = FALSE); @@ -183,8 +196,8 @@ public: BOOL verify(const U32* indices_array = NULL) const; void printDebugInfo() const; - void setGeomIndex(U16 idx) { mGeomIndex = idx; } - void setIndicesIndex(S32 idx) { mIndicesIndex = idx; } + void setGeomIndex(U16 idx); + void setIndicesIndex(S32 idx); void setDrawInfo(LLDrawInfo* draw_info); F32 getTextureVirtualSize() ; @@ -205,6 +218,19 @@ public: void removeAtlas() ; BOOL switchTexture() ; + //vertex buffer tracking + void setVertexBuffer(LLVertexBuffer* buffer); + void clearVertexBuffer(); //sets mVertexBuffer and mLastVertexBuffer to NULL + LLVertexBuffer* getVertexBuffer() const { return mVertexBuffer; } + U32 getRiggedVertexBufferDataMask() const; + S32 getRiggedIndex(U32 type) const; + void setRiggedIndex(U32 type, S32 index); + + static U32 getRiggedDataMask(U32 type); + +public: //aligned members + LLVector4a mExtents[2]; + private: F32 adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius ); BOOL calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) ; @@ -216,20 +242,19 @@ public: LLVector3 mCenterLocal; LLVector3 mCenterAgent; - LLVector3 mExtents[2]; + LLVector2 mTexExtents[2]; F32 mDistance; - LLPointer<LLVertexBuffer> mVertexBuffer; - LLPointer<LLVertexBuffer> mLastVertexBuffer; F32 mLastUpdateTime; + F32 mLastSkinTime; F32 mLastMoveTime; LLMatrix4* mTextureMatrix; LLDrawInfo* mDrawInfo; private: - friend class LLGeometryManager; - friend class LLVolumeGeometryManager; - + LLPointer<LLVertexBuffer> mVertexBuffer; + LLPointer<LLVertexBuffer> mLastVertexBuffer; + U32 mState; LLFacePool* mDrawPoolp; U32 mPoolType; @@ -254,6 +279,8 @@ private: S32 mTEOffset; S32 mReferenceIndex; + std::vector<S32> mRiggedIndex; + F32 mVSize; F32 mPixelArea; diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 279904b740..35712163eb 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -32,7 +32,9 @@ #include "llrect.h" #include "llerror.h" #include "llgl.h" +#include "llimagepng.h" #include "llrender.h" +#include "llrendertarget.h" #include "lllocalcliprect.h" #include "llmath.h" #include "llfontgl.h" @@ -49,6 +51,8 @@ #include "llfasttimer.h" #include "lltreeiterators.h" #include "llmetricperformancetester.h" +#include "llviewerstats.h" + ////////////////////////////////////////////////////////////////////////////// static const S32 MAX_VISIBLE_HISTORY = 10; @@ -1020,6 +1024,327 @@ F64 LLFastTimerView::getTime(const std::string& name) return 0.0; } +void saveChart(const std::string& label, const char* suffix, LLImageRaw* scratch) +{ + //read result back into raw image + glReadPixels(0, 0, 1024, 512, GL_RGB, GL_UNSIGNED_BYTE, scratch->getData()); + + //write results to disk + LLPointer<LLImagePNG> result = new LLImagePNG(); + result->encode(scratch, 0.f); + + std::string ext = result->getExtension(); + std::string filename = llformat("%s_%s.%s", label.c_str(), suffix, ext.c_str()); + + std::string out_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, filename); + result->save(out_file); +} + +//static +void LLFastTimerView::exportCharts(const std::string& base, const std::string& target) +{ + //allocate render target for drawing charts + LLRenderTarget buffer; + buffer.allocate(1024,512, GL_RGB, FALSE, FALSE); + + + LLSD cur; + + LLSD base_data; + + { //read base log into memory + S32 i = 0; + std::ifstream is(base.c_str()); + while (!is.eof() && LLSDSerialize::fromXML(cur, is)) + { + base_data[i++] = cur; + } + is.close(); + } + + LLSD cur_data; + std::set<std::string> chart_names; + + { //read current log into memory + S32 i = 0; + std::ifstream is(target.c_str()); + while (!is.eof() && LLSDSerialize::fromXML(cur, is)) + { + cur_data[i++] = cur; + + for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter) + { + std::string label = iter->first; + chart_names.insert(label); + } + } + is.close(); + } + + //get time domain + LLSD::Real cur_total_time = 0.0; + + for (U32 i = 0; i < cur_data.size(); ++i) + { + cur_total_time += cur_data[i]["Total"]["Time"].asReal(); + } + + LLSD::Real base_total_time = 0.0; + for (U32 i = 0; i < base_data.size(); ++i) + { + base_total_time += base_data[i]["Total"]["Time"].asReal(); + } + + //allocate raw scratch space + LLPointer<LLImageRaw> scratch = new LLImageRaw(1024, 512, 3); + + gGL.pushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-0.05, 1.05, -0.05, 1.05, -1.0, 1.0); + + //render charts + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + buffer.bindTarget(); + + for (std::set<std::string>::iterator iter = chart_names.begin(); iter != chart_names.end(); ++iter) + { + std::string label = *iter; + + LLSD::Real max_time = 0.0; + LLSD::Integer max_calls = 0; + LLSD::Real max_execution = 0.0; + + std::vector<LLSD::Real> cur_execution; + std::vector<LLSD::Real> cur_times; + std::vector<LLSD::Integer> cur_calls; + + std::vector<LLSD::Real> base_execution; + std::vector<LLSD::Real> base_times; + std::vector<LLSD::Integer> base_calls; + + for (U32 i = 0; i < cur_data.size(); ++i) + { + LLSD::Real time = cur_data[i][label]["Time"].asReal(); + LLSD::Integer calls = cur_data[i][label]["Calls"].asInteger(); + + LLSD::Real execution = 0.0; + if (calls > 0) + { + execution = time/calls; + cur_execution.push_back(execution); + cur_times.push_back(time); + } + + cur_calls.push_back(calls); + } + + for (U32 i = 0; i < base_data.size(); ++i) + { + LLSD::Real time = base_data[i][label]["Time"].asReal(); + LLSD::Integer calls = base_data[i][label]["Calls"].asInteger(); + + LLSD::Real execution = 0.0; + if (calls > 0) + { + execution = time/calls; + base_execution.push_back(execution); + base_times.push_back(time); + } + + base_calls.push_back(calls); + } + + std::sort(base_calls.begin(), base_calls.end()); + std::sort(base_times.begin(), base_times.end()); + std::sort(base_execution.begin(), base_execution.end()); + + std::sort(cur_calls.begin(), cur_calls.end()); + std::sort(cur_times.begin(), cur_times.end()); + std::sort(cur_execution.begin(), cur_execution.end()); + + //remove outliers + const U32 OUTLIER_CUTOFF = 512; + if (base_times.size() > OUTLIER_CUTOFF) + { + ll_remove_outliers(base_times, 1.f); + } + + if (base_execution.size() > OUTLIER_CUTOFF) + { + ll_remove_outliers(base_execution, 1.f); + } + + if (cur_times.size() > OUTLIER_CUTOFF) + { + ll_remove_outliers(cur_times, 1.f); + } + + if (cur_execution.size() > OUTLIER_CUTOFF) + { + ll_remove_outliers(cur_execution, 1.f); + } + + + max_time = llmax(base_times.empty() ? 0.0 : *base_times.rbegin(), cur_times.empty() ? 0.0 : *cur_times.rbegin()); + max_calls = llmax(base_calls.empty() ? 0 : *base_calls.rbegin(), cur_calls.empty() ? 0 : *cur_calls.rbegin()); + max_execution = llmax(base_execution.empty() ? 0.0 : *base_execution.rbegin(), cur_execution.empty() ? 0.0 : *cur_execution.rbegin()); + + + LLVector3 last_p; + + //==================================== + // basic + //==================================== + buffer.clear(); + + last_p.clear(); + + LLGLDisable cull(GL_CULL_FACE); + + LLVector3 base_col(0, 0.7f, 0.f); + LLVector3 cur_col(1.f, 0.f, 0.f); + + gGL.setSceneBlendType(LLRender::BT_ADD); + + gGL.color3fv(base_col.mV); + for (U32 i = 0; i < base_times.size(); ++i) + { + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex3fv(last_p.mV); + gGL.vertex3f(last_p.mV[0], 0.f, 0.f); + last_p.set((F32)i/(F32) base_times.size(), base_times[i]/max_time, 0.f); + gGL.vertex3fv(last_p.mV); + gGL.vertex3f(last_p.mV[0], 0.f, 0.f); + gGL.end(); + } + + gGL.flush(); + + + last_p.clear(); + { + LLGLEnable blend(GL_BLEND); + + gGL.color3fv(cur_col.mV); + for (U32 i = 0; i < cur_times.size(); ++i) + { + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex3f(last_p.mV[0], 0.f, 0.f); + gGL.vertex3fv(last_p.mV); + last_p.set((F32) i / (F32) cur_times.size(), cur_times[i]/max_time, 0.f); + gGL.vertex3f(last_p.mV[0], 0.f, 0.f); + gGL.vertex3fv(last_p.mV); + gGL.end(); + } + + gGL.flush(); + } + + saveChart(label, "time", scratch); + + //====================================== + // calls + //====================================== + buffer.clear(); + + last_p.clear(); + + gGL.color3fv(base_col.mV); + for (U32 i = 0; i < base_calls.size(); ++i) + { + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex3fv(last_p.mV); + gGL.vertex3f(last_p.mV[0], 0.f, 0.f); + last_p.set((F32) i / (F32) base_calls.size(), (F32)base_calls[i]/max_calls, 0.f); + gGL.vertex3fv(last_p.mV); + gGL.vertex3f(last_p.mV[0], 0.f, 0.f); + gGL.end(); + } + + gGL.flush(); + + { + LLGLEnable blend(GL_BLEND); + gGL.color3fv(cur_col.mV); + last_p.clear(); + + for (U32 i = 0; i < cur_calls.size(); ++i) + { + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex3f(last_p.mV[0], 0.f, 0.f); + gGL.vertex3fv(last_p.mV); + last_p.set((F32) i / (F32) cur_calls.size(), (F32) cur_calls[i]/max_calls, 0.f); + gGL.vertex3f(last_p.mV[0], 0.f, 0.f); + gGL.vertex3fv(last_p.mV); + gGL.end(); + + } + + gGL.flush(); + } + + saveChart(label, "calls", scratch); + + //====================================== + // execution + //====================================== + buffer.clear(); + + + gGL.color3fv(base_col.mV); + U32 count = 0; + U32 total_count = base_execution.size(); + + last_p.clear(); + + for (std::vector<LLSD::Real>::iterator iter = base_execution.begin(); iter != base_execution.end(); ++iter) + { + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex3fv(last_p.mV); + gGL.vertex3f(last_p.mV[0], 0.f, 0.f); + last_p.set((F32)count/(F32)total_count, *iter/max_execution, 0.f); + gGL.vertex3fv(last_p.mV); + gGL.vertex3f(last_p.mV[0], 0.f, 0.f); + gGL.end(); + count++; + } + + last_p.clear(); + + { + LLGLEnable blend(GL_BLEND); + gGL.color3fv(cur_col.mV); + count = 0; + total_count = cur_execution.size(); + + for (std::vector<LLSD::Real>::iterator iter = cur_execution.begin(); iter != cur_execution.end(); ++iter) + { + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex3f(last_p.mV[0], 0.f, 0.f); + gGL.vertex3fv(last_p.mV); + last_p.set((F32)count/(F32)total_count, *iter/max_execution, 0.f); + gGL.vertex3f(last_p.mV[0], 0.f, 0.f); + gGL.vertex3fv(last_p.mV); + gGL.end(); + count++; + } + + gGL.flush(); + } + + saveChart(label, "execution", scratch); + } + + buffer.flush(); + + gGL.popMatrix(); + glMatrixMode(GL_MODELVIEW); + gGL.popMatrix(); +} + //static LLSD LLFastTimerView::analyzePerformanceLogDefault(std::istream& is) { @@ -1030,6 +1355,10 @@ LLSD LLFastTimerView::analyzePerformanceLogDefault(std::istream& is) LLSD::Real total_time = 0.0; LLSD::Integer total_frames = 0; + typedef std::map<std::string,LLViewerStats::StatsAccumulator> stats_map_t; + stats_map_t time_stats; + stats_map_t sample_stats; + while (!is.eof() && LLSDSerialize::fromXML(cur, is)) { for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter) @@ -1046,35 +1375,31 @@ LLSD LLFastTimerView::analyzePerformanceLogDefault(std::istream& is) if (time > 0.0) { - ret[label]["TotalTime"] = ret[label]["TotalTime"].asReal() + time; - ret[label]["MaxTime"] = llmax(time, ret[label]["MaxTime"].asReal()); - - if (ret[label]["MinTime"].asReal() == 0) - { - ret[label]["MinTime"] = time; - } - else - { - ret[label]["MinTime"] = llmin(ret[label]["MinTime"].asReal(), time); - } - LLSD::Integer samples = iter->second["Calls"].asInteger(); - ret[label]["Samples"] = ret[label]["Samples"].asInteger() + samples; - ret[label]["MaxSamples"] = llmax(ret[label]["MaxSamples"].asInteger(), samples); - - if (ret[label]["MinSamples"].asInteger() == 0) - { - ret[label]["MinSamples"] = samples; - } - else - { - ret[label]["MinSamples"] = llmin(ret[label]["MinSamples"].asInteger(), samples); - } + time_stats[label].push(time); + sample_stats[label].push(samples); } } total_frames++; } + + for(stats_map_t::iterator it = time_stats.begin(); it != time_stats.end(); ++it) + { + std::string label = it->first; + ret[label]["TotalTime"] = time_stats[label].mSum; + ret[label]["MeanTime"] = time_stats[label].getMean(); + ret[label]["MaxTime"] = time_stats[label].getMaxValue(); + ret[label]["MinTime"] = time_stats[label].getMinValue(); + ret[label]["StdDevTime"] = time_stats[label].getStdDev(); + + ret[label]["Samples"] = sample_stats[label].mSum; + ret[label]["MaxSamples"] = sample_stats[label].getMaxValue(); + ret[label]["MinSamples"] = sample_stats[label].getMinValue(); + ret[label]["StdDevSamples"] = sample_stats[label].getStdDev(); + + ret[label]["Frames"] = (LLSD::Integer)time_stats[label].getCount(); + } ret["SessionTime"] = total_time; ret["FrameCount"] = total_frames; @@ -1109,8 +1434,27 @@ void LLFastTimerView::doAnalysisDefault(std::string baseline, std::string target std::ofstream os(output.c_str()); LLSD::Real session_time = current["SessionTime"].asReal(); - - os << "Label, % Change, % of Session, Cur Min, Cur Max, Cur Mean, Cur Total, Cur Samples, Base Min, Base Max, Base Mean, Base Total, Base Samples\n"; + os << + "Label, " + "% Change, " + "% of Session, " + "Cur Min, " + "Cur Max, " + "Cur Mean/sample, " + "Cur Mean/frame, " + "Cur StdDev/frame, " + "Cur Total, " + "Cur Frames, " + "Cur Samples, " + "Base Min, " + "Base Max, " + "Base Mean/sample, " + "Base Mean/frame, " + "Base StdDev/frame, " + "Base Total, " + "Base Frames, " + "Base Samples\n"; + for (LLSD::map_iterator iter = base.beginMap(); iter != base.endMap(); ++iter) { LLSD::String label = iter->first; @@ -1122,29 +1466,37 @@ void LLFastTimerView::doAnalysisDefault(std::string baseline, std::string target continue; } LLSD::Real a = base[label]["TotalTime"].asReal() / base[label]["Samples"].asReal(); - LLSD::Real b = current[label]["TotalTime"].asReal() / base[label]["Samples"].asReal(); + LLSD::Real b = current[label]["TotalTime"].asReal() / current[label]["Samples"].asReal(); LLSD::Real diff = b-a; LLSD::Real perc = diff/a * 100; - os << llformat("%s, %.2f, %.4f, %.4f, %.4f, %.4f, %.4f, %d, %.4f, %.4f, %.4f, %.4f, %d\n", + os << llformat("%s, %.2f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %d, %d, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %d, %d\n", label.c_str(), (F32) perc, (F32) (current[label]["TotalTime"].asReal()/session_time * 100.0), + (F32) current[label]["MinTime"].asReal(), (F32) current[label]["MaxTime"].asReal(), (F32) b, + (F32) current[label]["MeanTime"].asReal(), + (F32) current[label]["StdDevTime"].asReal(), (F32) current[label]["TotalTime"].asReal(), + current[label]["Frames"].asInteger(), current[label]["Samples"].asInteger(), (F32) base[label]["MinTime"].asReal(), (F32) base[label]["MaxTime"].asReal(), (F32) a, + (F32) base[label]["MeanTime"].asReal(), + (F32) base[label]["StdDevTime"].asReal(), (F32) base[label]["TotalTime"].asReal(), + base[label]["Frames"].asInteger(), base[label]["Samples"].asInteger()); } - + exportCharts(baseline, target); + os.flush(); os.close(); } diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h index b40d7ffc1a..ea8251191b 100644 --- a/indra/newview/llfasttimerview.h +++ b/indra/newview/llfasttimerview.h @@ -43,6 +43,7 @@ public: private: static void doAnalysisDefault(std::string baseline, std::string target, std::string output) ; static LLSD analyzePerformanceLogDefault(std::istream& is) ; + static void exportCharts(const std::string& base, const std::string& target); public: diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 4e16cc4217..3bdab75acf 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -203,7 +203,7 @@ BOOL LLFeatureManager::maskFeatures(const std::string& name) LL_DEBUGS("RenderInit") << "Unknown feature mask " << name << LL_ENDL; return FALSE; } - LL_DEBUGS("RenderInit") << "Applying Feature Mask: " << name << LL_ENDL; + LL_INFOS("RenderInit") << "Applying GPU Feature list: " << name << LL_ENDL; return maskList(*maskp); } @@ -378,13 +378,16 @@ void LLFeatureManager::parseGPUTable(std::string filename) return; } - std::string renderer = gGLManager.getRawGLString(); + std::string rawRenderer = gGLManager.getRawGLString(); + std::string renderer = rawRenderer; for (std::string::iterator i = renderer.begin(); i != renderer.end(); ++i) { *i = tolower(*i); } - - while (!file.eof()) + + bool gpuFound; + U32 lineNumber; + for (gpuFound = false, lineNumber = 0; !gpuFound && !file.eof(); lineNumber++) { char buffer[MAX_STRING]; /*Flawfinder: ignore*/ buffer[0] = 0; @@ -431,6 +434,7 @@ void LLFeatureManager::parseGPUTable(std::string filename) if (label.empty() || expr.empty() || cls.empty() || supported.empty()) { + LL_WARNS("RenderInit") << "invald gpu_table.txt:" << lineNumber << ": '" << buffer << "'" << LL_ENDL; continue; } @@ -444,18 +448,26 @@ void LLFeatureManager::parseGPUTable(std::string filename) if(boost::regex_search(renderer, re)) { // if we found it, stop! - file.close(); - LL_INFOS("RenderInit") << "GPU is " << label << llendl; + gpuFound = true; mGPUString = label; mGPUClass = (EGPUClass) strtol(cls.c_str(), NULL, 10); mGPUSupported = (BOOL) strtol(supported.c_str(), NULL, 10); - file.close(); - return; } } file.close(); - LL_WARNS("RenderInit") << "Couldn't match GPU to a class: " << gGLManager.getRawGLString() << LL_ENDL; + if ( gpuFound ) + { + LL_INFOS("RenderInit") << "GPU '" << rawRenderer << "' recognized as '" << mGPUString << "'" << LL_ENDL; + if (!mGPUSupported) + { + LL_INFOS("RenderInit") << "GPU '" << mGPUString << "' is not supported." << LL_ENDL; + } + } + else + { + LL_WARNS("RenderInit") << "GPU '" << rawRenderer << "' not recognized" << LL_ENDL; + } } // responder saves table into file @@ -729,6 +741,10 @@ void LLFeatureManager::applyBaseMasks() { maskFeatures("ATI"); } + if (gGLManager.mHasATIMemInfo && gGLManager.mVRAM < 256) + { + maskFeatures("ATIVramLT256"); + } if (gGLManager.mATIOldDriver) { maskFeatures("ATIOldDriver"); @@ -745,6 +761,14 @@ void LLFeatureManager::applyBaseMasks() { maskFeatures("OpenGLPre15"); } + if (gGLManager.mGLVersion < 3.f) + { + maskFeatures("OpenGLPre30"); + } + if (gGLManager.mNumTextureUnits <= 8) + { + maskFeatures("TexUnit8orLess"); + } // now mask by gpu string // Replaces ' ' with '_' in mGPUString to deal with inability for parser to handle spaces diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 51e76bcf9b..8c0ed29855 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -50,12 +50,14 @@ LLFilePicker LLFilePicker::sInstance; #define SOUND_FILTER L"Sounds (*.wav)\0*.wav\0" #define IMAGE_FILTER L"Images (*.tga; *.bmp; *.jpg; *.jpeg; *.png)\0*.tga;*.bmp;*.jpg;*.jpeg;*.png\0" #define ANIM_FILTER L"Animations (*.bvh)\0*.bvh\0" +#define COLLADA_FILTER L"Scene (*.dae)\0*.dae\0" #ifdef _CORY_TESTING #define GEOMETRY_FILTER L"SL Geometry (*.slg)\0*.slg\0" #endif #define XML_FILTER L"XML files (*.xml)\0*.xml\0" #define SLOBJECT_FILTER L"Objects (*.slobject)\0*.slobject\0" #define RAW_FILTER L"RAW files (*.raw)\0*.raw\0" +#define MODEL_FILTER L"Model files (*.dae)\0*.dae\0" #endif // @@ -185,6 +187,10 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter) mOFN.lpstrFilter = ANIM_FILTER \ L"\0"; break; + case FFLOAD_COLLADA: + mOFN.lpstrFilter = COLLADA_FILTER \ + L"\0"; + break; #ifdef _CORY_TESTING case FFLOAD_GEOMETRY: mOFN.lpstrFilter = GEOMETRY_FILTER \ @@ -203,6 +209,10 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter) mOFN.lpstrFilter = RAW_FILTER \ L"\0"; break; + case FFLOAD_MODEL: + mOFN.lpstrFilter = MODEL_FILTER \ + L"\0"; + break; default: res = FALSE; break; @@ -210,7 +220,7 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter) return res; } -BOOL LLFilePicker::getOpenFile(ELoadFilter filter) +BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking) { if( mLocked ) { @@ -235,8 +245,11 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter) setupFilter(filter); - // Modal, so pause agent - send_agent_pause(); + if (blocking) + { + // Modal, so pause agent + send_agent_pause(); + } reset(); @@ -247,10 +260,14 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter) std::string filename = utf16str_to_utf8str(llutf16string(mFilesW)); mFiles.push_back(filename); } - send_agent_resume(); - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); + if (blocking) + { + send_agent_resume(); + // Account for the fact that the app has been stalled. + LLFrameTimer::updateFrameTime(); + } + return success; } @@ -570,6 +587,15 @@ Boolean LLFilePicker::navOpenFilterProc(AEDesc *theItem, void *info, void *callB result = false; } } + else if (filter == FFLOAD_COLLADA) + { + if (fileInfo.filetype != 'DAE ' && + (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("dae"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) + ) + { + result = false; + } + } #ifdef _CORY_TESTING else if (filter == FFLOAD_GEOMETRY) { @@ -841,7 +867,7 @@ OSStatus LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& fi return error; } -BOOL LLFilePicker::getOpenFile(ELoadFilter filter) +BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking) { if( mLocked ) return FALSE; @@ -866,20 +892,29 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter) mNavOptions.optionFlags |= kNavSupportPackages; } - // Modal, so pause agent - send_agent_pause(); + if (blocking) + { + // Modal, so pause agent + send_agent_pause(); + } + { error = doNavChooseDialog(filter); } - send_agent_resume(); + if (error == noErr) { if (getFileCount()) success = true; } - // Account for the fact that the app has been stalled. - LLFrameTimer::updateFrameTime(); + if (blocking) + { + send_agent_resume(); + // Account for the fact that the app has been stalled. + LLFrameTimer::updateFrameTime(); + } + return success; } @@ -1140,6 +1175,12 @@ static std::string add_bvh_filter_to_gtkchooser(GtkWindow *picker) LLTrans::getString("animation_files") + " (*.bvh)"); } +static std::string add_collada_filter_to_gtkchooser(GtkWindow *picker) +{ + 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(); @@ -1248,7 +1289,7 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename return rtn; } -BOOL LLFilePicker::getOpenFile( ELoadFilter filter ) +BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking ) { BOOL rtn = FALSE; @@ -1276,6 +1317,9 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter ) case FFLOAD_ANIM: filtername = add_bvh_filter_to_gtkchooser(picker); break; + case FFLOAD_COLLADA: + filtername = add_collada_filter_to_gtkchooser(picker); + break; case FFLOAD_IMAGE: filtername = add_imageload_filter_to_gtkchooser(picker); break; diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index 596bfa3e69..cd843a8f33 100644 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -82,6 +82,8 @@ public: FFLOAD_XML = 6, FFLOAD_SLOBJECT = 7, FFLOAD_RAW = 8, + FFLOAD_MODEL = 9, + FFLOAD_COLLADA = 10, }; enum ESaveFilter @@ -105,7 +107,7 @@ public: // open the dialog. This is a modal operation BOOL getSaveFile( ESaveFilter filter = FFSAVE_ALL, const std::string& filename = LLStringUtil::null ); - BOOL getOpenFile( ELoadFilter filter = FFLOAD_ALL ); + BOOL getOpenFile( ELoadFilter filter = FFLOAD_ALL, bool blocking = true ); BOOL getMultipleOpenFiles( ELoadFilter filter = FFLOAD_ALL ); // Get the filename(s) found. getFirstFile() sets the pointer to @@ -190,4 +192,6 @@ public: ~LLFilePicker(); }; +const std::string upload_pick(void* data); + #endif diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index 8ab2229235..3d1650d2f5 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -91,11 +91,13 @@ void LLVolumeImplFlexible::onParameterChanged(U16 param_type, LLNetworkData *dat } } -void LLVolumeImplFlexible::onShift(const LLVector3 &shift_vector) +void LLVolumeImplFlexible::onShift(const LLVector4a &shift_vector) { + //VECTORIZE THIS + LLVector3 shift(shift_vector.getF32ptr()); for (int section = 0; section < (1<<FLEXIBLE_OBJECT_MAX_SECTIONS)+1; ++section) { - mSection[section].mPosition += shift_vector; + mSection[section].mPosition += shift; } } @@ -314,11 +316,13 @@ BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6 return FALSE; // (we are not initialized or updated) } - if (force_update) + bool visible = mVO->mDrawable->isVisible(); + + if (force_update && visible) { gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_POSITION, FALSE); } - else if (mVO->mDrawable->isVisible() && + else if (visible && !mVO->mDrawable->isState(LLDrawable::IN_REBUILD_Q1) && mVO->getPixelArea() > 256.f) { @@ -362,7 +366,7 @@ void LLVolumeImplFlexible::doFlexibleUpdate() LLFastTimer ftm(FTM_DO_FLEXIBLE_UPDATE); LLVolume* volume = mVO->getVolume(); LLPath *path = &volume->getPath(); - if (mSimulateRes == 0) + if ((mSimulateRes == 0 || !mInitialized) && mVO->mDrawable->isVisible()) // if its uninitialized but not visible, what then? - Nyx { mVO->markForUpdate(TRUE); if (!doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0)) @@ -690,6 +694,8 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable) } volume->updateRelativeXform(); + + if (mRenderRes > -1) { LLFastTimer t(FTM_DO_FLEXIBLE_UPDATE); doFlexibleUpdate(); diff --git a/indra/newview/llflexibleobject.h b/indra/newview/llflexibleobject.h index 9b952f1985..fef43d464d 100644 --- a/indra/newview/llflexibleobject.h +++ b/indra/newview/llflexibleobject.h @@ -84,7 +84,7 @@ class LLVolumeImplFlexible : public LLVolumeInterface void onSetVolume(const LLVolumeParams &volume_params, const S32 detail); void onSetScale(const LLVector3 &scale, BOOL damped); void onParameterChanged(U16 param_type, LLNetworkData *data, BOOL in_use, bool local_origin); - void onShift(const LLVector3 &shift_vector); + void onShift(const LLVector4a &shift_vector); bool isVolumeUnique() const { return true; } bool isVolumeGlobal() const { return true; } bool isActive() const { return true; } diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp index deebd69ec1..1f334815d6 100644 --- a/indra/newview/llfloateranimpreview.cpp +++ b/indra/newview/llfloateranimpreview.cpp @@ -994,6 +994,7 @@ void LLFloaterAnimPreview::onBtnOK(void* userdata) LLFloaterPerms::getNextOwnerPerms(), LLFloaterPerms::getGroupPerms(), LLFloaterPerms::getEveryonePerms(), name, callback, expected_upload_cost, userdata); + } else { @@ -1032,7 +1033,6 @@ LLPreviewAnimation::LLPreviewAnimation(S32 width, S32 height) : LLViewerDynamicT mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable); mDummyAvatar->startMotion(ANIM_AGENT_STAND, BASE_ANIM_TIME_OFFSET); mDummyAvatar->hideSkirt(); - gPipeline.markVisible(mDummyAvatar->mDrawable, *LLViewerCamera::getInstance()); // stop extraneous animations mDummyAvatar->stopMotion( ANIM_AGENT_HEAD_ROT, TRUE ); diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp index 50b19a4221..610142b5a9 100644 --- a/indra/newview/llfloaterbuyland.cpp +++ b/indra/newview/llfloaterbuyland.cpp @@ -461,15 +461,15 @@ void LLFloaterBuyLandUI::updateParcelInfo() if (!authorizedBuyer.isNull() && buyer != authorizedBuyer) { - // Maybe the parcel is set for sale to a group we are in.
- bool authorized_group =
- gAgent.hasPowerInGroup(authorizedBuyer,GP_LAND_DEED)
- && gAgent.hasPowerInGroup(authorizedBuyer,GP_LAND_SET_SALE_INFO);
-
- if (!authorized_group)
- {
- mCannotBuyReason = getString("set_to_sell_to_other");
- return;
+ // Maybe the parcel is set for sale to a group we are in. + bool authorized_group = + gAgent.hasPowerInGroup(authorizedBuyer,GP_LAND_DEED) + && gAgent.hasPowerInGroup(authorizedBuyer,GP_LAND_SET_SALE_INFO); + + if (!authorized_group) + { + mCannotBuyReason = getString("set_to_sell_to_other"); + return; } } } diff --git a/indra/newview/llfloaterdaycycle.cpp b/indra/newview/llfloaterdaycycle.cpp index eb429d7803..ebf7b98148 100644 --- a/indra/newview/llfloaterdaycycle.cpp +++ b/indra/newview/llfloaterdaycycle.cpp @@ -114,47 +114,16 @@ void LLFloaterDayCycle::initCallbacks(void) childSetCommitCallback("WLCurKeyMin", onKeyTimeChanged, NULL); childSetCommitCallback("WLKeyPresets", onKeyPresetChanged, NULL); - childSetCommitCallback("WLLengthOfDayHour", onTimeRateChanged, NULL); - childSetCommitCallback("WLLengthOfDayMin", onTimeRateChanged, NULL); - childSetCommitCallback("WLLengthOfDaySec", onTimeRateChanged, NULL); - childSetAction("WLUseLindenTime", onUseLindenTime, NULL); - childSetAction("WLAnimSky", onRunAnimSky, NULL); - childSetAction("WLStopAnimSky", onStopAnimSky, NULL); - - childSetAction("WLLoadDayCycle", onLoadDayCycle, NULL); - childSetAction("WLSaveDayCycle", onSaveDayCycle, NULL); - childSetAction("WLAddKey", onAddKey, NULL); childSetAction("WLDeleteKey", onDeleteKey, NULL); } void LLFloaterDayCycle::syncMenu() { -// std::map<std::string, LLVector4> & currentParams = LLWLParamManager::getInstance()->mCurParams.mParamValues; - // set time LLMultiSliderCtrl* sldr = LLFloaterDayCycle::sDayCycle->getChild<LLMultiSliderCtrl>("WLTimeSlider"); sldr->setCurSliderValue((F32)LLWLParamManager::getInstance()->mAnimator.getDayTime() * sHoursPerDay); - LLSpinCtrl* secSpin = sDayCycle->getChild<LLSpinCtrl>("WLLengthOfDaySec"); - LLSpinCtrl* minSpin = sDayCycle->getChild<LLSpinCtrl>("WLLengthOfDayMin"); - LLSpinCtrl* hourSpin = sDayCycle->getChild<LLSpinCtrl>("WLLengthOfDayHour"); - - F32 curRate; - F32 hours, min, sec; - - // get the current rate - curRate = LLWLParamManager::getInstance()->mDay.mDayRate; - hours = (F32)((int)(curRate / 60 / 60)); - curRate -= (hours * 60 * 60); - min = (F32)((int)(curRate / 60)); - curRate -= (min * 60); - sec = curRate; - - hourSpin->setValue(hours); - minSpin->setValue(min); - secSpin->setValue(sec); - // turn off Use Estate Time button if it's already being used if( LLWLParamManager::getInstance()->mAnimator.getUseLindenTime()) { @@ -309,81 +278,6 @@ void LLFloaterDayCycle::onClose(bool app_quitting) } } -void LLFloaterDayCycle::onRunAnimSky(void* userData) -{ - // if no keys, do nothing - if(sSliderToKey.size() == 0) - { - return; - } - - LLMultiSliderCtrl* sldr; - sldr = sDayCycle->getChild<LLMultiSliderCtrl>("WLDayCycleKeys"); - llassert_always(sSliderToKey.size() == sldr->getValue().size()); - - LLMultiSliderCtrl* tSldr = sDayCycle->getChild<LLMultiSliderCtrl>("WLTimeSlider"); - - sPreviousTimeType = LLWLParamManager::getInstance()->mAnimator.getTimeType(); - - // turn off linden time - LLWLParamManager::getInstance()->mAnimator.setTimeType(LLWLAnimator::TIME_CUSTOM); - - // set the param manager's track to the new one - LLWLParamManager::getInstance()->resetAnimator(tSldr->getCurSliderValue() / sHoursPerDay, true); - - llassert_always(LLWLParamManager::getInstance()->mAnimator.mTimeTrack.size() == sldr->getValue().size()); -} - -void LLFloaterDayCycle::onStopAnimSky(void* userData) -{ - // if no keys, do nothing - if(sSliderToKey.size() == 0) { - return; - } - - LLWLParamManager::getInstance()->mAnimator.deactivate(); // turn off animation and using linden time - LLMultiSliderCtrl* tSldr = sDayCycle->getChild<LLMultiSliderCtrl>("WLTimeSlider"); - LLWLParamManager::getInstance()->resetAnimator(tSldr->getCurSliderValue() / sHoursPerDay, false); - LLWLParamManager::getInstance()->mAnimator.setTimeType(sPreviousTimeType); -} - -void LLFloaterDayCycle::onUseLindenTime(void* userData) -{ - LLFloaterWindLight* wlfloater = LLFloaterReg::findTypedInstance<LLFloaterWindLight>("env_windlight"); - if (wlfloater) - { - LLComboBox* box = wlfloater->getChild<LLComboBox>("WLPresetsCombo"); - box->selectByValue(""); - } - LLWLParamManager::getInstance()->mAnimator.deactivate(); -} - -void LLFloaterDayCycle::onLoadDayCycle(void* userData) -{ - LLWLParamManager::getInstance()->mDay.loadDayCycleFromFile("Default.xml"); - - // sync it all up - syncSliderTrack(); - syncMenu(); - - // set the param manager's track to the new one - LLMultiSliderCtrl* tSldr; - tSldr = sDayCycle->getChild<LLMultiSliderCtrl>( - "WLTimeSlider"); - LLWLParamManager::getInstance()->resetAnimator( - tSldr->getCurSliderValue() / sHoursPerDay, false); - - // and draw it - LLWLParamManager::getInstance()->mAnimator.update( - LLWLParamManager::getInstance()->mCurParams); -} - -void LLFloaterDayCycle::onSaveDayCycle(void* userData) -{ - LLWLParamManager::getInstance()->mDay.saveDayCycle("Default.xml"); -} - - void LLFloaterDayCycle::onTimeSliderMoved(LLUICtrl* ctrl, void* userData) { LLMultiSliderCtrl* sldr = sDayCycle->getChild<LLMultiSliderCtrl>( @@ -501,34 +395,6 @@ void LLFloaterDayCycle::onKeyPresetChanged(LLUICtrl* ctrl, void* userData) syncTrack(); } -void LLFloaterDayCycle::onTimeRateChanged(LLUICtrl* ctrl, void* userData) -{ - // get the time - LLSpinCtrl* secSpin = sDayCycle->getChild<LLSpinCtrl>( - "WLLengthOfDaySec"); - - LLSpinCtrl* minSpin = sDayCycle->getChild<LLSpinCtrl>( - "WLLengthOfDayMin"); - - LLSpinCtrl* hourSpin = sDayCycle->getChild<LLSpinCtrl>( - "WLLengthOfDayHour"); - - F32 hour; - hour = (F32)hourSpin->getValue().asReal(); - F32 min; - min = (F32)minSpin->getValue().asReal(); - F32 sec; - sec = (F32)secSpin->getValue().asReal(); - - F32 time = 60.0f * 60.0f * hour + 60.0f * min + sec; - if(time <= 0) { - time = 1; - } - LLWLParamManager::getInstance()->mDay.mDayRate = time; - - syncTrack(); -} - void LLFloaterDayCycle::onAddKey(void* userData) { LLComboBox* comboBox = sDayCycle->getChild<LLComboBox>( diff --git a/indra/newview/llfloaterdaycycle.h b/indra/newview/llfloaterdaycycle.h index b09d1d5bf4..1454298269 100644 --- a/indra/newview/llfloaterdaycycle.h +++ b/indra/newview/llfloaterdaycycle.h @@ -83,15 +83,6 @@ public: /// if you change the combo box, change the frame static void onKeyPresetChanged(LLUICtrl* ctrl, void* userData); - /// run this when user says to run the sky animation - static void onRunAnimSky(void* userData); - - /// run this when user says to stop the sky animation - static void onStopAnimSky(void* userData); - - /// if you change the combo box, change the frame - static void onTimeRateChanged(LLUICtrl* ctrl, void* userData); - /// add a new key on slider static void onAddKey(void* userData); @@ -101,15 +92,6 @@ public: /// delete a key frame static void onDeleteKey(void* userData); - /// button to load day - static void onLoadDayCycle(void* userData); - - /// button to save day - static void onSaveDayCycle(void* userData); - - /// toggle for Linden time - static void onUseLindenTime(void* userData); - //// menu management diff --git a/indra/newview/llfloaterhardwaresettings.cpp b/indra/newview/llfloaterhardwaresettings.cpp index 1e91710552..42ec7d765b 100644 --- a/indra/newview/llfloaterhardwaresettings.cpp +++ b/indra/newview/llfloaterhardwaresettings.cpp @@ -50,7 +50,6 @@ LLFloaterHardwareSettings::LLFloaterHardwareSettings(const LLSD& key) // but init them anyway mUseVBO(0), mUseAniso(0), - mUseFBO(0), mFSAASamples(0), mGamma(0.0), mVideoCardMem(0), @@ -75,7 +74,6 @@ void LLFloaterHardwareSettings::refresh() mUseVBO = gSavedSettings.getBOOL("RenderVBOEnable"); mUseAniso = gSavedSettings.getBOOL("RenderAnisotropic"); - mUseFBO = gSavedSettings.getBOOL("RenderUseFBO"); mFSAASamples = gSavedSettings.getU32("RenderFSAASamples"); mGamma = gSavedSettings.getF32("RenderGamma"); mVideoCardMem = gSavedSettings.getS32("TextureMemory"); @@ -104,7 +102,7 @@ void LLFloaterHardwareSettings::refreshEnabledState() getChildView("(brightness, lower is brighter)")->setEnabled(!gPipeline.canUseWindLightShaders()); getChildView("fog")->setEnabled(!gPipeline.canUseWindLightShaders()); getChildView("fsaa")->setEnabled(gPipeline.canUseAntiAliasing()); - getChildView("antialiasing restart")->setVisible(!gSavedSettings.getBOOL("RenderUseFBO")); + getChildView("antialiasing restart")->setVisible(!gSavedSettings.getBOOL("RenderDeferred")); /* Enable to reset fsaa value to disabled when feature is not available. if (!gPipeline.canUseAntiAliasing()) @@ -139,7 +137,6 @@ void LLFloaterHardwareSettings::cancel() { gSavedSettings.setBOOL("RenderVBOEnable", mUseVBO); gSavedSettings.setBOOL("RenderAnisotropic", mUseAniso); - gSavedSettings.setBOOL("RenderUseFBO", mUseFBO); gSavedSettings.setU32("RenderFSAASamples", mFSAASamples); gSavedSettings.setF32("RenderGamma", mGamma); gSavedSettings.setS32("TextureMemory", mVideoCardMem); diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index d76e7885bc..e4d8e3513d 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -63,7 +63,7 @@ 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 PREF_BUTTON_HEIGHT = 16 + 7 + 16; -const S32 PREVIEW_TEXTURE_HEIGHT = 300; +const S32 PREVIEW_TEXTURE_HEIGHT = 320; //----------------------------------------------------------------------------- // LLFloaterImagePreview() @@ -787,8 +787,8 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance) } const LLVolumeFace &vf = mVolume->getVolumeFace(0); - U32 num_indices = vf.mIndices.size(); - U32 num_vertices = vf.mVertices.size(); + U32 num_indices = vf.mNumIndices; + U32 num_vertices = vf.mNumVertices; mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL, 0); mVertexBuffer->allocateBuffer(num_vertices, num_indices, TRUE); @@ -802,10 +802,16 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance) mVertexBuffer->getIndexStrider(index_strider); // build vertices and normals + LLStrider<LLVector3> pos; + pos = (LLVector3*) vf.mPositions; pos.setStride(16); + LLStrider<LLVector3> norm; + norm = (LLVector3*) vf.mNormals; norm.setStride(16); + + for (U32 i = 0; i < num_vertices; i++) { - *(vertex_strider++) = vf.mVertices[i].mPosition; - LLVector3 normal = vf.mVertices[i].mNormal; + *(vertex_strider++) = *pos++; + LLVector3 normal = *norm++; normal.normalize(); *(normal_strider++) = normal; } @@ -824,7 +830,6 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance) BOOL LLImagePreviewSculpted::render() { mNeedsUpdate = FALSE; - LLGLSUIDefault def; LLGLDisable no_blend(GL_BLEND); LLGLEnable cull(GL_CULL_FACE); @@ -869,7 +874,7 @@ BOOL LLImagePreviewSculpted::render() LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE); const LLVolumeFace &vf = mVolume->getVolumeFace(0); - U32 num_indices = vf.mIndices.size(); + U32 num_indices = vf.mNumIndices; mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL); @@ -882,7 +887,6 @@ BOOL LLImagePreviewSculpted::render() mVertexBuffer->draw(LLRender::TRIANGLES, num_indices, 0); gGL.popMatrix(); - return TRUE; } diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp new file mode 100644 index 0000000000..e8da1aa42c --- /dev/null +++ b/indra/newview/llfloatermodelpreview.cpp @@ -0,0 +1,5017 @@ +/** + * @file llfloatermodelpreview.cpp + * @brief LLFloaterModelPreview 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$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "dae.h" +//#include "dom.h" +#include "dom/domAsset.h" +#include "dom/domBind_material.h" +#include "dom/domCOLLADA.h" +#include "dom/domConstants.h" +#include "dom/domController.h" +#include "dom/domEffect.h" +#include "dom/domGeometry.h" +#include "dom/domInstance_geometry.h" +#include "dom/domInstance_material.h" +#include "dom/domInstance_node.h" +#include "dom/domInstance_effect.h" +#include "dom/domMaterial.h" +#include "dom/domMatrix.h" +#include "dom/domNode.h" +#include "dom/domProfile_COMMON.h" +#include "dom/domRotate.h" +#include "dom/domScale.h" +#include "dom/domTranslate.h" +#include "dom/domVisual_scene.h" + +#include "llfloatermodelpreview.h" + +#include "llfilepicker.h" +#include "llimagebmp.h" +#include "llimagetga.h" +#include "llimagejpeg.h" +#include "llimagepng.h" + +#include "llagent.h" +#include "llbutton.h" +#include "llcombobox.h" +#include "lldatapacker.h" +#include "lldrawable.h" +#include "lldrawpoolavatar.h" +#include "llrender.h" +#include "llface.h" +#include "lleconomy.h" +#include "llfocusmgr.h" +#include "llfloaterperms.h" +#include "lliconctrl.h" +#include "llmatrix4a.h" +#include "llmenubutton.h" +#include "llmeshrepository.h" +#include "llsdutil_math.h" +#include "lltextbox.h" +#include "lltoolmgr.h" +#include "llui.h" +#include "llvector4a.h" +#include "llviewercamera.h" +#include "llviewerwindow.h" +#include "llvoavatar.h" +#include "llvoavatarself.h" +#include "pipeline.h" +#include "lluictrlfactory.h" +#include "llviewercontrol.h" +#include "llviewermenu.h" +#include "llviewermenufile.h" +#include "llviewerregion.h" +#include "llviewertexturelist.h" +#include "llstring.h" +#include "llbutton.h" +#include "llcheckboxctrl.h" +#include "llradiogroup.h" +#include "llsdserialize.h" +#include "llsliderctrl.h" +#include "llspinctrl.h" +#include "lltoggleablemenu.h" +#include "llvfile.h" +#include "llvfs.h" +#include "llcallbacklist.h" + +#include "glod/glod.h" + +//static +S32 LLFloaterModelPreview::sUploadAmount = 10; +LLFloaterModelPreview* LLFloaterModelPreview::sInstance = NULL; +std::list<LLModelLoader*> LLModelLoader::sActiveLoaderList; + +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 PREF_BUTTON_HEIGHT = 16 + 7 + 16; +const S32 PREVIEW_TEXTURE_HEIGHT = 300; + +void drawBoxOutline(const LLVector3& pos, const LLVector3& size); + + +std::string lod_name[NUM_LOD+1] = +{ + "lowest", + "low", + "medium", + "high", + "I went off the end of the lod_name array. Me so smart." +}; + +std::string lod_triangles_name[NUM_LOD+1] = +{ + "lowest_triangles", + "low_triangles", + "medium_triangles", + "high_triangles", + "I went off the end of the lod_triangles_name array. Me so smart." +}; + +std::string lod_vertices_name[NUM_LOD+1] = +{ + "lowest_vertices", + "low_vertices", + "medium_vertices", + "high_vertices", + "I went off the end of the lod_vertices_name array. Me so smart." +}; + +std::string lod_status_name[NUM_LOD+1] = +{ + "lowest_status", + "low_status", + "medium_status", + "high_status", + "I went off the end of the lod_status_name array. Me so smart." +}; + +std::string lod_icon_name[NUM_LOD+1] = +{ + "status_icon_lowest", + "status_icon_low", + "status_icon_medium", + "status_icon_high", + "I went off the end of the lod_status_name array. Me so smart." +}; + +std::string lod_status_image[NUM_LOD+1] = +{ + "ModelImport_Status_Good", + "ModelImport_Status_Warning", + "ModelImport_Status_Error", + "I went off the end of the lod_status_image array. Me so smart." +}; + +std::string lod_label_name[NUM_LOD+1] = +{ + "lowest_label", + "low_label", + "medium_label", + "high_label", + "I went off the end of the lod_label_name array. Me so smart." +}; + +bool validate_face(const LLVolumeFace& face) +{ + for (U32 i = 0; i < face.mNumIndices; ++i) + { + if (face.mIndices[i] >= face.mNumVertices) + { + llwarns << "Face has invalid index." << llendl; + return false; + } + } + + return true; +} + +bool validate_model(const LLModel* mdl) +{ + if (mdl->getNumVolumeFaces() == 0) + { + llwarns << "Model has no faces!" << llendl; + return false; + } + + for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) + { + if (mdl->getVolumeFace(i).mNumVertices == 0) + { + llwarns << "Face has no vertices." << llendl; + return false; + } + + if (mdl->getVolumeFace(i).mNumIndices == 0) + { + llwarns << "Face has no indices." << llendl; + return false; + } + + if (!validate_face(mdl->getVolumeFace(i))) + { + return false; + } + } + + return true; +} + +BOOL stop_gloderror() +{ + GLuint error = glodGetError(); + + if (error != GLOD_NO_ERROR) + { + llwarns << "GLOD error detected, cannot generate LOD: " << std::hex << error << llendl; + return TRUE; + } + + return FALSE; +} + + +LLMeshFilePicker::LLMeshFilePicker(LLModelPreview* mp, S32 lod) + : LLFilePickerThread(LLFilePicker::FFLOAD_COLLADA) + { + mMP = mp; + mLOD = lod; + } + +void LLMeshFilePicker::notify(const std::string& filename) +{ + mMP->loadModel(mFile, mLOD); +} + + +//----------------------------------------------------------------------------- +// LLFloaterModelPreview() +//----------------------------------------------------------------------------- +LLFloaterModelPreview::LLFloaterModelPreview(const LLSD& key) : +LLFloater(key) +{ + sInstance = this; + mLastMouseX = 0; + mLastMouseY = 0; + mGLName = 0; + mStatusLock = new LLMutex(NULL); + + mLODMode[LLModel::LOD_HIGH] = 0; + for (U32 i = 0; i < LLModel::LOD_HIGH; i++) + { + mLODMode[i] = 1; + } +} + +//----------------------------------------------------------------------------- +// postBuild() +//----------------------------------------------------------------------------- +BOOL LLFloaterModelPreview::postBuild() +{ + if (!LLFloater::postBuild()) + { + return FALSE; + } + + childSetAction("lod_browse", onBrowseLOD, this); + + childSetCommitCallback("cancel_btn", onCancel, this); + childSetCommitCallback("crease_angle", onGenerateNormalsCommit, this); + childSetCommitCallback("generate_normals", onGenerateNormalsCommit, this); + + childSetCommitCallback("lod_generate", onAutoFillCommit, this); + + childSetCommitCallback("lod_mode", onLODParamCommit, this); + childSetCommitCallback("lod_error_threshold", onLODParamCommit, this); + childSetCommitCallback("lod_triangle_limit", onLODParamCommitTriangleLimit, this); + childSetCommitCallback("build_operator", onLODParamCommit, this); + childSetCommitCallback("queue_mode", onLODParamCommit, this); + childSetCommitCallback("border_mode", onLODParamCommit, this); + childSetCommitCallback("share_tolerance", onLODParamCommit, this); + + childSetTextArg("status", "[STATUS]", getString("status_idle")); + + //childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d",sUploadAmount)); + childSetAction("ok_btn", onUpload, this); + childDisable("ok_btn"); + + childSetAction("reset_btn", onReset, this); + + childSetAction("clear_materials", onClearMaterials, this); + + childSetCommitCallback("preview_lod_combo", onPreviewLODCommit, this); + + childSetCommitCallback("upload_skin", onUploadSkinCommit, this); + childSetCommitCallback("upload_joints", onUploadJointsCommit, this); + + childSetCommitCallback("import_scale", onImportScaleCommit, this); + childSetCommitCallback("pelvis_offset", onPelvisOffsetCommit, this); + + childSetCommitCallback("lod_file_or_limit", refresh, this); + childSetCommitCallback("physics_load_radio", refresh, this); + //childSetCommitCallback("physics_optimize", refresh, this); + //childSetCommitCallback("physics_use_hull", refresh, this); + + childDisable("upload_skin"); + childDisable("upload_joints"); + + childDisable("ok_btn"); + + mViewOptionMenuButton = getChild<LLMenuButton>("options_gear_btn"); + + mCommitCallbackRegistrar.add("ModelImport.ViewOption.Action", boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _2)); + mEnableCallbackRegistrar.add("ModelImport.ViewOption.Check", boost::bind(&LLFloaterModelPreview::isViewOptionChecked, this, _2)); + mEnableCallbackRegistrar.add("ModelImport.ViewOption.Enabled", boost::bind(&LLFloaterModelPreview::isViewOptionEnabled, this, _2)); + + + + mViewOptionMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_model_import_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mViewOptionMenuButton->setMenu(mViewOptionMenu, LLMenuButton::MP_BOTTOM_LEFT); + + initDecompControls(); + + LLView* preview_panel = getChild<LLView>("preview_panel"); + + mPreviewRect = preview_panel->getRect(); + + mModelPreview = new LLModelPreview(512, 512, this ); + mModelPreview->setPreviewTarget(16.f); + mModelPreview->setDetailsCallback(boost::bind(&LLFloaterModelPreview::setDetails, this, _1, _2, _3, _4, _5)); + + //set callbacks for left click on line editor rows + for (U32 i = 0; i <= LLModel::LOD_HIGH; i++) + { + LLTextBox* text = getChild<LLTextBox>(lod_label_name[i]); + if (text) + { + text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i)); + } + + text = getChild<LLTextBox>(lod_triangles_name[i]); + if (text) + { + text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i)); + } + + text = getChild<LLTextBox>(lod_vertices_name[i]); + if (text) + { + text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i)); + } + + text = getChild<LLTextBox>(lod_status_name[i]); + if (text) + { + text->setMouseDownCallback(boost::bind(&LLModelPreview::setPreviewLOD, mModelPreview, i)); + } + } + + return TRUE; +} + +//----------------------------------------------------------------------------- +// LLFloaterModelPreview() +//----------------------------------------------------------------------------- +LLFloaterModelPreview::~LLFloaterModelPreview() +{ + sInstance = NULL; + + if ( mModelPreview && mModelPreview->getResetJointFlag() ) + { + gAgentAvatarp->resetJointPositions(); + } + + + if ( mModelPreview ) + { + delete mModelPreview; + } + + if (mGLName) + { + LLImageGL::deleteTextures(1, &mGLName ); + } + + delete mStatusLock; + mStatusLock = NULL; +} + +void LLFloaterModelPreview::onViewOptionChecked(const LLSD& userdata) +{ + if (mModelPreview) + { + mModelPreview->mViewOption[userdata.asString()] = !mModelPreview->mViewOption[userdata.asString()]; + + mModelPreview->refresh(); + } +} + +bool LLFloaterModelPreview::isViewOptionChecked(const LLSD& userdata) +{ + if (mModelPreview) + { + return mModelPreview->mViewOption[userdata.asString()]; + } + + return false; +} + +bool LLFloaterModelPreview::isViewOptionEnabled(const LLSD& userdata) +{ + return !mViewOptionDisabled[userdata.asString()]; +} + +void LLFloaterModelPreview::setViewOptionEnabled(const std::string& option, bool enabled) +{ + mViewOptionDisabled[option] = !enabled; +} + +void LLFloaterModelPreview::enableViewOption(const std::string& option) +{ + setViewOptionEnabled(option, true); +} + +void LLFloaterModelPreview::disableViewOption(const std::string& option) +{ + setViewOptionEnabled(option, false); +} + +void LLFloaterModelPreview::loadModel(S32 lod) +{ + mModelPreview->mLoading = true; + + (new LLMeshFilePicker(mModelPreview, lod))->getFile(); +} + +//static +void LLFloaterModelPreview::onImportScaleCommit(LLUICtrl*,void* userdata) +{ + LLFloaterModelPreview *fp =(LLFloaterModelPreview *)userdata; + + if (!fp->mModelPreview) + { + return; + } + + fp->mModelPreview->calcResourceCost(); + fp->mModelPreview->refresh(); +} +//static +void LLFloaterModelPreview::onPelvisOffsetCommit( LLUICtrl*, void* userdata ) +{ + LLFloaterModelPreview *fp =(LLFloaterModelPreview*)userdata; + + if (!fp->mModelPreview) + { + return; + } + fp->mModelPreview->calcResourceCost(); + fp->mModelPreview->refresh(); +} + +//static +void LLFloaterModelPreview::onUploadJointsCommit(LLUICtrl*,void* userdata) +{ + LLFloaterModelPreview *fp =(LLFloaterModelPreview *)userdata; + + if (!fp->mModelPreview) + { + return; + } + + fp->mModelPreview->refresh(); +} + +//static +void LLFloaterModelPreview::onUploadSkinCommit(LLUICtrl*,void* userdata) +{ + LLFloaterModelPreview *fp =(LLFloaterModelPreview *)userdata; + + if (!fp->mModelPreview) + { + return; + } + + fp->mModelPreview->calcResourceCost(); + fp->mModelPreview->refresh(); + fp->mModelPreview->resetPreviewTarget(); + fp->mModelPreview->clearBuffers(); +} + +//static +void LLFloaterModelPreview::onPreviewLODCommit(LLUICtrl* ctrl, void* userdata) +{ + LLFloaterModelPreview *fp =(LLFloaterModelPreview *)userdata; + + if (!fp->mModelPreview) + { + return; + } + + S32 which_mode = 0; + + LLComboBox* combo = (LLComboBox*) ctrl; + + which_mode = (NUM_LOD-1)-combo->getFirstSelectedIndex(); // combo box list of lods is in reverse order + + fp->mModelPreview->setPreviewLOD(which_mode); +} + +//static +void LLFloaterModelPreview::onGenerateNormalsCommit(LLUICtrl* ctrl, void* userdata) +{ + LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata; + + fp->mModelPreview->generateNormals(); +} + +//static +void LLFloaterModelPreview::onExplodeCommit(LLUICtrl* ctrl, void* userdata) +{ + LLFloaterModelPreview* fp = LLFloaterModelPreview::sInstance; + + fp->mModelPreview->refresh(); +} + +//static +void LLFloaterModelPreview::onAutoFillCommit(LLUICtrl* ctrl, void* userdata) +{ + LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata; + + fp->mModelPreview->genLODs(); +} + +//static +void LLFloaterModelPreview::onLODParamCommit(LLUICtrl* ctrl, void* userdata) +{ + LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata; + fp->mModelPreview->onLODParamCommit(false); +} + +//static +void LLFloaterModelPreview::onLODParamCommitTriangleLimit(LLUICtrl* ctrl, void* userdata) +{ + LLFloaterModelPreview* fp = (LLFloaterModelPreview*) userdata; + fp->mModelPreview->onLODParamCommit(true); +} + + +//----------------------------------------------------------------------------- +// draw() +//----------------------------------------------------------------------------- +void LLFloaterModelPreview::draw() +{ + LLFloater::draw(); + LLRect r = getRect(); + + mModelPreview->update(); + + if (!mModelPreview->mLoading) + { + if ( mModelPreview->getLoadState() > LLModelLoader::ERROR_PARSING ) + { + childSetTextArg("status", "[STATUS]", getString(LLModel::getStatusString(mModelPreview->getLoadState() - LLModelLoader::ERROR_PARSING))); + } + else + { + childSetTextArg("status", "[STATUS]", getString("status_idle")); + } + } + + childSetTextArg("prim_cost", "[PRIM_COST]", llformat("%d", mModelPreview->mResourceCost)); + childSetTextArg("description_label", "[TEXTURES]", llformat("%d", mModelPreview->mTextureSet.size())); + + if (!mCurRequest.empty()) + { + LLMutexLock lock(mStatusLock); + childSetTextArg("status", "[STATUS]", mStatusMessage); + } + else + { + childSetVisible("Simplify", true); + childSetVisible("simplify_cancel", false); + childSetVisible("Decompose", true); + childSetVisible("decompose_cancel", false); + } + + U32 resource_cost = mModelPreview->mResourceCost*10; + + if (childGetValue("upload_textures").asBoolean()) + { + resource_cost += mModelPreview->mTextureSet.size()*10; + } + + childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d", resource_cost)); + + if (mModelPreview) + { + gGL.color3f(1.f, 1.f, 1.f); + + gGL.getTexUnit(0)->bind(mModelPreview); + + + LLView* preview_panel = getChild<LLView>("preview_panel"); + + LLRect rect = preview_panel->getRect(); + if (rect != mPreviewRect) + { + mModelPreview->refresh(); + mPreviewRect = preview_panel->getRect(); + } + + gGL.begin( LLRender::QUADS ); + { + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop-1); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mBottom); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mBottom); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mTop-1); + } + gGL.end(); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + } +} + +//----------------------------------------------------------------------------- +// handleMouseDown() +//----------------------------------------------------------------------------- +BOOL LLFloaterModelPreview::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; + } + + return LLFloater::handleMouseDown(x, y, mask); +} + +//----------------------------------------------------------------------------- +// handleMouseUp() +//----------------------------------------------------------------------------- +BOOL LLFloaterModelPreview::handleMouseUp(S32 x, S32 y, MASK mask) +{ + gFocusMgr.setMouseCapture(FALSE); + gViewerWindow->showCursor(); + return LLFloater::handleMouseUp(x, y, mask); +} + +//----------------------------------------------------------------------------- +// handleHover() +//----------------------------------------------------------------------------- +BOOL LLFloaterModelPreview::handleHover (S32 x, S32 y, MASK mask) +{ + MASK local_mask = mask & ~MASK_ALT; + + if (mModelPreview && hasMouseCapture()) + { + if (local_mask == MASK_PAN) + { + // pan here + mModelPreview->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; + + mModelPreview->rotate(yaw_radians, pitch_radians); + } + else + { + + F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f; + F32 zoom_amt = (F32)(y - mLastMouseY) * 0.02f; + + mModelPreview->rotate(yaw_radians, 0.f); + mModelPreview->zoom(zoom_amt); + } + + + mModelPreview->refresh(); + + LLUI::setMousePositionLocal(this, mLastMouseX, mLastMouseY); + } + + if (!mPreviewRect.pointInRect(x, y) || !mModelPreview) + { + 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; +} + +//----------------------------------------------------------------------------- +// handleScrollWheel() +//----------------------------------------------------------------------------- +BOOL LLFloaterModelPreview::handleScrollWheel(S32 x, S32 y, S32 clicks) +{ + if (mPreviewRect.pointInRect(x, y) && mModelPreview) + { + mModelPreview->zoom((F32)clicks * -0.2f); + mModelPreview->refresh(); + } + + return TRUE; +} + +//static +void LLFloaterModelPreview::onPhysicsParamCommit(LLUICtrl* ctrl, void* data) +{ + if (LLConvexDecomposition::getInstance() == NULL) + { + llinfos << "convex decomposition tool is a stub on this platform. cannot get decomp." << llendl; + return; + } + + if (sInstance) + { + LLCDParam* param = (LLCDParam*) data; + std::string name(param->mName); + sInstance->mDecompParams[name] = ctrl->getValue(); + + if (name == "Simplify Method") + { + if (ctrl->getValue().asInteger() == 0) + { + sInstance->childSetVisible("Retain%", true); + sInstance->childSetVisible("Detail Scale", false); + } + else + { + sInstance->childSetVisible("Retain%", false); + sInstance->childSetVisible("Detail Scale", true); + } + } + } +} + +//static +void LLFloaterModelPreview::onPhysicsStageExecute(LLUICtrl* ctrl, void* data) +{ + LLCDStageData* stage_data = (LLCDStageData*) data; + std::string stage = stage_data->mName; + + if (sInstance) + { + if (!sInstance->mCurRequest.empty()) + { + llinfos << "Decomposition request still pending." << llendl; + return; + } + + if (sInstance->mModelPreview) + { + for (S32 i = 0; i < sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS].size(); ++i) + { + LLModel* mdl = sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS][i]; + DecompRequest* request = new DecompRequest(stage, mdl); + sInstance->mCurRequest.insert(request); + gMeshRepo.mDecompThread->submitRequest(request); + } + } + + if (stage == "Decompose") + { + sInstance->setStatusMessage(sInstance->getString("decomposing")); + sInstance->childSetVisible("Decompose", false); + sInstance->childSetVisible("decompose_cancel", true); + } + else if (stage == "Simplify") + { + sInstance->setStatusMessage(sInstance->getString("simplifying")); + sInstance->childSetVisible("Simplify", false); + sInstance->childSetVisible("simplify_cancel", true); + } + } +} + +//static +void LLFloaterModelPreview::onPhysicsBrowse(LLUICtrl* ctrl, void* userdata) +{ + sInstance->loadModel(LLModel::LOD_PHYSICS); +} + +//static +void LLFloaterModelPreview::onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata) +{ + S32 which_mode = 3; + LLCtrlSelectionInterface* iface = sInstance->childGetSelectionInterface("physics_lod_combo"); + if (iface) + { + which_mode = iface->getFirstSelectedIndex(); + } + + sInstance->mModelPreview->setPhysicsFromLOD(which_mode); +} + +//static +void LLFloaterModelPreview::onCancel(LLUICtrl* ctrl, void* data) +{ + if (sInstance) + { + sInstance->closeFloater(false); + } +} + +//static +void LLFloaterModelPreview::onPhysicsStageCancel(LLUICtrl* ctrl, void*data) +{ + if (sInstance) + { + for (std::set<LLPointer<DecompRequest> >::iterator iter = sInstance->mCurRequest.begin(); + iter != sInstance->mCurRequest.end(); ++iter) + { + DecompRequest* req = *iter; + req->mContinue = 0; + } + + sInstance->mCurRequest.clear(); + } +} + +void LLFloaterModelPreview::initDecompControls() +{ + LLSD key; + + childSetCommitCallback("simplify_cancel", onPhysicsStageCancel, NULL); + childSetCommitCallback("decompose_cancel", onPhysicsStageCancel, NULL); + + childSetCommitCallback("physics_lod_combo", onPhysicsUseLOD, NULL); + childSetCommitCallback("physics_browse", onPhysicsBrowse, NULL); + + static const LLCDStageData* stage = NULL; + static S32 stage_count = 0; + + if (!stage && LLConvexDecomposition::getInstance() != NULL) + { + stage_count = LLConvexDecomposition::getInstance()->getStages(&stage); + } + + static const LLCDParam* param = NULL; + static S32 param_count = 0; + if (!param && LLConvexDecomposition::getInstance() != NULL) + { + param_count = LLConvexDecomposition::getInstance()->getParameters(¶m); + } + + for (S32 j = stage_count-1; j >= 0; --j) + { + LLButton* button = getChild<LLButton>(stage[j].mName); + if (button) + { + button->setCommitCallback(onPhysicsStageExecute, (void*) &stage[j]); + } + + gMeshRepo.mDecompThread->mStageID[stage[j].mName] = j; + // protected against stub by stage_count being 0 for stub above + LLConvexDecomposition::getInstance()->registerCallback(j, LLPhysicsDecomp::llcdCallback); + + //llinfos << "Physics decomp stage " << stage[j].mName << " (" << j << ") parameters:" << llendl; + //llinfos << "------------------------------------" << llendl; + + for (S32 i = 0; i < param_count; ++i) + { + if (param[i].mStage != j) + { + continue; + } + + std::string name(param[i].mName ? param[i].mName : ""); + std::string description(param[i].mDescription ? param[i].mDescription : ""); + + std::string type = "unknown"; + + llinfos << name << " - " << description << llendl; + + if (param[i].mType == LLCDParam::LLCD_FLOAT) + { + mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mFloat); + //llinfos << "Type: float, Default: " << param[i].mDefault.mFloat << llendl; + + LLSliderCtrl* slider = getChild<LLSliderCtrl>(name); + if (slider) + { + slider->setMinValue(param[i].mDetails.mRange.mLow.mFloat); + slider->setMaxValue(param[i].mDetails.mRange.mHigh.mFloat); + slider->setIncrement(param[i].mDetails.mRange.mDelta.mFloat); + slider->setValue(param[i].mDefault.mFloat); + slider->setCommitCallback(onPhysicsParamCommit, (void*) ¶m[i]); + } + } + else if (param[i].mType == LLCDParam::LLCD_INTEGER) + { + mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue); + //llinfos << "Type: integer, Default: " << param[i].mDefault.mIntOrEnumValue << llendl; + + LLSliderCtrl* slider = getChild<LLSliderCtrl>(name); + if (slider) + { + slider->setMinValue(param[i].mDetails.mRange.mLow.mIntOrEnumValue); + slider->setMaxValue(param[i].mDetails.mRange.mHigh.mIntOrEnumValue); + slider->setIncrement(param[i].mDetails.mRange.mDelta.mIntOrEnumValue); + slider->setValue(param[i].mDefault.mIntOrEnumValue); + slider->setCommitCallback(onPhysicsParamCommit, (void*) ¶m[i]); + } + } + else if (param[i].mType == LLCDParam::LLCD_BOOLEAN) + { + mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mBool); + //llinfos << "Type: boolean, Default: " << (param[i].mDefault.mBool ? "True" : "False") << llendl; + + LLCheckBoxCtrl* check_box = getChild<LLCheckBoxCtrl>(name); + if (check_box) + { + check_box->setValue(param[i].mDefault.mBool); + check_box->setCommitCallback(onPhysicsParamCommit, (void*) ¶m[i]); + } + } + else if (param[i].mType == LLCDParam::LLCD_ENUM) + { + mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue); + //llinfos << "Type: enum, Default: " << param[i].mDefault.mIntOrEnumValue << llendl; + + { //plug into combo box + + //llinfos << "Accepted values: " << llendl; + LLComboBox* combo_box = getChild<LLComboBox>(name); + for (S32 k = 0; k < param[i].mDetails.mEnumValues.mNumEnums; ++k) + { + //llinfos << param[i].mDetails.mEnumValues.mEnumsArray[k].mValue + // << " - " << param[i].mDetails.mEnumValues.mEnumsArray[k].mName << llendl; + + combo_box->add(param[i].mDetails.mEnumValues.mEnumsArray[k].mName, + LLSD::Integer(param[i].mDetails.mEnumValues.mEnumsArray[k].mValue)); + } + combo_box->setValue(param[i].mDefault.mIntOrEnumValue); + combo_box->setCommitCallback(onPhysicsParamCommit, (void*) ¶m[i]); + } + + //llinfos << "----" << llendl; + } + //llinfos << "-----------------------------" << llendl; + } + } + + childSetCommitCallback("physics_explode", LLFloaterModelPreview::onExplodeCommit, this); +} + +//----------------------------------------------------------------------------- +// onMouseCaptureLost() +//----------------------------------------------------------------------------- +// static +void LLFloaterModelPreview::onMouseCaptureLostModelPreview(LLMouseHandler* handler) +{ + gViewerWindow->showCursor(); +} + +//----------------------------------------------------------------------------- +// LLModelLoader +//----------------------------------------------------------------------------- +LLModelLoader::LLModelLoader( std::string filename, S32 lod, LLModelPreview* preview, JointTransformMap& jointMap, + std::deque<std::string>& jointsFromNodes ) +: mJointList( jointMap ) +, mJointsFromNode( jointsFromNodes ) +, LLThread("Model Loader"), mFilename(filename), mLod(lod), mPreview(preview), mFirstTransform(TRUE) +{ + mJointMap["mPelvis"] = "mPelvis"; + mJointMap["mTorso"] = "mTorso"; + mJointMap["mChest"] = "mChest"; + mJointMap["mNeck"] = "mNeck"; + mJointMap["mHead"] = "mHead"; + mJointMap["mSkull"] = "mSkull"; + mJointMap["mEyeRight"] = "mEyeRight"; + mJointMap["mEyeLeft"] = "mEyeLeft"; + mJointMap["mCollarLeft"] = "mCollarLeft"; + mJointMap["mShoulderLeft"] = "mShoulderLeft"; + mJointMap["mElbowLeft"] = "mElbowLeft"; + mJointMap["mWristLeft"] = "mWristLeft"; + mJointMap["mCollarRight"] = "mCollarRight"; + mJointMap["mShoulderRight"] = "mShoulderRight"; + mJointMap["mElbowRight"] = "mElbowRight"; + mJointMap["mWristRight"] = "mWristRight"; + mJointMap["mHipRight"] = "mHipRight"; + mJointMap["mKneeRight"] = "mKneeRight"; + mJointMap["mAnkleRight"] = "mAnkleRight"; + mJointMap["mFootRight"] = "mFootRight"; + mJointMap["mToeRight"] = "mToeRight"; + mJointMap["mHipLeft"] = "mHipLeft"; + mJointMap["mKneeLeft"] = "mKneeLeft"; + mJointMap["mAnkleLeft"] = "mAnkleLeft"; + mJointMap["mFootLeft"] = "mFootLeft"; + mJointMap["mToeLeft"] = "mToeLeft"; + + mJointMap["avatar_mPelvis"] = "mPelvis"; + mJointMap["avatar_mTorso"] = "mTorso"; + mJointMap["avatar_mChest"] = "mChest"; + mJointMap["avatar_mNeck"] = "mNeck"; + mJointMap["avatar_mHead"] = "mHead"; + mJointMap["avatar_mSkull"] = "mSkull"; + mJointMap["avatar_mEyeRight"] = "mEyeRight"; + mJointMap["avatar_mEyeLeft"] = "mEyeLeft"; + mJointMap["avatar_mCollarLeft"] = "mCollarLeft"; + mJointMap["avatar_mShoulderLeft"] = "mShoulderLeft"; + mJointMap["avatar_mElbowLeft"] = "mElbowLeft"; + mJointMap["avatar_mWristLeft"] = "mWristLeft"; + mJointMap["avatar_mCollarRight"] = "mCollarRight"; + mJointMap["avatar_mShoulderRight"] = "mShoulderRight"; + mJointMap["avatar_mElbowRight"] = "mElbowRight"; + mJointMap["avatar_mWristRight"] = "mWristRight"; + mJointMap["avatar_mHipRight"] = "mHipRight"; + mJointMap["avatar_mKneeRight"] = "mKneeRight"; + mJointMap["avatar_mAnkleRight"] = "mAnkleRight"; + mJointMap["avatar_mFootRight"] = "mFootRight"; + mJointMap["avatar_mToeRight"] = "mToeRight"; + mJointMap["avatar_mHipLeft"] = "mHipLeft"; + mJointMap["avatar_mKneeLeft"] = "mKneeLeft"; + mJointMap["avatar_mAnkleLeft"] = "mAnkleLeft"; + mJointMap["avatar_mFootLeft"] = "mFootLeft"; + mJointMap["avatar_mToeLeft"] = "mToeLeft"; + + + mJointMap["hip"] = "mPelvis"; + mJointMap["abdomen"] = "mTorso"; + mJointMap["chest"] = "mChest"; + mJointMap["neck"] = "mNeck"; + mJointMap["head"] = "mHead"; + mJointMap["figureHair"] = "mSkull"; + mJointMap["lCollar"] = "mCollarLeft"; + mJointMap["lShldr"] = "mShoulderLeft"; + mJointMap["lForeArm"] = "mElbowLeft"; + mJointMap["lHand"] = "mWristLeft"; + mJointMap["rCollar"] = "mCollarRight"; + mJointMap["rShldr"] = "mShoulderRight"; + mJointMap["rForeArm"] = "mElbowRight"; + mJointMap["rHand"] = "mWristRight"; + mJointMap["rThigh"] = "mHipRight"; + mJointMap["rShin"] = "mKneeRight"; + mJointMap["rFoot"] = "mFootRight"; + mJointMap["lThigh"] = "mHipLeft"; + mJointMap["lShin"] = "mKneeLeft"; + mJointMap["lFoot"] = "mFootLeft"; + + if (mPreview) + { + //only try to load from slm if viewer is configured to do so and this is the + //initial model load (not an LoD or physics shape) + mTrySLM = gSavedSettings.getBOOL("MeshImportUseSLM") && mPreview->mUploadData.empty(); + mPreview->setLoadState(STARTING); + } + else + { + mTrySLM = false; + } + + assert_main_thread(); + sActiveLoaderList.push_back(this) ; +} + +LLModelLoader::~LLModelLoader() +{ + assert_main_thread(); + sActiveLoaderList.remove(this); +} + +void stretch_extents(LLModel* model, LLMatrix4a& mat, LLVector4a& min, LLVector4a& max, BOOL& first_transform) +{ + LLVector4a box[] = + { + LLVector4a(-1, 1,-1), + LLVector4a(-1, 1, 1), + LLVector4a(-1,-1,-1), + LLVector4a(-1,-1, 1), + LLVector4a( 1, 1,-1), + LLVector4a( 1, 1, 1), + LLVector4a( 1,-1,-1), + LLVector4a( 1,-1, 1), + }; + + for (S32 j = 0; j < model->getNumVolumeFaces(); ++j) + { + const LLVolumeFace& face = model->getVolumeFace(j); + + LLVector4a center; + center.setAdd(face.mExtents[0], face.mExtents[1]); + center.mul(0.5f); + LLVector4a size; + size.setSub(face.mExtents[1],face.mExtents[0]); + size.mul(0.5f); + + for (U32 i = 0; i < 8; i++) + { + LLVector4a t; + t.setMul(size, box[i]); + t.add(center); + + LLVector4a v; + + mat.affineTransform(t, v); + + if (first_transform) + { + first_transform = FALSE; + min = max = v; + } + else + { + update_min_max(min, max, v); + } + } + } +} + +void stretch_extents(LLModel* model, LLMatrix4& mat, LLVector3& min, LLVector3& max, BOOL& first_transform) +{ + LLVector4a mina, maxa; + LLMatrix4a mata; + + mata.loadu(mat); + mina.load3(min.mV); + maxa.load3(max.mV); + + stretch_extents(model, mata, mina, maxa, first_transform); + + min.set(mina.getF32ptr()); + max.set(maxa.getF32ptr()); +} + +void LLModelLoader::run() +{ + if (!doLoadModel()) + { + mPreview = NULL; + } + + doOnIdleOneTime(boost::bind(&LLModelLoader::loadModelCallback,this)); +} + +bool LLModelLoader::doLoadModel() +{ + //first, look for a .slm file of the same name that was modified later + //than the .dae + + if (mTrySLM) + { + std::string filename = mFilename; + + std::string::size_type i = filename.rfind("."); + if (i != std::string::npos) + { + filename.replace(i, filename.size()-1, ".slm"); + llstat slm_status; + if (LLFile::stat(filename, &slm_status) == 0) + { //slm file exists + llstat dae_status; + if (LLFile::stat(mFilename, &dae_status) != 0 || + dae_status.st_mtime < slm_status.st_mtime) + { + if (loadFromSLM(filename)) + { //slm successfully loaded, if this fails, fall through and + //try loading from dae + + mLod = -1; //successfully loading from an slm implicitly sets all + //LoDs + return true; + } + } + } + } + } + + //no suitable slm exists, load from the .dae file + DAE dae; + domCOLLADA* dom = dae.open(mFilename); + + if (!dom) + { + return false; + } + + daeDatabase* db = dae.getDatabase(); + + daeInt count = db->getElementCount(NULL, COLLADA_TYPE_MESH); + + daeDocument* doc = dae.getDoc(mFilename); + if (!doc) + { + llwarns << "can't find internal doc" << llendl; + return false; + } + + daeElement* root = doc->getDomRoot(); + if (!root) + { + llwarns << "document has no root" << llendl; + return false; + } + + //get unit scale + mTransform.setIdentity(); + + domAsset::domUnit* unit = daeSafeCast<domAsset::domUnit>(root->getDescendant(daeElement::matchType(domAsset::domUnit::ID()))); + + if (unit) + { + F32 meter = unit->getMeter(); + mTransform.mMatrix[0][0] = meter; + mTransform.mMatrix[1][1] = meter; + mTransform.mMatrix[2][2] = meter; + } + + //get up axis rotation + LLMatrix4 rotation; + + domUpAxisType up = UPAXISTYPE_Y_UP; // default is Y_UP + domAsset::domUp_axis* up_axis = + daeSafeCast<domAsset::domUp_axis>(root->getDescendant(daeElement::matchType(domAsset::domUp_axis::ID()))); + + if (up_axis) + { + up = up_axis->getValue(); + } + + if (up == UPAXISTYPE_X_UP) + { + rotation.initRotation(0.0f, 90.0f * DEG_TO_RAD, 0.0f); + } + else if (up == UPAXISTYPE_Y_UP) + { + rotation.initRotation(90.0f * DEG_TO_RAD, 0.0f, 0.0f); + } + + rotation *= mTransform; + mTransform = rotation; + + + for (daeInt idx = 0; idx < count; ++idx) + { //build map of domEntities to LLModel + domMesh* mesh = NULL; + db->getElement((daeElement**) &mesh, idx, NULL, COLLADA_TYPE_MESH); + + if (mesh) + { + LLPointer<LLModel> model = LLModel::loadModelFromDomMesh(mesh); + + if(model->getStatus() != LLModel::NO_ERRORS) + { + setLoadState(ERROR_PARSING + model->getStatus()) ; + return true ; //abort + } + + if (model.notNull() && validate_model(model)) + { + mModelList.push_back(model); + mModel[mesh] = model; + } + } + } + + count = db->getElementCount(NULL, COLLADA_TYPE_SKIN); + for (daeInt idx = 0; idx < count; ++idx) + { //add skinned meshes as instances + domSkin* skin = NULL; + db->getElement((daeElement**) &skin, idx, NULL, COLLADA_TYPE_SKIN); + + if (skin) + { + domGeometry* geom = daeSafeCast<domGeometry>(skin->getSource().getElement()); + + if (geom) + { + domMesh* mesh = geom->getMesh(); + if (mesh) + { + LLModel* model = mModel[mesh]; + if (model) + { + LLVector3 mesh_scale_vector; + LLVector3 mesh_translation_vector; + model->getNormalizedScaleTranslation(mesh_scale_vector, mesh_translation_vector); + + LLMatrix4 normalized_transformation; + normalized_transformation.setTranslation(mesh_translation_vector); + + LLMatrix4 mesh_scale; + mesh_scale.initScale(mesh_scale_vector); + mesh_scale *= normalized_transformation; + normalized_transformation = mesh_scale; + + glh::matrix4f inv_mat((F32*) normalized_transformation.mMatrix); + inv_mat = inv_mat.inverse(); + LLMatrix4 inverse_normalized_transformation(inv_mat.m); + + domSkin::domBind_shape_matrix* bind_mat = skin->getBind_shape_matrix(); + + if (bind_mat) + { //get bind shape matrix + domFloat4x4& dom_value = bind_mat->getValue(); + + LLMeshSkinInfo& skin_info = model->mSkinInfo; + + for (int i = 0; i < 4; i++) + { + for(int j = 0; j < 4; j++) + { + skin_info.mBindShapeMatrix.mMatrix[i][j] = dom_value[i + j*4]; + } + } + + LLMatrix4 trans = normalized_transformation; + trans *= skin_info.mBindShapeMatrix; + skin_info.mBindShapeMatrix = trans; + + } + + + //Some collada setup for accessing the skeleton + daeElement* pElement = 0; + dae.getDatabase()->getElement( &pElement, 0, 0, "skeleton" ); + + //Try to get at the skeletal instance controller + domInstance_controller::domSkeleton* pSkeleton = daeSafeCast<domInstance_controller::domSkeleton>( pElement ); + bool missingSkeletonOrScene = false; + + //If no skeleton, do a breadth-first search to get at specific joints + bool rootNode = false; + bool skeletonWithNoRootNode = false; + + //Need to test for a skeleton that does not have a root node + //This occurs when your instance controller does not have an associated scene + if ( pSkeleton ) + { + daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement(); + if ( pSkeletonRootNode ) + { + rootNode = true; + } + else + { + skeletonWithNoRootNode = true; + } + + } + if ( !pSkeleton || !rootNode ) + { + daeElement* pScene = root->getDescendant("visual_scene"); + if ( !pScene ) + { + llwarns<<"No visual scene - unable to parse bone offsets "<<llendl; + missingSkeletonOrScene = true; + } + else + { + //Get the children at this level + daeTArray< daeSmartRef<daeElement> > children = pScene->getChildren(); + S32 childCount = children.getCount(); + + //Process any children that are joints + //Not all children are joints, some code be ambient lights, cameras, geometry etc.. + for (S32 i = 0; i < childCount; ++i) + { + domNode* pNode = daeSafeCast<domNode>(children[i]); + if ( isNodeAJoint( pNode ) ) + { + processJointNode( pNode, mJointList ); + } + } + } + } + else + //Has Skeleton + { + //Get the root node of the skeleton + daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement(); + if ( pSkeletonRootNode ) + { + //Once we have the root node - start acccessing it's joint components + const int jointCnt = mJointMap.size(); + std::map<std::string, std::string> :: const_iterator jointIt = mJointMap.begin(); + + //Loop over all the possible joints within the .dae - using the allowed joint list in the ctor. + for ( int i=0; i<jointCnt; ++i, ++jointIt ) + { + //Build a joint for the resolver to work with + char str[64]={0}; + sprintf(str,"./%s",(*jointIt).second.c_str() ); + //llwarns<<"Joint "<< str <<llendl; + + //Setup the resolver + daeSIDResolver resolver( pSkeletonRootNode, str ); + + //Look for the joint + domNode* pJoint = daeSafeCast<domNode>( resolver.getElement() ); + if ( pJoint ) + { + //Pull out the translate id and store it in the jointTranslations map + daeSIDResolver jointResolver( pJoint, "./translate" ); + domTranslate* pTranslate = daeSafeCast<domTranslate>( jointResolver.getElement() ); + + LLMatrix4 workingTransform; + + //Translation via SID + if ( pTranslate ) + { + extractTranslation( pTranslate, workingTransform ); + } + else + { + //Translation via child from element + daeElement* pTranslateElement = getChildFromElement( pJoint, "translate" ); + if ( pTranslateElement && pTranslateElement->typeID() != domTranslate::ID() ) + { + llwarns<< "The found element is not a translate node" <<llendl; + missingSkeletonOrScene = true; + } + else + { + extractTranslationViaElement( pTranslateElement, workingTransform ); + } + } + + //Store the joint transform w/respect to it's name. + mJointList[(*jointIt).second.c_str()] = workingTransform; + } + } + + //If anything failed in regards to extracting the skeleton, joints or translation id, + //mention it + if ( missingSkeletonOrScene ) + { + llwarns<< "Partial jointmap found in asset - did you mean to just have a partial map?" << llendl; + } + }//got skeleton? + } + + + domSkin::domJoints* joints = skin->getJoints(); + + domInputLocal_Array& joint_input = joints->getInput_array(); + + for (size_t i = 0; i < joint_input.getCount(); ++i) + { + domInputLocal* input = joint_input.get(i); + xsNMTOKEN semantic = input->getSemantic(); + + if (strcmp(semantic, COMMON_PROFILE_INPUT_JOINT) == 0) + { //found joint source, fill model->mJointMap and model->mSkinInfo.mJointNames + daeElement* elem = input->getSource().getElement(); + + domSource* source = daeSafeCast<domSource>(elem); + if (source) + { + + + domName_array* names_source = source->getName_array(); + + if (names_source) + { + domListOfNames &names = names_source->getValue(); + + for (size_t j = 0; j < names.getCount(); ++j) + { + std::string name(names.get(j)); + if (mJointMap.find(name) != mJointMap.end()) + { + name = mJointMap[name]; + } + model->mSkinInfo.mJointNames.push_back(name); + model->mSkinInfo.mJointMap[name] = j; + } + } + else + { + domIDREF_array* names_source = source->getIDREF_array(); + if (names_source) + { + xsIDREFS& names = names_source->getValue(); + + for (size_t j = 0; j < names.getCount(); ++j) + { + std::string name(names.get(j).getID()); + if (mJointMap.find(name) != mJointMap.end()) + { + name = mJointMap[name]; + } + model->mSkinInfo.mJointNames.push_back(name); + model->mSkinInfo.mJointMap[name] = j; + } + } + } + } + } + else if (strcmp(semantic, COMMON_PROFILE_INPUT_INV_BIND_MATRIX) == 0) + { //found inv_bind_matrix array, fill model->mInvBindMatrix + domSource* source = daeSafeCast<domSource>(input->getSource().getElement()); + if (source) + { + domFloat_array* t = source->getFloat_array(); + if (t) + { + domListOfFloats& transform = t->getValue(); + S32 count = transform.getCount()/16; + + for (S32 k = 0; k < count; ++k) + { + LLMatrix4 mat; + + for (int i = 0; i < 4; i++) + { + for(int j = 0; j < 4; j++) + { + mat.mMatrix[i][j] = transform[k*16 + i + j*4]; + } + } + + model->mSkinInfo.mInvBindMatrix.push_back(mat); + } + } + } + } + } + + //Now that we've parsed the joint array, let's determine if we have a full rig + //(which means we have all the joints that are required for an avatar versus + //a skinned asset attached to a node in a file that contains an entire skeleton, + //but does not use the skeleton). + buildJointToNodeMappingFromScene( root ); + mPreview->critiqueRigForUploadApplicability( model->mSkinInfo.mJointNames ); + + if ( !missingSkeletonOrScene ) + { + //Set the joint translations on the avatar - if it's a full mapping + //The joints are reset in the dtor + if ( mPreview->getRigWithSceneParity() ) + { + std::map<std::string, std::string> :: const_iterator masterJointIt = mJointMap.begin(); + std::map<std::string, std::string> :: const_iterator masterJointItEnd = mJointMap.end(); + for (;masterJointIt!=masterJointItEnd;++masterJointIt ) + { + std::string lookingForJoint = (*masterJointIt).first.c_str(); + + if ( mJointList.find( lookingForJoint ) != mJointList.end() ) + { + //llinfos<<"joint "<<lookingForJoint.c_str()<<llendl; + LLMatrix4 jointTransform = mJointList[lookingForJoint]; + LLJoint* pJoint = gAgentAvatarp->getJoint( lookingForJoint ); + if ( pJoint ) + { + pJoint->storeCurrentXform( jointTransform.getTranslation() ); + } + else + { + //Most likely an error in the asset. + llwarns<<"Tried to apply joint position from .dae, but it did not exist in the avatar rig." << llendl; + } + } + } + } + } //missingSkeletonOrScene + + + //We need to construct the alternate bind matrix (which contains the new joint positions) + //in the same order as they were stored in the joint buffer. The joints associated + //with the skeleton are not stored in the same order as they are in the exported joint buffer. + //This remaps the skeletal joints to be in the same order as the joints stored in the model. + std::vector<std::string> :: const_iterator jointIt = model->mSkinInfo.mJointNames.begin(); + const int jointCnt = model->mSkinInfo.mJointNames.size(); + for ( int i=0; i<jointCnt; ++i, ++jointIt ) + { + std::string lookingForJoint = (*jointIt).c_str(); + //Look for the joint xform that we extracted from the skeleton, using the jointIt as the key + //and store it in the alternate bind matrix + if ( mJointList.find( lookingForJoint ) != mJointList.end() ) + { + LLMatrix4 jointTransform = mJointList[lookingForJoint]; + LLMatrix4 newInverse = model->mSkinInfo.mInvBindMatrix[i]; + newInverse.setTranslation( mJointList[lookingForJoint].getTranslation() ); + model->mSkinInfo.mAlternateBindMatrix.push_back( newInverse ); + } + else + { + llwarns<<"Possibly misnamed/missing joint [" <<lookingForJoint.c_str()<<" ] "<<llendl; + } + } + + //grab raw position array + + domVertices* verts = mesh->getVertices(); + if (verts) + { + domInputLocal_Array& inputs = verts->getInput_array(); + for (size_t i = 0; i < inputs.getCount() && model->mPosition.empty(); ++i) + { + if (strcmp(inputs[i]->getSemantic(), COMMON_PROFILE_INPUT_POSITION) == 0) + { + domSource* pos_source = daeSafeCast<domSource>(inputs[i]->getSource().getElement()); + if (pos_source) + { + domFloat_array* pos_array = pos_source->getFloat_array(); + if (pos_array) + { + domListOfFloats& pos = pos_array->getValue(); + + for (size_t j = 0; j < pos.getCount(); j += 3) + { + if (pos.getCount() <= j+2) + { + llerrs << "WTF?" << llendl; + } + + LLVector3 v(pos[j], pos[j+1], pos[j+2]); + + //transform from COLLADA space to volume space + v = v * inverse_normalized_transformation; + + model->mPosition.push_back(v); + } + } + } + } + } + } + + //grab skin weights array + domSkin::domVertex_weights* weights = skin->getVertex_weights(); + if (weights) + { + domInputLocalOffset_Array& inputs = weights->getInput_array(); + domFloat_array* vertex_weights = NULL; + for (size_t i = 0; i < inputs.getCount(); ++i) + { + if (strcmp(inputs[i]->getSemantic(), COMMON_PROFILE_INPUT_WEIGHT) == 0) + { + domSource* weight_source = daeSafeCast<domSource>(inputs[i]->getSource().getElement()); + if (weight_source) + { + vertex_weights = weight_source->getFloat_array(); + } + } + } + + if (vertex_weights) + { + domListOfFloats& w = vertex_weights->getValue(); + domListOfUInts& vcount = weights->getVcount()->getValue(); + domListOfInts& v = weights->getV()->getValue(); + + U32 c_idx = 0; + for (size_t vc_idx = 0; vc_idx < vcount.getCount(); ++vc_idx) + { //for each vertex + daeUInt count = vcount[vc_idx]; + + //create list of weights that influence this vertex + LLModel::weight_list weight_list; + + for (daeUInt i = 0; i < count; ++i) + { //for each weight + daeInt joint_idx = v[c_idx++]; + daeInt weight_idx = v[c_idx++]; + + if (joint_idx == -1) + { + //ignore bindings to bind_shape_matrix + continue; + } + + F32 weight_value = w[weight_idx]; + + weight_list.push_back(LLModel::JointWeight(joint_idx, weight_value)); + } + + //sort by joint weight + std::sort(weight_list.begin(), weight_list.end(), LLModel::CompareWeightGreater()); + + std::vector<LLModel::JointWeight> wght; + + F32 total = 0.f; + + for (U32 i = 0; i < llmin((U32) 4, (U32) weight_list.size()); ++i) + { //take up to 4 most significant weights + if (weight_list[i].mWeight > 0.f) + { + wght.push_back( weight_list[i] ); + total += weight_list[i].mWeight; + } + } + + F32 scale = 1.f/total; + if (scale != 1.f) + { //normalize weights + for (U32 i = 0; i < wght.size(); ++i) + { + wght[i].mWeight *= scale; + } + } + + model->mSkinWeights[model->mPosition[vc_idx]] = wght; + } + + //add instance to scene for this model + + LLMatrix4 transformation = mTransform; + // adjust the transformation to compensate for mesh normalization + + LLMatrix4 mesh_translation; + mesh_translation.setTranslation(mesh_translation_vector); + mesh_translation *= transformation; + transformation = mesh_translation; + + LLMatrix4 mesh_scale; + mesh_scale.initScale(mesh_scale_vector); + mesh_scale *= transformation; + transformation = mesh_scale; + + std::vector<LLImportMaterial> materials; + materials.resize(model->getNumVolumeFaces()); + mScene[transformation].push_back(LLModelInstance(model, model->mLabel, transformation, materials)); + stretch_extents(model, transformation, mExtents[0], mExtents[1], mFirstTransform); + } + } + } + } + } + } + } + + daeElement* scene = root->getDescendant("visual_scene"); + + if (!scene) + { + llwarns << "document has no visual_scene" << llendl; + setLoadState( ERROR_PARSING ); + return false; + } + setLoadState( DONE ); + + processElement(scene); + + return true; +} + +void LLModelLoader::setLoadState(U32 state) +{ + if (mPreview) + { + mPreview->setLoadState(state); + } +} + +bool LLModelLoader::loadFromSLM(const std::string& filename) +{ + //only need to populate mScene with data from slm + llstat stat; + + if (LLFile::stat(filename, &stat)) + { //file does not exist + return false; + } + + S32 file_size = (S32) stat.st_size; + + llifstream ifstream(filename, std::ifstream::in | std::ifstream::binary); + LLSD data; + LLSDSerialize::fromBinary(data, ifstream, file_size); + ifstream.close(); + + //build model list for each LoD + model_list model[LLModel::NUM_LODS]; + + LLSD& mesh = data["mesh"]; + + LLVolumeParams volume_params; + volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); + + for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod) + { + for (U32 i = 0; i < mesh.size(); ++i) + { + std::stringstream str(mesh[i].asString()); + LLPointer<LLModel> loaded_model = new LLModel(volume_params, (F32) lod); + if (loaded_model->loadModel(str)) + { + loaded_model->mLocalID = i; + model[lod].push_back(loaded_model); + + if (lod == LLModel::LOD_HIGH && !loaded_model->mSkinInfo.mJointNames.empty()) + { + //check to see if rig is valid + mPreview->critiqueRigForUploadApplicability( loaded_model->mSkinInfo.mJointNames ); + } + } + else + { + llassert(model[lod].empty()); + } + } + } + + if (model[LLModel::LOD_HIGH].empty()) + { //failed to load high lod + return false; + } + + //load instance list + model_instance_list instance_list; + + LLSD& instance = data["instance"]; + + for (U32 i = 0; i < instance.size(); ++i) + { + //deserialize instance list + instance_list.push_back(LLModelInstance(instance[i])); + + //match up model instance pointers + S32 idx = instance_list[i].mLocalMeshID; + + for (U32 lod = 0; lod < LLModel::NUM_LODS; ++lod) + { + if (!model[lod].empty()) + { + instance_list[i].mLOD[lod] = model[lod][idx]; + } + } + + instance_list[i].mModel = model[LLModel::LOD_HIGH][idx]; + } + + + //convert instance_list to mScene + mFirstTransform = TRUE; + for (U32 i = 0; i < instance_list.size(); ++i) + { + LLModelInstance& cur_instance = instance_list[i]; + mScene[cur_instance.mTransform].push_back(cur_instance); + stretch_extents(cur_instance.mModel, cur_instance.mTransform, mExtents[0], mExtents[1], mFirstTransform); + } + + setLoadState( DONE ); + + return true; +} + +//static +bool LLModelLoader::isAlive(LLModelLoader* loader) +{ + if(!loader) + { + return false ; + } + + std::list<LLModelLoader*>::iterator iter = sActiveLoaderList.begin() ; + for(; iter != sActiveLoaderList.end() && (*iter) != loader; ++iter) ; + + return *iter == loader ; +} + +void LLModelLoader::loadModelCallback() +{ + assert_main_thread(); + + if (mPreview) + { + mPreview->loadModelCallback(mLod); + } + + while (!isStopped()) + { //wait until this thread is stopped before deleting self + apr_sleep(100); + } + + //doubel check if "this" is valid before deleting it, in case it is aborted during running. + if(!isAlive(this)) + { + return ; + } + + //cleanup model loader + if (mPreview) + { + mPreview->mModelLoader = NULL; + } + + delete this; +} +//----------------------------------------------------------------------------- +// buildJointToNodeMappingFromScene() +//----------------------------------------------------------------------------- +void LLModelLoader::buildJointToNodeMappingFromScene( daeElement* pRoot ) +{ + daeElement* pScene = pRoot->getDescendant("visual_scene"); + if ( pScene ) + { + daeTArray< daeSmartRef<daeElement> > children = pScene->getChildren(); + S32 childCount = children.getCount(); + for (S32 i = 0; i < childCount; ++i) + { + domNode* pNode = daeSafeCast<domNode>(children[i]); + processJointToNodeMapping( pNode ); + } + } +} +//----------------------------------------------------------------------------- +// processJointToNodeMapping() +//----------------------------------------------------------------------------- +void LLModelLoader::processJointToNodeMapping( domNode* pNode ) +{ + if ( isNodeAJoint( pNode ) ) + { + //1.Store the parent + std::string nodeName = pNode->getName(); + if ( !nodeName.empty() ) + { + mJointsFromNode.push_front( pNode->getName() ); + } + //2. Handle the kiddo's + daeTArray< daeSmartRef<daeElement> > childOfChild = pNode->getChildren(); + S32 childOfChildCount = childOfChild.getCount(); + for (S32 i = 0; i < childOfChildCount; ++i) + { + domNode* pChildNode = daeSafeCast<domNode>( childOfChild[i] ); + if ( pChildNode ) + { + processJointToNodeMapping( pChildNode ); + } + } + } +} + +//----------------------------------------------------------------------------- +// critiqueRigForUploadApplicability() +//----------------------------------------------------------------------------- +void LLModelPreview::critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset ) +{ + critiqueJointToNodeMappingFromScene(); + + //Determines the following use cases for a rig: + //1. It is suitable for upload with skin weights & joint positions, or + //2. It is suitable for upload as standard av with just skin weights + + bool isJointPositionUploadOK = isRigSuitableForJointPositionUpload( jointListFromAsset ); + bool isRigLegacyOK = isRigLegacy( jointListFromAsset ); + + //It's OK that both could end up being true, both default to false + if ( isJointPositionUploadOK ) + { + setRigValidForJointPositionUpload( true ); + } + + if ( isRigLegacyOK ) + { + setLegacyRigValid( true ); + } + + if ( getRigWithSceneParity() && isJointPositionUploadOK ) + { + setResetJointFlag( true ); + } +} +//----------------------------------------------------------------------------- +// critiqueJointToNodeMappingFromScene() +//----------------------------------------------------------------------------- +void LLModelPreview::critiqueJointToNodeMappingFromScene( void ) +{ + //Do the actual nodes back the joint listing from the dae? + //if yes then this is a fully rigged asset, otherwise it's just a partial rig + + std::deque<std::string>::iterator jointsFromNodeIt = mJointsFromNode.begin(); + std::deque<std::string>::iterator jointsFromNodeEndIt = mJointsFromNode.end(); + bool result = true; + + if ( !mJointsFromNode.empty() ) + { + for ( ;jointsFromNodeIt!=jointsFromNodeEndIt;++jointsFromNodeIt ) + { + std::string name = *jointsFromNodeIt; + if ( mJointTransformMap.find( name ) != mJointTransformMap.end() ) + { + continue; + } + else + { + llinfos<<"critiqueJointToNodeMappingFromScene is missing a: "<<name<<llendl; + result = false; + } + } + } + else + { + result = false; + } + + //Determines the following use cases for a rig: + //1. Full av rig w/1-1 mapping from the scene and joint array + //2. Partial rig but w/o parity between the scene and joint array + if ( result ) + { + setResetJointFlag( true ); + setRigWithSceneParity( true ); + } + else + { + setResetJointFlag( false ); + } +} +//----------------------------------------------------------------------------- +// isRigLegacy() +//----------------------------------------------------------------------------- +bool LLModelPreview::isRigLegacy( const std::vector<std::string> &jointListFromAsset ) +{ + //No joints in asset + if ( jointListFromAsset.size() == 0 ) + { + return false; + } + + bool result = false; + + std::deque<std::string> :: const_iterator masterJointIt = mMasterLegacyJointList.begin(); + std::deque<std::string> :: const_iterator masterJointEndIt = mMasterLegacyJointList.end(); + + std::vector<std::string> :: const_iterator modelJointIt = jointListFromAsset.begin(); + std::vector<std::string> :: const_iterator modelJointItEnd = jointListFromAsset.end(); + + for ( ;masterJointIt!=masterJointEndIt;++masterJointIt ) + { + result = false; + modelJointIt = jointListFromAsset.begin(); + + for ( ;modelJointIt!=modelJointItEnd; ++modelJointIt ) + { + if ( *masterJointIt == *modelJointIt ) + { + result = true; + break; + } + } + if ( !result ) + { + llinfos<<" Asset did not contain the joint (if you're u/l a fully rigged asset w/joint positions - it is required)." << *masterJointIt<< llendl; + break; + } + } + return result; +} +//----------------------------------------------------------------------------- +// isRigSuitableForJointPositionUpload() +//----------------------------------------------------------------------------- +bool LLModelPreview::isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset ) +{ + bool result = false; + + std::deque<std::string> :: const_iterator masterJointIt = mMasterJointList.begin(); + std::deque<std::string> :: const_iterator masterJointEndIt = mMasterJointList.end(); + + std::vector<std::string> :: const_iterator modelJointIt = jointListFromAsset.begin(); + std::vector<std::string> :: const_iterator modelJointItEnd = jointListFromAsset.end(); + + for ( ;masterJointIt!=masterJointEndIt;++masterJointIt ) + { + result = false; + modelJointIt = jointListFromAsset.begin(); + + for ( ;modelJointIt!=modelJointItEnd; ++modelJointIt ) + { + if ( *masterJointIt == *modelJointIt ) + { + result = true; + break; + } + } + if ( !result ) + { + llinfos<<" Asset did not contain the joint (if you're u/l a fully rigged asset w/joint positions - it is required)." << *masterJointIt<< llendl; + break; + } + } + return result; +} + + +//called in the main thread +void LLModelLoader::loadTextures() +{ + BOOL is_paused = isPaused() ; + pause() ; //pause the loader + + for(scene::iterator iter = mScene.begin(); iter != mScene.end(); ++iter) + { + for(U32 i = 0 ; i < iter->second.size(); i++) + { + for(U32 j = 0 ; j < iter->second[i].mMaterial.size() ; j++) + { + if(!iter->second[i].mMaterial[j].mDiffuseMapFilename.empty()) + { + iter->second[i].mMaterial[j].mDiffuseMap = + LLViewerTextureManager::getFetchedTextureFromUrl("file://" + iter->second[i].mMaterial[j].mDiffuseMapFilename, TRUE, LLViewerTexture::BOOST_PREVIEW); + iter->second[i].mMaterial[j].mDiffuseMap->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, TRUE, FALSE, mPreview, NULL, FALSE); + iter->second[i].mMaterial[j].mDiffuseMap->forceToSaveRawImage(); + } + } + } + } + + if(!is_paused) + { + unpause() ; + } +} + +//----------------------------------------------------------------------------- +// isNodeAJoint() +//----------------------------------------------------------------------------- +bool LLModelLoader::isNodeAJoint( domNode* pNode ) +{ + if ( !pNode || pNode->getName() == NULL) + { + return false; + } + + if ( mJointMap.find( pNode->getName() ) != mJointMap.end() ) + { + return true; + } + + return false; +} + +//----------------------------------------------------------------------------- +// extractTranslation() +//----------------------------------------------------------------------------- +void LLModelLoader::extractTranslation( domTranslate* pTranslate, LLMatrix4& transform ) +{ + domFloat3 jointTrans = pTranslate->getValue(); + LLVector3 singleJointTranslation( jointTrans[0], jointTrans[1], jointTrans[2] ); + transform.setTranslation( singleJointTranslation ); +} +//----------------------------------------------------------------------------- +// extractTranslationViaElement() +//----------------------------------------------------------------------------- +void LLModelLoader::extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform ) +{ + domTranslate* pTranslateChild = dynamic_cast<domTranslate*>( pTranslateElement ); + domFloat3 translateChild = pTranslateChild->getValue(); + LLVector3 singleJointTranslation( translateChild[0], translateChild[1], translateChild[2] ); + transform.setTranslation( singleJointTranslation ); +} +//----------------------------------------------------------------------------- +// processJointNode() +//----------------------------------------------------------------------------- +void LLModelLoader::processJointNode( domNode* pNode, JointTransformMap& jointTransforms ) +{ + if (pNode->getName() == NULL) + { + llwarns << "nameless node, can't process" << llendl; + return; + } + + //llwarns<<"ProcessJointNode# Node:" <<pNode->getName()<<llendl; + + //1. handle the incoming node - extract out translation via SID or element + + LLMatrix4 workingTransform; + + //Pull out the translate id and store it in the jointTranslations map + daeSIDResolver jointResolver( pNode, "./translate" ); + domTranslate* pTranslate = daeSafeCast<domTranslate>( jointResolver.getElement() ); + + //Translation via SID was successful + if ( pTranslate ) + { + extractTranslation( pTranslate, workingTransform ); + } + else + { + //Translation via child from element + daeElement* pTranslateElement = getChildFromElement( pNode, "translate" ); + if ( !pTranslateElement || pTranslateElement->typeID() != domTranslate::ID() ) + { + //llwarns<< "The found element is not a translate node" <<llendl; + daeSIDResolver jointResolver( pNode, "./matrix" ); + domMatrix* pMatrix = daeSafeCast<domMatrix>( jointResolver.getElement() ); + if ( pMatrix ) + { + //llinfos<<"A matrix SID was however found!"<<llendl; + domFloat4x4 domArray = pMatrix->getValue(); + for ( int i = 0; i < 4; i++ ) + { + for( int j = 0; j < 4; j++ ) + { + workingTransform.mMatrix[i][j] = domArray[i + j*4]; + } + } + } + else + { + llwarns<< "The found element is not translate or matrix node - most likely a corrupt export!" <<llendl; + } + } + else + { + extractTranslationViaElement( pTranslateElement, workingTransform ); + } + } + + //Store the working transform relative to the nodes name. + jointTransforms[ pNode->getName() ] = workingTransform; + + //2. handle the nodes children + + //Gather and handle the incoming nodes children + daeTArray< daeSmartRef<daeElement> > childOfChild = pNode->getChildren(); + S32 childOfChildCount = childOfChild.getCount(); + + for (S32 i = 0; i < childOfChildCount; ++i) + { + domNode* pChildNode = daeSafeCast<domNode>( childOfChild[i] ); + if ( pChildNode ) + { + processJointNode( pChildNode, jointTransforms ); + } + } +} +//----------------------------------------------------------------------------- +// getChildFromElement() +//----------------------------------------------------------------------------- +daeElement* LLModelLoader::getChildFromElement( daeElement* pElement, std::string const & name ) +{ + daeElement* pChildOfElement = pElement->getChild( name.c_str() ); + if ( pChildOfElement ) + { + return pChildOfElement; + } + llwarns<< "Could not find a child [" << name << "] for the element: \"" << pElement->getAttribute("id") << "\"" << llendl; + return NULL; +} + +void LLModelLoader::processElement(daeElement* element) +{ + LLMatrix4 saved_transform = mTransform; + + domTranslate* translate = daeSafeCast<domTranslate>(element); + if (translate) + { + domFloat3 dom_value = translate->getValue(); + + LLMatrix4 translation; + translation.setTranslation(LLVector3(dom_value[0], dom_value[1], dom_value[2])); + + translation *= mTransform; + mTransform = translation; + } + + domRotate* rotate = daeSafeCast<domRotate>(element); + if (rotate) + { + domFloat4 dom_value = rotate->getValue(); + + LLMatrix4 rotation; + rotation.initRotTrans(dom_value[3] * DEG_TO_RAD, LLVector3(dom_value[0], dom_value[1], dom_value[2]), LLVector3(0, 0, 0)); + + rotation *= mTransform; + mTransform = rotation; + } + + domScale* scale = daeSafeCast<domScale>(element); + if (scale) + { + domFloat3 dom_value = scale->getValue(); + + LLMatrix4 scaling; + scaling.initScale(LLVector3(dom_value[0], dom_value[1], dom_value[2])); + + scaling *= mTransform; + mTransform = scaling; + } + + domMatrix* matrix = daeSafeCast<domMatrix>(element); + if (matrix) + { + domFloat4x4 dom_value = matrix->getValue(); + + LLMatrix4 matrix_transform; + + for (int i = 0; i < 4; i++) + { + for(int j = 0; j < 4; j++) + { + matrix_transform.mMatrix[i][j] = dom_value[i + j*4]; + } + } + + matrix_transform *= mTransform; + mTransform = matrix_transform; + } + + domInstance_geometry* instance_geo = daeSafeCast<domInstance_geometry>(element); + if (instance_geo) + { + domGeometry* geo = daeSafeCast<domGeometry>(instance_geo->getUrl().getElement()); + if (geo) + { + domMesh* mesh = daeSafeCast<domMesh>(geo->getDescendant(daeElement::matchType(domMesh::ID()))); + if (mesh) + { + LLModel* model = mModel[mesh]; + if (model) + { + LLMatrix4 transformation = mTransform; + + std::vector<LLImportMaterial> materials = getMaterials(model, instance_geo); + + // adjust the transformation to compensate for mesh normalization + LLVector3 mesh_scale_vector; + LLVector3 mesh_translation_vector; + model->getNormalizedScaleTranslation(mesh_scale_vector, mesh_translation_vector); + + LLMatrix4 mesh_translation; + mesh_translation.setTranslation(mesh_translation_vector); + mesh_translation *= transformation; + transformation = mesh_translation; + + LLMatrix4 mesh_scale; + mesh_scale.initScale(mesh_scale_vector); + mesh_scale *= transformation; + transformation = mesh_scale; + + std::string label = getElementLabel(instance_geo); + mScene[transformation].push_back(LLModelInstance(model, label, transformation, materials)); + + stretch_extents(model, transformation, mExtents[0], mExtents[1], mFirstTransform); + } + } + } + } + + domInstance_node* instance_node = daeSafeCast<domInstance_node>(element); + if (instance_node) + { + daeElement* instance = instance_node->getUrl().getElement(); + if (instance) + { + processElement(instance); + } + } + + //process children + daeTArray< daeSmartRef<daeElement> > children = element->getChildren(); + for (S32 i = 0; i < children.getCount(); i++) + { + processElement(children[i]); + } + + domNode* node = daeSafeCast<domNode>(element); + if (node) + { //this element was a node, restore transform before processiing siblings + mTransform = saved_transform; + } +} + +std::vector<LLImportMaterial> LLModelLoader::getMaterials(LLModel* model, domInstance_geometry* instance_geo) +{ + std::vector<LLImportMaterial> materials; + for (int i = 0; i < model->mMaterialList.size(); i++) + { + LLImportMaterial import_material; + + domInstance_material* instance_mat = NULL; + + domBind_material::domTechnique_common* technique = + daeSafeCast<domBind_material::domTechnique_common>(instance_geo->getDescendant(daeElement::matchType(domBind_material::domTechnique_common::ID()))); + + if (technique) + { + daeTArray< daeSmartRef<domInstance_material> > inst_materials = technique->getChildrenByType<domInstance_material>(); + for (int j = 0; j < inst_materials.getCount(); j++) + { + std::string symbol(inst_materials[j]->getSymbol()); + + if (symbol == model->mMaterialList[i]) // found the binding + { + instance_mat = inst_materials[j]; + } + } + } + + if (instance_mat) + { + domMaterial* material = daeSafeCast<domMaterial>(instance_mat->getTarget().getElement()); + if (material) + { + domInstance_effect* instance_effect = + daeSafeCast<domInstance_effect>(material->getDescendant(daeElement::matchType(domInstance_effect::ID()))); + if (instance_effect) + { + domEffect* effect = daeSafeCast<domEffect>(instance_effect->getUrl().getElement()); + if (effect) + { + domProfile_COMMON* profile = + daeSafeCast<domProfile_COMMON>(effect->getDescendant(daeElement::matchType(domProfile_COMMON::ID()))); + if (profile) + { + import_material = profileToMaterial(profile); + } + } + } + } + } + + materials.push_back(import_material); + } + + return materials; +} + +LLImportMaterial LLModelLoader::profileToMaterial(domProfile_COMMON* material) +{ + LLImportMaterial mat; + mat.mFullbright = FALSE; + + daeElement* diffuse = material->getDescendant("diffuse"); + if (diffuse) + { + domCommon_color_or_texture_type_complexType::domTexture* texture = + daeSafeCast<domCommon_color_or_texture_type_complexType::domTexture>(diffuse->getDescendant("texture")); + if (texture) + { + domCommon_newparam_type_Array newparams = material->getNewparam_array(); + for (S32 i = 0; i < newparams.getCount(); i++) + { + domFx_surface_common* surface = newparams[i]->getSurface(); + if (surface) + { + domFx_surface_init_common* init = surface->getFx_surface_init_common(); + if (init) + { + domFx_surface_init_from_common_Array init_from = init->getInit_from_array(); + + if (init_from.getCount() > i) + { + domImage* image = daeSafeCast<domImage>(init_from[i]->getValue().getElement()); + if (image) + { + // we only support init_from now - embedded data will come later + domImage::domInit_from* init = image->getInit_from(); + if (init) + { + mat.mDiffuseMapFilename = cdom::uriToNativePath(init->getValue().str()); + mat.mDiffuseMapLabel = getElementLabel(material); + } + } + } + } + } + } + } + + domCommon_color_or_texture_type_complexType::domColor* color = + daeSafeCast<domCommon_color_or_texture_type_complexType::domColor>(diffuse->getDescendant("color")); + if (color) + { + domFx_color_common domfx_color = color->getValue(); + LLColor4 value = LLColor4(domfx_color[0], domfx_color[1], domfx_color[2], domfx_color[3]); + mat.mDiffuseColor = value; + } + } + + daeElement* emission = material->getDescendant("emission"); + if (emission) + { + LLColor4 emission_color = getDaeColor(emission); + if (((emission_color[0] + emission_color[1] + emission_color[2]) / 3.0) > 0.25) + { + mat.mFullbright = TRUE; + } + } + + return mat; +} + +// try to get a decent label for this element +std::string LLModelLoader::getElementLabel(daeElement *element) +{ + // if we have a name attribute, use it + std::string name = element->getAttribute("name"); + if (name.length()) + { + return name; + } + + // if we have an ID attribute, use it + if (element->getID()) + { + return std::string(element->getID()); + } + + // if we have a parent, use it + daeElement* parent = element->getParent(); + if (parent) + { + // if parent has a name, use it + std::string name = parent->getAttribute("name"); + if (name.length()) + { + return name; + } + + // if parent has an ID, use it + if (parent->getID()) + { + return std::string(parent->getID()); + } + } + + // try to use our type + daeString element_name = element->getElementName(); + if (element_name) + { + return std::string(element_name); + } + + // if all else fails, use "object" + return std::string("object"); +} + +LLColor4 LLModelLoader::getDaeColor(daeElement* element) +{ + LLColor4 value; + domCommon_color_or_texture_type_complexType::domColor* color = + daeSafeCast<domCommon_color_or_texture_type_complexType::domColor>(element->getDescendant("color")); + if (color) + { + domFx_color_common domfx_color = color->getValue(); + value = LLColor4(domfx_color[0], domfx_color[1], domfx_color[2], domfx_color[3]); + } + + return value; +} + +//----------------------------------------------------------------------------- +// LLModelPreview +//----------------------------------------------------------------------------- + +LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp) +: LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE), LLMutex(NULL) +, mPelvisZOffset( 0.0f ) +, mLegacyRigValid( false ) +, mRigValidJointUpload( false ) +, mResetJoints( false ) +, mRigParityWithScene( false ) +, mLastJointUpdate( false ) +{ + mNeedsUpdate = TRUE; + mCameraDistance = 0.f; + mCameraYaw = 0.f; + mCameraPitch = 0.f; + mCameraZoom = 1.f; + mTextureName = 0; + mPreviewLOD = 0; + mModelLoader = NULL; + mMaxTriangleLimit = 0; + mDirty = false; + mGenLOD = false; + mLoading = false; + mLoadState = LLModelLoader::STARTING; + mGroup = 0; + mBuildShareTolerance = 0.f; + mBuildQueueMode = GLOD_QUEUE_GREEDY; + mBuildBorderMode = GLOD_BORDER_UNLOCK; + mBuildOperator = GLOD_OPERATOR_EDGE_COLLAPSE; + + for (U32 i = 0; i < LLModel::NUM_LODS; ++i) + { + mRequestedTriangleCount[i] = 0; + } + + mViewOption["show_textures"] = false; + + mFMP = fmp; + + mHasPivot = false; + mModelPivot = LLVector3( 0.0f, 0.0f, 0.0f ); + + glodInit(); + + //move into joint mapper class + //1. joints for joint offset verification + mMasterJointList.push_front("mPelvis"); + mMasterJointList.push_front("mTorso"); + mMasterJointList.push_front("mChest"); + mMasterJointList.push_front("mNeck"); + mMasterJointList.push_front("mHead"); + mMasterJointList.push_front("mCollarLeft"); + mMasterJointList.push_front("mShoulderLeft"); + mMasterJointList.push_front("mElbowLeft"); + mMasterJointList.push_front("mWristLeft"); + mMasterJointList.push_front("mCollarRight"); + mMasterJointList.push_front("mShoulderRight"); + mMasterJointList.push_front("mElbowRight"); + mMasterJointList.push_front("mWristRight"); + mMasterJointList.push_front("mHipRight"); + mMasterJointList.push_front("mKneeRight"); + mMasterJointList.push_front("mFootRight"); + mMasterJointList.push_front("mHipLeft"); + mMasterJointList.push_front("mKneeLeft"); + mMasterJointList.push_front("mFootLeft"); + //2. legacy joint list - used to verify rigs that will not be using joint offsets + mMasterLegacyJointList.push_front("mPelvis"); + mMasterLegacyJointList.push_front("mTorso"); + mMasterLegacyJointList.push_front("mChest"); + mMasterLegacyJointList.push_front("mNeck"); + mMasterLegacyJointList.push_front("mHead"); + mMasterLegacyJointList.push_front("mHipRight"); + mMasterLegacyJointList.push_front("mKneeRight"); + mMasterLegacyJointList.push_front("mFootRight"); + mMasterLegacyJointList.push_front("mHipLeft"); + mMasterLegacyJointList.push_front("mKneeLeft"); + mMasterLegacyJointList.push_front("mFootLeft"); +} + +LLModelPreview::~LLModelPreview() +{ + if (mModelLoader) + { + delete mModelLoader; + mModelLoader = NULL; + } + //*HACK : *TODO : turn this back on when we understand why this crashes + //glodShutdown(); +} + +U32 LLModelPreview::calcResourceCost() +{ + assert_main_thread(); + + rebuildUploadData(); + + if (mFMP && mModelLoader) + { + if ( getLoadState() < LLModelLoader::ERROR_PARSING ) + { + mFMP->childEnable("ok_btn"); + } + } + + //Upload skin is selected BUT check to see if the joints coming in from the asset were malformed. + if ( mFMP && mFMP->childGetValue("upload_skin").asBoolean() ) + { + bool uploadingJointPositions = mFMP->childGetValue("upload_joints").asBoolean(); + if ( uploadingJointPositions && !isRigValidForJointPositionUpload() ) + { + mFMP->childDisable("ok_btn"); + } + else + if ( !isLegacyRigValid() ) + { + mFMP->childDisable("ok_btn"); + } + //ok_btn should not have been changed unless something was wrong with joint list + } + + U32 cost = 0; + std::set<LLModel*> accounted; + U32 num_points = 0; + U32 num_hulls = 0; + + F32 debug_scale = mFMP ? mFMP->childGetValue("import_scale").asReal() : 1.f; + mPelvisZOffset = mFMP ? mFMP->childGetValue("pelvis_offset").asReal() : 3.0f; + + if ( mFMP && mFMP->childGetValue("upload_joints").asBoolean() ) + { + gAgentAvatarp->setPelvisOffset( mPelvisZOffset ); + } + + F32 streaming_cost = 0.f; + F32 physics_cost = 0.f; + for (U32 i = 0; i < mUploadData.size(); ++i) + { + LLModelInstance& instance = mUploadData[i]; + + if (accounted.find(instance.mModel) == accounted.end()) + { + accounted.insert(instance.mModel); + + LLModel::Decomposition& decomp = + instance.mLOD[LLModel::LOD_PHYSICS] ? + instance.mLOD[LLModel::LOD_PHYSICS]->mPhysics : + instance.mModel->mPhysics; + + //update instance skin info for each lods pelvisZoffset + for ( int j=0; j<LLModel::NUM_LODS; ++j ) + { + if ( instance.mLOD[j] ) + { + instance.mLOD[j]->mSkinInfo.mPelvisOffset = mPelvisZOffset; + } + } + + std::stringstream ostr; + LLSD ret = LLModel::writeModel(ostr, + instance.mLOD[4], + instance.mLOD[3], + instance.mLOD[2], + instance.mLOD[1], + instance.mLOD[0], + decomp, + mFMP->childGetValue("upload_skin").asBoolean(), + mFMP->childGetValue("upload_joints").asBoolean(), + TRUE); + cost += gMeshRepo.calcResourceCost(ret); + + num_hulls += decomp.mHull.size(); + for (U32 i = 0; i < decomp.mHull.size(); ++i) + { + num_points += decomp.mHull[i].size(); + } + + //calculate streaming cost + LLMatrix4 transformation = instance.mTransform; + + LLVector3 position = LLVector3(0, 0, 0) * transformation; + + LLVector3 x_transformed = LLVector3(1, 0, 0) * transformation - position; + LLVector3 y_transformed = LLVector3(0, 1, 0) * transformation - position; + LLVector3 z_transformed = LLVector3(0, 0, 1) * transformation - position; + F32 x_length = x_transformed.normalize(); + F32 y_length = y_transformed.normalize(); + F32 z_length = z_transformed.normalize(); + LLVector3 scale = LLVector3(x_length, y_length, z_length); + + F32 radius = scale.length()*debug_scale; + + streaming_cost += LLMeshRepository::getStreamingCost(ret, radius); + } + } + + F32 scale = mFMP ? mFMP->childGetValue("import_scale").asReal()*2.f : 2.f; + + mDetailsSignal(mPreviewScale[0]*scale, mPreviewScale[1]*scale, mPreviewScale[2]*scale, streaming_cost, physics_cost); + + updateStatusMessages(); + + return cost; +} + +void LLFloaterModelPreview::setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost) +{ + childSetTextArg("import_dimensions", "[X]", llformat("%.3f", x)); + childSetTextArg("import_dimensions", "[Y]", llformat("%.3f", y)); + childSetTextArg("import_dimensions", "[Z]", llformat("%.3f", z)); + childSetTextArg("streaming cost", "[COST]", llformat("%.3f", streaming_cost)); + childSetTextArg("physics cost", "[COST]", llformat("%.3f", physics_cost)); +} + + +void LLModelPreview::rebuildUploadData() +{ + assert_main_thread(); + + mUploadData.clear(); + mTextureSet.clear(); + + //fill uploaddata instance vectors from scene data + + std::string requested_name = mFMP->getChild<LLUICtrl>("description_form")->getValue().asString(); + + + LLSpinCtrl* scale_spinner = mFMP->getChild<LLSpinCtrl>("import_scale"); + + if (!scale_spinner) + { + llerrs << "floater_model_preview.xml MUST contain import_scale spinner." << llendl; + } + + F32 scale = scale_spinner->getValue().asReal(); + + LLMatrix4 scale_mat; + scale_mat.initScale(LLVector3(scale, scale, scale)); + + F32 max_scale = 0.f; + + if ( mBaseScene.size() > 0 ) + { + mFMP->childEnable("ok_btn"); + } + + for (LLModelLoader::scene::iterator iter = mBaseScene.begin(); iter != mBaseScene.end(); ++iter) + { //for each transform in scene + LLMatrix4 mat = iter->first; + + // compute position + LLVector3 position = LLVector3(0, 0, 0) * mat; + + // compute scale + LLVector3 x_transformed = LLVector3(1, 0, 0) * mat - position; + LLVector3 y_transformed = LLVector3(0, 1, 0) * mat - position; + LLVector3 z_transformed = LLVector3(0, 0, 1) * mat - position; + F32 x_length = x_transformed.normalize(); + F32 y_length = y_transformed.normalize(); + F32 z_length = z_transformed.normalize(); + + max_scale = llmax(llmax(llmax(max_scale, x_length), y_length), z_length); + + mat *= scale_mat; + + for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter) + { //for each instance with said transform applied + LLModelInstance instance = *model_iter; + + LLModel* base_model = instance.mModel; + + if (base_model) + { + base_model->mRequestedLabel = requested_name; + } + + S32 idx = 0; + for (idx = 0; idx < mBaseModel.size(); ++idx) + { //find reference instance for this model + if (mBaseModel[idx] == base_model) + { + break; + } + } + + for (U32 i = 0; i < LLModel::NUM_LODS; i++) + { //fill LOD slots based on reference model index + if (!mModel[i].empty()) + { + instance.mLOD[i] = mModel[i][idx]; + } + else + { + instance.mLOD[i] = NULL; + } + } + + instance.mTransform = mat; + mUploadData.push_back(instance); + } + } + + F32 max_import_scale = DEFAULT_MAX_PRIM_SCALE/max_scale; + + scale_spinner->setMaxValue(max_import_scale); + + if (max_import_scale < scale) + { + scale_spinner->setValue(max_import_scale); + } + +} + +void LLModelPreview::saveUploadData(bool save_skinweights, bool save_joint_positions) +{ + if (!mLODFile[LLModel::LOD_HIGH].empty()) + { + std::string filename = mLODFile[LLModel::LOD_HIGH]; + + std::string::size_type i = filename.rfind("."); + if (i != std::string::npos) + { + filename.replace(i, filename.size()-1, ".slm"); + saveUploadData(filename, save_skinweights, save_joint_positions); + } + } +} + +void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_positions) +{ + if (!gSavedSettings.getBOOL("MeshImportUseSLM")) + { + return; + } + + std::set<LLPointer<LLModel> > meshes; + std::map<LLModel*, std::string> mesh_binary; + + LLModel::hull empty_hull; + + LLSD data; + + S32 mesh_id = 0; + + //build list of unique models and initialize local id + for (U32 i = 0; i < mUploadData.size(); ++i) + { + LLModelInstance& instance = mUploadData[i]; + + if (meshes.find(instance.mModel) == meshes.end()) + { + instance.mModel->mLocalID = mesh_id++; + meshes.insert(instance.mModel); + + std::stringstream str; + + LLModel::Decomposition& decomp = + instance.mLOD[LLModel::LOD_PHYSICS].notNull() ? + instance.mLOD[LLModel::LOD_PHYSICS]->mPhysics : + instance.mModel->mPhysics; + + LLModel::writeModel(str, + instance.mLOD[LLModel::LOD_PHYSICS], + instance.mLOD[LLModel::LOD_HIGH], + instance.mLOD[LLModel::LOD_MEDIUM], + instance.mLOD[LLModel::LOD_LOW], + instance.mLOD[LLModel::LOD_IMPOSTOR], + decomp, + save_skinweights, save_joint_positions); + + + data["mesh"][instance.mModel->mLocalID] = str.str(); + } + + data["instance"][i] = instance.asLLSD(); + } + + llofstream out(filename, std::ios_base::out | std::ios_base::binary); + LLSDSerialize::toBinary(data, out); + out.flush(); + out.close(); +} + +void LLModelPreview::clearModel(S32 lod) +{ + if (lod < 0 || lod > LLModel::LOD_PHYSICS) + { + return; + } + + mVertexBuffer[lod].clear(); + mModel[lod].clear(); + mScene[lod].clear(); +} + +void LLModelPreview::loadModel(std::string filename, S32 lod) +{ + assert_main_thread(); + + LLMutexLock lock(this); + + // This triggers if you bring up the file picker and then hit CANCEL. + // Just use the previous model (if any) and ignore that you brought up + // the file picker. + + if (filename.empty()) + { + if (mBaseModel.empty()) + { + // this is the initial file picking. Close the whole floater + // if we don't have a base model to show for high LOD. + mFMP->closeFloater(false); + mLoading = false; + } + return; + } + + if (mModelLoader) + { + llwarns << "Incompleted model load operation pending." << llendl; + return; + } + + mLODFile[lod] = filename; + + if (lod == LLModel::LOD_HIGH) + { + clearGLODGroup(); + } + + mModelLoader = new LLModelLoader(filename, lod, this, mJointTransformMap, mJointsFromNode ); + + mModelLoader->start(); + + mFMP->childSetTextArg("status", "[STATUS]", mFMP->getString("status_reading_file")); + + setPreviewLOD(lod); + + if ( getLoadState() >= LLModelLoader::ERROR_PARSING ) + { + mFMP->childDisable("ok_btn"); + } + + if (lod == mPreviewLOD) + { + mFMP->childSetText("lod_file", mLODFile[mPreviewLOD]); + } + else if (lod == LLModel::LOD_PHYSICS) + { + mFMP->childSetText("physics_file", mLODFile[lod]); + } + + mFMP->openFloater(); +} + +void LLModelPreview::setPhysicsFromLOD(S32 lod) +{ + assert_main_thread(); + + if (lod >= 0 && lod <= 3) + { + mModel[LLModel::LOD_PHYSICS] = mModel[lod]; + mScene[LLModel::LOD_PHYSICS] = mScene[lod]; + mLODFile[LLModel::LOD_PHYSICS].clear(); + mFMP->childSetText("physics_file", mLODFile[LLModel::LOD_PHYSICS]); + mVertexBuffer[LLModel::LOD_PHYSICS].clear(); + rebuildUploadData(); + refresh(); + updateStatusMessages(); + } +} + +void LLModelPreview::clearIncompatible(S32 lod) +{ + for (U32 i = 0; i <= LLModel::LOD_HIGH; i++) + { //clear out any entries that aren't compatible with this model + if (i != lod) + { + if (mModel[i].size() != mModel[lod].size()) + { + mModel[i].clear(); + mScene[i].clear(); + mVertexBuffer[i].clear(); + + if (i == LLModel::LOD_HIGH) + { + mBaseModel = mModel[lod]; + clearGLODGroup(); + mBaseScene = mScene[lod]; + mVertexBuffer[5].clear(); + } + } + } + } +} + +void LLModelPreview::clearGLODGroup() +{ + if (mGroup) + { + for (std::map<LLPointer<LLModel>, U32>::iterator iter = mObject.begin(); iter != mObject.end(); ++iter) + { + glodDeleteObject(iter->second); + stop_gloderror(); + } + mObject.clear(); + + glodDeleteGroup(mGroup); + stop_gloderror(); + mGroup = 0; + } +} + +void LLModelPreview::loadModelCallback(S32 lod) +{ + assert_main_thread(); + + LLMutexLock lock(this); + if (!mModelLoader) + { + mLoading = false ; + return; + } + if(getLoadState() >= LLModelLoader::ERROR_PARSING) + { + mLoading = false ; + return ; + } + + mModelLoader->loadTextures() ; + + if (lod == -1) + { //populate all LoDs from model loader scene + mBaseModel.clear(); + mBaseScene.clear(); + + bool skin_weights = false; + bool joint_positions = false; + + for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod) + { //for each LoD + + //clear scene and model info + mScene[lod].clear(); + mModel[lod].clear(); + mVertexBuffer[lod].clear(); + + if (mModelLoader->mScene.begin()->second[0].mLOD[lod].notNull()) + { //if this LoD exists in the loaded scene + + //copy scene to current LoD + mScene[lod] = mModelLoader->mScene; + + //touch up copied scene to look like current LoD + for (LLModelLoader::scene::iterator iter = mScene[lod].begin(); iter != mScene[lod].end(); ++iter) + { + LLModelLoader::model_instance_list& list = iter->second; + + for (LLModelLoader::model_instance_list::iterator list_iter = list.begin(); list_iter != list.end(); ++list_iter) + { + //override displayed model with current LoD + list_iter->mModel = list_iter->mLOD[lod]; + + //add current model to current LoD's model list (LLModel::mLocalID makes a good vector index) + S32 idx = list_iter->mModel->mLocalID; + + if (mModel[lod].size() <= idx) + { //stretch model list to fit model at given index + mModel[lod].resize(idx+1); + } + + mModel[lod][idx] = list_iter->mModel; + if (!list_iter->mModel->mSkinWeights.empty()) + { + skin_weights = true; + + if (!list_iter->mModel->mSkinInfo.mAlternateBindMatrix.empty()) + { + joint_positions = true; + } + } + } + } + } + } + + if (mFMP) + { + LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) mFMP; + + if (skin_weights) + { //enable uploading/previewing of skin weights if present in .slm file + fmp->enableViewOption("show_skin_weight"); + mViewOption["show_skin_weight"] = true; + fmp->childSetValue("upload_skin", true); + } + + if (joint_positions) + { + fmp->enableViewOption("show_joint_positions"); + mViewOption["show_joint_positions"] = true; + fmp->childSetValue("upload_joints", true); + } + } + + //copy high lod to base scene for LoD generation + mBaseScene = mScene[LLModel::LOD_HIGH]; + mBaseModel = mModel[LLModel::LOD_HIGH]; + + mDirty = true; + resetPreviewTarget(); + } + else + { //only replace given LoD + mModel[lod] = mModelLoader->mModelList; + mScene[lod] = mModelLoader->mScene; + mVertexBuffer[lod].clear(); + + setPreviewLOD(lod); + + if (lod == LLModel::LOD_HIGH) + { //save a copy of the highest LOD for automatic LOD manipulation + if (mBaseModel.empty()) + { //first time we've loaded a model, auto-gen LoD + mGenLOD = true; + } + + mBaseModel = mModel[lod]; + clearGLODGroup(); + + mBaseScene = mScene[lod]; + mVertexBuffer[5].clear(); + } + + clearIncompatible(lod); + + mDirty = true; + + if (lod == LLModel::LOD_HIGH) + { + resetPreviewTarget(); + } + } + + mLoading = false; + refresh(); + + mModelLoadedSignal(); +} + +void LLModelPreview::resetPreviewTarget() +{ + if ( mModelLoader ) + { + mPreviewTarget = (mModelLoader->mExtents[0] + mModelLoader->mExtents[1]) * 0.5f; + mPreviewScale = (mModelLoader->mExtents[1] - mModelLoader->mExtents[0]) * 0.5f; + } + + setPreviewTarget(mPreviewScale.magVec()*2.f); +} + +void LLModelPreview::generateNormals() +{ + assert_main_thread(); + + S32 which_lod = mPreviewLOD; + + + if (which_lod > 4 || which_lod < 0 || + mModel[which_lod].empty()) + { + return; + } + + F32 angle_cutoff = mFMP->childGetValue("crease_angle").asReal(); + + angle_cutoff *= DEG_TO_RAD; + + if (which_lod == 3 && !mBaseModel.empty()) + { + for (LLModelLoader::model_list::iterator iter = mBaseModel.begin(); iter != mBaseModel.end(); ++iter) + { + (*iter)->generateNormals(angle_cutoff); + } + + mVertexBuffer[5].clear(); + } + + for (LLModelLoader::model_list::iterator iter = mModel[which_lod].begin(); iter != mModel[which_lod].end(); ++iter) + { + (*iter)->generateNormals(angle_cutoff); + } + + mVertexBuffer[which_lod].clear(); + refresh(); + +} + +void LLModelPreview::clearMaterials() +{ + for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter) + { //for each transform in current scene + for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter) + { //for each instance with that transform + LLModelInstance& source_instance = *model_iter; + LLModel* source = source_instance.mModel; + + for (S32 i = 0; i < source->getNumVolumeFaces(); ++i) + { //for each face in instance + LLImportMaterial& source_material = source_instance.mMaterial[i]; + + //clear material info + source_material.mDiffuseColor = LLColor4(1,1,1,1); + source_material.mDiffuseMap = NULL; + source_material.mDiffuseMapFilename.clear(); + source_material.mDiffuseMapLabel.clear(); + source_material.mFullbright = false; + } + } + } + + mVertexBuffer[mPreviewLOD].clear(); + + if (mPreviewLOD == LLModel::LOD_HIGH) + { + mBaseScene = mScene[mPreviewLOD]; + mBaseModel = mModel[mPreviewLOD]; + clearGLODGroup(); + mVertexBuffer[5].clear(); + } + + mResourceCost = calcResourceCost(); + refresh(); +} + +void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_limit) +{ + if (mBaseModel.empty()) + { + return; + } + + LLVertexBuffer::unbind(); + + stop_gloderror(); + static U32 cur_name = 1; + + S32 limit = -1; + + U32 triangle_count = 0; + + for (LLModelLoader::model_list::iterator iter = mBaseModel.begin(); iter != mBaseModel.end(); ++iter) + { + LLModel* mdl = *iter; + for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) + { + triangle_count += mdl->getVolumeFace(i).mNumIndices/3; + } + } + + U32 base_triangle_count = triangle_count; + + U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; + + U32 lod_mode = 0; + + LLCtrlSelectionInterface* iface = mFMP->childGetSelectionInterface("lod_mode"); + if (iface) + { + lod_mode = iface->getFirstSelectedIndex(); + } + + F32 lod_error_threshold = mFMP->childGetValue("lod_error_threshold").asReal(); + + if (lod_mode == 0) + { + lod_mode = GLOD_TRIANGLE_BUDGET; + if (which_lod != -1) + { + limit = mFMP->childGetValue("lod_triangle_limit").asInteger(); + } + } + else + { + lod_mode = GLOD_ERROR_THRESHOLD; + } + + U32 build_operator = 0; + + iface = mFMP->childGetSelectionInterface("build_operator"); + if (iface) + { + build_operator = iface->getFirstSelectedIndex(); + } + + if (build_operator == 0) + { + build_operator = GLOD_OPERATOR_EDGE_COLLAPSE; + } + else + { + build_operator = GLOD_OPERATOR_HALF_EDGE_COLLAPSE; + } + + U32 queue_mode=0; + iface = mFMP->childGetSelectionInterface("queue_mode"); + if (iface) + { + queue_mode = iface->getFirstSelectedIndex(); + } + + if (queue_mode == 0) + { + queue_mode = GLOD_QUEUE_GREEDY; + } + else if (queue_mode == 1) + { + queue_mode = GLOD_QUEUE_LAZY; + } + else + { + queue_mode = GLOD_QUEUE_INDEPENDENT; + } + + U32 border_mode = 0; + + iface = mFMP->childGetSelectionInterface("border_mode"); + if (iface) + { + border_mode = iface->getFirstSelectedIndex(); + } + + if (border_mode == 0) + { + border_mode = GLOD_BORDER_UNLOCK; + } + else + { + border_mode = GLOD_BORDER_LOCK; + } + + bool object_dirty = false; + if (border_mode != mBuildBorderMode) + { + mBuildBorderMode = border_mode; + object_dirty = true; + } + + if (queue_mode != mBuildQueueMode) + { + mBuildQueueMode = queue_mode; + object_dirty = true; + } + + if (build_operator != mBuildOperator) + { + mBuildOperator = build_operator; + object_dirty = true; + } + + F32 share_tolerance = mFMP->childGetValue("share_tolerance").asReal(); + if (share_tolerance != mBuildShareTolerance) + { + mBuildShareTolerance = share_tolerance; + object_dirty = true; + } + + if (mGroup == 0) + { + object_dirty = true; + mGroup = cur_name++; + glodNewGroup(mGroup); + } + + if (object_dirty) + { + for (LLModelLoader::model_list::iterator iter = mBaseModel.begin(); iter != mBaseModel.end(); ++iter) + { //build GLOD objects for each model in base model list + LLModel* mdl = *iter; + + if (mObject[mdl] != 0) + { + glodDeleteObject(mObject[mdl]); + } + + mObject[mdl] = cur_name++; + + glodNewObject(mObject[mdl], mGroup, GLOD_DISCRETE); + stop_gloderror(); + + if (iter == mBaseModel.begin() && !mdl->mSkinWeights.empty()) + { //regenerate vertex buffer for skinned models to prevent animation feedback during LOD generation + mVertexBuffer[5].clear(); + } + + if (mVertexBuffer[5].empty()) + { + genBuffers(5, false); + } + + U32 tri_count = 0; + for (U32 i = 0; i < mVertexBuffer[5][mdl].size(); ++i) + { + mVertexBuffer[5][mdl][i]->setBuffer(type_mask); + U32 num_indices = mVertexBuffer[5][mdl][i]->getNumIndices(); + if (num_indices > 2) + { + glodInsertElements(mObject[mdl], i, GL_TRIANGLES, num_indices, GL_UNSIGNED_SHORT, mVertexBuffer[5][mdl][i]->getIndicesPointer(), 0, 0.f); + } + tri_count += num_indices/3; + stop_gloderror(); + } + + glodObjectParameteri(mObject[mdl], GLOD_BUILD_OPERATOR, build_operator); + stop_gloderror(); + + glodObjectParameteri(mObject[mdl], GLOD_BUILD_QUEUE_MODE, queue_mode); + stop_gloderror(); + + glodObjectParameteri(mObject[mdl], GLOD_BUILD_BORDER_MODE, border_mode); + stop_gloderror(); + + glodObjectParameterf(mObject[mdl], GLOD_BUILD_SHARE_TOLERANCE, share_tolerance); + stop_gloderror(); + + glodBuildObject(mObject[mdl]); + stop_gloderror(); + } + } + + + S32 start = LLModel::LOD_HIGH; + S32 end = 0; + + if (which_lod != -1) + { + start = end = which_lod; + } + + mMaxTriangleLimit = base_triangle_count; + + for (S32 lod = start; lod >= end; --lod) + { + if (which_lod == -1) + { + if (lod < start) + { + triangle_count /= decimation; + } + } + else + { + if (enforce_tri_limit) + { + triangle_count = limit; + } + else + { + for (S32 j=LLModel::LOD_HIGH; j>which_lod; --j) + { + triangle_count /= decimation; + } + } + } + + mModel[lod].clear(); + mModel[lod].resize(mBaseModel.size()); + mVertexBuffer[lod].clear(); + + U32 actual_tris = 0; + U32 actual_verts = 0; + U32 submeshes = 0; + + mRequestedTriangleCount[lod] = triangle_count; + + glodGroupParameteri(mGroup, GLOD_ADAPT_MODE, lod_mode); + stop_gloderror(); + + glodGroupParameteri(mGroup, GLOD_ERROR_MODE, GLOD_OBJECT_SPACE_ERROR); + stop_gloderror(); + + glodGroupParameterf(mGroup, GLOD_OBJECT_SPACE_ERROR_THRESHOLD, lod_error_threshold); + stop_gloderror(); + + if (lod_mode != GLOD_TRIANGLE_BUDGET) + { + glodGroupParameteri(mGroup, GLOD_MAX_TRIANGLES, 0); + } + else + { + //SH-632: always add 1 to desired amount to avoid decimating below desired amount + glodGroupParameteri(mGroup, GLOD_MAX_TRIANGLES, triangle_count+1); + } + + stop_gloderror(); + glodAdaptGroup(mGroup); + stop_gloderror(); + + for (U32 mdl_idx = 0; mdl_idx < mBaseModel.size(); ++mdl_idx) + { + LLModel* base = mBaseModel[mdl_idx]; + + GLint patch_count = 0; + glodGetObjectParameteriv(mObject[base], GLOD_NUM_PATCHES, &patch_count); + stop_gloderror(); + + LLVolumeParams volume_params; + volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); + mModel[lod][mdl_idx] = new LLModel(volume_params, 0.f); + + GLint* sizes = new GLint[patch_count*2]; + glodGetObjectParameteriv(mObject[base], GLOD_PATCH_SIZES, sizes); + stop_gloderror(); + + GLint* names = new GLint[patch_count]; + glodGetObjectParameteriv(mObject[base], GLOD_PATCH_NAMES, names); + stop_gloderror(); + + mModel[lod][mdl_idx]->setNumVolumeFaces(patch_count); + + LLModel* target_model = mModel[lod][mdl_idx]; + + for (GLint i = 0; i < patch_count; ++i) + { + LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(type_mask, 0); + + if (sizes[i*2+1] > 0 && sizes[i*2] > 0) + { + buff->allocateBuffer(sizes[i*2+1], sizes[i*2], true); + buff->setBuffer(type_mask); + glodFillElements(mObject[base], names[i], GL_UNSIGNED_SHORT, buff->getIndicesPointer()); + stop_gloderror(); + } + else + { //this face was eliminated, create a dummy triangle (one vertex, 3 indices, all 0) + buff->allocateBuffer(1, 3, true); + memset(buff->getMappedData(), 0, buff->getSize()); + memset(buff->getIndicesPointer(), 0, buff->getIndicesSize()); + } + + buff->validateRange(0, buff->getNumVerts()-1, buff->getNumIndices(), 0); + + LLStrider<LLVector3> pos; + LLStrider<LLVector3> norm; + LLStrider<LLVector2> tc; + LLStrider<U16> index; + + buff->getVertexStrider(pos); + buff->getNormalStrider(norm); + buff->getTexCoord0Strider(tc); + buff->getIndexStrider(index); + + target_model->setVolumeFaceData(names[i], pos, norm, tc, index, buff->getNumVerts(), buff->getNumIndices()); + actual_tris += buff->getNumIndices()/3; + actual_verts += buff->getNumVerts(); + ++submeshes; + + if (!validate_face(target_model->getVolumeFace(names[i]))) + { + llerrs << "Invalid face generated during LOD generation." << llendl; + } + } + + //blind copy skin weights and just take closest skin weight to point on + //decimated mesh for now (auto-generating LODs with skin weights is still a bit + //of an open problem). + target_model->mPosition = base->mPosition; + target_model->mSkinWeights = base->mSkinWeights; + target_model->mSkinInfo = base->mSkinInfo; + //copy material list + target_model->mMaterialList = base->mMaterialList; + + if (!validate_model(target_model)) + { + llerrs << "Invalid model generated when creating LODs" << llendl; + } + + delete [] sizes; + delete [] names; + } + + //rebuild scene based on mBaseScene + mScene[lod].clear(); + mScene[lod] = mBaseScene; + + for (U32 i = 0; i < mBaseModel.size(); ++i) + { + LLModel* mdl = mBaseModel[i]; + LLModel* target = mModel[lod][i]; + if (target) + { + for (LLModelLoader::scene::iterator iter = mScene[lod].begin(); iter != mScene[lod].end(); ++iter) + { + for (U32 j = 0; j < iter->second.size(); ++j) + { + if (iter->second[j].mModel == mdl) + { + iter->second[j].mModel = target; + } + } + } + } + } + } + + mResourceCost = calcResourceCost(); + + /*if (which_lod == -1 && mScene[LLModel::LOD_PHYSICS].empty()) + { //build physics scene + mScene[LLModel::LOD_PHYSICS] = mScene[LLModel::LOD_LOW]; + mModel[LLModel::LOD_PHYSICS] = mModel[LLModel::LOD_LOW]; + + for (U32 i = 1; i < mModel[LLModel::LOD_PHYSICS].size(); ++i) + { + mPhysicsQ.push(mModel[LLModel::LOD_PHYSICS][i]); + } + }*/ +} + +void LLModelPreview::updateStatusMessages() +{ + assert_main_thread(); + + //triangle/vertex/submesh count for each mesh asset for each lod + std::vector<S32> tris[LLModel::NUM_LODS]; + std::vector<S32> verts[LLModel::NUM_LODS]; + std::vector<S32> submeshes[LLModel::NUM_LODS]; + + //total triangle/vertex/submesh count for each lod + S32 total_tris[LLModel::NUM_LODS]; + S32 total_verts[LLModel::NUM_LODS]; + S32 total_submeshes[LLModel::NUM_LODS]; + + for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod) + { + //initialize total for this lod to 0 + total_tris[lod] = total_verts[lod] = total_submeshes[lod] = 0; + + for (U32 i = 0; i < mModel[lod].size(); ++i) + { //for each model in the lod + S32 cur_tris = 0; + S32 cur_verts = 0; + S32 cur_submeshes = mModel[lod][i]->getNumVolumeFaces(); + + for (S32 j = 0; j < cur_submeshes; ++j) + { //for each submesh (face), add triangles and vertices to current total + const LLVolumeFace& face = mModel[lod][i]->getVolumeFace(j); + cur_tris += face.mNumIndices/3; + cur_verts += face.mNumVertices; + } + + //add this model to the lod total + total_tris[lod] += cur_tris; + total_verts[lod] += cur_verts; + total_submeshes[lod] += cur_submeshes; + + //store this model's counts to asset data + tris[lod].push_back(cur_tris); + verts[lod].push_back(cur_verts); + submeshes[lod].push_back(cur_submeshes); + } + } + + if (mMaxTriangleLimit == 0) + { + mMaxTriangleLimit = total_tris[LLModel::LOD_HIGH]; + } + + + mFMP->childSetTextArg("submeshes_info", "[SUBMESHES]", llformat("%d", total_submeshes[LLModel::LOD_HIGH])); + + std::string mesh_status_na = mFMP->getString("mesh_status_na"); + + S32 upload_status[LLModel::LOD_HIGH+1]; + + bool upload_ok = true; + + for (S32 lod = 0; lod <= LLModel::LOD_HIGH; ++lod) + { + upload_status[lod] = 0; + + std::string message = "mesh_status_good"; + + if (total_tris[lod] > 0) + { + mFMP->childSetText(lod_triangles_name[lod], llformat("%d", total_tris[lod])); + mFMP->childSetText(lod_vertices_name[lod], llformat("%d", total_verts[lod])); + } + else + { + if (lod == LLModel::LOD_HIGH) + { + upload_status[lod] = 2; + message = "mesh_status_missing_lod"; + } + else + { + for (S32 i = lod-1; i >= 0; --i) + { + if (total_tris[i] > 0) + { + upload_status[lod] = 2; + message = "mesh_status_missing_lod"; + } + } + } + + mFMP->childSetText(lod_triangles_name[lod], mesh_status_na); + mFMP->childSetText(lod_vertices_name[lod], mesh_status_na); + } + + const U32 lod_high = LLModel::LOD_HIGH; + + if (lod != lod_high) + { + if (total_submeshes[lod] && total_submeshes[lod] != total_submeshes[lod_high]) + { //number of submeshes is different + message = "mesh_status_submesh_mismatch"; + upload_status[lod] = 2; + } + else if (!tris[lod].empty() && tris[lod].size() != tris[lod_high].size()) + { //number of meshes is different + message = "mesh_status_mesh_mismatch"; + upload_status[lod] = 2; + } + else if (!verts[lod].empty()) + { + for (U32 i = 0; i < verts[lod].size(); ++i) + { + S32 max_verts = i < verts[lod+1].size() ? verts[lod+1][i] : 0; + + if (max_verts > 0) + { + if (verts[lod][i] > max_verts) + { //too many vertices in this lod + message = "mesh_status_too_many_vertices"; + upload_status[lod] = 2; + } + } + } + } + } + + LLIconCtrl* icon = mFMP->getChild<LLIconCtrl>(lod_icon_name[lod]); + LLUIImagePtr img = LLUI::getUIImage(lod_status_image[upload_status[lod]]); + icon->setVisible(true); + icon->setImage(img); + + if (upload_status[lod] >= 2) + { + upload_ok = false; + } + + if (lod == mPreviewLOD) + { + mFMP->childSetText("lod_status_message_text", mFMP->getString(message)); + icon = mFMP->getChild<LLIconCtrl>("lod_status_message_icon"); + icon->setImage(img); + } + } + + bool errorStateFromLoader = getLoadState() >= LLModelLoader::ERROR_PARSING ? true : false; + + bool skinAndRigOk = true; + bool uploadingSkin = mFMP->childGetValue("upload_skin").asBoolean(); + bool uploadingJointPositions = mFMP->childGetValue("upload_joints").asBoolean(); + + if ( uploadingSkin ) + { + if ( uploadingJointPositions && !isRigValidForJointPositionUpload() ) + { + skinAndRigOk = false; + } + else + if ( !isLegacyRigValid() ) + { + skinAndRigOk = false; + } + } + + if ( upload_ok && !errorStateFromLoader && skinAndRigOk ) + { + mFMP->childEnable("ok_btn"); + } + + //add up physics triangles etc + S32 start = 0; + S32 end = mModel[LLModel::LOD_PHYSICS].size(); + + S32 phys_tris = 0; + S32 phys_hulls = 0; + S32 phys_points = 0; + + for (S32 i = start; i < end; ++i) + { //add up hulls and points and triangles for selected mesh(es) + LLModel* model = mModel[LLModel::LOD_PHYSICS][i]; + S32 cur_submeshes = model->getNumVolumeFaces(); + + LLModel::convex_hull_decomposition& decomp = model->mPhysics.mHull; + + if (!decomp.empty()) + { + phys_hulls += decomp.size(); + for (U32 i = 0; i < decomp.size(); ++i) + { + phys_points += decomp[i].size(); + } + } + else + { //choose physics shape OR decomposition, can't use both + for (S32 j = 0; j < cur_submeshes; ++j) + { //for each submesh (face), add triangles and vertices to current total + const LLVolumeFace& face = model->getVolumeFace(j); + phys_tris += face.mNumIndices/3; + } + } + } + + if (phys_tris > 0) + { + mFMP->childSetTextArg("physics_triangles", "[TRIANGLES]", llformat("%d", phys_tris)); + } + else + { + mFMP->childSetTextArg("physics_triangles", "[TRIANGLES]", mesh_status_na); + } + + if (phys_hulls > 0) + { + mFMP->childSetTextArg("physics_hulls", "[HULLS]", llformat("%d", phys_hulls)); + mFMP->childSetTextArg("physics_points", "[POINTS]", llformat("%d", phys_points)); + } + else + { + mFMP->childSetTextArg("physics_hulls", "[HULLS]", mesh_status_na); + mFMP->childSetTextArg("physics_points", "[POINTS]", mesh_status_na); + } + + LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance; + if (fmp) + { + if (phys_tris > 0 || phys_hulls > 0) + { + if (!fmp->isViewOptionEnabled("show_physics")) + { + fmp->enableViewOption("show_physics"); + mViewOption["show_physics"] = true; + } + } + else + { + fmp->disableViewOption("show_physics"); + mViewOption["show_physics"] = false; + + } + + //bool use_hull = fmp->childGetValue("physics_use_hull").asBoolean(); + + //fmp->childSetEnabled("physics_optimize", !use_hull); + + bool enable = phys_tris > 0 || phys_hulls > 0; + //enable = enable && !use_hull && fmp->childGetValue("physics_optimize").asBoolean(); + + //enable/disable "analysis" UI + LLPanel* panel = fmp->getChild<LLPanel>("physics analysis"); + LLView* child = panel->getFirstChild(); + while (child) + { + child->setEnabled(enable); + child = panel->findNextSibling(child); + } + + enable = phys_hulls > 0; + //enable/disable "simplification" UI + panel = fmp->getChild<LLPanel>("physics simplification"); + child = panel->getFirstChild(); + while (child) + { + child->setEnabled(enable); + child = panel->findNextSibling(child); + } + } + + const char* lod_controls[] = + { + "lod_mode", + "lod_triangle_limit", + "lod_error_tolerance", + "build_operator_text", + "queue_mode_text", + "border_mode_text", + "share_tolerance_text", + "build_operator", + "queue_mode", + "border_mode", + "share_tolerance" + }; + const U32 num_lod_controls = sizeof(lod_controls)/sizeof(char*); + + const char* file_controls[] = + { + "lod_browse", + "lod_file" + }; + const U32 num_file_controls = sizeof(file_controls)/sizeof(char*); + + if (fmp) + { + //enable/disable controls based on radio groups + if (mFMP->childGetValue("lod_from_file").asBoolean()) + { + fmp->mLODMode[mPreviewLOD] = 0; + for (U32 i = 0; i < num_file_controls; ++i) + { + mFMP->childEnable(file_controls[i]); + } + + for (U32 i = 0; i < num_lod_controls; ++i) + { + mFMP->childDisable(lod_controls[i]); + } + } + else if (mFMP->childGetValue("lod_none").asBoolean()) + { + fmp->mLODMode[mPreviewLOD] = 2; + for (U32 i = 0; i < num_file_controls; ++i) + { + mFMP->childDisable(file_controls[i]); + } + + for (U32 i = 0; i < num_lod_controls; ++i) + { + mFMP->childDisable(lod_controls[i]); + } + + if (!mModel[mPreviewLOD].empty()) + { + mModel[mPreviewLOD].clear(); + mScene[mPreviewLOD].clear(); + mVertexBuffer[mPreviewLOD].clear(); + + //this can cause phasing issues with the UI, so reenter this function and return + updateStatusMessages(); + return; + } + } + else + { // auto generate, also the default case for wizard which has no radio selection + fmp->mLODMode[mPreviewLOD] = 1; + + for (U32 i = 0; i < num_file_controls; ++i) + { + mFMP->childDisable(file_controls[i]); + } + + for (U32 i = 0; i < num_lod_controls; ++i) + { + mFMP->childEnable(lod_controls[i]); + } + + //if (threshold) + { + U32 lod_mode = 0; + LLCtrlSelectionInterface* iface = mFMP->childGetSelectionInterface("lod_mode"); + if (iface) + { + lod_mode = iface->getFirstSelectedIndex(); + } + + LLSpinCtrl* threshold = mFMP->getChild<LLSpinCtrl>("lod_error_threshold"); + LLSpinCtrl* limit = mFMP->getChild<LLSpinCtrl>("lod_triangle_limit"); + + limit->setMaxValue(mMaxTriangleLimit); + limit->setValue(mRequestedTriangleCount[mPreviewLOD]); + + if (lod_mode == 0) + { + limit->setVisible(true); + threshold->setVisible(false); + + limit->setMaxValue(mMaxTriangleLimit); + limit->setIncrement(mMaxTriangleLimit/32); + } + else + { + limit->setVisible(false); + threshold->setVisible(true); + } + } + } + } + + if (mFMP->childGetValue("physics_load_from_file").asBoolean()) + { + mFMP->childDisable("physics_lod_combo"); + mFMP->childEnable("physics_file"); + mFMP->childEnable("physics_browse"); + } + else + { + mFMP->childEnable("physics_lod_combo"); + mFMP->childDisable("physics_file"); + mFMP->childDisable("physics_browse"); + } +} + +void LLModelPreview::setPreviewTarget(F32 distance) +{ + mCameraDistance = distance; + mCameraZoom = 1.f; + mCameraPitch = 0.f; + mCameraYaw = 0.f; + mCameraOffset.clearVec(); +} + +void LLModelPreview::clearBuffers() +{ + for (U32 i = 0; i < 6; i++) + { + mVertexBuffer[i].clear(); + } +} + +void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) +{ + U32 tri_count = 0; + U32 vertex_count = 0; + U32 mesh_count = 0; + + + LLModelLoader::model_list* model = NULL; + + if (lod < 0 || lod > 4) + { + model = &mBaseModel; + lod = 5; + } + else + { + model = &(mModel[lod]); + } + + if (!mVertexBuffer[lod].empty()) + { + mVertexBuffer[lod].clear(); + } + + mVertexBuffer[lod].clear(); + + LLModelLoader::model_list::iterator base_iter = mBaseModel.begin(); + + for (LLModelLoader::model_list::iterator iter = model->begin(); iter != model->end(); ++iter) + { + LLModel* mdl = *iter; + if (!mdl) + { + continue; + } + + LLModel* base_mdl = *base_iter; + base_iter++; + + for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) + { + const LLVolumeFace &vf = mdl->getVolumeFace(i); + U32 num_vertices = vf.mNumVertices; + U32 num_indices = vf.mNumIndices; + + if (!num_vertices || ! num_indices) + { + continue; + } + + LLVertexBuffer* vb = NULL; + + bool skinned = include_skin_weights && !mdl->mSkinWeights.empty(); + + U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; + + if (skinned) + { + mask |= LLVertexBuffer::MAP_WEIGHT4; + } + + vb = new LLVertexBuffer(mask, 0); + + vb->allocateBuffer(num_vertices, num_indices, TRUE); + + LLStrider<LLVector3> vertex_strider; + LLStrider<LLVector3> normal_strider; + LLStrider<LLVector2> tc_strider; + LLStrider<U16> index_strider; + LLStrider<LLVector4> weights_strider; + + vb->getVertexStrider(vertex_strider); + vb->getNormalStrider(normal_strider); + vb->getTexCoord0Strider(tc_strider); + vb->getIndexStrider(index_strider); + + if (skinned) + { + vb->getWeight4Strider(weights_strider); + } + + LLVector4a::memcpyNonAliased16((F32*) vertex_strider.get(), (F32*) vf.mPositions, num_vertices*4*sizeof(F32)); + LLVector4a::memcpyNonAliased16((F32*) tc_strider.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32)); + LLVector4a::memcpyNonAliased16((F32*) normal_strider.get(), (F32*) vf.mNormals, num_vertices*4*sizeof(F32)); + + if (skinned) + { + for (U32 i = 0; i < num_vertices; i++) + { + //find closest weight to vf.mVertices[i].mPosition + LLVector3 pos(vf.mPositions[i].getF32ptr()); + + const LLModel::weight_list& weight_list = base_mdl->getJointInfluences(pos); + + LLVector4 w(0,0,0,0); + if (weight_list.size() > 4) + { + llerrs << "WTF?" << llendl; + } + + for (U32 i = 0; i < weight_list.size(); ++i) + { + F32 wght = llmin(weight_list[i].mWeight, 0.999999f); + F32 joint = (F32) weight_list[i].mJointIdx; + w.mV[i] = joint + wght; + } + + *(weights_strider++) = w; + } + } + + // build indices + for (U32 i = 0; i < num_indices; i++) + { + *(index_strider++) = vf.mIndices[i]; + } + + mVertexBuffer[lod][mdl].push_back(vb); + + vertex_count += num_vertices; + tri_count += num_indices/3; + ++mesh_count; + + } + } +} + +void LLModelPreview::update() +{ + if (mDirty) + { + mDirty = false; + mResourceCost = calcResourceCost(); + refresh(); + updateStatusMessages(); + } + + if (mGenLOD) + { + mGenLOD = false; + genLODs(); + refresh(); + updateStatusMessages(); + } + +} +//----------------------------------------------------------------------------- +// changeAvatarsJointPositions() +//----------------------------------------------------------------------------- +void LLModelPreview::changeAvatarsJointPositions( LLModel* pModel ) +{ + if ( mMasterJointList.empty() ) + { + return; + } + + std::vector<std::string> :: const_iterator jointListItBegin = pModel->mSkinInfo.mJointNames.begin(); + std::vector<std::string> :: const_iterator jointListItEnd = pModel->mSkinInfo.mJointNames.end(); + + S32 index = 0; + for ( ; jointListItBegin!=jointListItEnd; ++jointListItBegin, ++index ) + { + std::string elem = *jointListItBegin; + //llinfos<<"joint "<<elem<<llendl; + + S32 matrixCnt = pModel->mSkinInfo.mAlternateBindMatrix.size(); + if ( matrixCnt < 1 ) + { + llinfos<<"Total WTF moment :"<<matrixCnt<<llendl; + } + else + { + LLMatrix4 jointTransform = pModel->mSkinInfo.mAlternateBindMatrix[index]; + + LLJoint* pJoint = gAgentAvatarp->getJoint( elem ); + if ( pJoint ) + { + pJoint->storeCurrentXform( jointTransform.getTranslation() ); + } + } + } +} +//----------------------------------------------------------------------------- +// getTranslationForJointOffset() +//----------------------------------------------------------------------------- +LLVector3 LLModelPreview::getTranslationForJointOffset( std::string joint ) +{ + LLMatrix4 jointTransform; + if ( mJointTransformMap.find( joint ) != mJointTransformMap.end() ) + { + jointTransform = mJointTransformMap[joint]; + return jointTransform.getTranslation(); + } + return LLVector3(0.0f,0.0f,0.0f); +} +//----------------------------------------------------------------------------- +// render() +//----------------------------------------------------------------------------- +BOOL LLModelPreview::render() +{ + assert_main_thread(); + + LLMutexLock lock(this); + mNeedsUpdate = FALSE; + + bool edges = mViewOption["show_edges"]; + bool joint_positions = mViewOption["show_joint_positions"]; + bool skin_weight = mViewOption["show_skin_weight"]; + bool textures = mViewOption["show_textures"]; + bool physics = mViewOption["show_physics"]; + + S32 width = getWidth(); + S32 height = getHeight(); + + LLGLSUIDefault def; + LLGLDisable no_blend(GL_BLEND); + LLGLEnable cull(GL_CULL_FACE); + LLGLDepthTest depth(GL_TRUE); + LLGLDisable fog(GL_FOG); + + { + //clear background to blue + glMatrixMode(GL_PROJECTION); + gGL.pushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, width, 0.0f, height, -1.0f, 1.0f); + + glMatrixMode(GL_MODELVIEW); + gGL.pushMatrix(); + glLoadIdentity(); + + gGL.color4f(0.169f, 0.169f, 0.169f, 1.f); + + gl_rect_2d_simple( width, height ); + + glMatrixMode(GL_PROJECTION); + gGL.popMatrix(); + + glMatrixMode(GL_MODELVIEW); + gGL.popMatrix(); + } + + LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance; + + bool has_skin_weights = false; + bool upload_skin = mFMP->childGetValue("upload_skin").asBoolean(); + bool upload_joints = mFMP->childGetValue("upload_joints").asBoolean(); + + bool resetJoints = false; + if ( upload_joints != mLastJointUpdate ) + { + if ( mLastJointUpdate ) + { + resetJoints = true; + } + + mLastJointUpdate = upload_joints; + + } + + for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter) + { + for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter) + { + LLModelInstance& instance = *model_iter; + LLModel* model = instance.mModel; + model->mPelvisOffset = mPelvisZOffset; + if (!model->mSkinWeights.empty()) + { + has_skin_weights = true; + } + } + } + + if (has_skin_weights) + { //model has skin weights, enable view options for skin weights and joint positions + if (fmp) + { + fmp->enableViewOption("show_skin_weight"); + fmp->setViewOptionEnabled("show_joint_positions", skin_weight); + } + mFMP->childEnable("upload_skin"); + } + else + { + mFMP->childDisable("upload_skin"); + if (fmp) + { + mViewOption["show_skin_weight"] = false; + fmp->disableViewOption("show_skin_weight"); + fmp->disableViewOption("show_joint_positions"); + } + skin_weight = false; + } + + if (upload_skin && !has_skin_weights) + { //can't upload skin weights if model has no skin weights + mFMP->childSetValue("upload_skin", false); + upload_skin = false; + } + + if (!upload_skin && upload_joints) + { //can't upload joints if not uploading skin weights + mFMP->childSetValue("upload_joints", false); + upload_joints = false; + } + + mFMP->childSetEnabled("upload_joints", upload_skin); + + //poke at avatar when we upload custom joints + /* + if ( upload_joints ) + { + for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter) + { + for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter) + { + LLModelInstance& instance = *model_iter; + LLModel* model = instance.mModel; + if ( !model->mSkinWeights.empty() ) + { + changeAvatarsJointPositions( model ); + } + } + } + } + */ + + F32 explode = mFMP->childGetValue("physics_explode").asReal(); + + glClear(GL_DEPTH_BUFFER_BIT); + + LLRect preview_rect = mFMP->getChildView("preview_panel")->getRect(); + F32 aspect = (F32) preview_rect.getWidth()/preview_rect.getHeight(); + + LLViewerCamera::getInstance()->setAspect(aspect); + + LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom); + + LLVector3 offset = mCameraOffset; + LLVector3 target_pos = mPreviewTarget+offset; + + F32 z_near = 0.001f; + F32 z_far = mCameraDistance+mPreviewScale.magVec()+mCameraOffset.magVec(); + + if (skin_weight) + { + target_pos = gAgentAvatarp->getPositionAgent(); + z_near = 0.01f; + z_far = 1024.f; + mCameraDistance = 16.f; + + //render avatar previews every frame + refresh(); + } + + glLoadIdentity(); + gPipeline.enableLightsPreview(); + + LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) * + LLQuaternion(mCameraYaw, LLVector3::z_axis); + + LLQuaternion av_rot = camera_rot; + LLViewerCamera::getInstance()->setOriginAndLookAt( + target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + offset) * av_rot), // camera + LLVector3::z_axis, // up + target_pos); // point of interest + + + LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, width, height, FALSE, z_near, z_far); + + stop_glerror(); + + gGL.pushMatrix(); + const F32 BRIGHTNESS = 0.9f; + gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS); + + LLGLEnable normalize(GL_NORMALIZE); + + if (!mBaseModel.empty() && mVertexBuffer[5].empty()) + { + genBuffers(-1, skin_weight); + //genBuffers(3); + //genLODs(); + } + + if (!mModel[mPreviewLOD].empty()) + { + bool regen = mVertexBuffer[mPreviewLOD].empty(); + if (!regen) + { + const std::vector<LLPointer<LLVertexBuffer> >& vb_vec = mVertexBuffer[mPreviewLOD].begin()->second; + if (!vb_vec.empty()) + { + const LLVertexBuffer* buff = vb_vec[0]; + regen = buff->hasDataType(LLVertexBuffer::TYPE_WEIGHT4) != skin_weight; + } + } + + if (regen) + { + genBuffers(mPreviewLOD, skin_weight); + } + + if (!skin_weight) + { + for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter) + { + LLModelInstance& instance = *iter; + + LLModel* model = instance.mLOD[mPreviewLOD]; + + if (!model) + { + continue; + } + + gGL.pushMatrix(); + LLMatrix4 mat = instance.mTransform; + + glMultMatrixf((GLfloat*) mat.mMatrix); + + for (U32 i = 0; i < mVertexBuffer[mPreviewLOD][model].size(); ++i) + { + LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i]; + + buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); + + if (textures) + { + glColor4fv(instance.mMaterial[i].mDiffuseColor.mV); + if (i < instance.mMaterial.size() && instance.mMaterial[i].mDiffuseMap.notNull()) + { + if (instance.mMaterial[i].mDiffuseMap->getDiscardLevel() > -1) + { + gGL.getTexUnit(0)->bind(instance.mMaterial[i].mDiffuseMap, true); + mTextureSet.insert(instance.mMaterial[i].mDiffuseMap.get()); + } + } + } + else + { + glColor4f(1,1,1,1); + } + + buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + glColor3f(0.4f, 0.4f, 0.4f); + + if (edges) + { + glLineWidth(3.f); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glLineWidth(1.f); + } + } + gGL.popMatrix(); + } + + if (physics) + { + glClear(GL_DEPTH_BUFFER_BIT); + LLGLEnable blend(GL_BLEND); + gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_ZERO); + + for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter) + { + LLModelInstance& instance = *iter; + + LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS]; + + if (!model) + { + continue; + } + + gGL.pushMatrix(); + LLMatrix4 mat = instance.mTransform; + + glMultMatrixf((GLfloat*) mat.mMatrix); + + + bool render_mesh = true; + + LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread; + if (decomp) + { + LLMutexLock(decomp->mMutex); + + LLModel::Decomposition& physics = model->mPhysics; + + if (physics.mMesh.empty()) + { //build vertex buffer for physics mesh + gMeshRepo.buildPhysicsMesh(physics); + } + + if (!physics.mMesh.empty()) + { //render hull instead of mesh + render_mesh = false; + for (U32 i = 0; i < physics.mMesh.size(); ++i) + { + if (explode > 0.f) + { + gGL.pushMatrix(); + + LLVector3 offset = model->mHullCenter[i]-model->mCenterOfHullCenters; + offset *= explode; + + gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]); + } + + static std::vector<LLColor4U> hull_colors; + + if (i+1 >= hull_colors.size()) + { + hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 255)); + } + + glColor4ubv(hull_colors[i].mV); + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals); + + if (explode > 0.f) + { + gGL.popMatrix(); + } + } + } + } + + if (render_mesh) + { + if (mVertexBuffer[LLModel::LOD_PHYSICS].empty()) + { + genBuffers(LLModel::LOD_PHYSICS, false); + } + for (U32 i = 0; i < mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); ++i) + { + LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i]; + + buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); + + buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + glColor4f(0.4f, 0.4f, 0.0f, 0.4f); + + buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0); + + glColor3f(1.f, 1.f, 0.f); + + glLineWidth(3.f); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glLineWidth(1.f); + } + } + + gGL.popMatrix(); + } + + gGL.setSceneBlendType(LLRender::BT_ALPHA); + } + } + else + { + LLVOAvatarSelf* avatar = gAgentAvatarp; + target_pos = avatar->getPositionAgent(); + + LLViewerCamera::getInstance()->setOriginAndLookAt( + target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + offset) * av_rot), // camera + LLVector3::z_axis, // up + target_pos); // point of interest + + if (joint_positions) + { + avatar->renderCollisionVolumes(); + } + + for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter) + { + for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter) + { + LLModelInstance& instance = *model_iter; + LLModel* model = instance.mModel; + + if (!model->mSkinWeights.empty()) + { + for (U32 i = 0; i < mVertexBuffer[mPreviewLOD][model].size(); ++i) + { + LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i]; + + const LLVolumeFace& face = model->getVolumeFace(i); + + LLStrider<LLVector3> position; + buffer->getVertexStrider(position); + + LLStrider<LLVector4> weight; + buffer->getWeight4Strider(weight); + + //quick 'n dirty software vertex skinning + + //build matrix palette + + LLMatrix4 mat[64]; + for (U32 j = 0; j < model->mSkinInfo.mJointNames.size(); ++j) + { + LLJoint* joint = avatar->getJoint(model->mSkinInfo.mJointNames[j]); + if (joint) + { + mat[j] = model->mSkinInfo.mInvBindMatrix[j]; + mat[j] *= joint->getWorldMatrix(); + } + } + + for (U32 j = 0; j < buffer->getRequestedVerts(); ++j) + { + LLMatrix4 final_mat; + final_mat.mMatrix[0][0] = final_mat.mMatrix[1][1] = final_mat.mMatrix[2][2] = final_mat.mMatrix[3][3] = 0.f; + + LLVector4 wght; + S32 idx[4]; + + F32 scale = 0.f; + for (U32 k = 0; k < 4; k++) + { + F32 w = weight[j].mV[k]; + + idx[k] = (S32) floorf(w); + wght.mV[k] = w - floorf(w); + scale += wght.mV[k]; + } + + wght *= 1.f/scale; + + for (U32 k = 0; k < 4; k++) + { + F32* src = (F32*) mat[idx[k]].mMatrix; + F32* dst = (F32*) final_mat.mMatrix; + + F32 w = wght.mV[k]; + + for (U32 l = 0; l < 16; l++) + { + dst[l] += src[l]*w; + } + } + + //VECTORIZE THIS + LLVector3 v(face.mPositions[j].getF32ptr()); + + v = v * model->mSkinInfo.mBindShapeMatrix; + v = v * final_mat; + + position[j] = v; + } + + buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); + glColor4fv(instance.mMaterial[i].mDiffuseColor.mV); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0); + glColor3f(0.4f, 0.4f, 0.4f); + + if (edges) + { + glLineWidth(3.f); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glLineWidth(1.f); + } + } + } + } + } + } + } + + gGL.popMatrix(); + + return TRUE; +} + +//----------------------------------------------------------------------------- +// refresh() +//----------------------------------------------------------------------------- +void LLModelPreview::refresh() +{ + mNeedsUpdate = TRUE; +} + +//----------------------------------------------------------------------------- +// rotate() +//----------------------------------------------------------------------------- +void LLModelPreview::rotate(F32 yaw_radians, F32 pitch_radians) +{ + mCameraYaw = mCameraYaw + yaw_radians; + + mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f); +} + +//----------------------------------------------------------------------------- +// zoom() +//----------------------------------------------------------------------------- +void LLModelPreview::zoom(F32 zoom_amt) +{ + F32 new_zoom = mCameraZoom+zoom_amt; + + mCameraZoom = llclamp(new_zoom, 1.f, 10.f); +} + +void LLModelPreview::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); +} + +void LLModelPreview::setPreviewLOD(S32 lod) +{ + lod = llclamp(lod, 0, (S32) LLModel::LOD_HIGH); + + if (lod != mPreviewLOD) + { + mPreviewLOD = lod; + + LLComboBox* combo_box = mFMP->getChild<LLComboBox>("preview_lod_combo"); + combo_box->setCurrentByIndex((NUM_LOD-1)-mPreviewLOD); // combo box list of lods is in reverse order + mFMP->childSetTextArg("lod_table_footer", "[DETAIL]", mFMP->getString(lod_name[mPreviewLOD])); + mFMP->childSetText("lod_file", mLODFile[mPreviewLOD]); + + // the wizard has three lod drop downs + LLComboBox* combo_box2 = mFMP->getChild<LLComboBox>("preview_lod_combo2"); + combo_box2->setCurrentByIndex((NUM_LOD-1)-mPreviewLOD); // combo box list of lods is in reverse order + + LLComboBox* combo_box3 = mFMP->getChild<LLComboBox>("preview_lod_combo3"); + combo_box3->setCurrentByIndex((NUM_LOD-1)-mPreviewLOD); // combo box list of lods is in reverse order + + LLColor4 highlight_color = LLUIColorTable::instance().getColor("MeshImportTableHighlightColor"); + LLColor4 normal_color = LLUIColorTable::instance().getColor("MeshImportTableNormalColor"); + + for (S32 i = 0; i <= LLModel::LOD_HIGH; ++i) + { + const LLColor4& color = (i == lod) ? highlight_color : normal_color; + + mFMP->childSetColor(lod_status_name[i], color); + mFMP->childSetColor(lod_label_name[i], color); + mFMP->childSetColor(lod_triangles_name[i], color); + mFMP->childSetColor(lod_vertices_name[i], color); + } + + LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance; + if (fmp) + { + LLRadioGroup* radio = fmp->getChild<LLRadioGroup>("lod_file_or_limit"); + radio->selectNthItem(fmp->mLODMode[mPreviewLOD]); + } + } + refresh(); + updateStatusMessages(); +} + +//static +void LLFloaterModelPreview::onBrowseLOD(void* data) +{ + assert_main_thread(); + + LLFloaterModelPreview* mp = (LLFloaterModelPreview*) data; + mp->loadModel(mp->mModelPreview->mPreviewLOD); +} + +//static +void LLFloaterModelPreview::onReset(void* user_data) +{ + assert_main_thread(); + + LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) user_data; + LLModelPreview* mp = fmp->mModelPreview; + std::string filename = mp->mLODFile[3]; + mp->loadModel(filename,3); +} + +//static +void LLFloaterModelPreview::onUpload(void* user_data) +{ + assert_main_thread(); + + LLFloaterModelPreview* mp = (LLFloaterModelPreview*) user_data; + + mp->mModelPreview->rebuildUploadData(); + + bool upload_skinweights = mp->childGetValue("upload_skin").asBoolean(); + bool upload_joint_positions = mp->childGetValue("upload_joints").asBoolean(); + + mp->mModelPreview->saveUploadData(upload_skinweights, upload_joint_positions); + + gMeshRepo.uploadModel(mp->mModelPreview->mUploadData, mp->mModelPreview->mPreviewScale, + mp->childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions); + + mp->closeFloater(false); +} + + +//static +void LLFloaterModelPreview::onClearMaterials(void* user_data) +{ + LLFloaterModelPreview* mp = (LLFloaterModelPreview*) user_data; + mp->mModelPreview->clearMaterials(); +} + +//static +void LLFloaterModelPreview::refresh(LLUICtrl* ctrl, void* user_data) +{ + sInstance->mModelPreview->mDirty = true; +} + +void LLFloaterModelPreview::updateResourceCost() +{ + U32 cost = mModelPreview->mResourceCost; + childSetLabelArg("ok_btn", "[AMOUNT]", llformat("%d",cost)); +} + +//static +void LLModelPreview::textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ) +{ + LLModelPreview* preview = (LLModelPreview*) userdata; + preview->refresh(); +} + +void LLModelPreview::onLODParamCommit(bool enforce_tri_limit) +{ + genLODs(mPreviewLOD, 3, enforce_tri_limit); + updateStatusMessages(); + refresh(); +} + +LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LLModel* mdl) +{ + mStage = stage; + mContinue = 1; + mModel = mdl; + mDecompID = &mdl->mDecompID; + mParams = sInstance->mDecompParams; + + //copy out positions and indices + if (mdl) + { + U16 index_offset = 0; + + mPositions.clear(); + mIndices.clear(); + + //queue up vertex positions and indices + for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) + { + const LLVolumeFace& face = mdl->getVolumeFace(i); + if (mPositions.size() + face.mNumVertices > 65535) + { + continue; + } + + for (U32 j = 0; j < face.mNumVertices; ++j) + { + mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr())); + } + + for (U32 j = 0; j < face.mNumIndices; ++j) + { + mIndices.push_back(face.mIndices[j]+index_offset); + } + + index_offset += face.mNumVertices; + } + } +} + +void LLFloaterModelPreview::setStatusMessage(const std::string& msg) +{ + LLMutexLock lock(mStatusLock); + mStatusMessage = msg; +} + +S32 LLFloaterModelPreview::DecompRequest::statusCallback(const char* status, S32 p1, S32 p2) +{ + if (mContinue) + { + setStatusMessage(llformat("%s: %d/%d", status, p1, p2)); + if (LLFloaterModelPreview::sInstance) + { + LLFloaterModelPreview::sInstance->setStatusMessage(mStatusMessage); + } + } + + return mContinue; +} + +void LLFloaterModelPreview::DecompRequest::completed() +{ //called from the main thread + if (mContinue) + { + mModel->setConvexHullDecomposition(mHull); + + if (sInstance) + { + if (mContinue) + { + if (sInstance->mModelPreview) + { + sInstance->mModelPreview->mDirty = true; + LLFloaterModelPreview::sInstance->mModelPreview->refresh(); + } + } + + sInstance->mCurRequest.erase(this); + } + } + else if (sInstance) + { + llassert(sInstance->mCurRequest.find(this) == sInstance->mCurRequest.end()); + } +} diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h new file mode 100644 index 0000000000..4d8b46807f --- /dev/null +++ b/indra/newview/llfloatermodelpreview.h @@ -0,0 +1,420 @@ +/** + * @file llfloatermodelpreview.h + * @brief LLFloaterModelPreview 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$ + */ + +#ifndef LL_LLFLOATERMODELPREVIEW_H +#define LL_LLFLOATERMODELPREVIEW_H + +#include "llfloaternamedesc.h" + +#include "lldynamictexture.h" +#include "llfloatermodelwizard.h" +#include "llquaternion.h" +#include "llmeshrepository.h" +#include "llmodel.h" +#include "llthread.h" +#include "llviewermenufile.h" + +class LLComboBox; +class LLJoint; +class LLViewerJointMesh; +class LLVOAvatar; +class LLTextBox; +class LLVertexBuffer; +class LLModelPreview; +class LLFloaterModelPreview; +class daeElement; +class domProfile_COMMON; +class domInstance_geometry; +class domNode; +class domTranslate; +class LLMenuButton; +class LLToggleableMenu; + +typedef std::map<std::string, LLMatrix4> JointTransformMap; +typedef std::map<std::string, LLMatrix4>:: iterator JointTransformMapIt; + +const S32 NUM_LOD = 4; + +class LLModelLoader : public LLThread +{ +public: + typedef enum + { + STARTING = 0, + READING_FILE, + CREATING_FACES, + GENERATING_VERTEX_BUFFERS, + GENERATING_LOD, + DONE, + ERROR_PARSING //basically loading failed + } eLoadState; + + U32 mState; + std::string mFilename; + S32 mLod; + LLModelPreview* mPreview; + LLMatrix4 mTransform; + BOOL mFirstTransform; + LLVector3 mExtents[2]; + bool mTrySLM; + + std::map<daeElement*, LLPointer<LLModel> > mModel; + + typedef std::vector<LLPointer<LLModel> > model_list; + model_list mModelList; + + typedef std::vector<LLModelInstance> model_instance_list; + + typedef std::map<LLMatrix4, model_instance_list > scene; + + scene mScene; + + typedef std::queue<LLPointer<LLModel> > model_queue; + + //queue of models that need a physics rep + model_queue mPhysicsQ; + + LLModelLoader( std::string filename, S32 lod, LLModelPreview* preview, JointTransformMap& jointMap, + std::deque<std::string>& jointsFromNodes ); + ~LLModelLoader() ; + + virtual void run(); + bool doLoadModel(); + bool loadFromSLM(const std::string& filename); + void loadModelCallback(); + + void loadTextures() ; //called in the main thread. + void processElement(daeElement* element); + std::vector<LLImportMaterial> getMaterials(LLModel* model, domInstance_geometry* instance_geo); + LLImportMaterial profileToMaterial(domProfile_COMMON* material); + std::string getElementLabel(daeElement *element); + LLColor4 getDaeColor(daeElement* element); + + daeElement* getChildFromElement( daeElement* pElement, std::string const & name ); + + bool isNodeAJoint( domNode* pNode ); + void processJointNode( domNode* pNode, std::map<std::string,LLMatrix4>& jointTransforms ); + void extractTranslation( domTranslate* pTranslate, LLMatrix4& transform ); + void extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform ); + + void setLoadState(U32 state); + + void buildJointToNodeMappingFromScene( daeElement* pRoot ); + void processJointToNodeMapping( domNode* pNode ); + + + //map of avatar joints as named in COLLADA assets to internal joint names + std::map<std::string, std::string> mJointMap; + JointTransformMap& mJointList; + std::deque<std::string>& mJointsFromNode; + +private: + static std::list<LLModelLoader*> sActiveLoaderList; + static bool isAlive(LLModelLoader* loader) ; +}; + +class LLFloaterModelPreview : public LLFloater +{ +public: + + class DecompRequest : public LLPhysicsDecomp::Request + { + public: + S32 mContinue; + LLPointer<LLModel> mModel; + + DecompRequest(const std::string& stage, LLModel* mdl); + virtual S32 statusCallback(const char* status, S32 p1, S32 p2); + virtual void completed(); + + }; + static LLFloaterModelPreview* sInstance; + + LLFloaterModelPreview(const LLSD& key); + virtual ~LLFloaterModelPreview(); + + virtual BOOL postBuild(); + + BOOL handleMouseDown(S32 x, S32 y, MASK mask); + BOOL handleMouseUp(S32 x, S32 y, MASK mask); + BOOL handleHover(S32 x, S32 y, MASK mask); + BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + + static void onMouseCaptureLostModelPreview(LLMouseHandler*); + static void setUploadAmount(S32 amount) { sUploadAmount = amount; } + + void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost); + + static void onBrowseLOD(void* data); + + static void onReset(void* data); + + static void onUpload(void* data); + + static void onClearMaterials(void* data); + + static void refresh(LLUICtrl* ctrl, void* data); + + void updateResourceCost(); + + void loadModel(S32 lod); + + void onViewOptionChecked(const LLSD& userdata); + bool isViewOptionChecked(const LLSD& userdata); + bool isViewOptionEnabled(const LLSD& userdata); + void setViewOptionEnabled(const std::string& option, bool enabled); + void enableViewOption(const std::string& option); + void disableViewOption(const std::string& option); + +protected: + friend class LLModelPreview; + friend class LLMeshFilePicker; + friend class LLPhysicsDecomp; + + static void onImportScaleCommit(LLUICtrl*, void*); + static void onPelvisOffsetCommit(LLUICtrl*, void*); + static void onUploadJointsCommit(LLUICtrl*,void*); + static void onUploadSkinCommit(LLUICtrl*,void*); + + static void onPreviewLODCommit(LLUICtrl*,void*); + + static void onGenerateNormalsCommit(LLUICtrl*,void*); + + static void onAutoFillCommit(LLUICtrl*,void*); + static void onLODParamCommit(LLUICtrl*,void*); + static void onLODParamCommitTriangleLimit(LLUICtrl*,void*); + + static void onExplodeCommit(LLUICtrl*, void*); + + static void onPhysicsParamCommit(LLUICtrl* ctrl, void* userdata); + static void onPhysicsStageExecute(LLUICtrl* ctrl, void* userdata); + static void onCancel(LLUICtrl* ctrl, void* userdata); + static void onPhysicsStageCancel(LLUICtrl* ctrl, void* userdata); + + static void onPhysicsBrowse(LLUICtrl* ctrl, void* userdata); + static void onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata); + static void onPhysicsOptimize(LLUICtrl* ctrl, void* userdata); + static void onPhysicsDecomposeBack(LLUICtrl* ctrl, void* userdata); + static void onPhysicsSimplifyBack(LLUICtrl* ctrl, void* userdata); + + void draw(); + + void initDecompControls(); + + void setStatusMessage(const std::string& msg); + + LLModelPreview* mModelPreview; + + LLPhysicsDecomp::decomp_params mDecompParams; + + S32 mLastMouseX; + S32 mLastMouseY; + LLRect mPreviewRect; + U32 mGLName; + static S32 sUploadAmount; + + std::set<LLPointer<DecompRequest> > mCurRequest; + std::string mStatusMessage; + + //use "disabled" as false by default + std::map<std::string, bool> mViewOptionDisabled; + + //store which lod mode each LOD is using + // 0 - load from file + // 1 - auto generate + // 2 - None + S32 mLODMode[4]; + + LLMenuButton* mViewOptionMenuButton; + LLToggleableMenu* mViewOptionMenu; + LLMutex* mStatusLock; + +}; + +class LLMeshFilePicker : public LLFilePickerThread +{ +public: + LLMeshFilePicker(LLModelPreview* mp, S32 lod); + virtual void notify(const std::string& filename); + +private: + LLModelPreview* mMP; + S32 mLOD; +}; + + +class LLModelPreview : public LLViewerDynamicTexture, public LLMutex +{ + typedef boost::signals2::signal<void (F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost)> details_signal_t; + typedef boost::signals2::signal<void (void)> model_loaded_signal_t; + +public: + LLModelPreview(S32 width, S32 height, LLFloater* fmp); + virtual ~LLModelPreview(); + + void resetPreviewTarget(); + void setPreviewTarget(F32 distance); + void setTexture(U32 name) { mTextureName = name; } + + void setPhysicsFromLOD(S32 lod); + BOOL render(); + void update(); + void genBuffers(S32 lod, bool skinned); + void clearBuffers(); + void refresh(); + void rotate(F32 yaw_radians, F32 pitch_radians); + void zoom(F32 zoom_amt); + void pan(F32 right, F32 up); + virtual BOOL needsRender() { return mNeedsUpdate; } + void setPreviewLOD(S32 lod); + void clearModel(S32 lod); + void loadModel(std::string filename, S32 lod); + void loadModelCallback(S32 lod); + void genLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false); + void generateNormals(); + void clearMaterials(); + U32 calcResourceCost(); + void rebuildUploadData(); + void saveUploadData(bool save_skinweights, bool save_joint_poisitions); + void saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_poisitions); + void clearIncompatible(S32 lod); + void updateStatusMessages(); + void clearGLODGroup(); + void onLODParamCommit(bool enforce_tri_limit); + + const bool getModelPivot( void ) const { return mHasPivot; } + void setHasPivot( bool val ) { mHasPivot = val; } + void setModelPivot( const LLVector3& pivot ) { mModelPivot = pivot; } + + //Sets the current avatars joints to new positions + //Makes in world go to shit, however + void changeAvatarsJointPositions( LLModel* pModel ); + //Determines the viability of an asset to be used as an avatar rig (w or w/o joint upload caps) + void critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset ); + void critiqueJointToNodeMappingFromScene( void ); + //Is a rig valid so that it can be used as a criteria for allowing for uploading of joint positions + //Accessors for joint position upload friendly rigs + const bool isRigValidForJointPositionUpload( void ) const { return mRigValidJointUpload; } + void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; } + bool isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset ); + //Determines if a rig is a legacy from the joint list + bool isRigLegacy( const std::vector<std::string> &jointListFromAsset ); + //Accessors for the legacy rigs + const bool isLegacyRigValid( void ) const { return mLegacyRigValid; } + void setLegacyRigValid( bool rigValid ) { mLegacyRigValid = rigValid; } + + static void textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); + + boost::signals2::connection setDetailsCallback( const details_signal_t::slot_type& cb ){ return mDetailsSignal.connect(cb); } + boost::signals2::connection setModelLoadedCallback( const model_loaded_signal_t::slot_type& cb ){ return mModelLoadedSignal.connect(cb); } + + void setLoadState( U32 state ) { mLoadState = state; } + U32 getLoadState() { return mLoadState; } + //setRestJointFlag: If an asset comes through that changes the joints, we want the reset to persist + void setResetJointFlag( bool state ) { if ( !mResetJoints ) mResetJoints = state; } + const bool getResetJointFlag( void ) const { return mResetJoints; } + void setRigWithSceneParity( bool state ) { mRigParityWithScene = state; } + const bool getRigWithSceneParity( void ) const { return mRigParityWithScene; } + + LLVector3 getTranslationForJointOffset( std::string joint ); + + protected: + friend class LLModelLoader; + friend class LLFloaterModelPreview; + friend class LLFloaterModelWizard; + friend class LLFloaterModelPreview::DecompRequest; + friend class LLFloaterModelWizard::DecompRequest; + friend class LLPhysicsDecomp; + + LLFloater* mFMP; + + BOOL mNeedsUpdate; + bool mDirty; + bool mGenLOD; + U32 mTextureName; + F32 mCameraDistance; + F32 mCameraYaw; + F32 mCameraPitch; + F32 mCameraZoom; + LLVector3 mCameraOffset; + LLVector3 mPreviewTarget; + LLVector3 mPreviewScale; + S32 mPreviewLOD; + U32 mResourceCost; + std::string mLODFile[LLModel::NUM_LODS]; + bool mLoading; + U32 mLoadState; + bool mResetJoints; + bool mRigParityWithScene; + + std::map<std::string, bool> mViewOption; + + //GLOD object parameters (must rebuild object if these change) + F32 mBuildShareTolerance; + U32 mBuildQueueMode; + U32 mBuildOperator; + U32 mBuildBorderMode; + S32 mRequestedTriangleCount[LLModel::NUM_LODS]; + + + LLModelLoader* mModelLoader; + + LLModelLoader::scene mScene[LLModel::NUM_LODS]; + LLModelLoader::scene mBaseScene; + + LLModelLoader::model_list mModel[LLModel::NUM_LODS]; + LLModelLoader::model_list mBaseModel; + + U32 mGroup; + std::map<LLPointer<LLModel>, U32> mObject; + U32 mMaxTriangleLimit; + + LLMeshUploadThread::instance_list mUploadData; + std::set<LLViewerFetchedTexture* > mTextureSet; + + //map of vertex buffers to models (one vertex buffer in vector per face in model + std::map<LLModel*, std::vector<LLPointer<LLVertexBuffer> > > mVertexBuffer[LLModel::NUM_LODS+1]; + + details_signal_t mDetailsSignal; + model_loaded_signal_t mModelLoadedSignal; + + LLVector3 mModelPivot; + bool mHasPivot; + + float mPelvisZOffset; + + bool mRigValidJointUpload; + bool mLegacyRigValid; + + bool mLastJointUpdate; + + std::deque<std::string> mMasterJointList; + std::deque<std::string> mMasterLegacyJointList; + std::deque<std::string> mJointsFromNode; + JointTransformMap mJointTransformMap; +}; + +#endif // LL_LLFLOATERMODELPREVIEW_H diff --git a/indra/newview/llfloatermodelwizard.cpp b/indra/newview/llfloatermodelwizard.cpp new file mode 100644 index 0000000000..faf81dbc5c --- /dev/null +++ b/indra/newview/llfloatermodelwizard.cpp @@ -0,0 +1,679 @@ +/** + * @file llfloatermodelwizard.cpp + * @author Leyla Farazha + * @brief Implementation of the LLFloaterModelWizard 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$ + */ + + +#include "llviewerprecompiledheaders.h" + +#include "llbutton.h" +#include "lldrawable.h" +#include "llcheckboxctrl.h" +#include "llcombobox.h" +#include "llfloater.h" +#include "llfloatermodelwizard.h" +#include "llfloatermodelpreview.h" +#include "llfloaterreg.h" +#include "llsliderctrl.h" +#include "lltoolmgr.h" +#include "llviewerwindow.h" + +LLFloaterModelWizard* LLFloaterModelWizard::sInstance = NULL; + +static const std::string stateNames[]={ + "choose_file", + "optimize", + "physics", + "physics2", + "review", + "upload"}; + +LLFloaterModelWizard::LLFloaterModelWizard(const LLSD& key) + : LLFloater(key) +{ + mLastEnabledState = CHOOSE_FILE; + sInstance = this; + + mCommitCallbackRegistrar.add("Wizard.Choose", boost::bind(&LLFloaterModelWizard::setState, this, CHOOSE_FILE)); + mCommitCallbackRegistrar.add("Wizard.Optimize", boost::bind(&LLFloaterModelWizard::setState, this, OPTIMIZE)); + mCommitCallbackRegistrar.add("Wizard.Physics", boost::bind(&LLFloaterModelWizard::setState, this, PHYSICS)); + mCommitCallbackRegistrar.add("Wizard.Physics2", boost::bind(&LLFloaterModelWizard::setState, this, PHYSICS2)); + mCommitCallbackRegistrar.add("Wizard.Review", boost::bind(&LLFloaterModelWizard::setState, this, REVIEW)); + mCommitCallbackRegistrar.add("Wizard.Upload", boost::bind(&LLFloaterModelWizard::setState, this, UPLOAD)); +} +LLFloaterModelWizard::~LLFloaterModelWizard() +{ + sInstance = NULL; +} +void LLFloaterModelWizard::setState(int state) +{ + + mState = state; + + for(size_t t=0; t<LL_ARRAY_SIZE(stateNames); ++t) + { + LLView *view = getChildView(stateNames[t]+"_panel"); + if (view) + { + view->setVisible(state == (int) t ? TRUE : FALSE); + } + } + + if (state == CHOOSE_FILE) + { + mModelPreview->mViewOption["show_physics"] = false; + + getChildView("close")->setVisible(false); + getChildView("back")->setVisible(true); + getChildView("back")->setEnabled(false); + getChildView("next")->setVisible(true); + getChildView("upload")->setVisible(false); + getChildView("cancel")->setVisible(true); + } + + if (state == OPTIMIZE) + { + if (mLastEnabledState < state) + { + mModelPreview->genLODs(-1); + } + + mModelPreview->mViewOption["show_physics"] = false; + + getChildView("back")->setVisible(true); + getChildView("back")->setEnabled(true); + getChildView("close")->setVisible(false); + getChildView("next")->setVisible(true); + getChildView("upload")->setVisible(false); + getChildView("cancel")->setVisible(true); + } + + if (state == PHYSICS) + { + if (mLastEnabledState < state) + { + mModelPreview->setPhysicsFromLOD(1); + } + + mModelPreview->mViewOption["show_physics"] = true; + + getChildView("next")->setVisible(true); + getChildView("upload")->setVisible(false); + getChildView("close")->setVisible(false); + getChildView("back")->setVisible(true); + getChildView("back")->setEnabled(true); + getChildView("cancel")->setVisible(true); + } + + if (state == PHYSICS2) + { + if (mLastEnabledState < state) + { + executePhysicsStage("Decompose"); + } + + mModelPreview->mViewOption["show_physics"] = true; + + getChildView("next")->setVisible(true); + getChildView("next")->setEnabled(true); + getChildView("upload")->setVisible(false); + getChildView("close")->setVisible(false); + getChildView("back")->setVisible(true); + getChildView("back")->setEnabled(true); + getChildView("cancel")->setVisible(true); + } + + if (state == REVIEW) + { + + mModelPreview->mViewOption["show_physics"] = false; + + getChildView("close")->setVisible(false); + getChildView("next")->setVisible(false); + getChildView("back")->setVisible(true); + getChildView("back")->setEnabled(true); + getChildView("upload")->setVisible(true); + getChildView("cancel")->setVisible(true); + } + + if (state == UPLOAD) + { + getChildView("close")->setVisible(true); + getChildView("next")->setVisible(false); + getChildView("back")->setVisible(false); + getChildView("upload")->setVisible(false); + getChildView("cancel")->setVisible(false); + } + + updateButtons(); +} + + + +void LLFloaterModelWizard::updateButtons() +{ + if (mLastEnabledState < mState) + { + mLastEnabledState = mState; + } + + for(size_t i=0; i<LL_ARRAY_SIZE(stateNames); ++i) + { + LLButton *button = getChild<LLButton>(stateNames[i]+"_btn"); + + if (i == mState) + { + button->setEnabled(TRUE); + button->setToggleState(TRUE); + } + else if (i <= mLastEnabledState) + { + button->setEnabled(TRUE); + button->setToggleState(FALSE); + } + else + { + button->setEnabled(FALSE); + } + } + + LLButton *physics_button = getChild<LLButton>(stateNames[PHYSICS]+"_btn"); + + if (mState == PHYSICS2) + { + physics_button->setVisible(false); + } + else + { + physics_button->setVisible(true); + } + +} + +void LLFloaterModelWizard::loadModel() +{ + mModelPreview->mLoading = TRUE; + + (new LLMeshFilePicker(mModelPreview, 3))->getFile(); +} + +void LLFloaterModelWizard::onClickCancel() +{ + closeFloater(); +} + +void LLFloaterModelWizard::onClickBack() +{ + setState(llmax((int) CHOOSE_FILE, mState-1)); +} + +void LLFloaterModelWizard::onClickNext() +{ + setState(llmin((int) UPLOAD, mState+1)); +} + +bool LLFloaterModelWizard::onEnableNext() +{ + return true; +} + +bool LLFloaterModelWizard::onEnableBack() +{ + return true; +} + + +//----------------------------------------------------------------------------- +// handleMouseDown() +//----------------------------------------------------------------------------- +BOOL LLFloaterModelWizard::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; + } + + return LLFloater::handleMouseDown(x, y, mask); +} + +//----------------------------------------------------------------------------- +// handleMouseUp() +//----------------------------------------------------------------------------- +BOOL LLFloaterModelWizard::handleMouseUp(S32 x, S32 y, MASK mask) +{ + gFocusMgr.setMouseCapture(FALSE); + gViewerWindow->showCursor(); + return LLFloater::handleMouseUp(x, y, mask); +} + +//----------------------------------------------------------------------------- +// handleHover() +//----------------------------------------------------------------------------- +BOOL LLFloaterModelWizard::handleHover (S32 x, S32 y, MASK mask) +{ + MASK local_mask = mask & ~MASK_ALT; + + if (mModelPreview && hasMouseCapture()) + { + if (local_mask == MASK_PAN) + { + // pan here + mModelPreview->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; + + mModelPreview->rotate(yaw_radians, pitch_radians); + } + else + { + + F32 yaw_radians = (F32)(x - mLastMouseX) * -0.01f; + F32 zoom_amt = (F32)(y - mLastMouseY) * 0.02f; + + mModelPreview->rotate(yaw_radians, 0.f); + mModelPreview->zoom(zoom_amt); + } + + + mModelPreview->refresh(); + + LLUI::setMousePositionLocal(this, mLastMouseX, mLastMouseY); + } + + if (!mPreviewRect.pointInRect(x, y) || !mModelPreview) + { + 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; +} + +//----------------------------------------------------------------------------- +// handleScrollWheel() +//----------------------------------------------------------------------------- +BOOL LLFloaterModelWizard::handleScrollWheel(S32 x, S32 y, S32 clicks) +{ + if (mPreviewRect.pointInRect(x, y) && mModelPreview) + { + mModelPreview->zoom((F32)clicks * -0.2f); + mModelPreview->refresh(); + } + + return TRUE; +} + +void LLFloaterModelWizard::initDecompControls() +{ + LLSD key; + + static const LLCDStageData* stage = NULL; + static S32 stage_count = 0; + + if (!stage && LLConvexDecomposition::getInstance() != NULL) + { + stage_count = LLConvexDecomposition::getInstance()->getStages(&stage); + } + + static const LLCDParam* param = NULL; + static S32 param_count = 0; + if (!param && LLConvexDecomposition::getInstance() != NULL) + { + param_count = LLConvexDecomposition::getInstance()->getParameters(¶m); + } + + for (S32 j = stage_count-1; j >= 0; --j) + { + gMeshRepo.mDecompThread->mStageID[stage[j].mName] = j; + // protected against stub by stage_count being 0 for stub above + LLConvexDecomposition::getInstance()->registerCallback(j, LLPhysicsDecomp::llcdCallback); + + for (S32 i = 0; i < param_count; ++i) + { + if (param[i].mStage != j) + { + continue; + } + + std::string name(param[i].mName ? param[i].mName : ""); + std::string description(param[i].mDescription ? param[i].mDescription : ""); + + if (param[i].mType == LLCDParam::LLCD_FLOAT) + { + mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mFloat); + } + else if (param[i].mType == LLCDParam::LLCD_INTEGER) + { + mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue); + } + else if (param[i].mType == LLCDParam::LLCD_BOOLEAN) + { + mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mBool); + } + else if (param[i].mType == LLCDParam::LLCD_ENUM) + { + mDecompParams[param[i].mName] = LLSD(param[i].mDefault.mIntOrEnumValue); + } + } + } + + mDecompParams["Simplify Method"] = 0; // set it to retain % +} + +//static +void LLFloaterModelWizard::executePhysicsStage(std::string stage_name) +{ + if (sInstance) + { + F64 physics_accuracy = sInstance->getChild<LLSliderCtrl>("physics_slider")->getValue().asReal(); + + sInstance->mDecompParams["Retain%"] = physics_accuracy; + + if (!sInstance->mCurRequest.empty()) + { + llinfos << "Decomposition request still pending." << llendl; + return; + } + + if (sInstance->mModelPreview) + { + for (S32 i = 0; i < sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS].size(); ++i) + { + LLModel* mdl = sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS][i]; + DecompRequest* request = new DecompRequest(stage_name, mdl); + sInstance->mCurRequest.insert(request); + gMeshRepo.mDecompThread->submitRequest(request); + } + } + } +} + +LLFloaterModelWizard::DecompRequest::DecompRequest(const std::string& stage, LLModel* mdl) +{ + mStage = stage; + mContinue = 1; + mModel = mdl; + mDecompID = &mdl->mDecompID; + mParams = sInstance->mDecompParams; + + //copy out positions and indices + if (mdl) + { + U16 index_offset = 0; + + mPositions.clear(); + mIndices.clear(); + + //queue up vertex positions and indices + for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) + { + const LLVolumeFace& face = mdl->getVolumeFace(i); + if (mPositions.size() + face.mNumVertices > 65535) + { + continue; + } + + for (U32 j = 0; j < face.mNumVertices; ++j) + { + mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr())); + } + + for (U32 j = 0; j < face.mNumIndices; ++j) + { + mIndices.push_back(face.mIndices[j]+index_offset); + } + + index_offset += face.mNumVertices; + } + } +} + + +S32 LLFloaterModelWizard::DecompRequest::statusCallback(const char* status, S32 p1, S32 p2) +{ + setStatusMessage(llformat("%s: %d/%d", status, p1, p2)); + + return mContinue; +} + +void LLFloaterModelWizard::DecompRequest::completed() +{ //called from the main thread + mModel->setConvexHullDecomposition(mHull); + + if (sInstance) + { + if (sInstance->mModelPreview) + { + sInstance->mModelPreview->mDirty = true; + LLFloaterModelWizard::sInstance->mModelPreview->refresh(); + } + + sInstance->mCurRequest.erase(this); + } + + if (mStage == "Decompose") + { + executePhysicsStage("Simplify"); + } +} + + +BOOL LLFloaterModelWizard::postBuild() +{ + LLView* preview_panel = getChildView("preview_panel"); + + childSetValue("import_scale", (F32) 0.67335826); + + getChild<LLUICtrl>("browse")->setCommitCallback(boost::bind(&LLFloaterModelWizard::loadModel, this)); + //getChild<LLUICtrl>("lod_file")->setCommitCallback(boost::bind(&LLFloaterModelWizard::loadModel, this)); + getChild<LLUICtrl>("cancel")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickCancel, this)); + getChild<LLUICtrl>("close")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickCancel, this)); + getChild<LLUICtrl>("back")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickBack, this)); + getChild<LLUICtrl>("next")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onClickNext, this)); + getChild<LLUICtrl>("preview_lod_combo")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onPreviewLODCommit, this, _1)); + getChild<LLUICtrl>("preview_lod_combo2")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onPreviewLODCommit, this, _1)); + getChild<LLUICtrl>("preview_lod_combo3")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onPreviewLODCommit, this, _1)); + getChild<LLUICtrl>("accuracy_slider")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onAccuracyPerformance, this, _2)); + getChild<LLUICtrl>("upload")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onUpload, this)); + getChild<LLUICtrl>("physics_slider")->setCommitCallback(boost::bind(&LLFloaterModelWizard::onPhysicsChanged, this)); + + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + + enable_registrar.add("Next.OnEnable", boost::bind(&LLFloaterModelWizard::onEnableNext, this)); + enable_registrar.add("Back.OnEnable", boost::bind(&LLFloaterModelWizard::onEnableBack, this)); + + + mPreviewRect = preview_panel->getRect(); + + mModelPreview = new LLModelPreview(512, 512, this); + mModelPreview->setPreviewTarget(16.f); + mModelPreview->setDetailsCallback(boost::bind(&LLFloaterModelWizard::setDetails, this, _1, _2, _3, _4, _5)); + mModelPreview->setModelLoadedCallback(boost::bind(&LLFloaterModelWizard::modelLoadedCallback, this)); + mModelPreview->mViewOption["show_textures"] = true; + + center(); + + setState(CHOOSE_FILE); + + childSetTextArg("import_dimensions", "[X]", LLStringUtil::null); + childSetTextArg("import_dimensions", "[Y]", LLStringUtil::null); + childSetTextArg("import_dimensions", "[Z]", LLStringUtil::null); + + initDecompControls(); + + return TRUE; +} + + +void LLFloaterModelWizard::setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost) +{ + // iterate through all the panels, setting the dimensions + for(size_t t=0; t<LL_ARRAY_SIZE(stateNames); ++t) + { + LLPanel *panel = getChild<LLPanel>(stateNames[t]+"_panel"); + if (panel) + { + panel->childSetText("dimension_x", llformat("%.1f", x)); + panel->childSetText("dimension_y", llformat("%.1f", y)); + panel->childSetText("dimension_z", llformat("%.1f", z)); + panel->childSetTextArg("streaming cost", "[COST]", llformat("%.3f", streaming_cost)); + panel->childSetTextArg("physics cost", "[COST]", llformat("%.3f", physics_cost)); + } + } +} + +void LLFloaterModelWizard::modelLoadedCallback() +{ + mLastEnabledState = CHOOSE_FILE; + getChild<LLCheckBoxCtrl>("confirm_checkbox")->set(FALSE); + updateButtons(); +} + +void LLFloaterModelWizard::onPhysicsChanged() +{ + mLastEnabledState = PHYSICS; + updateButtons(); +} + +void LLFloaterModelWizard::onUpload() +{ + mModelPreview->rebuildUploadData(); + + gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale, + true, false, false); + + setState(UPLOAD); + +} + +void LLFloaterModelWizard::onAccuracyPerformance(const LLSD& data) +{ + int val = (int) data.asInteger(); + + mModelPreview->genLODs(-1, NUM_LOD-val); + + mModelPreview->refresh(); +} + + +void LLFloaterModelWizard::onPreviewLODCommit(LLUICtrl* ctrl) +{ + if (!mModelPreview) + { + return; + } + + S32 which_mode = 0; + + LLComboBox* combo = (LLComboBox*) ctrl; + + which_mode = (NUM_LOD-1)-combo->getFirstSelectedIndex(); // combo box list of lods is in reverse order + + mModelPreview->setPreviewLOD(which_mode); +} + +void LLFloaterModelWizard::refresh() +{ + if (mState == CHOOSE_FILE) + { + bool model_loaded = false; + + if (mModelPreview && mModelPreview->getLoadState() == LLModelLoader::DONE) + { + model_loaded = true; + } + + getChildView("next")->setEnabled(model_loaded); + } + if (mState == REVIEW) + { + getChildView("upload")->setEnabled(getChild<LLCheckBoxCtrl>("confirm_checkbox")->getValue().asBoolean()); + } + +} + +void LLFloaterModelWizard::draw() +{ + refresh(); + + LLFloater::draw(); + LLRect r = getRect(); + + mModelPreview->update(); + + if (mModelPreview) + { + gGL.color3f(1.f, 1.f, 1.f); + + gGL.getTexUnit(0)->bind(mModelPreview); + + LLView *view = getChildView(stateNames[mState]+"_panel"); + LLView* preview_panel = view->getChildView("preview_panel"); + + LLRect rect = preview_panel->getRect(); + if (rect != mPreviewRect) + { + mModelPreview->refresh(); + mPreviewRect = preview_panel->getRect(); + } + + LLRect item_rect; + preview_panel->localRectToOtherView(preview_panel->getLocalRect(), &item_rect, this); + + gGL.begin( LLRender::QUADS ); + { + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2i(item_rect.mLeft, item_rect.mTop-1); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2i(item_rect.mLeft, item_rect.mBottom); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2i(item_rect.mRight-1, item_rect.mBottom); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2i(item_rect.mRight-1, item_rect.mTop-1); + } + gGL.end(); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + } +} diff --git a/indra/newview/llfloatermodelwizard.h b/indra/newview/llfloatermodelwizard.h new file mode 100644 index 0000000000..b166d26295 --- /dev/null +++ b/indra/newview/llfloatermodelwizard.h @@ -0,0 +1,113 @@ +/** + * @file llfloatermodelwizard.h + * + * $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$ + */ + +#ifndef LLFLOATERMODELWIZARD_H +#define LLFLOATERMODELWIZARD_H + + +#include "llmeshrepository.h" +#include "llmodel.h" +#include "llthread.h" + + +class LLModelPreview; + + +class LLFloaterModelWizard : public LLFloater +{ +public: + + class DecompRequest : public LLPhysicsDecomp::Request + { + public: + S32 mContinue; + LLPointer<LLModel> mModel; + + DecompRequest(const std::string& stage, LLModel* mdl); + virtual S32 statusCallback(const char* status, S32 p1, S32 p2); + virtual void completed(); + + }; + + static LLFloaterModelWizard* sInstance; + + LLFloaterModelWizard(const LLSD& key); + virtual ~LLFloaterModelWizard(); + /*virtual*/ BOOL postBuild(); + void draw(); + void refresh(); + + BOOL handleMouseDown(S32 x, S32 y, MASK mask); + BOOL handleMouseUp(S32 x, S32 y, MASK mask); + BOOL handleHover(S32 x, S32 y, MASK mask); + BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); + + void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost); + void modelLoadedCallback(); + void onPhysicsChanged(); + void initDecompControls(); + + LLPhysicsDecomp::decomp_params mDecompParams; + std::set<LLPointer<DecompRequest> > mCurRequest; + std::string mStatusMessage; + static void executePhysicsStage(std::string stage_name); + +private: + enum EWizardState + { + CHOOSE_FILE = 0, + OPTIMIZE, + PHYSICS, + PHYSICS2, + REVIEW, + UPLOAD + }; + + void setState(int state); + void updateButtons(); + void onClickCancel(); + void onClickBack(); + void onClickNext(); + bool onEnableNext(); + bool onEnableBack(); + void loadModel(); + void onPreviewLODCommit(LLUICtrl*); + void onAccuracyPerformance(const LLSD& data); + void onUpload(); + + LLModelPreview* mModelPreview; + LLRect mPreviewRect; + int mState; + + S32 mLastMouseX; + S32 mLastMouseY; + + U32 mLastEnabledState; + + +}; + + +#endif diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index c7fce83b03..4b15695cbf 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -987,9 +987,15 @@ void LLFloaterPreference::refreshEnabledState() LLCheckBoxCtrl* ctrl_avatar_vp = getChild<LLCheckBoxCtrl>("AvatarVertexProgram"); // Avatar Render Mode LLCheckBoxCtrl* ctrl_avatar_cloth = getChild<LLCheckBoxCtrl>("AvatarCloth"); + + bool avatar_vp_enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP"); + if (LLViewerShaderMgr::sInitialized) + { + S32 max_avatar_shader = LLViewerShaderMgr::instance()->mMaxAvatarShaderLevel; + avatar_vp_enabled = (max_avatar_shader > 0) ? TRUE : FALSE; + } - S32 max_avatar_shader = LLViewerShaderMgr::instance()->mMaxAvatarShaderLevel; - ctrl_avatar_vp->setEnabled((max_avatar_shader > 0) ? TRUE : FALSE); + ctrl_avatar_vp->setEnabled(avatar_vp_enabled); if (gSavedSettings.getBOOL("VertexShaderEnable") == FALSE || gSavedSettings.getBOOL("RenderAvatarVP") == FALSE) @@ -1006,7 +1012,7 @@ void LLFloaterPreference::refreshEnabledState() LLCheckBoxCtrl* ctrl_shader_enable = getChild<LLCheckBoxCtrl>("BasicShaders"); // radio set for terrain detail mode LLRadioGroup* mRadioTerrainDetail = getChild<LLRadioGroup>("TerrainDetailRadio"); // can be linked with control var - + ctrl_shader_enable->setEnabled(LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable")); BOOL shaders = ctrl_shader_enable->get(); @@ -1029,26 +1035,28 @@ void LLFloaterPreference::refreshEnabledState() //Deferred/SSAO/Shadows LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders"); - if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderUseFBO") && - LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && - shaders) - { - BOOL enabled = (ctrl_wind_light->get()) ? TRUE : FALSE; + + BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && + shaders && + gGLManager.mHasFramebufferObject && + gSavedSettings.getBOOL("RenderAvatarVP") && + (ctrl_wind_light->get()) ? TRUE : FALSE; - ctrl_deferred->setEnabled(enabled); + ctrl_deferred->setEnabled(enabled); - LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO"); - LLComboBox* ctrl_shadow = getChild<LLComboBox>("ShadowDetail"); + LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO"); + LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF"); + LLComboBox* ctrl_shadow = getChild<LLComboBox>("ShadowDetail"); - enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO") && (ctrl_deferred->get() ? TRUE : FALSE); + enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO") && (ctrl_deferred->get() ? TRUE : FALSE); - ctrl_ssao->setEnabled(enabled); + ctrl_ssao->setEnabled(enabled); + ctrl_dof->setEnabled(enabled); - enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail"); - - ctrl_shadow->setEnabled(enabled); - } + enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail"); + ctrl_shadow->setEnabled(enabled); + // now turn off any features that are unavailable disableUnavailableSettings(); @@ -1067,6 +1075,7 @@ void LLFloaterPreference::disableUnavailableSettings() LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders"); LLComboBox* ctrl_shadows = getChild<LLComboBox>("ShadowDetail"); LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO"); + LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF"); // if vertex shaders off, disable all shader related products if(!LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable")) @@ -1092,6 +1101,9 @@ void LLFloaterPreference::disableUnavailableSettings() ctrl_ssao->setEnabled(FALSE); ctrl_ssao->setValue(FALSE); + ctrl_dof->setEnabled(FALSE); + ctrl_dof->setValue(FALSE); + ctrl_deferred->setEnabled(FALSE); ctrl_deferred->setValue(FALSE); } @@ -1109,12 +1121,16 @@ void LLFloaterPreference::disableUnavailableSettings() ctrl_ssao->setEnabled(FALSE); ctrl_ssao->setValue(FALSE); + ctrl_dof->setEnabled(FALSE); + ctrl_dof->setValue(FALSE); + ctrl_deferred->setEnabled(FALSE); ctrl_deferred->setValue(FALSE); } // disabled deferred - if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred")) + if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") || + !gGLManager.mHasFramebufferObject) { ctrl_shadows->setEnabled(FALSE); ctrl_shadows->setValue(0); @@ -1122,6 +1138,9 @@ void LLFloaterPreference::disableUnavailableSettings() ctrl_ssao->setEnabled(FALSE); ctrl_ssao->setValue(FALSE); + ctrl_dof->setEnabled(FALSE); + ctrl_dof->setValue(FALSE); + ctrl_deferred->setEnabled(FALSE); ctrl_deferred->setValue(FALSE); } @@ -1163,6 +1182,9 @@ void LLFloaterPreference::disableUnavailableSettings() ctrl_ssao->setEnabled(FALSE); ctrl_ssao->setValue(FALSE); + ctrl_dof->setEnabled(FALSE); + ctrl_dof->setValue(FALSE); + ctrl_deferred->setEnabled(FALSE); ctrl_deferred->setValue(FALSE); } diff --git a/indra/newview/llfloaterregiondebugconsole.cpp b/indra/newview/llfloaterregiondebugconsole.cpp index ada0dcf569..c7fab2573f 100644 --- a/indra/newview/llfloaterregiondebugconsole.cpp +++ b/indra/newview/llfloaterregiondebugconsole.cpp @@ -58,8 +58,6 @@ namespace { // Signal used to notify the floater of responses from the asynchronous // API. - typedef boost::signals2::signal< - void (const std::string& output)> console_reply_signal_t; console_reply_signal_t sConsoleReplySignal; const std::string PROMPT("\n\n> "); @@ -132,6 +130,11 @@ namespace }; } +boost::signals2::connection LLFloaterRegionDebugConsole::setConsoleReplyCallback(const console_reply_signal_t::slot_type& cb) +{ + return sConsoleReplySignal.connect(cb); +} + LLFloaterRegionDebugConsole::LLFloaterRegionDebugConsole(LLSD const & key) : LLFloater(key), mOutput(NULL) { diff --git a/indra/newview/llfloaterregiondebugconsole.h b/indra/newview/llfloaterregiondebugconsole.h index 3aa525724e..fd3af4152e 100644 --- a/indra/newview/llfloaterregiondebugconsole.h +++ b/indra/newview/llfloaterregiondebugconsole.h @@ -35,6 +35,9 @@ class LLTextEditor; +typedef boost::signals2::signal< + void (const std::string& output)> console_reply_signal_t; + class LLFloaterRegionDebugConsole : public LLFloater, public LLHTTPClient::Responder { public: @@ -48,6 +51,8 @@ public: LLTextEditor * mOutput; + static boost::signals2::connection setConsoleReplyCallback(const console_reply_signal_t::slot_type& cb); + private: void onReplyReceived(const std::string& output); diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 9d1cbb47ee..e2f661c809 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -60,6 +60,7 @@ #include "llfloatertopobjects.h" // added to fix SL-32336 #include "llfloatergroups.h" #include "llfloaterreg.h" +#include "llfloaterregiondebugconsole.h" #include "llfloatertelehub.h" #include "llfloaterwindlight.h" #include "llinventorymodel.h" @@ -172,9 +173,30 @@ bool estate_dispatch_initialized = false; //S32 LLFloaterRegionInfo::sRequestSerial = 0; LLUUID LLFloaterRegionInfo::sRequestInvoice; + +void LLFloaterRegionInfo::onConsoleReplyReceived(const std::string& output) +{ + llwarns << "here is what they're giving us: " << output << llendl; + + if (output.find("FALSE") != std::string::npos) + { + getChild<LLUICtrl>("mesh_rez_enabled_check")->setValue(FALSE); + } + else + { + getChild<LLUICtrl>("mesh_rez_enabled_check")->setValue(TRUE); + } +} + + LLFloaterRegionInfo::LLFloaterRegionInfo(const LLSD& seed) : LLFloater(seed) { + mConsoleReplySignalConnection = LLFloaterRegionDebugConsole::setConsoleReplyCallback( + boost::bind( + &LLFloaterRegionInfo::onConsoleReplyReceived, + this, + _1)); } BOOL LLFloaterRegionInfo::postBuild() @@ -191,9 +213,14 @@ BOOL LLFloaterRegionInfo::postBuild() panel->buildFromFile("panel_region_general.xml"); mTab->addTabPanel(LLTabContainer::TabPanelParams().panel(panel).select_tab(true)); - panel = new LLPanelRegionDebugInfo; + panel = new LLPanelEstateInfo; mInfoPanels.push_back(panel); - panel->buildFromFile("panel_region_debug.xml"); + panel->buildFromFile("panel_region_estate.xml"); + mTab->addTabPanel(panel); + + panel = new LLPanelEstateCovenant; + mInfoPanels.push_back(panel); + panel->buildFromFile("panel_region_covenant.xml"); mTab->addTabPanel(panel); panel = new LLPanelRegionTerrainInfo; @@ -206,14 +233,9 @@ BOOL LLFloaterRegionInfo::postBuild() panel->buildFromFile("panel_region_environment.xml"); mTab->addTabPanel(panel); - panel = new LLPanelEstateInfo; - mInfoPanels.push_back(panel); - panel->buildFromFile("panel_region_estate.xml"); - mTab->addTabPanel(panel); - - panel = new LLPanelEstateCovenant; + panel = new LLPanelRegionDebugInfo; mInfoPanels.push_back(panel); - panel->buildFromFile("panel_region_covenant.xml"); + panel->buildFromFile("panel_region_debug.xml"); mTab->addTabPanel(panel); gMessageSystem->setHandlerFunc( @@ -228,12 +250,14 @@ BOOL LLFloaterRegionInfo::postBuild() LLFloaterRegionInfo::~LLFloaterRegionInfo() { + mConsoleReplySignalConnection.disconnect(); } void LLFloaterRegionInfo::onOpen(const LLSD& key) { refreshFromRegion(gAgent.getRegion()); requestRegionInfo(); + requestMeshRezInfo(); } // static @@ -626,6 +650,7 @@ BOOL LLPanelRegionGeneralInfo::postBuild() initCtrl("access_combo"); initCtrl("restrict_pushobject"); initCtrl("block_parcel_search_check"); + initCtrl("mesh_rez_enabled_check"); childSetAction("kick_btn", boost::bind(&LLPanelRegionGeneralInfo::onClickKick, this)); childSetAction("kick_all_btn", onClickKickAll, this); @@ -733,8 +758,43 @@ bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const L return false; } +class ConsoleRequestResponder : public LLHTTPClient::Responder +{ +public: + /*virtual*/ + void error(U32 status, const std::string& reason) + { + llwarns << "requesting mesh_rez_enabled failed" << llendl; + } +}; +// called if this request times out. +class ConsoleUpdateResponder : public LLHTTPClient::Responder +{ +public: + /* virtual */ + void error(U32 status, const std::string& reason) + { + llwarns << "Updating mesh enabled region setting failed" << llendl; + } +}; + +void LLFloaterRegionInfo::requestMeshRezInfo() +{ + std::string sim_console_url = gAgent.getRegion()->getCapability("SimConsoleAsync"); + + if (!sim_console_url.empty()) + { + std::string request_str = "get mesh_rez_enabled"; + + LLHTTPClient::post( + sim_console_url, + LLSD(request_str), + new ConsoleRequestResponder); + } +} + // setregioninfo // strings[0] = 'Y' - block terraform, 'N' - not // strings[1] = 'Y' - block fly, 'N' - not @@ -806,6 +866,27 @@ BOOL LLPanelRegionGeneralInfo::sendUpdate() sendEstateOwnerMessage(gMessageSystem, "setregioninfo", invoice, strings); } + std::string sim_console_url = gAgent.getRegion()->getCapability("SimConsoleAsync"); + + if (!sim_console_url.empty()) + { + std::string update_str = "set mesh_rez_enabled "; + if (getChild<LLUICtrl>("mesh_rez_enabled_check")->getValue().asBoolean()) + { + update_str += "true"; + } + else + { + update_str += "false"; + } + + LLHTTPClient::post( + sim_console_url, + LLSD(update_str), + new ConsoleUpdateResponder); + } + + // if we changed access levels, tell user about it LLViewerRegion* region = gAgent.getRegion(); if (region && (getChild<LLUICtrl>("access_combo")->getValue().asInteger() != region->getSimAccess()) ) diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index 713afae1f6..324b3fb157 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -94,11 +94,16 @@ public: virtual void refresh(); void requestRegionInfo(); + void requestMeshRezInfo(); private: LLFloaterRegionInfo(const LLSD& seed); ~LLFloaterRegionInfo(); + + void onConsoleReplyReceived(const std::string& output); + + boost::signals2::connection mConsoleReplySignalConnection;; protected: void onTabSelected(const LLSD& param); diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 364fbad193..73c1f99fa0 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -32,6 +32,7 @@ #include "llcoord.h" //#include "llgl.h" +#include "llagent.h" #include "llagentcamera.h" #include "llbutton.h" #include "llcheckboxctrl.h" @@ -420,27 +421,83 @@ void LLFloaterTools::refresh() // Refresh object and prim count labels LLLocale locale(LLLocale::USER_LOCALE); - std::string obj_count_string; - LLResMgr::getInstance()->getIntegerString(obj_count_string, LLSelectMgr::getInstance()->getSelection()->getRootObjectCount()); - getChild<LLUICtrl>("obj_count")->setTextArg("[COUNT]", obj_count_string); - std::string prim_count_string; - LLResMgr::getInstance()->getIntegerString(prim_count_string, LLSelectMgr::getInstance()->getSelection()->getObjectCount()); - getChild<LLUICtrl>("prim_count")->setTextArg("[COUNT]", prim_count_string); - - // calculate selection rendering cost - if (sShowObjectCost) - { - std::string prim_cost_string; - LLResMgr::getInstance()->getIntegerString(prim_cost_string, calcRenderCost()); - getChild<LLUICtrl>("RenderingCost")->setTextArg("[COUNT]", prim_cost_string); + + if ((gAgent.getRegion() && gAgent.getRegion()->getCapability("GetMesh").empty()) || !gSavedSettings.getBOOL("MeshEnabled")) + { + std::string obj_count_string; + LLResMgr::getInstance()->getIntegerString(obj_count_string, LLSelectMgr::getInstance()->getSelection()->getRootObjectCount()); + getChild<LLUICtrl>("obj_count")->setTextArg("[COUNT]", obj_count_string); + std::string prim_count_string; + LLResMgr::getInstance()->getIntegerString(prim_count_string, LLSelectMgr::getInstance()->getSelection()->getObjectCount()); + getChild<LLUICtrl>("prim_count")->setTextArg("[COUNT]", prim_count_string); + + // calculate selection rendering cost + if (sShowObjectCost) + { + std::string prim_cost_string; + LLResMgr::getInstance()->getIntegerString(prim_cost_string, calcRenderCost()); + getChild<LLUICtrl>("RenderingCost")->setTextArg("[COUNT]", prim_cost_string); + } + + // disable the object and prim counts if nothing selected + bool have_selection = ! LLSelectMgr::getInstance()->getSelection()->isEmpty(); + getChildView("obj_count")->setEnabled(have_selection); + getChildView("prim_count")->setEnabled(have_selection); + getChildView("RenderingCost")->setEnabled(have_selection && sShowObjectCost); } + else + { + // Get the number of objects selected + std::string root_object_count_string; + std::string object_count_string; + + LLResMgr::getInstance()->getIntegerString( + root_object_count_string, + LLSelectMgr::getInstance()->getSelection()->getRootObjectCount()); + LLResMgr::getInstance()->getIntegerString( + object_count_string, + LLSelectMgr::getInstance()->getSelection()->getObjectCount()); + + F32 obj_cost = + LLSelectMgr::getInstance()->getSelection()->getSelectedObjectCost(); + F32 link_cost = + LLSelectMgr::getInstance()->getSelection()->getSelectedLinksetCost(); + F32 obj_physics_cost = + LLSelectMgr::getInstance()->getSelection()->getSelectedPhysicsCost(); + F32 link_physics_cost = + LLSelectMgr::getInstance()->getSelection()->getSelectedLinksetPhysicsCost(); + + // Update the text for the counts + childSetTextArg( + "linked_set_count", + "[COUNT]", + root_object_count_string); + childSetTextArg("object_count", "[COUNT]", object_count_string); + + // Update the text for the resource costs + childSetTextArg("linked_set_cost","[COST]",llformat("%.1f", link_cost)); + childSetTextArg("object_cost", "[COST]", llformat("%.1f", obj_cost)); + childSetTextArg("linked_set_cost","[PHYSICS]",llformat("%.1f", link_physics_cost)); + childSetTextArg("object_cost", "[PHYSICS]", llformat("%.1f", obj_physics_cost)); + + // Display rendering cost if needed + if (sShowObjectCost) + { + std::string prim_cost_string; + LLResMgr::getInstance()->getIntegerString(prim_cost_string, calcRenderCost()); + getChild<LLUICtrl>("RenderingCost")->setTextArg("[COUNT]", prim_cost_string); + } - // disable the object and prim counts if nothing selected - bool have_selection = ! LLSelectMgr::getInstance()->getSelection()->isEmpty(); - getChildView("obj_count")->setEnabled(have_selection); - getChildView("prim_count")->setEnabled(have_selection); - getChildView("RenderingCost")->setEnabled(have_selection && sShowObjectCost); + // disable the object and prim counts if nothing selected + bool have_selection = ! LLSelectMgr::getInstance()->getSelection()->isEmpty(); + childSetEnabled("linked_set_count", have_selection); + childSetEnabled("object_count", have_selection); + childSetEnabled("linked_set_cost", have_selection); + childSetEnabled("object_cost", have_selection); + getChildView("RenderingCost")->setEnabled(have_selection && sShowObjectCost); + } + // Refresh child tabs mPanelPermissions->refresh(); @@ -730,8 +787,18 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) getChildView("Strength:")->setVisible( land_visible); } - getChildView("obj_count")->setVisible( !land_visible); - getChildView("prim_count")->setVisible( !land_visible); + bool show_mesh_cost = gAgent.getRegion() && + !gAgent.getRegion()->getCapability("GetMesh").empty() && + gSavedSettings.getBOOL("MeshEnabled"); + + getChildView("obj_count")->setVisible( !land_visible && !show_mesh_cost); + getChildView("prim_count")->setVisible( !land_visible && !show_mesh_cost); + getChildView("linked_set_count")->setVisible( !land_visible && show_mesh_cost); + getChildView("linked_set_cost")->setVisible( !land_visible && show_mesh_cost); + getChildView("object_count")->setVisible( !land_visible && show_mesh_cost); + getChildView("object_cost")->setVisible( !land_visible && show_mesh_cost); + getChildView("RenderingCost")->setVisible( !land_visible && sShowObjectCost); + mTab->setVisible(!land_visible); mPanelLandInfo->setVisible(land_visible); } @@ -988,30 +1055,33 @@ void LLFloaterTools::onClickGridOptions() S32 LLFloaterTools::calcRenderCost() { - S32 cost = 0; - std::set<LLUUID> textures; - - for (LLObjectSelection::iterator selection_iter = LLSelectMgr::getInstance()->getSelection()->begin(); - selection_iter != LLSelectMgr::getInstance()->getSelection()->end(); - ++selection_iter) - { - LLSelectNode *select_node = *selection_iter; - if (select_node) - { - LLVOVolume *viewer_volume = (LLVOVolume*)select_node->getObject(); - if (viewer_volume) - { - cost += viewer_volume->getRenderCost(textures); - cost += textures.size() * LLVOVolume::ARC_TEXTURE_COST; - textures.clear(); - } - } - } - - - return cost; + S32 cost = 0; + std::set<LLUUID> textures; + + for (LLObjectSelection::iterator selection_iter = LLSelectMgr::getInstance()->getSelection()->begin(); + selection_iter != LLSelectMgr::getInstance()->getSelection()->end(); + ++selection_iter) + { + LLSelectNode *select_node = *selection_iter; + if (select_node) + { + LLViewerObject *vobj = select_node->getObject(); + if (vobj->getVolume()) + { + LLVOVolume* volume = (LLVOVolume*) vobj; + + cost += volume->getRenderCost(textures); + cost += textures.size() * LLVOVolume::ARC_TEXTURE_COST; + textures.clear(); + } + } + } + + + return cost; } + // static void LLFloaterTools::setEditTool(void* tool_pointer) { diff --git a/indra/newview/llfloaterwindlight.cpp b/indra/newview/llfloaterwindlight.cpp index b90f576555..fb69e6f594 100644 --- a/indra/newview/llfloaterwindlight.cpp +++ b/indra/newview/llfloaterwindlight.cpp @@ -180,8 +180,6 @@ void LLFloaterWindLight::initCallbacks(void) childSetCommitCallback("WLCloudDetailDensity", onColorControlBMoved, ¶m_mgr->mCloudDetail); // Cloud extras - static std::string use_classic_clouds = "SkyUseClassicClouds"; - childSetCommitCallback("WLCloudCoverage", onFloatControlMoved, ¶m_mgr->mCloudCoverage); childSetCommitCallback("WLCloudScale", onFloatControlMoved, ¶m_mgr->mCloudScale); childSetCommitCallback("WLCloudLockX", onCloudScrollXToggled, NULL); @@ -189,8 +187,7 @@ void LLFloaterWindLight::initCallbacks(void) childSetCommitCallback("WLCloudScrollX", onCloudScrollXMoved, NULL); childSetCommitCallback("WLCloudScrollY", onCloudScrollYMoved, NULL); childSetCommitCallback("WLDistanceMult", onFloatControlMoved, ¶m_mgr->mDistanceMult); - getChild<LLUICtrl>("DrawClassicClouds")->setCommitCallback(boost::bind(LLSavedSettingsGlue::setBOOL, _1, "SkyUseClassicClouds")); - + // WL Top childSetAction("WLDayCycleMenuButton", onOpenDayCycle, NULL); // Load/save @@ -373,7 +370,6 @@ void LLFloaterWindLight::syncMenu() bool lockY = !param_mgr->mCurParams.getEnableCloudScrollY(); childSetValue("WLCloudLockX", lockX); childSetValue("WLCloudLockY", lockY); - childSetValue("DrawClassicClouds", gSavedSettings.getBOOL("SkyUseClassicClouds")); // disable if locked, enable if not if(lockX) diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp index f990b9294d..30858871ec 100644 --- a/indra/newview/llgiveinventory.cpp +++ b/indra/newview/llgiveinventory.cpp @@ -311,6 +311,9 @@ void LLGiveInventory::logInventoryOffer(const LLUUID& to_agent, const LLUUID &im std::string full_name; if (gCacheName->getFullName(to_agent, full_name)) { + // Build a new format username or firstname_lastname for legacy names + // to use it for a history log filename. + full_name = LLCacheName::buildUsername(full_name); LLIMModel::instance().logToFile(full_name, LLTrans::getString("SECOND_LIFE"), im_session_id, LLTrans::getString("inventory_item_offered-im")); } } diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index 7c56e610ce..97fa551441 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -40,10 +40,12 @@ #include "llsidetray.h" #include "llstatusbar.h" // can_afford_transaction() #include "llimfloater.h" +#include "groupchatlistener.h" // // Globals // +static GroupChatListener sGroupChatListener; class LLGroupHandler : public LLCommandHandler { @@ -320,10 +322,9 @@ void LLGroupActions::closeGroup(const LLUUID& group_id) // static -void LLGroupActions::startIM(const LLUUID& group_id) +LLUUID LLGroupActions::startIM(const LLUUID& group_id) { - if (group_id.isNull()) - return; + if (group_id.isNull()) return LLUUID::null; LLGroupData group_data; if (gAgent.getGroupData(group_id, group_data)) @@ -337,12 +338,14 @@ void LLGroupActions::startIM(const LLUUID& group_id) LLIMFloater::show(session_id); } make_ui_sound("UISndStartIM"); + return session_id; } else { // this should never happen, as starting a group IM session // relies on you belonging to the group and hence having the group data make_ui_sound("UISndInvalidOp"); + return LLUUID::null; } } diff --git a/indra/newview/llgroupactions.h b/indra/newview/llgroupactions.h index c52a25818b..3f9852f194 100644 --- a/indra/newview/llgroupactions.h +++ b/indra/newview/llgroupactions.h @@ -87,7 +87,7 @@ public: /** * Start group instant messaging session. */ - static void startIM(const LLUUID& group_id); + static LLUUID startIM(const LLUUID& group_id); /** * End group instant messaging session. diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp index 568b0ae585..7e1025c41b 100644 --- a/indra/newview/llhudicon.cpp +++ b/indra/newview/llhudicon.cpp @@ -33,6 +33,7 @@ #include "llviewerobject.h" #include "lldrawable.h" +#include "llvector4a.h" #include "llviewercamera.h" #include "llviewertexture.h" #include "llviewerwindow.h" @@ -255,21 +256,42 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector3& start, const LLVector3& en LLVector3 x_scale = image_aspect * (F32)gViewerWindow->getWindowHeightScaled() * mScale * scale_factor * x_pixel_vec; LLVector3 y_scale = (F32)gViewerWindow->getWindowHeightScaled() * mScale * scale_factor * y_pixel_vec; - LLVector3 lower_left = icon_position - (x_scale * 0.5f); - LLVector3 lower_right = icon_position + (x_scale * 0.5f); - LLVector3 upper_left = icon_position - (x_scale * 0.5f) + y_scale; - LLVector3 upper_right = icon_position + (x_scale * 0.5f) + y_scale; + LLVector4a x_scalea; + LLVector4a icon_positiona; + LLVector4a y_scalea; - - F32 t = 0.f; - LLVector3 dir = end-start; + x_scalea.load3(x_scale.mV); + x_scalea.mul(0.5f); + y_scalea.load3(y_scale.mV); + + icon_positiona.load3(icon_position.mV); + + LLVector4a lower_left; + lower_left.setSub(icon_positiona, x_scalea); + LLVector4a lower_right; + lower_right.setAdd(icon_positiona, x_scalea); + LLVector4a upper_left; + upper_left.setAdd(lower_left, y_scalea); + LLVector4a upper_right; + upper_right.setAdd(lower_right, y_scalea); + + LLVector4a enda; + enda.load3(end.mV); + LLVector4a starta; + starta.load3(start.mV); + LLVector4a dir; + dir.setSub(enda, starta); + + F32 a,b,t; - if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, start, dir, NULL, NULL, &t, FALSE) || - LLTriangleRayIntersect(upper_left, lower_left, lower_right, start, dir, NULL, NULL, &t, FALSE)) + if (LLTriangleRayIntersect(upper_right, upper_left, lower_right, starta, dir, a,b,t) || + LLTriangleRayIntersect(upper_left, lower_left, lower_right, starta, dir, a,b,t)) { if (intersection) { - *intersection = start + dir*t; + dir.mul(t); + starta.add(dir); + *intersection = LLVector3(starta.getF32ptr()); } return TRUE; } diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index fc758569e4..82e1f2dfb5 100644 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -146,24 +146,43 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3& mOffsetY = lltrunc(mHeight * ((mVertAlignment == ALIGN_VERT_CENTER) ? 0.5f : 1.f)); + LLVector3 position = mPositionAgent; + + if (mSourceObject) + { //get intersection of eye through mPositionAgent to plane of source object + //using this position keeps the camera from focusing on some seemingly random + //point several meters in front of the nametag + const LLVector3& p = mSourceObject->getPositionAgent(); + const LLVector3& n = LLViewerCamera::getInstance()->getAtAxis(); + const LLVector3& eye = LLViewerCamera::getInstance()->getOrigin(); + + LLVector3 ray = position-eye; + ray.normalize(); + + LLVector3 delta = p-position; + F32 dist = delta*n; + F32 dt = dist/(ray*n); + position += ray*dt; + } + // scale screen size of borders down //RN: for now, text on hud objects is never occluded LLVector3 x_pixel_vec; LLVector3 y_pixel_vec; - LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); + LLViewerCamera::getInstance()->getPixelVectors(position, y_pixel_vec, x_pixel_vec); LLVector3 width_vec = mWidth * x_pixel_vec; LLVector3 height_vec = mHeight * y_pixel_vec; LLCoordGL screen_pos; - LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE); + LLViewerCamera::getInstance()->projectPosAgentToScreen(position, screen_pos, FALSE); LLVector2 screen_offset; screen_offset = updateScreenPos(mPositionOffset); - LLVector3 render_position = mPositionAgent + LLVector3 render_position = position + (x_pixel_vec * screen_offset.mV[VX]) + (y_pixel_vec * screen_offset.mV[VY]); @@ -197,10 +216,10 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3& } LLVector3 dir = end-start; - F32 t = 0.f; + F32 a, b, t; - if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, NULL, NULL, &t, FALSE) || - LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, NULL, NULL, &t, FALSE) ) + if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) || + LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) ) { if (t <= 1.f) { diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 38c5ba71bd..4de6976534 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -195,7 +195,7 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& // set P2P type by default mSessionType = P2P_SESSION; - if (IM_NOTHING_SPECIAL == type || IM_SESSION_P2P_INVITE == type) + if (IM_NOTHING_SPECIAL == mType || IM_SESSION_P2P_INVITE == mType) { mVoiceChannel = new LLVoiceChannelP2P(session_id, name, other_participant_id); mOtherParticipantIsAvatar = LLVoiceClient::getInstance()->isParticipantAvatar(mSessionID); @@ -249,7 +249,7 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& new LLSessionTimeoutTimer(mSessionID, SESSION_INITIALIZATION_TIMEOUT); } - if (IM_NOTHING_SPECIAL == type) + if (IM_NOTHING_SPECIAL == mType) { mCallBackEnabled = LLVoiceClient::getInstance()->isSessionCallBackPossible(mSessionID); mTextIMPossible = LLVoiceClient::getInstance()->isSessionTextIMPossible(mSessionID); @@ -269,10 +269,10 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& // Localizing name of ad-hoc session. STORM-153 // Changing name should happen here- after the history file was created, so that // history files have consistent (English) names in different locales. - if (isAdHocSessionType() && IM_SESSION_INVITE == type) + if (isAdHocSessionType() && IM_SESSION_INVITE == mType) { - LLAvatarNameCache::get(mOtherParticipantID, - boost::bind(&LLIMModel::LLIMSession::onAdHocNameCache, + LLAvatarNameCache::get(mOtherParticipantID, + boost::bind(&LLIMModel::LLIMSession::onAdHocNameCache, this, _2)); } } @@ -553,23 +553,10 @@ bool LLIMModel::LLIMSession::isOtherParticipantAvaline() return !mOtherParticipantIsAvatar; } -void LLIMModel::LLIMSession::onAvatarNameCache(const LLUUID& avatar_id, const LLAvatarName& av_name) -{ - if (av_name.mUsername.empty()) - { - // display names is off, use mDisplayName which will be the legacy name - mHistoryFileName = LLCacheName::buildUsername(av_name.mDisplayName); - } - else - { - mHistoryFileName = av_name.mUsername; - } -} - void LLIMModel::LLIMSession::buildHistoryFileName() { mHistoryFileName = mName; - + //ad-hoc requires sophisticated chat history saving schemes if (isAdHoc()) { @@ -583,17 +570,35 @@ void LLIMModel::LLIMSession::buildHistoryFileName() { std::set<LLUUID> sorted_uuids(mInitialTargetIDs.begin(), mInitialTargetIDs.end()); mHistoryFileName = mName + " hash" + generateHash(sorted_uuids); - return; } - - //in case of incoming ad-hoc sessions - mHistoryFileName = mName + " " + LLLogChat::timestamp(true) + " " + mSessionID.asString().substr(0, 4); + else + { + //in case of incoming ad-hoc sessions + mHistoryFileName = mName + " " + LLLogChat::timestamp(true) + " " + mSessionID.asString().substr(0, 4); + } } - - // look up username to use as the log name - if (isP2P()) + else if (isP2P()) // look up username to use as the log name { - LLAvatarNameCache::get(mOtherParticipantID, boost::bind(&LLIMModel::LLIMSession::onAvatarNameCache, this, _1, _2)); + LLAvatarName av_name; + // For outgoing sessions we already have a cached name + // so no need for a callback in LLAvatarNameCache::get() + if (LLAvatarNameCache::get(mOtherParticipantID, &av_name)) + { + if (av_name.mUsername.empty()) + { + // Display names are off, use mDisplayName which will be the legacy name + mHistoryFileName = LLCacheName::buildUsername(av_name.mDisplayName); + } + else + { + mHistoryFileName = av_name.mUsername; + } + } + else + { + // Incoming P2P sessions include a name that we can use to build a history file name + mHistoryFileName = LLCacheName::buildUsername(mName); + } } } @@ -615,7 +620,6 @@ std::string LLIMModel::LLIMSession::generateHash(const std::set<LLUUID>& sorted_ return participants_md5_hash.asString(); } - void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, const LLUUID& new_session_id) { LLIMSession* session = findIMSession(old_session_id); @@ -798,11 +802,6 @@ bool LLIMModel::logToFile(const std::string& file_name, const std::string& from, } } -bool LLIMModel::logToFile(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text) -{ - return logToFile(LLIMModel::getInstance()->getHistoryFileName(session_id), from, from_id, utf8_text); -} - bool LLIMModel::proccessOnlineOfflineNotification( const LLUUID& session_id, const std::string& utf8_text) @@ -856,8 +855,11 @@ LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id, } addToHistory(session_id, from_name, from_id, utf8_text); - if (log2file) logToFile(session_id, from_name, from_id, utf8_text); - + if (log2file) + { + logToFile(getHistoryFileName(session_id), from_name, from_id, utf8_text); + } + session->mNumUnread++; //update count of unread messages from real participant @@ -2468,6 +2470,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess std::string session_name; // since we select user to share item with - his name is already in cache gCacheName->getFullName(args["user_id"], session_name); + session_name = LLCacheName::buildUsername(session_name); LLIMModel::instance().logToFile(session_name, SYSTEM_FROM, LLUUID::null, message.getString()); } } diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index a15776c207..0ee56c8070 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -98,13 +98,6 @@ public: /** ad-hoc sessions involve sophisticated chat history file naming schemes */ void buildHistoryFileName(); - void onAvatarNameCache(const LLUUID& avatar_id, const LLAvatarName& av_name); - - void onAdHocNameCache(const LLAvatarName& av_name); - - //*TODO make private - static std::string generateHash(const std::set<LLUUID>& sorted_uuids); - LLUUID mSessionID; std::string mName; EInstantMessage mType; @@ -139,6 +132,11 @@ public: //if IM session is created for a voice call bool mStartedAsIMCall; + + private: + void onAdHocNameCache(const LLAvatarName& av_name); + + static std::string generateHash(const std::set<LLUUID>& sorted_uuids); }; @@ -293,12 +291,7 @@ private: /** * Add message to a list of message associated with session specified by session_id */ - bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text); - - /** - * Save an IM message into a file - */ - bool logToFile(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text); + bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text); }; class LLIMSessionObserver diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index bdb9f6167a..86c8a1a9b5 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -917,6 +917,14 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, // Only should happen for broken links. new_listener = new LLLinkItemBridge(inventory, root, uuid); break; + case LLAssetType::AT_MESH: + if(!(inv_type == LLInventoryType::IT_MESH)) + { + llwarns << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << llendl; + } + new_listener = new LLMeshBridge(inventory, root, uuid); + break; + default: llinfos << "Unhandled asset type (llassetstorage.h): " << (S32)asset_type << llendl; @@ -2266,6 +2274,9 @@ LLUIImagePtr LLFolderBridge::getIcon() const LLUIImagePtr LLFolderBridge::getIcon(LLFolderType::EType preferred_type) { return LLUI::getUIImage(LLViewerFolderType::lookupIconName(preferred_type, FALSE)); + /*case LLAssetType::AT_MESH: + control = "inv_folder_mesh.tga"; + break;*/ } LLUIImagePtr LLFolderBridge::getOpenIcon() const @@ -2725,12 +2736,13 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop, case DAD_CALLINGCARD: case DAD_LANDMARK: case DAD_SCRIPT: + case DAD_CLOTHING: case DAD_OBJECT: case DAD_NOTECARD: - case DAD_CLOTHING: case DAD_BODYPART: case DAD_ANIMATION: case DAD_GESTURE: + case DAD_MESH: accept = dragItemIntoFolder(inv_item, drop); break; case DAD_LINK: @@ -2760,7 +2772,11 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop, accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data, drop); } break; + case DAD_ROOT_CATEGORY: + case DAD_NONE: + break; default: + llwarns << "Unhandled cargo type for drag&drop " << cargo_type << llendl; break; } return accept; @@ -3752,6 +3768,7 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop, case DAD_BODYPART: case DAD_ANIMATION: case DAD_GESTURE: + case DAD_MESH: { LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data; const LLPermissions& perm = inv_item->getPermissions(); @@ -4928,6 +4945,7 @@ void LLWearableBridge::removeFromAvatar() } } + // +=================================================+ // | LLLinkItemBridge | // +=================================================+ @@ -4958,6 +4976,63 @@ void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } // +=================================================+ +// | LLMeshBridge | +// +=================================================+ + +LLUIImagePtr LLMeshBridge::getIcon() const +{ + return LLInventoryIcon::getIcon(LLAssetType::AT_MESH, LLInventoryType::IT_MESH, 0, FALSE); +} + +void LLMeshBridge::openItem() +{ + LLViewerInventoryItem* item = getItem(); + + if (item) + { + // open mesh + } +} + +void LLMeshBridge::previewItem() +{ + LLViewerInventoryItem* item = getItem(); + if(item) + { + // preview mesh + } +} + + +void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags) +{ + lldebugs << "LLMeshBridge::buildContextMenu()" << llendl; + std::vector<std::string> items; + std::vector<std::string> disabled_items; + + if(isItemInTrash()) + { + items.push_back(std::string("Purge Item")); + if (!isItemRemovable()) + { + disabled_items.push_back(std::string("Purge Item")); + } + + items.push_back(std::string("Restore Item")); + } + else + { + items.push_back(std::string("Properties")); + + getClipboardEntries(true, items, disabled_items, flags); + } + + + hide_context_entries(menu, items, disabled_items); +} + + +// +=================================================+ // | LLLinkBridge | // +=================================================+ // For broken folder links. @@ -5263,6 +5338,7 @@ public: { wearOnAvatar(); } + virtual ~LLWearableBridgeAction(){} protected: LLWearableBridgeAction(const LLUUID& id,LLInventoryModel* model) : LLInvFVBridgeAction(id,model) {} diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 5ac328dcef..1e849c8812 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -41,6 +41,7 @@ class LLMenuGL; class LLCallingCardObserver; class LLViewerJointAttachment; + typedef std::vector<std::string> menuentry_vec_t; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -523,6 +524,24 @@ protected: static std::string sPrefix; }; + +class LLMeshBridge : public LLItemBridge +{ + friend class LLInvFVBridge; +public: + virtual LLUIImagePtr getIcon() const; + virtual void openItem(); + virtual void previewItem(); + virtual void buildContextMenu(LLMenuGL& menu, U32 flags); + +protected: + LLMeshBridge(LLInventoryPanel* inventory, + LLFolderView* root, + const LLUUID& uuid) : + LLItemBridge(inventory, root, uuid) {} +}; + + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLInvFVBridgeAction // @@ -553,13 +572,23 @@ protected: LLInventoryModel* mModel; }; -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// Recent Inventory Panel related classes -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLMeshBridgeAction: public LLInvFVBridgeAction +{ + friend class LLInvFVBridgeAction; +public: + virtual void doIt() ; + virtual ~LLMeshBridgeAction(){} +protected: + LLMeshBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){} + +}; + + // Overridden version of the Inventory-Folder-View-Bridge for Folders class LLRecentItemsFolderBridge : public LLFolderBridge { + friend class LLInvFVBridgeAction; public: // Creates context menu for Folders related to Recent Inventory Panel. // Uses base logic and than removes from visible items "New..." menu items. diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index ba9bea02b9..db3b968730 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -853,3 +853,4 @@ void LLOpenFoldersWithSelection::doFolder(LLFolderViewFolder* folder) folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP); } } + diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp index 95dea219a8..34734d57c5 100644 --- a/indra/newview/llinventoryicon.cpp +++ b/indra/newview/llinventoryicon.cpp @@ -86,6 +86,7 @@ LLIconDictionary::LLIconDictionary() addEntry(LLInventoryIcon::ICONNAME_LINKITEM, new IconEntry("Inv_LinkItem")); addEntry(LLInventoryIcon::ICONNAME_LINKFOLDER, new IconEntry("Inv_LinkFolder")); + addEntry(LLInventoryIcon::ICONNAME_MESH, new IconEntry("Inv_Mesh")); addEntry(LLInventoryIcon::ICONNAME_INVALID, new IconEntry("Inv_Invalid")); @@ -159,6 +160,8 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type, case LLAssetType::AT_OBJECT: idx = ICONNAME_OBJECT; break; + case LLAssetType::AT_MESH: + idx = ICONNAME_MESH; default: break; } diff --git a/indra/newview/llinventoryicon.h b/indra/newview/llinventoryicon.h index 694b56d572..c7e2998a20 100644 --- a/indra/newview/llinventoryicon.h +++ b/indra/newview/llinventoryicon.h @@ -74,6 +74,7 @@ public: ICONNAME_LINKITEM, ICONNAME_LINKFOLDER, + ICONNAME_MESH, ICONNAME_INVALID, ICONNAME_COUNT, diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h index 86e11dff17..b183a2052d 100644 --- a/indra/newview/llinventoryitemslist.h +++ b/indra/newview/llinventoryitemslist.h @@ -38,7 +38,6 @@ class LLViewerInventoryItem; class LLInventoryItemsList : public LLFlatListViewEx { - LOG_CLASS(LLInventoryItemsList); public: struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params> { diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index b1975c7261..b5180854ef 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -631,6 +631,12 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item) return mask; } + // We're hiding mesh types + if (item->getType() == LLAssetType::AT_MESH) + { + return mask; + } + LLViewerInventoryItem* old_item = getItem(item->getUUID()); LLPointer<LLViewerInventoryItem> new_item; if(old_item) @@ -1263,6 +1269,12 @@ void LLInventoryModel::addCategory(LLViewerInventoryCategory* category) //llinfos << "LLInventoryModel::addCategory()" << llendl; if(category) { + // We aren't displaying the Meshes folder + if (category->mPreferredType == LLFolderType::FT_MESH) + { + return; + } + // try to localize default names first. See EXT-8319, EXT-7051. category->localizeName(); diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 36c5d12897..00de6a86e1 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -608,6 +608,7 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia request_params["channel"] = LLVersionInfo::getChannel(); request_params["id0"] = mSerialNumber; request_params["host_id"] = gSavedSettings.getString("HostID"); + request_params["extended_errors"] = true; // request message_id and message_args mRequestData.clear(); mRequestData["method"] = "login_to_simulator"; diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp index 9cdc092257..738d82e732 100644 --- a/indra/newview/llmanipscale.cpp +++ b/indra/newview/llmanipscale.cpp @@ -52,6 +52,7 @@ #include "llui.h" #include "llviewercamera.h" #include "llviewerobject.h" +#include "llviewerregion.h" #include "llviewerwindow.h" #include "llhudrender.h" #include "llworld.h" @@ -85,6 +86,22 @@ const LLManip::EManipPart MANIPULATOR_IDS[NUM_MANIPULATORS] = }; +F32 get_default_max_prim_scale(bool is_flora) +{ + // a bit of a hack, but if it's foilage, we don't want to use the + // new larger scale which would result in giant trees and grass + if (gSavedSettings.getBOOL("MeshEnabled") && + gAgent.getRegion() && + !gAgent.getRegion()->getCapability("GetMesh").empty() && + !is_flora) + { + return DEFAULT_MAX_PRIM_SCALE; + } + else + { + return DEFAULT_MAX_PRIM_SCALE_NO_MESH; + } +} // static void LLManipScale::setUniform(BOOL b) @@ -242,7 +259,7 @@ void LLManipScale::render() // range != zero F32 fraction_of_fov = BOX_HANDLE_BASE_SIZE / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels(); F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView(); // radians - mBoxHandleSize = fsqrtf(range_squared) * tan(apparent_angle) * BOX_HANDLE_BASE_FACTOR; + mBoxHandleSize = (F32) sqrtf(range_squared) * tan(apparent_angle) * BOX_HANDLE_BASE_FACTOR; } else { @@ -948,8 +965,8 @@ void LLManipScale::dragCorner( S32 x, S32 y ) mInSnapRegime = FALSE; } - F32 max_scale_factor = DEFAULT_MAX_PRIM_SCALE / MIN_PRIM_SCALE; - F32 min_scale_factor = MIN_PRIM_SCALE / DEFAULT_MAX_PRIM_SCALE; + F32 max_scale_factor = get_default_max_prim_scale() / MIN_PRIM_SCALE; + F32 min_scale_factor = MIN_PRIM_SCALE / get_default_max_prim_scale(); // find max and min scale factors that will make biggest object hit max absolute scale and smallest object hit min absolute scale for (LLObjectSelection::iterator iter = mObjectSelection->begin(); @@ -961,7 +978,7 @@ void LLManipScale::dragCorner( S32 x, S32 y ) { const LLVector3& scale = selectNode->mSavedScale; - F32 cur_max_scale_factor = llmin( DEFAULT_MAX_PRIM_SCALE / scale.mV[VX], DEFAULT_MAX_PRIM_SCALE / scale.mV[VY], DEFAULT_MAX_PRIM_SCALE / scale.mV[VZ] ); + F32 cur_max_scale_factor = llmin( get_default_max_prim_scale(LLPickInfo::isFlora(cur)) / scale.mV[VX], get_default_max_prim_scale(LLPickInfo::isFlora(cur)) / scale.mV[VY], get_default_max_prim_scale(LLPickInfo::isFlora(cur)) / scale.mV[VZ] ); max_scale_factor = llmin( max_scale_factor, cur_max_scale_factor ); F32 cur_min_scale_factor = llmax( MIN_PRIM_SCALE / scale.mV[VX], MIN_PRIM_SCALE / scale.mV[VY], MIN_PRIM_SCALE / scale.mV[VZ] ); @@ -1258,7 +1275,7 @@ void LLManipScale::stretchFace( const LLVector3& drag_start_agent, const LLVecto F32 denom = axis * dir_local; F32 desired_delta_size = is_approx_zero(denom) ? 0.f : (delta_local_mag / denom); // in meters - F32 desired_scale = llclamp(selectNode->mSavedScale.mV[axis_index] + desired_delta_size, MIN_PRIM_SCALE, DEFAULT_MAX_PRIM_SCALE); + F32 desired_scale = llclamp(selectNode->mSavedScale.mV[axis_index] + desired_delta_size, MIN_PRIM_SCALE, get_default_max_prim_scale(LLPickInfo::isFlora(cur))); // propagate scale constraint back to position offset desired_delta_size = desired_scale - selectNode->mSavedScale.mV[axis_index]; // propagate constraint back to position @@ -1958,7 +1975,7 @@ F32 LLManipScale::partToMaxScale( S32 part, const LLBBox &bbox ) const max_extent = bbox_extents.mV[i]; } } - max_scale_factor = bbox_extents.magVec() * DEFAULT_MAX_PRIM_SCALE / max_extent; + max_scale_factor = bbox_extents.magVec() * get_default_max_prim_scale() / max_extent; if (getUniform()) { @@ -1973,7 +1990,7 @@ F32 LLManipScale::partToMinScale( S32 part, const LLBBox &bbox ) const { LLVector3 bbox_extents = unitVectorToLocalBBoxExtent( partToUnitVector( part ), bbox ); bbox_extents.abs(); - F32 min_extent = DEFAULT_MAX_PRIM_SCALE; + F32 min_extent = get_default_max_prim_scale(); for (U32 i = VX; i <= VZ; i++) { if (bbox_extents.mV[i] > 0.f && bbox_extents.mV[i] < min_extent) diff --git a/indra/newview/llmanipscale.h b/indra/newview/llmanipscale.h index 5559f557c0..5cb8898fd0 100644 --- a/indra/newview/llmanipscale.h +++ b/indra/newview/llmanipscale.h @@ -39,6 +39,9 @@ #include "llviewerobject.h" #include "llbbox.h" + +F32 get_default_max_prim_scale(bool is_flora = false); + class LLToolComposite; class LLColor4; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp new file mode 100644 index 0000000000..0b96a3b34f --- /dev/null +++ b/indra/newview/llmeshrepository.cpp @@ -0,0 +1,3827 @@ +/** + * @file llmeshrepository.cpp + * @brief Mesh repository 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$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "apr_pools.h" +#include "apr_dso.h" +#include "llhttpstatuscodes.h" +#include "llmeshrepository.h" + +#include "llagent.h" +#include "llappviewer.h" +#include "llbufferstream.h" +#include "llcurl.h" +#include "lldatapacker.h" +#include "llfasttimer.h" +#include "llfloatermodelpreview.h" +#include "llfloaterperms.h" +#include "lleconomy.h" +#include "llimagej2c.h" +#include "llhost.h" +#include "llnotificationsutil.h" +#include "llsd.h" +#include "llsdutil_math.h" +#include "llsdserialize.h" +#include "llthread.h" +#include "llvfile.h" +#include "llviewercontrol.h" +#include "llviewermenufile.h" +#include "llviewerobjectlist.h" +#include "llviewerregion.h" +#include "llviewertexturelist.h" +#include "llvolume.h" +#include "llvolumemgr.h" +#include "llvovolume.h" +#include "llworld.h" +#include "material_codes.h" +#include "pipeline.h" +#include "llinventorymodel.h" +#include "llfoldertype.h" + +#ifndef LL_WINDOWS +#include "netdb.h" +#endif + +#include <queue> + +LLFastTimer::DeclareTimer FTM_MESH_UPDATE("Mesh Update"); +LLFastTimer::DeclareTimer FTM_LOAD_MESH("Load Mesh"); + +LLMeshRepository gMeshRepo; + +const U32 MAX_MESH_REQUESTS_PER_SECOND = 100; + +U32 LLMeshRepository::sBytesReceived = 0; +U32 LLMeshRepository::sHTTPRequestCount = 0; +U32 LLMeshRepository::sHTTPRetryCount = 0; +U32 LLMeshRepository::sCacheBytesRead = 0; +U32 LLMeshRepository::sCacheBytesWritten = 0; +U32 LLMeshRepository::sPeakKbps = 0; + + +const U32 MAX_TEXTURE_UPLOAD_RETRIES = 5; + +std::string header_lod[] = +{ + "lowest_lod", + "low_lod", + "medium_lod", + "high_lod" +}; + + +//get the number of bytes resident in memory for given volume +U32 get_volume_memory_size(const LLVolume* volume) +{ + U32 indices = 0; + U32 vertices = 0; + + for (U32 i = 0; i < volume->getNumVolumeFaces(); ++i) + { + const LLVolumeFace& face = volume->getVolumeFace(i); + indices += face.mNumIndices; + vertices += face.mNumVertices; + } + + + return indices*2+vertices*11+sizeof(LLVolume)+sizeof(LLVolumeFace)*volume->getNumVolumeFaces(); +} + +void get_vertex_buffer_from_mesh(LLCDMeshData& mesh, LLModel::PhysicsMesh& res, F32 scale = 1.f) +{ + res.mPositions.clear(); + res.mNormals.clear(); + + const F32* v = mesh.mVertexBase; + + if (mesh.mIndexType == LLCDMeshData::INT_16) + { + U16* idx = (U16*) mesh.mIndexBase; + for (S32 j = 0; j < mesh.mNumTriangles; ++j) + { + F32* mp0 = (F32*) ((U8*)v+idx[0]*mesh.mVertexStrideBytes); + F32* mp1 = (F32*) ((U8*)v+idx[1]*mesh.mVertexStrideBytes); + F32* mp2 = (F32*) ((U8*)v+idx[2]*mesh.mVertexStrideBytes); + + idx = (U16*) (((U8*)idx)+mesh.mIndexStrideBytes); + + LLVector3 v0(mp0); + LLVector3 v1(mp1); + LLVector3 v2(mp2); + + LLVector3 n = (v1-v0)%(v2-v0); + n.normalize(); + + res.mPositions.push_back(v0*scale); + res.mPositions.push_back(v1*scale); + res.mPositions.push_back(v2*scale); + + res.mNormals.push_back(n); + res.mNormals.push_back(n); + res.mNormals.push_back(n); + } + } + else + { + U32* idx = (U32*) mesh.mIndexBase; + for (S32 j = 0; j < mesh.mNumTriangles; ++j) + { + F32* mp0 = (F32*) ((U8*)v+idx[0]*mesh.mVertexStrideBytes); + F32* mp1 = (F32*) ((U8*)v+idx[1]*mesh.mVertexStrideBytes); + F32* mp2 = (F32*) ((U8*)v+idx[2]*mesh.mVertexStrideBytes); + + idx = (U32*) (((U8*)idx)+mesh.mIndexStrideBytes); + + LLVector3 v0(mp0); + LLVector3 v1(mp1); + LLVector3 v2(mp2); + + LLVector3 n = (v1-v0)%(v2-v0); + n.normalize(); + + res.mPositions.push_back(v0*scale); + res.mPositions.push_back(v1*scale); + res.mPositions.push_back(v2*scale); + + res.mNormals.push_back(n); + res.mNormals.push_back(n); + res.mNormals.push_back(n); + } + } +} + +S32 LLMeshRepoThread::sActiveHeaderRequests = 0; +S32 LLMeshRepoThread::sActiveLODRequests = 0; +U32 LLMeshRepoThread::sMaxConcurrentRequests = 1; + + +class LLTextureCostResponder : public LLCurl::Responder +{ +public: + LLTextureUploadData mData; + LLMeshUploadThread* mThread; + + LLTextureCostResponder(LLTextureUploadData data, LLMeshUploadThread* thread) + : mData(data), mThread(thread) + { + + } + + virtual void completed(U32 status, const std::string& reason, const LLSD& content) + { + mThread->mPendingConfirmations--; + if (isGoodStatus(status)) + { + mThread->priceResult(mData, content); + } + else + { + llwarns << status << ": " << reason << llendl; + + if (mData.mRetries < MAX_TEXTURE_UPLOAD_RETRIES) + { + llwarns << "Retrying. (" << ++mData.mRetries << ")" << llendl; + + if (status == 499 || status == 500) + { + mThread->uploadTexture(mData); + } + else + { + llerrs << "Unhandled status " << status << llendl; + } + } + else + { + llwarns << "Giving up after " << mData.mRetries << " retries." << llendl; + } + } + } +}; + +class LLTextureUploadResponder : public LLCurl::Responder +{ +public: + LLTextureUploadData mData; + LLMeshUploadThread* mThread; + + LLTextureUploadResponder(LLTextureUploadData data, LLMeshUploadThread* thread) + : mData(data), mThread(thread) + { + } + + virtual void completed(U32 status, const std::string& reason, const LLSD& content) + { + mThread->mPendingUploads--; + if (isGoodStatus(status)) + { + mData.mUUID = content["new_asset"].asUUID(); + gMeshRepo.updateInventory(LLMeshRepository::inventory_data(mData.mPostData, content)); + mThread->onTextureUploaded(mData); + } + else + { + llwarns << status << ": " << reason << llendl; + llwarns << "Retrying. (" << ++mData.mRetries << ")" << llendl; + + if (status == 404) + { + mThread->uploadTexture(mData); + } + else if (status == 499) + { + mThread->mConfirmedTextureQ.push(mData); + } + else + { + llerrs << "Unhandled status " << status << llendl; + } + } + } +}; + +class LLMeshCostResponder : public LLCurl::Responder +{ +public: + LLMeshUploadData mData; + LLMeshUploadThread* mThread; + + LLMeshCostResponder(LLMeshUploadData data, LLMeshUploadThread* thread) + : mData(data), mThread(thread) + { + + } + + virtual void completed(U32 status, const std::string& reason, const LLSD& content) + { + mThread->mPendingConfirmations--; + + if (isGoodStatus(status)) + { + mThread->priceResult(mData, content); + } + else + { + llwarns << status << ": " << reason << llendl; + + if (status == HTTP_INTERNAL_ERROR) + { + llwarns << "Retrying. (" << ++mData.mRetries << ")" << llendl; + mThread->uploadModel(mData); + } + else if (status == HTTP_BAD_REQUEST) + { + llwarns << "Status 400 received from server, giving up." << llendl; + } + else if (status == HTTP_NOT_FOUND) + { + llwarns <<"Status 404 received, server is disconnected, giving up." << llendl ; + } + else + { + llerrs << "Unhandled status " << status << llendl; + } + } + } +}; + +class LLMeshUploadResponder : public LLCurl::Responder +{ +public: + LLMeshUploadData mData; + LLMeshUploadThread* mThread; + + LLMeshUploadResponder(LLMeshUploadData data, LLMeshUploadThread* thread) + : mData(data), mThread(thread) + { + } + + virtual void completed(U32 status, const std::string& reason, const LLSD& content) + { + mThread->mPendingUploads--; + if (isGoodStatus(status)) + { + mData.mUUID = content["new_asset"].asUUID(); + if (mData.mUUID.isNull()) + { + LLSD args; + std::string message = content["error"]["message"]; + std::string identifier = content["error"]["identifier"]; + std::string invalidity_identifier = content["error"]["invalidity_identifier"]; + + args["MESSAGE"] = message; + args["IDENTIFIER"] = identifier; + args["INVALIDITY_IDENTIFIER"] = invalidity_identifier; + args["LABEL"] = mData.mBaseModel->mLabel; + + gMeshRepo.uploadError(args); + } + else + { + gMeshRepo.updateInventory(LLMeshRepository::inventory_data(mData.mPostData, content)); + mThread->onModelUploaded(mData); + } + } + else + { + llwarns << status << ": " << reason << llendl; + llwarns << "Retrying. (" << ++mData.mRetries << ")" << llendl; + + if (status == 404) + { + mThread->uploadModel(mData); + } + else if (status == 499) + { + mThread->mConfirmedQ.push(mData); + } + else if (status != 500) + { //drop internal server errors on the floor, otherwise grab + llerrs << "Unhandled status " << status << llendl; + } + } + } +}; + + +class LLMeshHeaderResponder : public LLCurl::Responder +{ +public: + LLVolumeParams mMeshParams; + + LLMeshHeaderResponder(const LLVolumeParams& mesh_params) + : mMeshParams(mesh_params) + { + } + + virtual void completedRaw(U32 status, const std::string& reason, + const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer); + +}; + +class LLMeshLODResponder : public LLCurl::Responder +{ +public: + LLVolumeParams mMeshParams; + S32 mLOD; + U32 mRequestedBytes; + U32 mOffset; + + LLMeshLODResponder(const LLVolumeParams& mesh_params, S32 lod, U32 offset, U32 requested_bytes) + : mMeshParams(mesh_params), mLOD(lod), mOffset(offset), mRequestedBytes(requested_bytes) + { + } + + virtual void completedRaw(U32 status, const std::string& reason, + const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer); + +}; + +class LLMeshSkinInfoResponder : public LLCurl::Responder +{ +public: + LLUUID mMeshID; + U32 mRequestedBytes; + U32 mOffset; + + LLMeshSkinInfoResponder(const LLUUID& id, U32 offset, U32 size) + : mMeshID(id), mRequestedBytes(size), mOffset(offset) + { + } + + virtual void completedRaw(U32 status, const std::string& reason, + const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer); + +}; + +class LLMeshDecompositionResponder : public LLCurl::Responder +{ +public: + LLUUID mMeshID; + U32 mRequestedBytes; + U32 mOffset; + + LLMeshDecompositionResponder(const LLUUID& id, U32 offset, U32 size) + : mMeshID(id), mRequestedBytes(size), mOffset(offset) + { + } + + virtual void completedRaw(U32 status, const std::string& reason, + const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer); + +}; + +class LLMeshPhysicsShapeResponder : public LLCurl::Responder +{ +public: + LLUUID mMeshID; + U32 mRequestedBytes; + U32 mOffset; + + LLMeshPhysicsShapeResponder(const LLUUID& id, U32 offset, U32 size) + : mMeshID(id), mRequestedBytes(size), mOffset(offset) + { + } + + virtual void completedRaw(U32 status, const std::string& reason, + const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer); + +}; + +class LLModelObjectUploadResponder: public LLCurl::Responder +{ + LLSD mObjectAsset; + LLMeshUploadThread* mThread; + +public: + LLModelObjectUploadResponder(LLMeshUploadThread* thread, const LLSD& object_asset): + mThread(thread), + mObjectAsset(object_asset) + { + } + + virtual void completedRaw(U32 status, const std::string& reason, + const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer) + { + assert_main_thread(); + + llinfos << "completed" << llendl; + mThread->mPendingUploads--; + mThread->mFinished = true; + } +}; + +class LLWholeModelFeeResponder: public LLCurl::Responder +{ + LLMeshUploadThread* mThread; +public: + LLWholeModelFeeResponder(LLMeshUploadThread* thread): + mThread(thread) + { + } + virtual void completedRaw(U32 status, const std::string& reason, + const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer) + { + assert_main_thread(); + llinfos << "completed" << llendl; + mThread->mPendingUploads--; + } + +}; + +LLMeshRepoThread::LLMeshRepoThread() +: LLThread("mesh repo", NULL) +{ + mWaiting = false; + mMutex = new LLMutex(NULL); + mHeaderMutex = new LLMutex(NULL); + mSignal = new LLCondition(NULL); +} + +LLMeshRepoThread::~LLMeshRepoThread() +{ + delete mMutex; + mMutex = NULL; + delete mHeaderMutex; + mHeaderMutex = NULL; + delete mSignal; + mSignal = NULL; +} + +void LLMeshRepoThread::run() +{ + mCurlRequest = new LLCurlRequest(); + LLCDResult res = LLConvexDecomposition::initThread(); + if (res != LLCD_OK) + { + llwarns << "convex decomposition unable to be loaded" << llendl; + } + + while (!LLApp::isQuitting()) + { + mWaiting = true; + mSignal->wait(); + mWaiting = false; + + if (!LLApp::isQuitting()) + { + static U32 count = 0; + + static F32 last_hundred = gFrameTimeSeconds; + + if (gFrameTimeSeconds - last_hundred > 1.f) + { //a second has gone by, clear count + last_hundred = gFrameTimeSeconds; + count = 0; + } + + // NOTE: throttling intentionally favors LOD requests over header requests + + while (!mLODReqQ.empty() && count < MAX_MESH_REQUESTS_PER_SECOND && sActiveLODRequests < sMaxConcurrentRequests) + { + { + mMutex->lock(); + LODRequest req = mLODReqQ.front(); + mLODReqQ.pop(); + mMutex->unlock(); + if (fetchMeshLOD(req.mMeshParams, req.mLOD)) + { + count++; + } + } + } + + while (!mHeaderReqQ.empty() && count < MAX_MESH_REQUESTS_PER_SECOND && sActiveHeaderRequests < sMaxConcurrentRequests) + { + { + mMutex->lock(); + HeaderRequest req = mHeaderReqQ.front(); + mHeaderReqQ.pop(); + mMutex->unlock(); + if (fetchMeshHeader(req.mMeshParams)) + { + count++; + } + } + } + + { //mSkinRequests is protected by mSignal + std::set<LLUUID> incomplete; + for (std::set<LLUUID>::iterator iter = mSkinRequests.begin(); iter != mSkinRequests.end(); ++iter) + { + LLUUID mesh_id = *iter; + if (!fetchMeshSkinInfo(mesh_id)) + { + incomplete.insert(mesh_id); + } + } + mSkinRequests = incomplete; + } + + { //mDecompositionRequests is protected by mSignal + std::set<LLUUID> incomplete; + for (std::set<LLUUID>::iterator iter = mDecompositionRequests.begin(); iter != mDecompositionRequests.end(); ++iter) + { + LLUUID mesh_id = *iter; + if (!fetchMeshDecomposition(mesh_id)) + { + incomplete.insert(mesh_id); + } + } + mDecompositionRequests = incomplete; + } + + { //mPhysicsShapeRequests is protected by mSignal + std::set<LLUUID> incomplete; + for (std::set<LLUUID>::iterator iter = mPhysicsShapeRequests.begin(); iter != mPhysicsShapeRequests.end(); ++iter) + { + LLUUID mesh_id = *iter; + if (!fetchMeshPhysicsShape(mesh_id)) + { + incomplete.insert(mesh_id); + } + } + mPhysicsShapeRequests = incomplete; + } + + mCurlRequest->process(); + } + } + + if (mSignal->isLocked()) + { //make sure to let go of the mutex associated with the given signal before shutting down + mSignal->unlock(); + } + + res = LLConvexDecomposition::quitThread(); + if (res != LLCD_OK) + { + llwarns << "convex decomposition unable to be quit" << llendl; + } + + delete mCurlRequest; + mCurlRequest = NULL; +} + +void LLMeshRepoThread::loadMeshSkinInfo(const LLUUID& mesh_id) +{ //protected by mSignal, no locking needed here + mSkinRequests.insert(mesh_id); +} + +void LLMeshRepoThread::loadMeshDecomposition(const LLUUID& mesh_id) +{ //protected by mSignal, no locking needed here + mDecompositionRequests.insert(mesh_id); +} + +void LLMeshRepoThread::loadMeshPhysicsShape(const LLUUID& mesh_id) +{ //protected by mSignal, no locking needed here + mPhysicsShapeRequests.insert(mesh_id); +} + + +void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod) +{ //protected by mSignal, no locking needed here + + mesh_header_map::iterator iter = mMeshHeader.find(mesh_params.getSculptID()); + if (iter != mMeshHeader.end()) + { //if we have the header, request LOD byte range + LODRequest req(mesh_params, lod); + { + LLMutexLock lock(mMutex); + mLODReqQ.push(req); + } + } + else + { + HeaderRequest req(mesh_params); + + pending_lod_map::iterator pending = mPendingLOD.find(mesh_params); + + if (pending != mPendingLOD.end()) + { //append this lod request to existing header request + pending->second.push_back(lod); + if (pending->second.size() > 4) + { + llerrs << "WTF?" << llendl; + } + } + else + { //if no header request is pending, fetch header + LLMutexLock lock(mMutex); + mHeaderReqQ.push(req); + mPendingLOD[mesh_params].push_back(lod); + } + } +} + +//static +std::string LLMeshRepoThread::constructUrl(LLUUID mesh_id) +{ + std::string http_url; + + if (gAgent.getRegion()) + { + http_url = gMeshRepo.mGetMeshCapability; + } + + if (!http_url.empty()) + { + http_url += "/?mesh_id="; + http_url += mesh_id.asString().c_str(); + } + else + { + llwarns << "Current region does not have GetMesh capability! Cannot load " << mesh_id << ".mesh" << llendl; + } + + return http_url; +} + +bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) +{ //protected by mMutex + mHeaderMutex->lock(); + + if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) + { //we have no header info for this mesh, do nothing + mHeaderMutex->unlock(); + return false; + } + + U32 header_size = mMeshHeaderSize[mesh_id]; + + if (header_size > 0) + { + S32 offset = header_size + mMeshHeader[mesh_id]["skin"]["offset"].asInteger(); + S32 size = mMeshHeader[mesh_id]["skin"]["size"].asInteger(); + + mHeaderMutex->unlock(); + + if (offset >= 0 && size > 0) + { + //check VFS for mesh skin info + LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); + if (file.getSize() >= offset+size) + { + LLMeshRepository::sCacheBytesRead += size; + file.seek(offset); + U8* buffer = new U8[size]; + file.read(buffer, size); + + //make sure buffer isn't all 0's (reserved block but not written) + bool zero = true; + for (S32 i = 0; i < llmin(size, 1024) && zero; ++i) + { + zero = buffer[i] > 0 ? false : true; + } + + if (!zero) + { //attempt to parse + if (skinInfoReceived(mesh_id, buffer, size)) + { + delete[] buffer; + return true; + } + } + + delete[] buffer; + } + + //reading from VFS failed for whatever reason, fetch from sim + std::vector<std::string> headers; + headers.push_back("Accept: application/octet-stream"); + + std::string http_url = constructUrl(mesh_id); + if (!http_url.empty()) + { + ++sActiveLODRequests; + LLMeshRepository::sHTTPRequestCount++; + mCurlRequest->getByteRange(constructUrl(mesh_id), headers, offset, size, + new LLMeshSkinInfoResponder(mesh_id, offset, size)); + } + } + } + else + { + mHeaderMutex->unlock(); + } + + //early out was not hit, effectively fetched + return true; +} + +bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) +{ //protected by mMutex + mHeaderMutex->lock(); + + if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) + { //we have no header info for this mesh, do nothing + mHeaderMutex->unlock(); + return false; + } + + U32 header_size = mMeshHeaderSize[mesh_id]; + + if (header_size > 0) + { + S32 offset = header_size + mMeshHeader[mesh_id]["decomposition"]["offset"].asInteger(); + S32 size = mMeshHeader[mesh_id]["decomposition"]["size"].asInteger(); + + mHeaderMutex->unlock(); + + if (offset >= 0 && size > 0) + { + //check VFS for mesh skin info + LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); + if (file.getSize() >= offset+size) + { + LLMeshRepository::sCacheBytesRead += size; + file.seek(offset); + U8* buffer = new U8[size]; + file.read(buffer, size); + + //make sure buffer isn't all 0's (reserved block but not written) + bool zero = true; + for (S32 i = 0; i < llmin(size, 1024) && zero; ++i) + { + zero = buffer[i] > 0 ? false : true; + } + + if (!zero) + { //attempt to parse + if (decompositionReceived(mesh_id, buffer, size)) + { + delete[] buffer; + return true; + } + } + + delete[] buffer; + } + + //reading from VFS failed for whatever reason, fetch from sim + std::vector<std::string> headers; + headers.push_back("Accept: application/octet-stream"); + + std::string http_url = constructUrl(mesh_id); + if (!http_url.empty()) + { + ++sActiveLODRequests; + LLMeshRepository::sHTTPRequestCount++; + mCurlRequest->getByteRange(http_url, headers, offset, size, + new LLMeshDecompositionResponder(mesh_id, offset, size)); + } + } + } + else + { + mHeaderMutex->unlock(); + } + + //early out was not hit, effectively fetched + return true; +} + +bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) +{ //protected by mMutex + mHeaderMutex->lock(); + + if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) + { //we have no header info for this mesh, do nothing + mHeaderMutex->unlock(); + return false; + } + + U32 header_size = mMeshHeaderSize[mesh_id]; + + if (header_size > 0) + { + S32 offset = header_size + mMeshHeader[mesh_id]["physics_shape"]["offset"].asInteger(); + S32 size = mMeshHeader[mesh_id]["physics_shape"]["size"].asInteger(); + + mHeaderMutex->unlock(); + + if (offset >= 0 && size > 0) + { + //check VFS for mesh physics shape info + LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); + if (file.getSize() >= offset+size) + { + LLMeshRepository::sCacheBytesRead += size; + file.seek(offset); + U8* buffer = new U8[size]; + file.read(buffer, size); + + //make sure buffer isn't all 0's (reserved block but not written) + bool zero = true; + for (S32 i = 0; i < llmin(size, 1024) && zero; ++i) + { + zero = buffer[i] > 0 ? false : true; + } + + if (!zero) + { //attempt to parse + if (physicsShapeReceived(mesh_id, buffer, size)) + { + delete[] buffer; + return true; + } + } + + delete[] buffer; + } + + //reading from VFS failed for whatever reason, fetch from sim + std::vector<std::string> headers; + headers.push_back("Accept: application/octet-stream"); + + std::string http_url = constructUrl(mesh_id); + if (!http_url.empty()) + { + ++sActiveLODRequests; + LLMeshRepository::sHTTPRequestCount++; + mCurlRequest->getByteRange(http_url, headers, offset, size, + new LLMeshPhysicsShapeResponder(mesh_id, offset, size)); + } + } + else + { //no physics shape whatsoever, report back NULL + physicsShapeReceived(mesh_id, NULL, 0); + } + } + else + { + mHeaderMutex->unlock(); + } + + //early out was not hit, effectively fetched + return true; +} + +bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params) +{ + bool retval = false; + + { + //look for mesh in asset in vfs + LLVFile file(gVFS, mesh_params.getSculptID(), LLAssetType::AT_MESH); + + S32 size = file.getSize(); + + if (size > 0) + { + U8 buffer[1024]; + S32 bytes = llmin(size, 1024); + LLMeshRepository::sCacheBytesRead += bytes; + file.read(buffer, bytes); + if (headerReceived(mesh_params, buffer, bytes)) + { //did not do an HTTP request, return false + return false; + } + } + } + + //either cache entry doesn't exist or is corrupt, request header from simulator + + std::vector<std::string> headers; + headers.push_back("Accept: application/octet-stream"); + + std::string http_url = constructUrl(mesh_params.getSculptID()); + if (!http_url.empty()) + { + ++sActiveHeaderRequests; + retval = true; + //grab first 4KB if we're going to bother with a fetch. Cache will prevent future fetches if a full mesh fits + //within the first 4KB + LLMeshRepository::sHTTPRequestCount++; + mCurlRequest->getByteRange(http_url, headers, 0, 4096, new LLMeshHeaderResponder(mesh_params)); + } + + return retval; +} + +bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod) +{ //protected by mMutex + mHeaderMutex->lock(); + + bool retval = false; + + LLUUID mesh_id = mesh_params.getSculptID(); + + U32 header_size = mMeshHeaderSize[mesh_id]; + + if (header_size > 0) + { + S32 offset = header_size + mMeshHeader[mesh_id][header_lod[lod]]["offset"].asInteger(); + S32 size = mMeshHeader[mesh_id][header_lod[lod]]["size"].asInteger(); + mHeaderMutex->unlock(); + if (offset >= 0 && size > 0) + { + + //check VFS for mesh asset + LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH); + if (file.getSize() >= offset+size) + { + LLMeshRepository::sCacheBytesRead += size; + file.seek(offset); + U8* buffer = new U8[size]; + file.read(buffer, size); + + //make sure buffer isn't all 0's (reserved block but not written) + bool zero = true; + for (S32 i = 0; i < llmin(size, 1024) && zero; ++i) + { + zero = buffer[i] > 0 ? false : true; + } + + if (!zero) + { //attempt to parse + if (lodReceived(mesh_params, lod, buffer, size)) + { + delete[] buffer; + return false; + } + } + + delete[] buffer; + } + + //reading from VFS failed for whatever reason, fetch from sim + std::vector<std::string> headers; + headers.push_back("Accept: application/octet-stream"); + + std::string http_url = constructUrl(mesh_id); + if (!http_url.empty()) + { + ++sActiveLODRequests; + retval = true; + LLMeshRepository::sHTTPRequestCount++; + mCurlRequest->getByteRange(constructUrl(mesh_id), headers, offset, size, + new LLMeshLODResponder(mesh_params, lod, offset, size)); + } + else + { + mUnavailableQ.push(LODRequest(mesh_params, lod)); + } + } + else + { + mUnavailableQ.push(LODRequest(mesh_params, lod)); + } + } + else + { + mHeaderMutex->unlock(); + } + + return retval; +} + +bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size) +{ + LLSD header; + + U32 header_size = 0; + if (data_size > 0) + { + std::string res_str((char*) data, data_size); + + std::string deprecated_header("<? LLSD/Binary ?>"); + + if (res_str.substr(0, deprecated_header.size()) == deprecated_header) + { + res_str = res_str.substr(deprecated_header.size()+1, data_size); + header_size = deprecated_header.size()+1; + } + data_size = res_str.size(); + + std::istringstream stream(res_str); + + if (!LLSDSerialize::fromBinary(header, stream, data_size)) + { + llwarns << "Mesh header parse error. Not a valid mesh asset!" << llendl; + return false; + } + + header_size += stream.tellg(); + } + else + { + llinfos + << "Marking header as non-existent, will not retry." << llendl; + header["404"] = 1; + } + + { + U32 cost = gMeshRepo.calcResourceCost(header); + + LLUUID mesh_id = mesh_params.getSculptID(); + + mHeaderMutex->lock(); + mMeshHeaderSize[mesh_id] = header_size; + mMeshHeader[mesh_id] = header; + mMeshResourceCost[mesh_id] = cost; + mHeaderMutex->unlock(); + + //check for pending requests + pending_lod_map::iterator iter = mPendingLOD.find(mesh_params); + if (iter != mPendingLOD.end()) + { + LLMutexLock lock(mMutex); + for (U32 i = 0; i < iter->second.size(); ++i) + { + LODRequest req(mesh_params, iter->second[i]); + mLODReqQ.push(req); + } + } + mPendingLOD.erase(iter); + } + + return true; +} + +bool LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size) +{ + LLVolume* volume = new LLVolume(mesh_params, LLVolumeLODGroup::getVolumeScaleFromDetail(lod)); + std::string mesh_string((char*) data, data_size); + std::istringstream stream(mesh_string); + + if (volume->unpackVolumeFaces(stream, data_size)) + { + LoadedMesh mesh(volume, mesh_params, lod); + if (volume->getNumFaces() > 0) + { + LLMutexLock lock(mMutex); + mLoadedQ.push(mesh); + return true; + } + } + + return false; +} + +bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size) +{ + LLSD skin; + + if (data_size > 0) + { + std::string res_str((char*) data, data_size); + + std::istringstream stream(res_str); + + if (!unzip_llsd(skin, stream, data_size)) + { + llwarns << "Mesh skin info parse error. Not a valid mesh asset!" << llendl; + return false; + } + } + + { + LLMeshSkinInfo info(skin); + info.mMeshID = mesh_id; + + //llinfos<<"info pelvis offset"<<info.mPelvisOffset<<llendl; + mSkinInfoQ.push(info); + } + + return true; +} + +bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size) +{ + LLSD decomp; + + if (data_size > 0) + { + std::string res_str((char*) data, data_size); + + std::istringstream stream(res_str); + + if (!unzip_llsd(decomp, stream, data_size)) + { + llwarns << "Mesh decomposition parse error. Not a valid mesh asset!" << llendl; + return false; + } + } + + { + LLModel::Decomposition* d = new LLModel::Decomposition(decomp); + d->mMeshID = mesh_id; + mDecompositionQ.push(d); + } + + return true; +} + +bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size) +{ + LLSD physics_shape; + + LLModel::Decomposition* d = new LLModel::Decomposition(); + d->mMeshID = mesh_id; + + if (data == NULL) + { //no data, no physics shape exists + d->mPhysicsShapeMesh.clear(); + } + else + { + LLVolumeParams volume_params; + volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); + volume_params.setSculptID(mesh_id, LL_SCULPT_TYPE_MESH); + LLPointer<LLVolume> volume = new LLVolume(volume_params,0); + std::string mesh_string((char*) data, data_size); + std::istringstream stream(mesh_string); + + if (volume->unpackVolumeFaces(stream, data_size)) + { + //load volume faces into decomposition buffer + S32 vertex_count = 0; + S32 index_count = 0; + + for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) + { + const LLVolumeFace& face = volume->getVolumeFace(i); + vertex_count += face.mNumVertices; + index_count += face.mNumIndices; + } + + d->mPhysicsShapeMesh.clear(); + + std::vector<LLVector3>& pos = d->mPhysicsShapeMesh.mPositions; + std::vector<LLVector3>& norm = d->mPhysicsShapeMesh.mNormals; + + for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) + { + const LLVolumeFace& face = volume->getVolumeFace(i); + + for (S32 i = 0; i < face.mNumIndices; ++i) + { + U16 idx = face.mIndices[i]; + + pos.push_back(LLVector3(face.mPositions[idx].getF32ptr())); + norm.push_back(LLVector3(face.mNormals[idx].getF32ptr())); + } + } + } + } + + mDecompositionQ.push(d); + return true; +} + +LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, LLVector3& scale, bool upload_textures, + bool upload_skin, bool upload_joints) +: LLThread("mesh upload"), + mDiscarded(FALSE) +{ + mInstanceList = data; + mUploadTextures = upload_textures; + mUploadSkin = upload_skin; + mUploadJoints = upload_joints; + mMutex = new LLMutex(NULL); + mCurlRequest = NULL; + mPendingConfirmations = 0; + mPendingUploads = 0; + mPendingCost = 0; + mFinished = false; + mOrigin = gAgent.getPositionAgent(); + mHost = gAgent.getRegionHost(); + + mUploadObjectAssetCapability = gAgent.getRegion()->getCapability("UploadObjectAsset"); + mNewInventoryCapability = gAgent.getRegion()->getCapability("NewFileAgentInventoryVariablePrice"); + mWholeModelUploadCapability = gAgent.getRegion()->getCapability("NewFileAgentInventory"); + + mOrigin += gAgent.getAtAxis() * scale.magVec(); +} + +LLMeshUploadThread::~LLMeshUploadThread() +{ + +} + +LLMeshUploadThread::DecompRequest::DecompRequest(LLModel* mdl, LLModel* base_model, LLMeshUploadThread* thread) +{ + mStage = "single_hull"; + mModel = mdl; + mDecompID = &mdl->mDecompID; + mBaseModel = base_model; + mThread = thread; + + //copy out positions and indices + if (mdl) + { + U16 index_offset = 0; + + mPositions.clear(); + mIndices.clear(); + + //queue up vertex positions and indices + for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i) + { + const LLVolumeFace& face = mdl->getVolumeFace(i); + if (mPositions.size() + face.mNumVertices > 65535) + { + continue; + } + + for (U32 j = 0; j < face.mNumVertices; ++j) + { + mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr())); + } + + for (U32 j = 0; j < face.mNumIndices; ++j) + { + mIndices.push_back(face.mIndices[j]+index_offset); + } + + index_offset += face.mNumVertices; + } + } + + mThread->mFinalDecomp = this; + mThread->mPhysicsComplete = false; +} + +void LLMeshUploadThread::DecompRequest::completed() +{ + if (mThread->mFinalDecomp == this) + { + mThread->mPhysicsComplete = true; + } + + if (mHull.size() != 1) + { + llerrs << "WTF?" << llendl; + } + + mThread->mHullMap[mBaseModel] = mHull[0]; +} + +//called in the main thread. +void LLMeshUploadThread::preStart() +{ + //build map of LLModel refs to instances for callbacks + for (instance_list::iterator iter = mInstanceList.begin(); iter != mInstanceList.end(); ++iter) + { + mInstance[iter->mModel].push_back(*iter); + } +} + +void LLMeshUploadThread::discard() +{ + LLMutexLock lock(mMutex) ; + mDiscarded = TRUE ; +} + +BOOL LLMeshUploadThread::isDiscarded() +{ + LLMutexLock lock(mMutex) ; + return mDiscarded ; +} + +void LLMeshUploadThread::run() +{ + if (gSavedSettings.getBOOL("MeshUseWholeModelUpload")) + { + doWholeModelUpload(); + } + else + { + doIterativeUpload(); + } +} + +#if 0 +void dumpLLSDToFile(LLSD& content, std::string& filename) +{ + std::ofstream of(filename); + LLSDSerialize::toPrettyXML(content,of); +} +#endif + +void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) +{ + // TODO where do textures go? + + LLSD result; + + result["folder_id"] = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT); + result["asset_type"] = "mesh"; + result["inventory_type"] = "object"; + result["name"] = "your name here"; + result["description"] = "your description here"; + + // TODO "optional" fields from the spec + + LLSD res; + res["mesh_list"] = LLSD::emptyArray(); + res["texture_list"] = LLSD::emptyArray(); + S32 mesh_num = 0; + S32 texture_num = 0; + + std::set<LLViewerTexture* > textures; + + for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter) + { + LLMeshUploadData data; + data.mBaseModel = iter->first; + + LLModelInstance& instance = *(iter->second.begin()); + + for (S32 i = 0; i < 5; i++) + { + data.mModel[i] = instance.mLOD[i]; + } + + std::stringstream ostr; + + LLModel::Decomposition& decomp = + data.mModel[LLModel::LOD_PHYSICS].notNull() ? + data.mModel[LLModel::LOD_PHYSICS]->mPhysics : + data.mBaseModel->mPhysics; + + decomp.mBaseHull = mHullMap[data.mBaseModel]; + + LLSD mesh_header = LLModel::writeModel( + ostr, + data.mModel[LLModel::LOD_PHYSICS], + data.mModel[LLModel::LOD_HIGH], + data.mModel[LLModel::LOD_MEDIUM], + data.mModel[LLModel::LOD_LOW], + data.mModel[LLModel::LOD_IMPOSTOR], + decomp, + mUploadSkin, + mUploadJoints); + + data.mAssetData = ostr.str(); + + LLSD mesh_entry; + + LLVector3 pos, scale; + LLQuaternion rot; + LLMatrix4 transformation = instance.mTransform; + decomposeMeshMatrix(transformation,pos,rot,scale); + + mesh_entry["childpos"] = ll_sd_from_vector3(pos); + mesh_entry["childrot"] = ll_sd_from_quaternion(rot); + mesh_entry["scale"] = ll_sd_from_vector3(scale); + + // TODO should be binary. + std::string str = ostr.str(); + mesh_entry["mesh_data"] = LLSD::Binary(str.begin(),str.end()); + + res["mesh_list"][mesh_num] = mesh_entry; + + // TODO how do textures in the list map to textures in the meshes? + if (mUploadTextures) + { + for (std::vector<LLImportMaterial>::iterator material_iter = instance.mMaterial.begin(); + material_iter != instance.mMaterial.end(); ++material_iter) + { + + if (textures.find(material_iter->mDiffuseMap.get()) == textures.end()) + { + textures.insert(material_iter->mDiffuseMap.get()); + + std::stringstream ostr; + if (include_textures) // otherwise data is blank. + { + LLTextureUploadData data(material_iter->mDiffuseMap.get(), material_iter->mDiffuseMapLabel); + if (!data.mTexture->isRawImageValid()) + { + data.mTexture->reloadRawImage(data.mTexture->getDiscardLevel()); + } + + LLPointer<LLImageJ2C> upload_file = + LLViewerTextureList::convertToUploadFile(data.mTexture->getRawImage()); + ostr.write((const char*) upload_file->getData(), upload_file->getDataSize()); + } + LLSD texture_entry; + texture_entry["texture_data"] = ostr.str(); + res["texture_list"][texture_num] = texture_entry; + texture_num++; + } + } + } + + mesh_num++; + } + + result["asset_resources"] = res; +#if 0 + std::string name("whole_model.xml"); + dumpLLSDToFile(result,name); +#endif + + dest = result; +} + +void LLMeshUploadThread::doWholeModelUpload() +{ + mCurlRequest = new LLCurlRequest(); + + // Queue up models for hull generation (viewer-side) + for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter) + { + LLMeshUploadData data; + data.mBaseModel = iter->first; + + LLModelInstance& instance = *(iter->second.begin()); + + for (S32 i = 0; i < 5; i++) + { + data.mModel[i] = instance.mLOD[i]; + } + + //queue up models for hull generation + LLModel* physics = NULL; + + if (data.mModel[LLModel::LOD_PHYSICS].notNull()) + { + physics = data.mModel[LLModel::LOD_PHYSICS]; + } + else if (data.mModel[LLModel::LOD_MEDIUM].notNull()) + { + physics = data.mModel[LLModel::LOD_MEDIUM]; + } + else + { + physics = data.mModel[LLModel::LOD_HIGH]; + } + + if (!physics) + { + llerrs << "WTF?" << llendl; + } + + DecompRequest* request = new DecompRequest(physics, data.mBaseModel, this); + gMeshRepo.mDecompThread->submitRequest(request); + } + + while (!mPhysicsComplete) + { + apr_sleep(100); + } + + bool do_include_textures = false; // not needed for initial cost/validation check. + LLSD model_data; + wholeModelToLLSD(model_data, do_include_textures); + + mPendingUploads++; + LLCurlRequest::headers_t headers; + mCurlRequest->post(mWholeModelUploadCapability, headers, model_data.asString(), + new LLWholeModelFeeResponder(this)); + + // Currently a no-op. + mFinished = true; +} + +void LLMeshUploadThread::doIterativeUpload() +{ + if(isDiscarded()) + { + mFinished = true; + return ; + } + + mCurlRequest = new LLCurlRequest(); + + std::set<LLViewerTexture* > textures; + + //populate upload queue with relevant models + for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter) + { + LLMeshUploadData data; + data.mBaseModel = iter->first; + + LLModelInstance& instance = *(iter->second.begin()); + + for (S32 i = 0; i < 5; i++) + { + data.mModel[i] = instance.mLOD[i]; + } + + uploadModel(data); + + if (mUploadTextures) + { + for (std::vector<LLImportMaterial>::iterator material_iter = instance.mMaterial.begin(); + material_iter != instance.mMaterial.end(); ++material_iter) + { + + if (textures.find(material_iter->mDiffuseMap.get()) == textures.end()) + { + textures.insert(material_iter->mDiffuseMap.get()); + + LLTextureUploadData data(material_iter->mDiffuseMap.get(), material_iter->mDiffuseMapLabel); + uploadTexture(data); + } + } + } + + //queue up models for hull generation + DecompRequest* request = new DecompRequest(data.mModel[LLModel::LOD_HIGH], data.mBaseModel, this); + gMeshRepo.mDecompThread->submitRequest(request); + } + + while (!mPhysicsComplete) + { + apr_sleep(100); + } + + //upload textures + bool done = false; + do + { + if (!mTextureQ.empty()) + { + sendCostRequest(mTextureQ.front()); + mTextureQ.pop(); + } + + if (!mConfirmedTextureQ.empty()) + { + doUploadTexture(mConfirmedTextureQ.front()); + mConfirmedTextureQ.pop(); + } + + mCurlRequest->process(); + + done = mTextureQ.empty() && mConfirmedTextureQ.empty(); + } + while (!done || mCurlRequest->getQueued() > 0); + + LLSD object_asset; + object_asset["objects"] = LLSD::emptyArray(); + + done = false; + do + { + static S32 count = 0; + static F32 last_hundred = gFrameTimeSeconds; + if (gFrameTimeSeconds - last_hundred > 1.f) + { + last_hundred = gFrameTimeSeconds; + count = 0; + } + + //how many requests to push before calling process + const S32 PUSH_PER_PROCESS = 32; + + S32 tcount = llmin(count+PUSH_PER_PROCESS, 100); + + while (!mUploadQ.empty() && count < tcount) + { //send any pending upload requests + mMutex->lock(); + LLMeshUploadData data = mUploadQ.front(); + mUploadQ.pop(); + mMutex->unlock(); + sendCostRequest(data); + count++; + } + + tcount = llmin(count+PUSH_PER_PROCESS, 100); + + while (!mConfirmedQ.empty() && count < tcount) + { //process any meshes that have been confirmed for upload + LLMeshUploadData& data = mConfirmedQ.front(); + doUploadModel(data); + mConfirmedQ.pop(); + count++; + } + + tcount = llmin(count+PUSH_PER_PROCESS, 100); + + while (!mInstanceQ.empty() && count < tcount && !isDiscarded()) + { //create any objects waiting for upload + count++; + object_asset["objects"].append(createObject(mInstanceQ.front())); + mInstanceQ.pop(); + } + + mCurlRequest->process(); + + done = isDiscarded() || (mInstanceQ.empty() && mConfirmedQ.empty() && mUploadQ.empty()); + } + while (!done || mCurlRequest->getQueued() > 0); + + delete mCurlRequest; + mCurlRequest = NULL; + + // now upload the object asset + std::string url = mUploadObjectAssetCapability; + + if (object_asset["objects"][0].has("permissions")) + { //copy permissions from first available object to be used for coalesced object + object_asset["permissions"] = object_asset["objects"][0]["permissions"]; + } + + if(!isDiscarded()) + { + mPendingUploads++; + LLHTTPClient::post(url, object_asset, new LLModelObjectUploadResponder(this,object_asset)); + } + else + { + mFinished = true; + } +} + +void LLMeshUploadThread::uploadModel(LLMeshUploadData& data) +{ //called from arbitrary thread + { + LLMutexLock lock(mMutex); + mUploadQ.push(data); + } +} + +void LLMeshUploadThread::uploadTexture(LLTextureUploadData& data) +{ //called from mesh upload thread + mTextureQ.push(data); +} + + +static LLFastTimer::DeclareTimer FTM_NOTIFY_MESH_LOADED("Notify Loaded"); +static LLFastTimer::DeclareTimer FTM_NOTIFY_MESH_UNAVAILABLE("Notify Unavailable"); + +void LLMeshRepoThread::notifyLoadedMeshes() +{ + while (!mLoadedQ.empty()) + { + mMutex->lock(); + LoadedMesh mesh = mLoadedQ.front(); + mLoadedQ.pop(); + mMutex->unlock(); + + if (mesh.mVolume && mesh.mVolume->getNumVolumeFaces() > 0) + { + gMeshRepo.notifyMeshLoaded(mesh.mMeshParams, mesh.mVolume); + } + else + { + gMeshRepo.notifyMeshUnavailable(mesh.mMeshParams, + LLVolumeLODGroup::getVolumeDetailFromScale(mesh.mVolume->getDetail())); + } + } + + while (!mUnavailableQ.empty()) + { + mMutex->lock(); + LODRequest req = mUnavailableQ.front(); + mUnavailableQ.pop(); + mMutex->unlock(); + + gMeshRepo.notifyMeshUnavailable(req.mMeshParams, req.mLOD); + } + + while (!mSkinInfoQ.empty()) + { + gMeshRepo.notifySkinInfoReceived(mSkinInfoQ.front()); + mSkinInfoQ.pop(); + } + + while (!mDecompositionQ.empty()) + { + gMeshRepo.notifyDecompositionReceived(mDecompositionQ.front()); + mDecompositionQ.pop(); + } +} + +S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod) +{ //only ever called from main thread + LLMutexLock lock(mHeaderMutex); + mesh_header_map::iterator iter = mMeshHeader.find(mesh_params.getSculptID()); + + if (iter != mMeshHeader.end()) + { + LLSD& header = iter->second; + + return LLMeshRepository::getActualMeshLOD(header, lod); + } + + return lod; +} + +//static +S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod) +{ + lod = llclamp(lod, 0, 3); + + if (header.has("404")) + { + return -1; + } + + if (header[header_lod[lod]]["size"].asInteger() > 0) + { + return lod; + } + + //search down to find the next available lower lod + for (S32 i = lod-1; i >= 0; --i) + { + if (header[header_lod[i]]["size"].asInteger() > 0) + { + return i; + } + } + + //search up to find then ext available higher lod + for (S32 i = lod+1; i < 4; ++i) + { + if (header[header_lod[i]]["size"].asInteger() > 0) + { + return i; + } + } + + //header exists and no good lod found, treat as 404 + header["404"] = 1; + return -1; +} + +U32 LLMeshRepoThread::getResourceCost(const LLUUID& mesh_id) +{ + LLMutexLock lock(mHeaderMutex); + + std::map<LLUUID, U32>::iterator iter = mMeshResourceCost.find(mesh_id); + if (iter != mMeshResourceCost.end()) + { + return iter->second; + } + + return 0; +} + +void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header) +{ + mThread->mMeshHeader[data.mUUID] = header; + + // we cache the mesh for default parameters + LLVolumeParams volume_params; + volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); + volume_params.setSculptID(data.mUUID, LL_SCULPT_TYPE_MESH); + + for (U32 i = 0; i < 4; i++) + { + if (data.mModel[i].notNull()) + { + LLPointer<LLVolume> volume = new LLVolume(volume_params, LLVolumeLODGroup::getVolumeScaleFromDetail(i)); + volume->copyVolumeFaces(data.mModel[i]); + } + } + +} + +void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason, + const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer) +{ + + LLMeshRepoThread::sActiveLODRequests--; + S32 data_size = buffer->countAfter(channels.in(), NULL); + + if (status < 200 || status > 400) + { + llwarns << status << ": " << reason << llendl; + } + + if (data_size < mRequestedBytes) + { + if (status == 499 || status == 503) + { //timeout or service unavailable, try again + LLMeshRepository::sHTTPRetryCount++; + gMeshRepo.mThread->loadMeshLOD(mMeshParams, mLOD); + } + else + { + llwarns << "Unhandled status " << status << llendl; + } + return; + } + + LLMeshRepository::sBytesReceived += mRequestedBytes; + + U8* data = NULL; + + if (data_size > 0) + { + data = new U8[data_size]; + buffer->readAfter(channels.in(), NULL, data, data_size); + } + + if (gMeshRepo.mThread->lodReceived(mMeshParams, mLOD, data, data_size)) + { + //good fetch from sim, write to VFS for caching + LLVFile file(gVFS, mMeshParams.getSculptID(), LLAssetType::AT_MESH, LLVFile::WRITE); + + S32 offset = mOffset; + S32 size = mRequestedBytes; + + if (file.getSize() >= offset+size) + { + file.seek(offset); + file.write(data, size); + LLMeshRepository::sCacheBytesWritten += size; + } + } + + delete [] data; +} + +void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason, + const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer) +{ + S32 data_size = buffer->countAfter(channels.in(), NULL); + + if (status < 200 || status > 400) + { + llwarns << status << ": " << reason << llendl; + } + + if (data_size < mRequestedBytes) + { + if (status == 499 || status == 503) + { //timeout or service unavailable, try again + LLMeshRepository::sHTTPRetryCount++; + gMeshRepo.mThread->loadMeshSkinInfo(mMeshID); + } + else + { + llwarns << "Unhandled status " << status << llendl; + } + return; + } + + LLMeshRepository::sBytesReceived += mRequestedBytes; + + U8* data = NULL; + + if (data_size > 0) + { + data = new U8[data_size]; + buffer->readAfter(channels.in(), NULL, data, data_size); + } + + if (gMeshRepo.mThread->skinInfoReceived(mMeshID, data, data_size)) + { + //good fetch from sim, write to VFS for caching + LLVFile file(gVFS, mMeshID, LLAssetType::AT_MESH, LLVFile::WRITE); + + S32 offset = mOffset; + S32 size = mRequestedBytes; + + if (file.getSize() >= offset+size) + { + LLMeshRepository::sCacheBytesWritten += size; + file.seek(offset); + file.write(data, size); + } + } + + delete [] data; +} + +void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& reason, + const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer) +{ + S32 data_size = buffer->countAfter(channels.in(), NULL); + + if (status < 200 || status > 400) + { + llwarns << status << ": " << reason << llendl; + } + + if (data_size < mRequestedBytes) + { + if (status == 499 || status == 503) + { //timeout or service unavailable, try again + LLMeshRepository::sHTTPRetryCount++; + gMeshRepo.mThread->loadMeshDecomposition(mMeshID); + } + else + { + llwarns << "Unhandled status " << status << llendl; + } + return; + } + + LLMeshRepository::sBytesReceived += mRequestedBytes; + + U8* data = NULL; + + if (data_size > 0) + { + data = new U8[data_size]; + buffer->readAfter(channels.in(), NULL, data, data_size); + } + + if (gMeshRepo.mThread->decompositionReceived(mMeshID, data, data_size)) + { + //good fetch from sim, write to VFS for caching + LLVFile file(gVFS, mMeshID, LLAssetType::AT_MESH, LLVFile::WRITE); + + S32 offset = mOffset; + S32 size = mRequestedBytes; + + if (file.getSize() >= offset+size) + { + LLMeshRepository::sCacheBytesWritten += size; + file.seek(offset); + file.write(data, size); + } + } + + delete [] data; +} + +void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& reason, + const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer) +{ + S32 data_size = buffer->countAfter(channels.in(), NULL); + + if (status < 200 || status > 400) + { + llwarns << status << ": " << reason << llendl; + } + + if (data_size < mRequestedBytes) + { + if (status == 499 || status == 503) + { //timeout or service unavailable, try again + LLMeshRepository::sHTTPRetryCount++; + gMeshRepo.mThread->loadMeshPhysicsShape(mMeshID); + } + else + { + llwarns << "Unhandled status " << status << llendl; + } + return; + } + + LLMeshRepository::sBytesReceived += mRequestedBytes; + + U8* data = NULL; + + if (data_size > 0) + { + data = new U8[data_size]; + buffer->readAfter(channels.in(), NULL, data, data_size); + } + + if (gMeshRepo.mThread->physicsShapeReceived(mMeshID, data, data_size)) + { + //good fetch from sim, write to VFS for caching + LLVFile file(gVFS, mMeshID, LLAssetType::AT_MESH, LLVFile::WRITE); + + S32 offset = mOffset; + S32 size = mRequestedBytes; + + if (file.getSize() >= offset+size) + { + LLMeshRepository::sCacheBytesWritten += size; + file.seek(offset); + file.write(data, size); + } + } + + delete [] data; +} + +void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason, + const LLChannelDescriptors& channels, + const LLIOPipe::buffer_ptr_t& buffer) +{ + LLMeshRepoThread::sActiveHeaderRequests--; + if (status < 200 || status > 400) + { + //llwarns + // << "Header responder failed with status: " + // << status << ": " << reason << llendl; + + // 503 (service unavailable) or 499 (timeout) + // can be due to server load and can be retried + + // TODO*: Add maximum retry logic, exponential backoff + // and (somewhat more optional than the others) retries + // again after some set period of time + if (status == 503 || status == 499) + { //retry + LLMeshRepository::sHTTPRetryCount++; + LLMeshRepoThread::HeaderRequest req(mMeshParams); + LLMutexLock lock(gMeshRepo.mThread->mMutex); + gMeshRepo.mThread->mHeaderReqQ.push(req); + + return; + } + } + + S32 data_size = buffer->countAfter(channels.in(), NULL); + + U8* data = NULL; + + if (data_size > 0) + { + data = new U8[data_size]; + buffer->readAfter(channels.in(), NULL, data, data_size); + } + + LLMeshRepository::sBytesReceived += llmin(data_size, 4096); + + if (!gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size)) + { + llwarns + << "Unable to parse mesh header: " + << status << ": " << reason << llendl; + } + else if (data && data_size > 0) + { + //header was successfully retrieved from sim, cache in vfs + LLUUID mesh_id = mMeshParams.getSculptID(); + LLSD header = gMeshRepo.mThread->mMeshHeader[mesh_id]; + + std::stringstream str; + + S32 lod_bytes = 0; + + for (U32 i = 0; i < LLModel::LOD_PHYSICS; ++i) + { //figure out how many bytes we'll need to reserve in the file + std::string lod_name = header_lod[i]; + lod_bytes = llmax(lod_bytes, header[lod_name]["offset"].asInteger()+header[lod_name]["size"].asInteger()); + } + + //just in case skin info or decomposition is at the end of the file (which it shouldn't be) + lod_bytes = llmax(lod_bytes, header["skin"]["offset"].asInteger() + header["skin"]["size"].asInteger()); + lod_bytes = llmax(lod_bytes, header["decomposition"]["offset"].asInteger() + header["decomposition"]["size"].asInteger()); + + S32 header_bytes = (S32) gMeshRepo.mThread->mMeshHeaderSize[mesh_id]; + S32 bytes = lod_bytes + header_bytes; + + + //it's possible for the remote asset to have more data than is needed for the local cache + //only allocate as much space in the VFS as is needed for the local cache + data_size = llmin(data_size, bytes); + + LLVFile file(gVFS, mesh_id, LLAssetType::AT_MESH, LLVFile::WRITE); + if (file.getMaxSize() >= bytes || file.setMaxSize(bytes)) + { + LLMeshRepository::sCacheBytesWritten += data_size; + + file.write((const U8*) data, data_size); + + //zero out the rest of the file + U8 block[4096]; + memset(block, 0, 4096); + + while (bytes-file.tell() > 4096) + { + file.write(block, 4096); + } + + S32 remaining = bytes-file.tell(); + + if (remaining < 0 || remaining > 4096) + { + llerrs << "Bad padding of mesh asset cache entry." << llendl; + } + + if (remaining > 0) + { + file.write(block, remaining); + } + } + } + + delete [] data; +} + + +LLMeshRepository::LLMeshRepository() +: mMeshMutex(NULL), + mMeshThreadCount(0), + mThread(NULL) +{ + +} + +void LLMeshRepository::init() +{ + mMeshMutex = new LLMutex(NULL); + + LLConvexDecomposition::getInstance()->initSystem(); + + mDecompThread = new LLPhysicsDecomp(); + mDecompThread->start(); + + while (!mDecompThread->mInited) + { //wait for physics decomp thread to init + apr_sleep(100); + } + + + + mThread = new LLMeshRepoThread(); + mThread->start(); +} + +void LLMeshRepository::shutdown() +{ + llinfos << "Shutting down mesh repository." << llendl; + + for (U32 i = 0; i < mUploads.size(); ++i) + { + llinfos << "Discard the pending mesh uploads " << llendl; + mUploads[i]->discard() ; //discard the uploading requests. + } + + mThread->mSignal->signal(); + + while (!mThread->isStopped()) + { + apr_sleep(10); + } + delete mThread; + mThread = NULL; + + for (U32 i = 0; i < mUploads.size(); ++i) + { + llinfos << "Waiting for pending mesh upload " << i << "/" << mUploads.size() << llendl; + while (!mUploads[i]->isStopped()) + { + apr_sleep(10); + } + delete mUploads[i]; + } + + mUploads.clear(); + + delete mMeshMutex; + mMeshMutex = NULL; + + llinfos << "Shutting down decomposition system." << llendl; + + if (mDecompThread) + { + mDecompThread->shutdown(); + delete mDecompThread; + mDecompThread = NULL; + } + + LLConvexDecomposition::quitSystem(); +} + +//called in the main thread. +S32 LLMeshRepository::update() +{ + if(mUploadWaitList.empty()) + { + return 0 ; + } + + S32 size = mUploadWaitList.size() ; + for (S32 i = 0; i < size; ++i) + { + mUploads.push_back(mUploadWaitList[i]); + mUploadWaitList[i]->preStart() ; + mUploadWaitList[i]->start() ; + } + mUploadWaitList.clear() ; + + return size ; +} + +S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 detail, S32 last_lod) +{ + if (detail < 0 || detail > 4) + { + return detail; + } + + LLFastTimer t(FTM_LOAD_MESH); + + { + LLMutexLock lock(mMeshMutex); + //add volume to list of loading meshes + mesh_load_map::iterator iter = mLoadingMeshes[detail].find(mesh_params); + if (iter != mLoadingMeshes[detail].end()) + { //request pending for this mesh, append volume id to list + iter->second.insert(vobj->getID()); + } + else + { + //first request for this mesh + mLoadingMeshes[detail][mesh_params].insert(vobj->getID()); + mPendingRequests.push_back(LLMeshRepoThread::LODRequest(mesh_params, detail)); + } + } + + //do a quick search to see if we can't display something while we wait for this mesh to load + LLVolume* volume = vobj->getVolume(); + + if (volume) + { + if (volume->getNumVolumeFaces() == 0 && !volume->isTetrahedron()) + { + volume->makeTetrahedron(); + } + + LLVolumeParams params = volume->getParams(); + + LLVolumeLODGroup* group = LLPrimitive::getVolumeManager()->getGroup(params); + + if (group) + { + //first, see if last_lod is available (don't transition down to avoid funny popping a la SH-641) + if (last_lod >= 0) + { + LLVolume* lod = group->refLOD(last_lod); + if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0) + { + group->derefLOD(lod); + return last_lod; + } + group->derefLOD(lod); + } + + //next, see what the next lowest LOD available might be + for (S32 i = detail-1; i >= 0; --i) + { + LLVolume* lod = group->refLOD(i); + if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0) + { + group->derefLOD(lod); + return i; + } + + group->derefLOD(lod); + } + + //no lower LOD is a available, is a higher lod available? + for (S32 i = detail+1; i < 4; ++i) + { + LLVolume* lod = group->refLOD(i); + if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0) + { + group->derefLOD(lod); + return i; + } + + group->derefLOD(lod); + } + } + else + { + llerrs << "WTF?" << llendl; + } + } + + return detail; +} + +static LLFastTimer::DeclareTimer FTM_START_MESH_THREAD("Start Thread"); +static LLFastTimer::DeclareTimer FTM_LOAD_MESH_LOD("Load LOD"); +static LLFastTimer::DeclareTimer FTM_MESH_LOCK1("Lock 1"); +static LLFastTimer::DeclareTimer FTM_MESH_LOCK2("Lock 2"); + +void LLMeshRepository::notifyLoadedMeshes() +{ //called from main thread + + LLMeshRepoThread::sMaxConcurrentRequests = gSavedSettings.getU32("MeshMaxConcurrentRequests"); + + //clean up completed upload threads + for (std::vector<LLMeshUploadThread*>::iterator iter = mUploads.begin(); iter != mUploads.end(); ) + { + LLMeshUploadThread* thread = *iter; + + if (thread->isStopped() && thread->finished()) + { + iter = mUploads.erase(iter); + delete thread; + } + else + { + ++iter; + } + } + + //update inventory + if (!mInventoryQ.empty()) + { + LLMutexLock lock(mMeshMutex); + while (!mInventoryQ.empty()) + { + inventory_data& data = mInventoryQ.front(); + + LLAssetType::EType asset_type = LLAssetType::lookup(data.mPostData["asset_type"].asString()); + LLInventoryType::EType inventory_type = LLInventoryType::lookup(data.mPostData["inventory_type"].asString()); + + on_new_single_inventory_upload_complete( + asset_type, + inventory_type, + data.mPostData["asset_type"].asString(), + data.mPostData["folder_id"].asUUID(), + data.mPostData["name"], + data.mPostData["description"], + data.mResponse, + 0); + + mInventoryQ.pop(); + } + } + + //call completed callbacks on finished decompositions + mDecompThread->notifyCompleted(); + + if (!mThread->mWaiting) + { //curl thread is churning, wait for it to go idle + return; + } + + static std::string region_name("never name a region this"); + + if (gAgent.getRegion()) + { //update capability url + if (gAgent.getRegion()->getName() != region_name && gAgent.getRegion()->capabilitiesReceived()) + { + region_name = gAgent.getRegion()->getName(); + + mGetMeshCapability = gAgent.getRegion()->getCapability("GetMesh"); + } + } + + LLFastTimer t(FTM_MESH_UPDATE); + + { + LLFastTimer t(FTM_MESH_LOCK1); + mMeshMutex->lock(); + } + + { + LLFastTimer t(FTM_MESH_LOCK2); + mThread->mMutex->lock(); + } + + //popup queued error messages from background threads + while (!mUploadErrorQ.empty()) + { + LLNotificationsUtil::add("MeshUploadError", mUploadErrorQ.front()); + mUploadErrorQ.pop(); + } + + S32 push_count = LLMeshRepoThread::sMaxConcurrentRequests-(LLMeshRepoThread::sActiveHeaderRequests+LLMeshRepoThread::sActiveLODRequests); + + if (push_count > 0) + { + //calculate "score" for pending requests + + //create score map + std::map<LLUUID, F32> score_map; + + for (U32 i = 0; i < 4; ++i) + { + for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin(); iter != mLoadingMeshes[i].end(); ++iter) + { + F32 max_score = 0.f; + for (std::set<LLUUID>::iterator obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter) + { + LLViewerObject* object = gObjectList.findObject(*obj_iter); + + if (object) + { + LLDrawable* drawable = object->mDrawable; + if (drawable) + { + F32 cur_score = drawable->getRadius()/llmax(drawable->mDistanceWRTCamera, 1.f); + max_score = llmax(max_score, cur_score); + } + } + } + + score_map[iter->first.getSculptID()] = max_score; + } + } + + //set "score" for pending requests + for (std::vector<LLMeshRepoThread::LODRequest>::iterator iter = mPendingRequests.begin(); iter != mPendingRequests.end(); ++iter) + { + iter->mScore = score_map[iter->mMeshParams.getSculptID()]; + } + + //sort by "score" + std::sort(mPendingRequests.begin(), mPendingRequests.end(), LLMeshRepoThread::CompareScoreGreater()); + + while (!mPendingRequests.empty() && push_count > 0) + { + LLFastTimer t(FTM_LOAD_MESH_LOD); + LLMeshRepoThread::LODRequest& request = mPendingRequests.front(); + mThread->loadMeshLOD(request.mMeshParams, request.mLOD); + mPendingRequests.erase(mPendingRequests.begin()); + push_count--; + } + } + + //send skin info requests + while (!mPendingSkinRequests.empty()) + { + mThread->loadMeshSkinInfo(mPendingSkinRequests.front()); + mPendingSkinRequests.pop(); + } + + //send decomposition requests + while (!mPendingDecompositionRequests.empty()) + { + mThread->loadMeshDecomposition(mPendingDecompositionRequests.front()); + mPendingDecompositionRequests.pop(); + } + + //send physics shapes decomposition requests + while (!mPendingPhysicsShapeRequests.empty()) + { + mThread->loadMeshPhysicsShape(mPendingPhysicsShapeRequests.front()); + mPendingPhysicsShapeRequests.pop(); + } + + mThread->notifyLoadedMeshes(); + + mThread->mMutex->unlock(); + mMeshMutex->unlock(); + + mThread->mSignal->signal(); +} + +void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo& info) +{ + mSkinMap[info.mMeshID] = info; + mLoadingSkins.erase(info.mMeshID); +} + +void LLMeshRepository::notifyDecompositionReceived(LLModel::Decomposition* decomp) +{ + decomposition_map::iterator iter = mDecompositionMap.find(decomp->mMeshID); + if (iter == mDecompositionMap.end()) + { //just insert decomp into map + mDecompositionMap[decomp->mMeshID] = decomp; + } + else + { //merge decomp with existing entry + iter->second->merge(decomp); + delete decomp; + } + + mLoadingDecompositions.erase(decomp->mMeshID); +} + +void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVolume* volume) +{ //called from main thread + S32 detail = LLVolumeLODGroup::getVolumeDetailFromScale(volume->getDetail()); + + //get list of objects waiting to be notified this mesh is loaded + mesh_load_map::iterator obj_iter = mLoadingMeshes[detail].find(mesh_params); + + if (volume && obj_iter != mLoadingMeshes[detail].end()) + { + //make sure target volume is still valid + if (volume->getNumVolumeFaces() <= 0) + { + llwarns << "Mesh loading returned empty volume." << llendl; + volume->makeTetrahedron(); + } + + { //update system volume + LLVolume* sys_volume = LLPrimitive::getVolumeManager()->refVolume(mesh_params, detail); + if (sys_volume) + { + sys_volume->copyVolumeFaces(volume); + LLPrimitive::getVolumeManager()->unrefVolume(sys_volume); + } + else + { + llwarns << "Couldn't find system volume for given mesh." << llendl; + } + } + + //notify waiting LLVOVolume instances that their requested mesh is available + for (std::set<LLUUID>::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) + { + LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter); + if (vobj) + { + vobj->notifyMeshLoaded(); + } + } + + mLoadingMeshes[detail].erase(mesh_params); + } +} + +void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 lod) +{ //called from main thread + //get list of objects waiting to be notified this mesh is loaded + mesh_load_map::iterator obj_iter = mLoadingMeshes[lod].find(mesh_params); + + F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(lod); + + if (obj_iter != mLoadingMeshes[lod].end()) + { + for (std::set<LLUUID>::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) + { + LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter); + if (vobj) + { + LLVolume* obj_volume = vobj->getVolume(); + + if (obj_volume && + obj_volume->getDetail() == detail && + obj_volume->getParams() == mesh_params) + { //should force volume to find most appropriate LOD + vobj->setVolume(obj_volume->getParams(), lod); + } + } + } + + mLoadingMeshes[lod].erase(mesh_params); + } +} + +S32 LLMeshRepository::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod) +{ + return mThread->getActualMeshLOD(mesh_params, lod); +} + +U32 LLMeshRepository::calcResourceCost(LLSD& header) +{ + U32 bytes = 0; + + for (U32 i = 0; i < 4; i++) + { + bytes += header[header_lod[i]]["size"].asInteger(); + } + + bytes += header["skin"]["size"].asInteger(); + + return bytes/4096 + 1; +} + +U32 LLMeshRepository::getResourceCost(const LLUUID& mesh_id) +{ + return mThread->getResourceCost(mesh_id); +} + +const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id) +{ + if (mesh_id.notNull()) + { + skin_map::iterator iter = mSkinMap.find(mesh_id); + if (iter != mSkinMap.end()) + { + return &(iter->second); + } + + //no skin info known about given mesh, try to fetch it + { + LLMutexLock lock(mMeshMutex); + //add volume to list of loading meshes + std::set<LLUUID>::iterator iter = mLoadingSkins.find(mesh_id); + if (iter == mLoadingSkins.end()) + { //no request pending for this skin info + mLoadingSkins.insert(mesh_id); + mPendingSkinRequests.push(mesh_id); + } + } + } + + return NULL; +} + +void LLMeshRepository::fetchPhysicsShape(const LLUUID& mesh_id) +{ + if (mesh_id.notNull()) + { + LLModel::Decomposition* decomp = NULL; + decomposition_map::iterator iter = mDecompositionMap.find(mesh_id); + if (iter != mDecompositionMap.end()) + { + decomp = iter->second; + } + + //decomposition block hasn't been fetched yet + if (!decomp || decomp->mPhysicsShapeMesh.empty()) + { + LLMutexLock lock(mMeshMutex); + //add volume to list of loading meshes + std::set<LLUUID>::iterator iter = mLoadingPhysicsShapes.find(mesh_id); + if (iter == mLoadingPhysicsShapes.end()) + { //no request pending for this skin info + mLoadingPhysicsShapes.insert(mesh_id); + mPendingPhysicsShapeRequests.push(mesh_id); + } + } + } + +} + +LLModel::Decomposition* LLMeshRepository::getDecomposition(const LLUUID& mesh_id) +{ + LLModel::Decomposition* ret = NULL; + + if (mesh_id.notNull()) + { + decomposition_map::iterator iter = mDecompositionMap.find(mesh_id); + if (iter != mDecompositionMap.end()) + { + ret = iter->second; + } + + //decomposition block hasn't been fetched yet + if (!ret || ret->mBaseHullMesh.empty()) + { + LLMutexLock lock(mMeshMutex); + //add volume to list of loading meshes + std::set<LLUUID>::iterator iter = mLoadingDecompositions.find(mesh_id); + if (iter == mLoadingDecompositions.end()) + { //no request pending for this skin info + mLoadingDecompositions.insert(mesh_id); + mPendingDecompositionRequests.push(mesh_id); + } + } + } + + return ret; +} + +void LLMeshRepository::buildHull(const LLVolumeParams& params, S32 detail) +{ + LLVolume* volume = LLPrimitive::sVolumeManager->refVolume(params, detail); + + if (!volume->mHullPoints) + { + //all default params + //execute first stage + //set simplify mode to retain + //set retain percentage to zero + //run second stage + } + + LLPrimitive::sVolumeManager->unrefVolume(volume); +} + +bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id) +{ + LLSD mesh = mThread->getMeshHeader(mesh_id); + return mesh.has("physics_shape") && mesh["physics_shape"].has("size") && (mesh["physics_shape"]["size"].asInteger() > 0); +} + +LLSD& LLMeshRepository::getMeshHeader(const LLUUID& mesh_id) +{ + return mThread->getMeshHeader(mesh_id); +} + +LLSD& LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id) +{ + static LLSD dummy_ret; + if (mesh_id.notNull()) + { + LLMutexLock lock(mHeaderMutex); + mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); + if (iter != mMeshHeader.end()) + { + return iter->second; + } + } + + return dummy_ret; +} + + +void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures, + bool upload_skin, bool upload_joints) +{ + LLMeshUploadThread* thread = new LLMeshUploadThread(data, scale, upload_textures, upload_skin, upload_joints); + mUploadWaitList.push_back(thread); +} + +S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod) +{ + if (mThread) + { + LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); + if (iter != mThread->mMeshHeader.end()) + { + LLSD& header = iter->second; + + if (header.has("404")) + { + return -1; + } + + S32 size = header[header_lod[lod]]["size"].asInteger(); + return size; + } + + } + + return -1; + +} + +void LLMeshUploadThread::sendCostRequest(LLMeshUploadData& data) +{ + if(isDiscarded()) + { + return ; + } + + //write model file to memory buffer + std::stringstream ostr; + + LLModel::Decomposition& decomp = + data.mModel[LLModel::LOD_PHYSICS].notNull() ? + data.mModel[LLModel::LOD_PHYSICS]->mPhysics : + data.mBaseModel->mPhysics; + + LLSD header = LLModel::writeModel( + ostr, + data.mModel[LLModel::LOD_PHYSICS], + data.mModel[LLModel::LOD_HIGH], + data.mModel[LLModel::LOD_MEDIUM], + data.mModel[LLModel::LOD_LOW], + data.mModel[LLModel::LOD_IMPOSTOR], + decomp, + mUploadSkin, + mUploadJoints, + true); + + std::string desc = data.mBaseModel->mLabel; + + // Grab the total vertex count of the model + // along with other information for the "asset_resources" map + // to send to the server. + LLSD asset_resources = LLSD::emptyMap(); + + + std::string url = mNewInventoryCapability; + + if (!url.empty()) + { + LLSD body = generate_new_resource_upload_capability_body( + LLAssetType::AT_MESH, + desc, + desc, + LLFolderType::FT_MESH, + LLInventoryType::IT_MESH, + LLFloaterPerms::getNextOwnerPerms(), + LLFloaterPerms::getGroupPerms(), + LLFloaterPerms::getEveryonePerms()); + + body["asset_resources"] = asset_resources; + + mPendingConfirmations++; + LLCurlRequest::headers_t headers; + + data.mPostData = body; + + mCurlRequest->post(url, headers, body, new LLMeshCostResponder(data, this)); + } +} + +void LLMeshUploadThread::sendCostRequest(LLTextureUploadData& data) +{ + if(isDiscarded()) + { + return ; + } + + if (data.mTexture && data.mTexture->getDiscardLevel() >= 0) + { + LLSD asset_resources = LLSD::emptyMap(); + + std::string url = mNewInventoryCapability; + + if (!url.empty()) + { + LLSD body = generate_new_resource_upload_capability_body( + LLAssetType::AT_TEXTURE, + data.mLabel, + data.mLabel, + LLFolderType::FT_TEXTURE, + LLInventoryType::IT_TEXTURE, + LLFloaterPerms::getNextOwnerPerms(), + LLFloaterPerms::getGroupPerms(), + LLFloaterPerms::getEveryonePerms()); + + body["asset_resources"] = asset_resources; + + mPendingConfirmations++; + LLCurlRequest::headers_t headers; + + data.mPostData = body; + mCurlRequest->post(url, headers, body, new LLTextureCostResponder(data, this)); + } + } +} + + +void LLMeshUploadThread::doUploadModel(LLMeshUploadData& data) +{ + if(isDiscarded()) + { + return ; + } + + if (!data.mRSVP.empty()) + { + std::stringstream ostr; + + LLModel::Decomposition& decomp = + data.mModel[LLModel::LOD_PHYSICS].notNull() ? + data.mModel[LLModel::LOD_PHYSICS]->mPhysics : + data.mBaseModel->mPhysics; + + decomp.mBaseHull = mHullMap[data.mBaseModel]; + + LLModel::writeModel( + ostr, + data.mModel[LLModel::LOD_PHYSICS], + data.mModel[LLModel::LOD_HIGH], + data.mModel[LLModel::LOD_MEDIUM], + data.mModel[LLModel::LOD_LOW], + data.mModel[LLModel::LOD_IMPOSTOR], + decomp, + mUploadSkin, + mUploadJoints); + + data.mAssetData = ostr.str(); + + LLCurlRequest::headers_t headers; + mPendingUploads++; + + mCurlRequest->post(data.mRSVP, headers, data.mAssetData, new LLMeshUploadResponder(data, this)); + } +} + +void LLMeshUploadThread::doUploadTexture(LLTextureUploadData& data) +{ + if(isDiscarded()) + { + return ; + } + + if (!data.mRSVP.empty()) + { + std::stringstream ostr; + + if (!data.mTexture->isRawImageValid()) + { + data.mTexture->reloadRawImage(data.mTexture->getDiscardLevel()); + } + + LLPointer<LLImageJ2C> upload_file = LLViewerTextureList::convertToUploadFile(data.mTexture->getRawImage()); + + ostr.write((const char*) upload_file->getData(), upload_file->getDataSize()); + + data.mAssetData = ostr.str(); + + LLCurlRequest::headers_t headers; + mPendingUploads++; + + mCurlRequest->post(data.mRSVP, headers, data.mAssetData, new LLTextureUploadResponder(data, this)); + } +} + + +void LLMeshUploadThread::onModelUploaded(LLMeshUploadData& data) +{ + createObjects(data); +} + +void LLMeshUploadThread::onTextureUploaded(LLTextureUploadData& data) +{ + mTextureMap[data.mTexture] = data; +} + + +void LLMeshUploadThread::createObjects(LLMeshUploadData& data) +{ + instance_list& instances = mInstance[data.mBaseModel]; + + for (instance_list::iterator iter = instances.begin(); iter != instances.end(); ++iter) + { //create prims that reference given mesh + LLModelInstance& instance = *iter; + instance.mMeshID = data.mUUID; + mInstanceQ.push(instance); + } +} + +void LLMeshUploadThread::decomposeMeshMatrix(LLMatrix4& transformation, + LLVector3& result_pos, + LLQuaternion& result_rot, + LLVector3& result_scale) +{ + // check for reflection + BOOL reflected = (transformation.determinant() < 0); + + // compute position + LLVector3 position = LLVector3(0, 0, 0) * transformation; + + // compute scale + LLVector3 x_transformed = LLVector3(1, 0, 0) * transformation - position; + LLVector3 y_transformed = LLVector3(0, 1, 0) * transformation - position; + LLVector3 z_transformed = LLVector3(0, 0, 1) * transformation - position; + F32 x_length = x_transformed.normalize(); + F32 y_length = y_transformed.normalize(); + F32 z_length = z_transformed.normalize(); + LLVector3 scale = LLVector3(x_length, y_length, z_length); + + // adjust for "reflected" geometry + LLVector3 x_transformed_reflected = x_transformed; + if (reflected) + { + x_transformed_reflected *= -1.0; + } + + // compute rotation + LLMatrix3 rotation_matrix; + rotation_matrix.setRows(x_transformed_reflected, y_transformed, z_transformed); + LLQuaternion quat_rotation = rotation_matrix.quaternion(); + quat_rotation.normalize(); // the rotation_matrix might not have been orthoginal. make it so here. + LLVector3 euler_rotation; + quat_rotation.getEulerAngles(&euler_rotation.mV[VX], &euler_rotation.mV[VY], &euler_rotation.mV[VZ]); + + result_pos = position + mOrigin; + result_scale = scale; + result_rot = quat_rotation; +} + + +LLSD LLMeshUploadThread::createObject(LLModelInstance& instance) +{ + LLMatrix4 transformation = instance.mTransform; + + if (instance.mMeshID.isNull()) + { + llerrs << "WTF?" << llendl; + } + + // check for reflection + BOOL reflected = (transformation.determinant() < 0); + + // compute position + LLVector3 position = LLVector3(0, 0, 0) * transformation; + + // compute scale + LLVector3 x_transformed = LLVector3(1, 0, 0) * transformation - position; + LLVector3 y_transformed = LLVector3(0, 1, 0) * transformation - position; + LLVector3 z_transformed = LLVector3(0, 0, 1) * transformation - position; + F32 x_length = x_transformed.normalize(); + F32 y_length = y_transformed.normalize(); + F32 z_length = z_transformed.normalize(); + LLVector3 scale = LLVector3(x_length, y_length, z_length); + + // adjust for "reflected" geometry + LLVector3 x_transformed_reflected = x_transformed; + if (reflected) + { + x_transformed_reflected *= -1.0; + } + + // compute rotation + LLMatrix3 rotation_matrix; + rotation_matrix.setRows(x_transformed_reflected, y_transformed, z_transformed); + LLQuaternion quat_rotation = rotation_matrix.quaternion(); + quat_rotation.normalize(); // the rotation_matrix might not have been orthoginal. make it so here. + LLVector3 euler_rotation; + quat_rotation.getEulerAngles(&euler_rotation.mV[VX], &euler_rotation.mV[VY], &euler_rotation.mV[VZ]); + + // + // build parameter block to construct this prim + // + + LLSD object_params; + + // create prim + + // set volume params + U8 sculpt_type = LL_SCULPT_TYPE_MESH; + if (reflected) + { + sculpt_type |= LL_SCULPT_FLAG_MIRROR; + } + LLVolumeParams volume_params; + volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE ); + volume_params.setBeginAndEndS( 0.f, 1.f ); + volume_params.setBeginAndEndT( 0.f, 1.f ); + volume_params.setRatio ( 1, 1 ); + volume_params.setShear ( 0, 0 ); + volume_params.setSculptID(instance.mMeshID, sculpt_type); + object_params["shape"] = volume_params.asLLSD(); + + object_params["material"] = LL_MCODE_WOOD; + + object_params["group-id"] = gAgent.getGroupID(); + object_params["pos"] = ll_sd_from_vector3(position + mOrigin); + object_params["rotation"] = ll_sd_from_quaternion(quat_rotation); + object_params["scale"] = ll_sd_from_vector3(scale); + object_params["name"] = instance.mLabel; + + // load material from dae file + object_params["facelist"] = LLSD::emptyArray(); + for (S32 i = 0; i < instance.mMaterial.size(); i++) + { + LLTextureEntry te; + LLImportMaterial& mat = instance.mMaterial[i]; + + te.setColor(mat.mDiffuseColor); + + LLUUID diffuse_id = mTextureMap[mat.mDiffuseMap].mUUID; + + if (diffuse_id.notNull()) + { + te.setID(diffuse_id); + } + else + { + te.setID(LLUUID("5748decc-f629-461c-9a36-a35a221fe21f")); // blank texture + } + + te.setFullbright(mat.mFullbright); + + object_params["facelist"][i] = te.asLLSD(); + } + + // set extra parameters + LLSculptParams sculpt_params; + sculpt_params.setSculptTexture(instance.mMeshID); + sculpt_params.setSculptType(sculpt_type); + U8 buffer[MAX_OBJECT_PARAMS_SIZE+1]; + LLDataPackerBinaryBuffer dp(buffer, MAX_OBJECT_PARAMS_SIZE); + sculpt_params.pack(dp); + std::vector<U8> v(dp.getCurrentSize()); + memcpy(&v[0], buffer, dp.getCurrentSize()); + LLSD extra_parameter; + extra_parameter["extra_parameter"] = sculpt_params.mType; + extra_parameter["param_data"] = v; + object_params["extra_parameters"].append(extra_parameter); + + LLPermissions perm; + perm.setOwnerAndGroup(gAgent.getID(), gAgent.getID(), LLUUID::null, false); + perm.setCreator(gAgent.getID()); + + perm.initMasks(PERM_ITEM_UNRESTRICTED | PERM_MOVE, //base + PERM_ITEM_UNRESTRICTED | PERM_MOVE, //owner + LLFloaterPerms::getEveryonePerms(), + LLFloaterPerms::getGroupPerms(), + LLFloaterPerms::getNextOwnerPerms()); + + object_params["permissions"] = ll_create_sd_from_permissions(perm); + + object_params["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL); + + return object_params; +} + +void LLMeshUploadThread::priceResult(LLMeshUploadData& data, const LLSD& content) +{ + mPendingCost += content["upload_price"].asInteger(); + data.mRSVP = content["rsvp"].asString(); + + mConfirmedQ.push(data); +} + +void LLMeshUploadThread::priceResult(LLTextureUploadData& data, const LLSD& content) +{ + mPendingCost += content["upload_price"].asInteger(); + data.mRSVP = content["rsvp"].asString(); + + mConfirmedTextureQ.push(data); +} + + +bool LLImportMaterial::operator<(const LLImportMaterial &rhs) const +{ + if (mDiffuseMap != rhs.mDiffuseMap) + { + return mDiffuseMap < rhs.mDiffuseMap; + } + + if (mDiffuseMapFilename != rhs.mDiffuseMapFilename) + { + return mDiffuseMapFilename < rhs.mDiffuseMapFilename; + } + + if (mDiffuseMapLabel != rhs.mDiffuseMapLabel) + { + return mDiffuseMapLabel < rhs.mDiffuseMapLabel; + } + + if (mDiffuseColor != rhs.mDiffuseColor) + { + return mDiffuseColor < rhs.mDiffuseColor; + } + + return mFullbright < rhs.mFullbright; +} + + +void LLMeshRepository::updateInventory(inventory_data data) +{ + LLMutexLock lock(mMeshMutex); + mInventoryQ.push(data); +} + +void LLMeshRepository::uploadError(LLSD& args) +{ + LLMutexLock lock(mMeshMutex); + mUploadErrorQ.push(args); +} + +//static +F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod) +{ + F32 dlowest = llmin(radius/0.03f, 256.f); + F32 dlow = llmin(radius/0.06f, 256.f); + F32 dmid = llmin(radius/0.24f, 256.f); + + F32 bytes_lowest = header["lowest_lod"]["size"].asReal()/1024.f; + F32 bytes_low = header["low_lod"]["size"].asReal()/1024.f; + F32 bytes_mid = header["medium_lod"]["size"].asReal()/1024.f; + F32 bytes_high = header["high_lod"]["size"].asReal()/1024.f; + + if (bytes) + { + *bytes = 0; + *bytes += header["lowest_lod"]["size"].asInteger(); + *bytes += header["low_lod"]["size"].asInteger(); + *bytes += header["medium_lod"]["size"].asInteger(); + *bytes += header["high_lod"]["size"].asInteger(); + } + + + if (bytes_visible) + { + lod = LLMeshRepository::getActualMeshLOD(header, lod); + if (lod >= 0 && lod <= 3) + { + *bytes_visible = header[header_lod[lod]]["size"].asInteger(); + } + } + + if (bytes_high == 0.f) + { + return 0.f; + } + + if (bytes_mid == 0.f) + { + bytes_mid = bytes_high; + } + + if (bytes_low == 0.f) + { + bytes_low = bytes_mid; + } + + if (bytes_lowest == 0.f) + { + bytes_lowest = bytes_low; + } + + F32 max_area = 65536.f; + F32 min_area = 1.f; + + F32 high_area = llmin(F_PI*dmid*dmid, max_area); + F32 mid_area = llmin(F_PI*dlow*dlow, max_area); + F32 low_area = llmin(F_PI*dlowest*dlowest, max_area); + F32 lowest_area = max_area; + + lowest_area -= low_area; + low_area -= mid_area; + mid_area -= high_area; + + high_area = llclamp(high_area, min_area, max_area); + mid_area = llclamp(mid_area, min_area, max_area); + low_area = llclamp(low_area, min_area, max_area); + lowest_area = llclamp(lowest_area, min_area, max_area); + + F32 total_area = high_area + mid_area + low_area + lowest_area; + high_area /= total_area; + mid_area /= total_area; + low_area /= total_area; + lowest_area /= total_area; + + F32 weighted_avg = bytes_high*high_area + + bytes_mid*mid_area + + bytes_low*low_area + + bytes_lowest*lowest_area; + + return weighted_avg * gSavedSettings.getF32("MeshStreamingCostScaler"); +} + + +LLPhysicsDecomp::LLPhysicsDecomp() +: LLThread("Physics Decomp") +{ + mInited = false; + mQuitting = false; + mDone = false; + + mSignal = new LLCondition(NULL); + mMutex = new LLMutex(NULL); +} + +LLPhysicsDecomp::~LLPhysicsDecomp() +{ + shutdown(); + + delete mSignal; + mSignal = NULL; + delete mMutex; + mMutex = NULL; +} + +void LLPhysicsDecomp::shutdown() +{ + if (mSignal) + { + mQuitting = true; + mSignal->signal(); + + while (!isStopped()) + { + apr_sleep(10); + } + } +} + +void LLPhysicsDecomp::submitRequest(LLPhysicsDecomp::Request* request) +{ + LLMutexLock lock(mMutex); + mRequestQ.push(request); + mSignal->signal(); +} + +//static +S32 LLPhysicsDecomp::llcdCallback(const char* status, S32 p1, S32 p2) +{ + if (gMeshRepo.mDecompThread && gMeshRepo.mDecompThread->mCurRequest.notNull()) + { + return gMeshRepo.mDecompThread->mCurRequest->statusCallback(status, p1, p2); + } + + return 1; +} + +void LLPhysicsDecomp::setMeshData(LLCDMeshData& mesh) +{ + mesh.mVertexBase = mCurRequest->mPositions[0].mV; + mesh.mVertexStrideBytes = 12; + mesh.mNumVertices = mCurRequest->mPositions.size(); + + mesh.mIndexType = LLCDMeshData::INT_16; + mesh.mIndexBase = &(mCurRequest->mIndices[0]); + mesh.mIndexStrideBytes = 6; + + mesh.mNumTriangles = mCurRequest->mIndices.size()/3; + + LLCDResult ret = LLCD_OK; + if (LLConvexDecomposition::getInstance() != NULL) + { + ret = LLConvexDecomposition::getInstance()->setMeshData(&mesh); + } + + if (ret) + { + llerrs << "Convex Decomposition thread valid but could not set mesh data" << llendl; + } +} + +void LLPhysicsDecomp::doDecomposition() +{ + LLCDMeshData mesh; + S32 stage = mStageID[mCurRequest->mStage]; + + if (LLConvexDecomposition::getInstance() == NULL) + { + // stub library. do nothing. + return; + } + + //load data intoLLCD + if (stage == 0) + { + setMeshData(mesh); + } + + //build parameter map + std::map<std::string, const LLCDParam*> param_map; + + static const LLCDParam* params = NULL; + static S32 param_count = 0; + if (!params) + { + param_count = LLConvexDecomposition::getInstance()->getParameters(¶ms); + } + + for (S32 i = 0; i < param_count; ++i) + { + param_map[params[i].mName] = params+i; + } + + //set parameter values + for (decomp_params::iterator iter = mCurRequest->mParams.begin(); iter != mCurRequest->mParams.end(); ++iter) + { + const std::string& name = iter->first; + const LLSD& value = iter->second; + + const LLCDParam* param = param_map[name]; + + if (param == NULL) + { //couldn't find valid parameter + continue; + } + + U32 ret = LLCD_OK; + + if (param->mType == LLCDParam::LLCD_FLOAT) + { + ret = LLConvexDecomposition::getInstance()->setParam(param->mName, (F32) value.asReal()); + } + else if (param->mType == LLCDParam::LLCD_INTEGER || + param->mType == LLCDParam::LLCD_ENUM) + { + ret = LLConvexDecomposition::getInstance()->setParam(param->mName, value.asInteger()); + } + else if (param->mType == LLCDParam::LLCD_BOOLEAN) + { + ret = LLConvexDecomposition::getInstance()->setParam(param->mName, value.asBoolean()); + } + + if (ret) + { + llerrs << "WTF?" << llendl; + } + } + + mCurRequest->setStatusMessage("Executing."); + + LLCDResult ret = LLCD_OK; + + if (LLConvexDecomposition::getInstance() != NULL) + { + ret = LLConvexDecomposition::getInstance()->executeStage(stage); + } + + if (ret) + { + llwarns << "Convex Decomposition thread valid but could not execute stage " << stage << llendl; + LLMutexLock lock(mMutex); + + mCurRequest->mHull.clear(); + mCurRequest->mHullMesh.clear(); + + mCurRequest->setStatusMessage("FAIL"); + + completeCurrent(); + } + else + { + mCurRequest->setStatusMessage("Reading results"); + + S32 num_hulls =0; + if (LLConvexDecomposition::getInstance() != NULL) + { + num_hulls = LLConvexDecomposition::getInstance()->getNumHullsFromStage(stage); + } + + mMutex->lock(); + mCurRequest->mHull.clear(); + mCurRequest->mHull.resize(num_hulls); + + mCurRequest->mHullMesh.clear(); + mCurRequest->mHullMesh.resize(num_hulls); + mMutex->unlock(); + + for (S32 i = 0; i < num_hulls; ++i) + { + std::vector<LLVector3> p; + LLCDHull hull; + // if LLConvexDecomposition is a stub, num_hulls should have been set to 0 above, and we should not reach this code + LLConvexDecomposition::getInstance()->getHullFromStage(stage, i, &hull); + + const F32* v = hull.mVertexBase; + + for (S32 j = 0; j < hull.mNumVertices; ++j) + { + LLVector3 vert(v[0], v[1], v[2]); + p.push_back(vert); + v = (F32*) (((U8*) v) + hull.mVertexStrideBytes); + } + + LLCDMeshData mesh; + // if LLConvexDecomposition is a stub, num_hulls should have been set to 0 above, and we should not reach this code + LLConvexDecomposition::getInstance()->getMeshFromStage(stage, i, &mesh); + + get_vertex_buffer_from_mesh(mesh, mCurRequest->mHullMesh[i]); + + mMutex->lock(); + mCurRequest->mHull[i] = p; + mMutex->unlock(); + } + + { + LLMutexLock lock(mMutex); + + mCurRequest->setStatusMessage("FAIL"); + completeCurrent(); + } + } +} + +void LLPhysicsDecomp::completeCurrent() +{ + LLMutexLock lock(mMutex); + mCompletedQ.push(mCurRequest); + mCurRequest = NULL; +} + +void LLPhysicsDecomp::notifyCompleted() +{ + if (!mCompletedQ.empty()) + { + LLMutexLock lock(mMutex); + while (!mCompletedQ.empty()) + { + Request* req = mCompletedQ.front(); + req->completed(); + mCompletedQ.pop(); + } + } +} + + +void make_box(LLPhysicsDecomp::Request * request) +{ + LLVector3 min,max; + min = request->mPositions[0]; + max = min; + + for (U32 i = 0; i < request->mPositions.size(); ++i) + { + update_min_max(min, max, request->mPositions[i]); + } + + request->mHull.clear(); + + LLModel::hull box; + box.push_back(LLVector3(min[0],min[1],min[2])); + box.push_back(LLVector3(max[0],min[1],min[2])); + box.push_back(LLVector3(min[0],max[1],min[2])); + box.push_back(LLVector3(max[0],max[1],min[2])); + box.push_back(LLVector3(min[0],min[1],max[2])); + box.push_back(LLVector3(max[0],min[1],max[2])); + box.push_back(LLVector3(min[0],max[1],max[2])); + box.push_back(LLVector3(max[0],max[1],max[2])); + + request->mHull.push_back(box); +} + + +void LLPhysicsDecomp::doDecompositionSingleHull() +{ + LLCDMeshData mesh; + + setMeshData(mesh); + + + //set all parameters to default + std::map<std::string, const LLCDParam*> param_map; + + static const LLCDParam* params = NULL; + static S32 param_count = 0; + + if (!params) + { + param_count = LLConvexDecomposition::getInstance()->getParameters(¶ms); + } + + LLConvexDecomposition* decomp = LLConvexDecomposition::getInstance(); + + if (decomp == NULL) + { + //stub. do nothing. + return; + } + + for (S32 i = 0; i < param_count; ++i) + { + decomp->setParam(params[i].mName, params[i].mDefault.mIntOrEnumValue); + } + + const S32 STAGE_DECOMPOSE = mStageID["Decompose"]; + const S32 STAGE_SIMPLIFY = mStageID["Simplify"]; + const S32 DECOMP_PREVIEW = 0; + const S32 SIMPLIFY_RETAIN = 0; + + decomp->setParam("Decompose Quality", DECOMP_PREVIEW); + decomp->setParam("Simplify Method", SIMPLIFY_RETAIN); + decomp->setParam("Retain%", 0.f); + + LLCDResult ret = LLCD_OK; + ret = decomp->executeStage(STAGE_DECOMPOSE); + + if (ret) + { + llwarns << "Could not execute decomposition stage when attempting to create single hull." << llendl; + make_box(mCurRequest); + } + else + { + ret = decomp->executeStage(STAGE_SIMPLIFY); + + if (ret) + { + llwarns << "Could not execute simiplification stage when attempting to create single hull." << llendl; + make_box(mCurRequest); + } + else + { + S32 num_hulls =0; + if (LLConvexDecomposition::getInstance() != NULL) + { + num_hulls = LLConvexDecomposition::getInstance()->getNumHullsFromStage(STAGE_SIMPLIFY); + } + + mMutex->lock(); + mCurRequest->mHull.clear(); + mCurRequest->mHull.resize(num_hulls); + mCurRequest->mHullMesh.clear(); + mMutex->unlock(); + + for (S32 i = 0; i < num_hulls; ++i) + { + std::vector<LLVector3> p; + LLCDHull hull; + // if LLConvexDecomposition is a stub, num_hulls should have been set to 0 above, and we should not reach this code + LLConvexDecomposition::getInstance()->getHullFromStage(STAGE_SIMPLIFY, i, &hull); + + const F32* v = hull.mVertexBase; + + for (S32 j = 0; j < hull.mNumVertices; ++j) + { + LLVector3 vert(v[0], v[1], v[2]); + p.push_back(vert); + v = (F32*) (((U8*) v) + hull.mVertexStrideBytes); + } + + mMutex->lock(); + mCurRequest->mHull[i] = p; + mMutex->unlock(); + } + } + } + + + { + completeCurrent(); + + } +} + + +void LLPhysicsDecomp::run() +{ + LLConvexDecomposition* decomp = LLConvexDecomposition::getInstance(); + if (decomp == NULL) + { + // stub library. Set init to true so the main thread + // doesn't wait for this to finish. + mInited = true; + return; + } + + decomp->initThread(); + mInited = true; + + static const LLCDStageData* stages = NULL; + static S32 num_stages = 0; + + if (!stages) + { + num_stages = decomp->getStages(&stages); + } + + for (S32 i = 0; i < num_stages; i++) + { + mStageID[stages[i].mName] = i; + } + + while (!mQuitting) + { + mSignal->wait(); + while (!mQuitting && !mRequestQ.empty()) + { + { + LLMutexLock lock(mMutex); + mCurRequest = mRequestQ.front(); + mRequestQ.pop(); + } + + S32& id = *(mCurRequest->mDecompID); + if (id == -1) + { + decomp->genDecomposition(id); + } + decomp->bindDecomposition(id); + + if (mCurRequest->mStage == "single_hull") + { + doDecompositionSingleHull(); + } + else + { + doDecomposition(); + } + } + } + + decomp->quitThread(); + + if (mSignal->isLocked()) + { //let go of mSignal's associated mutex + mSignal->unlock(); + } + + mDone = true; +} + +void LLPhysicsDecomp::Request::setStatusMessage(const std::string& msg) +{ + mStatusMessage = msg; +} + +LLModelInstance::LLModelInstance(LLSD& data) +{ + mLocalMeshID = data["mesh_id"].asInteger(); + mLabel = data["label"].asString(); + mTransform.setValue(data["transform"]); + + for (U32 i = 0; i < data["material"].size(); ++i) + { + mMaterial.push_back(LLImportMaterial(data["material"][i])); + } +} + + +LLSD LLModelInstance::asLLSD() +{ + LLSD ret; + + ret["mesh_id"] = mModel->mLocalID; + ret["label"] = mLabel; + ret["transform"] = mTransform.getValue(); + + for (U32 i = 0; i < mMaterial.size(); ++i) + { + ret["material"][i] = mMaterial[i].asLLSD(); + } + + return ret; +} + +LLImportMaterial::LLImportMaterial(LLSD& data) +{ + mDiffuseMapFilename = data["diffuse"]["filename"].asString(); + mDiffuseMapLabel = data["diffuse"]["label"].asString(); + mDiffuseColor.setValue(data["diffuse"]["color"]); + mFullbright = data["fullbright"].asBoolean(); +} + + +LLSD LLImportMaterial::asLLSD() +{ + LLSD ret; + + ret["diffuse"]["filename"] = mDiffuseMapFilename; + ret["diffuse"]["label"] = mDiffuseMapLabel; + ret["diffuse"]["color"] = mDiffuseColor.getValue(); + ret["fullbright"] = mFullbright; + + return ret; +} + +void LLMeshRepository::buildPhysicsMesh(LLModel::Decomposition& decomp) +{ + decomp.mMesh.resize(decomp.mHull.size()); + + for (U32 i = 0; i < decomp.mHull.size(); ++i) + { + LLCDHull hull; + hull.mNumVertices = decomp.mHull[i].size(); + hull.mVertexBase = decomp.mHull[i][0].mV; + hull.mVertexStrideBytes = 12; + + LLCDMeshData mesh; + LLCDResult res = LLCD_OK; + if (LLConvexDecomposition::getInstance() != NULL) + { + res = LLConvexDecomposition::getInstance()->getMeshFromHull(&hull, &mesh); + } + if (res == LLCD_OK) + { + get_vertex_buffer_from_mesh(mesh, decomp.mMesh[i]); + } + } + + if (!decomp.mBaseHull.empty() && decomp.mBaseHullMesh.empty()) + { //get mesh for base hull + LLCDHull hull; + hull.mNumVertices = decomp.mBaseHull.size(); + hull.mVertexBase = decomp.mBaseHull[0].mV; + hull.mVertexStrideBytes = 12; + + LLCDMeshData mesh; + LLCDResult res = LLCD_OK; + if (LLConvexDecomposition::getInstance() != NULL) + { + res = LLConvexDecomposition::getInstance()->getMeshFromHull(&hull, &mesh); + } + if (res == LLCD_OK) + { + get_vertex_buffer_from_mesh(mesh, decomp.mBaseHullMesh); + } + } +} diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h new file mode 100644 index 0000000000..802e3e1aba --- /dev/null +++ b/indra/newview/llmeshrepository.h @@ -0,0 +1,551 @@ +/** + * @file llmeshrepository.h + * @brief Client-side repository of mesh assets. + * + * $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$ + */ + +#ifndef LL_MESH_REPOSITORY_H +#define LL_MESH_REPOSITORY_H + +#include "llassettype.h" +#include "llmodel.h" +#include "lluuid.h" +#include "llviewertexture.h" +#include "llvolume.h" + +#define LLCONVEXDECOMPINTER_STATIC 1 + +#include "llconvexdecomposition.h" + +class LLVOVolume; +class LLMeshResponder; +class LLCurlRequest; +class LLMutex; +class LLCondition; +class LLVFS; +class LLMeshRepository; + +class LLMeshUploadData +{ +public: + LLPointer<LLModel> mBaseModel; + LLPointer<LLModel> mModel[5]; + LLUUID mUUID; + U32 mRetries; + std::string mRSVP; + std::string mAssetData; + LLSD mPostData; + + LLMeshUploadData() + { + mRetries = 0; + } +}; + +class LLTextureUploadData +{ +public: + LLViewerFetchedTexture* mTexture; + LLUUID mUUID; + std::string mRSVP; + std::string mLabel; + U32 mRetries; + std::string mAssetData; + LLSD mPostData; + + LLTextureUploadData() + { + mRetries = 0; + } + + LLTextureUploadData(LLViewerFetchedTexture* texture, std::string& label) + : mTexture(texture), mLabel(label) + { + mRetries = 0; + } +}; + +class LLImportMaterial +{ +public: + LLPointer<LLViewerFetchedTexture> mDiffuseMap; + std::string mDiffuseMapFilename; + std::string mDiffuseMapLabel; + LLColor4 mDiffuseColor; + bool mFullbright; + + bool operator<(const LLImportMaterial ¶ms) const; + + LLImportMaterial() + : mFullbright(false) + { + mDiffuseColor.set(1,1,1,1); + } + + LLImportMaterial(LLSD& data); + + LLSD asLLSD(); +}; + +class LLModelInstance +{ +public: + LLPointer<LLModel> mModel; + LLPointer<LLModel> mLOD[5]; + + std::string mLabel; + + LLUUID mMeshID; + S32 mLocalMeshID; + + LLMatrix4 mTransform; + std::vector<LLImportMaterial> mMaterial; + + LLModelInstance(LLModel* model, const std::string& label, LLMatrix4& transform, std::vector<LLImportMaterial>& materials) + : mModel(model), mLabel(label), mTransform(transform), mMaterial(materials) + { + mLocalMeshID = -1; + } + + LLModelInstance(LLSD& data); + + LLSD asLLSD(); +}; + +class LLPhysicsDecomp : public LLThread +{ +public: + + typedef std::map<std::string, LLSD> decomp_params; + + class Request : public LLRefCount + { + public: + //input params + S32* mDecompID; + std::string mStage; + std::vector<LLVector3> mPositions; + std::vector<U16> mIndices; + decomp_params mParams; + + //output state + std::string mStatusMessage; + std::vector<LLModel::PhysicsMesh> mHullMesh; + LLModel::convex_hull_decomposition mHull; + + //status message callback, called from decomposition thread + virtual S32 statusCallback(const char* status, S32 p1, S32 p2) = 0; + + //completed callback, called from the main thread + virtual void completed() = 0; + + virtual void setStatusMessage(const std::string& msg); + }; + + LLCondition* mSignal; + LLMutex* mMutex; + + bool mInited; + bool mQuitting; + bool mDone; + + LLPhysicsDecomp(); + ~LLPhysicsDecomp(); + + void shutdown(); + + void submitRequest(Request* request); + static S32 llcdCallback(const char*, S32, S32); + void cancel(); + + void setMeshData(LLCDMeshData& mesh); + void doDecomposition(); + void doDecompositionSingleHull(); + + virtual void run(); + + void completeCurrent(); + void notifyCompleted(); + + std::map<std::string, S32> mStageID; + + typedef std::queue<LLPointer<Request> > request_queue; + request_queue mRequestQ; + + LLPointer<Request> mCurRequest; + + std::queue<LLPointer<Request> > mCompletedQ; + +}; + +class LLMeshRepoThread : public LLThread +{ +public: + + static S32 sActiveHeaderRequests; + static S32 sActiveLODRequests; + static U32 sMaxConcurrentRequests; + + LLCurlRequest* mCurlRequest; + LLMutex* mMutex; + LLMutex* mHeaderMutex; + LLCondition* mSignal; + + bool mWaiting; + + //map of known mesh headers + typedef std::map<LLUUID, LLSD> mesh_header_map; + mesh_header_map mMeshHeader; + + std::map<LLUUID, U32> mMeshHeaderSize; + std::map<LLUUID, U32> mMeshResourceCost; + + class HeaderRequest + { + public: + const LLVolumeParams mMeshParams; + + HeaderRequest(const LLVolumeParams& mesh_params) + : mMeshParams(mesh_params) + { + } + + bool operator<(const HeaderRequest& rhs) const + { + return mMeshParams < rhs.mMeshParams; + } + }; + + class LODRequest + { + public: + LLVolumeParams mMeshParams; + S32 mLOD; + F32 mScore; + + LODRequest(const LLVolumeParams& mesh_params, S32 lod) + : mMeshParams(mesh_params), mLOD(lod), mScore(0.f) + { + } + }; + + struct CompareScoreGreater + { + bool operator()(const LODRequest& lhs, const LODRequest& rhs) + { + return lhs.mScore > rhs.mScore; // greatest = first + } + }; + + + class LoadedMesh + { + public: + LLPointer<LLVolume> mVolume; + LLVolumeParams mMeshParams; + S32 mLOD; + + LoadedMesh(LLVolume* volume, const LLVolumeParams& mesh_params, S32 lod) + : mVolume(volume), mMeshParams(mesh_params), mLOD(lod) + { + } + + }; + + //set of requested skin info + std::set<LLUUID> mSkinRequests; + + //queue of completed skin info requests + std::queue<LLMeshSkinInfo> mSkinInfoQ; + + //set of requested decompositions + std::set<LLUUID> mDecompositionRequests; + + //set of requested physics shapes + std::set<LLUUID> mPhysicsShapeRequests; + + //queue of completed Decomposition info requests + std::queue<LLModel::Decomposition*> mDecompositionQ; + + //queue of requested headers + std::queue<HeaderRequest> mHeaderReqQ; + + //queue of requested LODs + std::queue<LODRequest> mLODReqQ; + + //queue of unavailable LODs (either asset doesn't exist or asset doesn't have desired LOD) + std::queue<LODRequest> mUnavailableQ; + + //queue of successfully loaded meshes + std::queue<LoadedMesh> mLoadedQ; + + //map of pending header requests and currently desired LODs + typedef std::map<LLVolumeParams, std::vector<S32> > pending_lod_map; + pending_lod_map mPendingLOD; + + static std::string constructUrl(LLUUID mesh_id); + + LLMeshRepoThread(); + ~LLMeshRepoThread(); + + virtual void run(); + + void loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod); + bool fetchMeshHeader(const LLVolumeParams& mesh_params); + bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod); + bool headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size); + bool lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size); + bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size); + bool decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size); + bool physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size); + LLSD& getMeshHeader(const LLUUID& mesh_id); + + void notifyLoadedMeshes(); + S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod); + U32 getResourceCost(const LLUUID& mesh_params); + + void loadMeshSkinInfo(const LLUUID& mesh_id); + void loadMeshDecomposition(const LLUUID& mesh_id); + void loadMeshPhysicsShape(const LLUUID& mesh_id); + + //send request for skin info, returns true if header info exists + // (should hold onto mesh_id and try again later if header info does not exist) + bool fetchMeshSkinInfo(const LLUUID& mesh_id); + + //send request for decomposition, returns true if header info exists + // (should hold onto mesh_id and try again later if header info does not exist) + bool fetchMeshDecomposition(const LLUUID& mesh_id); + + //send request for PhysicsShape, returns true if header info exists + // (should hold onto mesh_id and try again later if header info does not exist) + bool fetchMeshPhysicsShape(const LLUUID& mesh_id); + + +}; + +class LLMeshUploadThread : public LLThread +{ +public: + class DecompRequest : public LLPhysicsDecomp::Request + { + public: + LLPointer<LLModel> mModel; + LLPointer<LLModel> mBaseModel; + + LLMeshUploadThread* mThread; + + DecompRequest(LLModel* mdl, LLModel* base_model, LLMeshUploadThread* thread); + + S32 statusCallback(const char* status, S32 p1, S32 p2) { return 1; } + void completed(); + }; + + LLPointer<DecompRequest> mFinalDecomp; + bool mPhysicsComplete; + + typedef std::map<LLPointer<LLModel>, std::vector<LLVector3> > hull_map; + hull_map mHullMap; + + typedef std::vector<LLModelInstance> instance_list; + instance_list mInstanceList; + + typedef std::map<LLPointer<LLModel>, instance_list> instance_map; + instance_map mInstance; + + LLMutex* mMutex; + LLCurlRequest* mCurlRequest; + S32 mPendingConfirmations; + S32 mPendingUploads; + S32 mPendingCost; + LLVector3 mOrigin; + bool mFinished; + bool mUploadTextures; + bool mUploadSkin; + bool mUploadJoints; + BOOL mDiscarded ; + + LLHost mHost; + std::string mUploadObjectAssetCapability; + std::string mNewInventoryCapability; + std::string mWholeModelUploadCapability; + + std::queue<LLMeshUploadData> mUploadQ; + std::queue<LLMeshUploadData> mConfirmedQ; + std::queue<LLModelInstance> mInstanceQ; + + std::queue<LLTextureUploadData> mTextureQ; + std::queue<LLTextureUploadData> mConfirmedTextureQ; + + std::map<LLViewerFetchedTexture*, LLTextureUploadData> mTextureMap; + + LLMeshUploadThread(instance_list& data, LLVector3& scale, bool upload_textures, + bool upload_skin, bool upload_joints); + ~LLMeshUploadThread(); + + void uploadTexture(LLTextureUploadData& data); + void doUploadTexture(LLTextureUploadData& data); + void sendCostRequest(LLTextureUploadData& data); + void priceResult(LLTextureUploadData& data, const LLSD& content); + void onTextureUploaded(LLTextureUploadData& data); + + void uploadModel(LLMeshUploadData& data); + void sendCostRequest(LLMeshUploadData& data); + void doUploadModel(LLMeshUploadData& data); + void onModelUploaded(LLMeshUploadData& data); + void createObjects(LLMeshUploadData& data); + LLSD createObject(LLModelInstance& instance); + void priceResult(LLMeshUploadData& data, const LLSD& content); + + bool finished() { return mFinished; } + virtual void run(); + void preStart(); + void discard() ; + BOOL isDiscarded(); + + void doWholeModelUpload(); + void doIterativeUpload(); + + void wholeModelToLLSD(LLSD& dest, bool include_textures); + + void decomposeMeshMatrix(LLMatrix4& transformation, + LLVector3& result_pos, + LLQuaternion& result_rot, + LLVector3& result_scale); +}; + +class LLMeshRepository +{ +public: + + //metrics + static U32 sBytesReceived; + static U32 sHTTPRequestCount; + static U32 sHTTPRetryCount; + static U32 sCacheBytesRead; + static U32 sCacheBytesWritten; + static U32 sPeakKbps; + + static F32 getStreamingCost(LLSD& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1); + + LLMeshRepository(); + + void init(); + void shutdown(); + S32 update() ; + + //mesh management functions + S32 loadMesh(LLVOVolume* volume, const LLVolumeParams& mesh_params, S32 detail = 0, S32 last_lod = -1); + + void notifyLoadedMeshes(); + void notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVolume* volume); + void notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 lod); + void notifySkinInfoReceived(LLMeshSkinInfo& info); + void notifyDecompositionReceived(LLModel::Decomposition* info); + + S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod); + static S32 getActualMeshLOD(LLSD& header, S32 lod); + U32 calcResourceCost(LLSD& header); + U32 getResourceCost(const LLUUID& mesh_params); + const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id); + LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id); + void fetchPhysicsShape(const LLUUID& mesh_id); + bool hasPhysicsShape(const LLUUID& mesh_id); + + void buildHull(const LLVolumeParams& params, S32 detail); + void buildPhysicsMesh(LLModel::Decomposition& decomp); + + LLSD& getMeshHeader(const LLUUID& mesh_id); + + void uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures, + bool upload_skin, bool upload_joints); + + S32 getMeshSize(const LLUUID& mesh_id, S32 lod); + + typedef std::map<LLVolumeParams, std::set<LLUUID> > mesh_load_map; + mesh_load_map mLoadingMeshes[4]; + + typedef std::map<LLUUID, LLMeshSkinInfo> skin_map; + skin_map mSkinMap; + + typedef std::map<LLUUID, LLModel::Decomposition*> decomposition_map; + decomposition_map mDecompositionMap; + + LLMutex* mMeshMutex; + + std::vector<LLMeshRepoThread::LODRequest> mPendingRequests; + + //list of mesh ids awaiting skin info + std::set<LLUUID> mLoadingSkins; + + //list of mesh ids that need to send skin info fetch requests + std::queue<LLUUID> mPendingSkinRequests; + + //list of mesh ids awaiting decompositions + std::set<LLUUID> mLoadingDecompositions; + + //list of mesh ids that need to send decomposition fetch requests + std::queue<LLUUID> mPendingDecompositionRequests; + + //list of mesh ids awaiting physics shapes + std::set<LLUUID> mLoadingPhysicsShapes; + + //list of mesh ids that need to send physics shape fetch requests + std::queue<LLUUID> mPendingPhysicsShapeRequests; + + U32 mMeshThreadCount; + + void cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header); + + LLMeshRepoThread* mThread; + std::vector<LLMeshUploadThread*> mUploads; + std::vector<LLMeshUploadThread*> mUploadWaitList; + + LLPhysicsDecomp* mDecompThread; + + class inventory_data + { + public: + LLSD mPostData; + LLSD mResponse; + + inventory_data(const LLSD& data, const LLSD& content) + : mPostData(data), mResponse(content) + { + } + }; + + std::queue<inventory_data> mInventoryQ; + + std::queue<LLSD> mUploadErrorQ; + + void uploadError(LLSD& args); + void updateInventory(inventory_data data); + + std::string mGetMeshCapability; + +}; + +extern LLMeshRepository gMeshRepo; + +#endif + diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index 6805630ef1..d64fdbe6a5 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -1,25 +1,25 @@ -/** +/** * @file llnamelistctrl.h * @brief A list of names, automatically refreshing from the name cache. * * $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$ */ @@ -58,7 +58,7 @@ public: NameItem() : name("name"), target("target", INDIVIDUAL) - {} + {} }; struct NameColumn : public LLInitParam::Choice<NameColumn> @@ -83,7 +83,7 @@ protected: LLNameListCtrl(const Params&); friend class LLUICtrlFactory; public: - // Add a user to the list by name. It will be added, the name + // Add a user to the list by name. It will be added, the name // requested from the cache, and updated as necessary. void addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE, const std::string& suffix = LLStringUtil::null); @@ -92,7 +92,7 @@ public: /*virtual*/ LLScrollListItem* addElement(const LLSD& element, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL); LLScrollListItem* addNameItemRow(const NameItem& value, EAddPosition pos = ADD_BOTTOM, const std::string& suffix = LLStringUtil::null); - // Add a user to the list by name. It will be added, the name + // Add a user to the list by name. It will be added, the name // requested from the cache, and updated as necessary. void addGroupNameItem(const LLUUID& group_id, EAddPosition pos = ADD_BOTTOM, BOOL enabled = TRUE); @@ -126,7 +126,7 @@ private: /** * LLNameListCtrl item - * + * * We don't use LLScrollListItem to be able to override getUUID(), which is needed * because the name list item value is not simply an UUID but a map (uuid, is_group). */ diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp index 70d588db52..de90023f3b 100644 --- a/indra/newview/llnotificationhandlerutil.cpp +++ b/indra/newview/llnotificationhandlerutil.cpp @@ -27,13 +27,17 @@ #include "llviewerprecompiledheaders.h" // must be first include -#include "llnotificationhandler.h" +#include "llavatarnamecache.h" + +#include "llfloaterreg.h" #include "llnotifications.h" -#include "llimview.h" +#include "llurlaction.h" + #include "llagent.h" -#include "llfloaterreg.h" -#include "llnearbychat.h" #include "llimfloater.h" +#include "llimview.h" +#include "llnearbychat.h" +#include "llnotificationhandler.h" using namespace LLNotificationsUI; @@ -275,7 +279,11 @@ void LLHandlerUtil::logToIM(const EInstantMessage& session_type, { from = SYSTEM_FROM; } - LLIMModel::instance().logToFile(session_name, from, from_id, message); + + // Build a new format username or firstname_lastname for legacy names + // to use it for a history log filename. + std::string user_name = LLCacheName::buildUsername(session_name); + LLIMModel::instance().logToFile(user_name, from, from_id, message); } else { diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index bce496cbad..07c7f35989 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -376,6 +376,11 @@ struct LLPanelFaceSetAlignedTEFunctor : public LLSelectedTEFunctor return true; } + if (facep->getViewerObject()->getVolume()->getNumVolumeFaces() <= te) + { + return true; + } + bool set_aligned = true; if (facep == mCenterFace) { @@ -418,6 +423,12 @@ struct LLPanelFaceGetIsAlignedTEFunctor : public LLSelectedTEFunctor { return false; } + + if (facep->getViewerObject()->getVolume()->getNumVolumeFaces() <= te) + { //volume face does not exist, can't be aligned + return false; + } + if (facep == mCenterFace) { return true; diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index cdf6e51bf8..e64192c2ae 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -154,6 +154,7 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, case DAD_ANIMATION: case DAD_GESTURE: case DAD_CALLINGCARD: + case DAD_MESH: { LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data; if(gInventory.getItem(inv_item->getUUID()) diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 27f341b4f6..d0810d0772 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -34,6 +34,7 @@ #include "llmd5.h" #include "llsecondlifeurls.h" #include "v4color.h" +#include "llversionviewer.h" #include "llappviewer.h" #include "llbutton.h" @@ -747,12 +748,20 @@ void LLPanelLogin::loadLoginPage() LLVersionInfo::getShortVersion().c_str(), LLVersionInfo::getBuild()); - char* curl_channel = curl_escape(LLVersionInfo::getChannel().c_str(), 0); + char* curl_channel ; char* curl_version = curl_escape(version.c_str(), 0); + if(strcmp(LLVersionInfo::getChannel().c_str(), LL_CHANNEL)) + { + curl_channel = curl_escape(LLVersionInfo::getChannel().c_str(), 0); + } + else //if LL_CHANNEL, direct it to "Second Life Beta Viewer". + { + curl_channel = curl_escape("Second Life Beta Viewer", 0); + } oStr << "&channel=" << curl_channel; oStr << "&version=" << curl_version; - + curl_free(curl_channel); curl_free(curl_version); diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index f79a1bb5ab..bc4998dd0c 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -686,6 +686,7 @@ void LLFloaterInventoryFinder::updateElementsFromFilter() getChild<LLUICtrl>("check_clothing")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE)); getChild<LLUICtrl>("check_gesture")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE)); getChild<LLUICtrl>("check_landmark")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK)); + getChild<LLUICtrl>("check_mesh")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_MESH)); getChild<LLUICtrl>("check_notecard")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD)); getChild<LLUICtrl>("check_object")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT)); getChild<LLUICtrl>("check_script")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LSL)); @@ -737,6 +738,12 @@ void LLFloaterInventoryFinder::draw() filtered_by_all_types = FALSE; } + if (!getChild<LLUICtrl>("check_mesh")->getValue()) + { + filter &= ~(0x1 << LLInventoryType::IT_MESH); + filtered_by_all_types = FALSE; + } + if (!getChild<LLUICtrl>("check_notecard")->getValue()) { filter &= ~(0x1 << LLInventoryType::IT_NOTECARD); @@ -833,6 +840,7 @@ void LLFloaterInventoryFinder::selectAllTypes(void* user_data) self->getChild<LLUICtrl>("check_clothing")->setValue(TRUE); self->getChild<LLUICtrl>("check_gesture")->setValue(TRUE); self->getChild<LLUICtrl>("check_landmark")->setValue(TRUE); + self->getChild<LLUICtrl>("check_mesh")->setValue(TRUE); self->getChild<LLUICtrl>("check_notecard")->setValue(TRUE); self->getChild<LLUICtrl>("check_object")->setValue(TRUE); self->getChild<LLUICtrl>("check_script")->setValue(TRUE); @@ -852,6 +860,7 @@ void LLFloaterInventoryFinder::selectNoTypes(void* user_data) self->getChild<LLUICtrl>("check_clothing")->setValue(FALSE); self->getChild<LLUICtrl>("check_gesture")->setValue(FALSE); self->getChild<LLUICtrl>("check_landmark")->setValue(FALSE); + self->getChild<LLUICtrl>("check_mesh")->setValue(FALSE); self->getChild<LLUICtrl>("check_notecard")->setValue(FALSE); self->getChild<LLUICtrl>("check_object")->setValue(FALSE); self->getChild<LLUICtrl>("check_script")->setValue(FALSE); diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp index a7f1ab28fd..2bbd15ae11 100644 --- a/indra/newview/llpanelnearbymedia.cpp +++ b/indra/newview/llpanelnearbymedia.cpp @@ -356,7 +356,7 @@ void LLPanelNearByMedia::updateListItem(LLScrollListItem* item, LLViewerMediaImp debug_str += llformat("%g/", (float)impl->getInterest()); // proximity distance is actually distance squared -- display it as straight distance. - debug_str += llformat("%g/", fsqrtf(impl->getProximityDistance())); + debug_str += llformat("%g/", (F32) sqrt(impl->getProximityDistance())); // s += llformat("%g/", (float)impl->getCPUUsage()); // s += llformat("%g/", (float)impl->getApproximateTextureInterest()); diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index a0c320ba19..64af6c2157 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -131,7 +131,8 @@ BOOL LLPanelObject::postBuild() // Phantom checkbox mCheckPhantom = getChild<LLCheckBoxCtrl>("Phantom Checkbox Ctrl"); childSetCommitCallback("Phantom Checkbox Ctrl",onCommitPhantom,this); - + + // Position mLabelPosition = getChild<LLTextBox>("label position"); mCtrlPosX = getChild<LLSpinCtrl>("Pos X"); @@ -519,6 +520,7 @@ void LLPanelObject::getState( ) mCheckPhantom->set( mIsPhantom ); mCheckPhantom->setEnabled( roots_selected>0 && editable && !is_flexible ); + #if 0 // 1.9.2 mCastShadows = root_objectp->flagCastShadows(); mCheckCastShadows->set( mCastShadows ); @@ -569,6 +571,7 @@ void LLPanelObject::getState( ) BOOL enabled = FALSE; BOOL hole_enabled = FALSE; F32 scale_x=1.f, scale_y=1.f; + BOOL isMesh = FALSE; if( !objectp || !objectp->getVolume() || !editable || !single_volume) { @@ -599,10 +602,9 @@ void LLPanelObject::getState( ) // Only allowed to change these parameters for objects // that you have permissions on AND are not attachments. enabled = root_objectp->permModify(); - - const LLVolumeParams &volume_params = objectp->getVolume()->getParams(); - + // Volume type + const LLVolumeParams &volume_params = objectp->getVolume()->getParams(); U8 path = volume_params.getPathParams().getCurveType(); U8 profile_and_hole = volume_params.getProfileParams().getCurveType(); U8 profile = profile_and_hole & LL_PCODE_PROFILE_MASK; @@ -833,7 +835,7 @@ void LLPanelObject::getState( ) } mSpinSkew->set( skew ); } - + // Compute control visibility, label names, and twist range. // Start with defaults. BOOL cut_visible = TRUE; @@ -1101,7 +1103,9 @@ void LLPanelObject::getState( ) if (selected_item == MI_SCULPT) { - LLUUID id; + + + LLUUID id; LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT); @@ -1113,26 +1117,29 @@ void LLPanelObject::getState( ) mSculptTypeRevert = sculpt_params->getSculptType(); } + U8 sculpt_type = sculpt_params->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; + isMesh = (sculpt_stitching == LL_SCULPT_TYPE_MESH); + LLTextureCtrl* mTextureCtrl = getChild<LLTextureCtrl>("sculpt texture control"); if(mTextureCtrl) { mTextureCtrl->setTentative(FALSE); - mTextureCtrl->setEnabled(editable); + mTextureCtrl->setEnabled(editable && !isMesh); if (editable) mTextureCtrl->setImageAssetID(sculpt_params->getSculptTexture()); else mTextureCtrl->setImageAssetID(LLUUID::null); } - U8 sculpt_type = sculpt_params->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; + mComboBaseType->setEnabled(!isMesh); if (mCtrlSculptType) { mCtrlSculptType->setCurrentByIndex(sculpt_stitching); - mCtrlSculptType->setEnabled(editable); + mCtrlSculptType->setEnabled(editable && !isMesh); } if (mCtrlSculptMirror) @@ -1151,14 +1158,14 @@ void LLPanelObject::getState( ) { mLabelSculptType->setEnabled(TRUE); } + } } else { - mSculptTextureRevert = LLUUID::null; + mSculptTextureRevert = LLUUID::null; } - //---------------------------------------------------------------------------- mObject = objectp; @@ -1786,6 +1793,17 @@ void LLPanelObject::sendSculpt() if (mCtrlSculptType) sculpt_type |= mCtrlSculptType->getCurrentIndex(); + bool enabled = sculpt_type != LL_SCULPT_TYPE_MESH; + + if (mCtrlSculptMirror) + { + mCtrlSculptMirror->setEnabled(enabled ? TRUE : FALSE); + } + if (mCtrlSculptInvert) + { + mCtrlSculptInvert->setEnabled(enabled ? TRUE : FALSE); + } + if ((mCtrlSculptMirror) && (mCtrlSculptMirror->get())) sculpt_type |= LL_SCULPT_FLAG_MIRROR; @@ -1808,6 +1826,26 @@ void LLPanelObject::refresh() { mRootObject = NULL; } + + bool enable_mesh = gSavedSettings.getBOOL("MeshEnabled") && + gAgent.getRegion() && + !gAgent.getRegion()->getCapability("GetMesh").empty(); + + F32 max_scale = get_default_max_prim_scale(LLPickInfo::isFlora(mObject)); + + getChild<LLSpinCtrl>("Scale X")->setMaxValue(max_scale); + getChild<LLSpinCtrl>("Scale Y")->setMaxValue(max_scale); + getChild<LLSpinCtrl>("Scale Z")->setMaxValue(max_scale); + + BOOL found = mCtrlSculptType->itemExists("Mesh"); + if (enable_mesh && !found) + { + mCtrlSculptType->add("Mesh"); + } + else if (!enable_mesh && found) + { + mCtrlSculptType->remove("Mesh"); + } } @@ -1894,6 +1932,7 @@ void LLPanelObject::clearCtrls() mCheckTemporary ->setEnabled( FALSE ); mCheckPhantom ->set(FALSE); mCheckPhantom ->setEnabled( FALSE ); + #if 0 // 1.9.2 mCheckCastShadows->set(FALSE); mCheckCastShadows->setEnabled( FALSE ); diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h index e07bf007ec..e2f2a4400d 100644 --- a/indra/newview/llpanelobject.h +++ b/indra/newview/llpanelobject.h @@ -62,14 +62,14 @@ public: static void onCommitPosition( LLUICtrl* ctrl, void* userdata); static void onCommitScale( LLUICtrl* ctrl, void* userdata); static void onCommitRotation( LLUICtrl* ctrl, void* userdata); - static void onCommitPhysics( LLUICtrl* ctrl, void* userdata); static void onCommitTemporary( LLUICtrl* ctrl, void* userdata); static void onCommitPhantom( LLUICtrl* ctrl, void* userdata); static void onCommitCastShadows( LLUICtrl* ctrl, void* userdata); + static void onCommitPhysics( LLUICtrl* ctrl, void* userdata); + static void onCommitMaterial( LLUICtrl* ctrl, void* userdata); static void onCommitParametric(LLUICtrl* ctrl, void* userdata); - static void onCommitMaterial( LLUICtrl* ctrl, void* userdata); void onCommitSculpt(const LLSD& data); void onCancelSculpt(const LLSD& data); @@ -87,6 +87,7 @@ protected: void sendIsPhysical(); void sendIsTemporary(); void sendIsPhantom(); + void sendCastShadows(); void sendSculpt(); diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 0b6267c9e6..bfe6cab52f 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -802,6 +802,7 @@ BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop, case DAD_ANIMATION: case DAD_GESTURE: case DAD_CALLINGCARD: + case DAD_MESH: accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data); if(accept && drop) { @@ -1227,6 +1228,116 @@ LLUIImagePtr LLTaskWearableBridge::getIcon() const return LLInventoryIcon::getIcon(mAssetType, mInventoryType, mFlags, FALSE ); } +///---------------------------------------------------------------------------- +/// Class LLTaskMeshBridge +///---------------------------------------------------------------------------- + +class LLTaskMeshBridge : public LLTaskInvFVBridge +{ +public: + LLTaskMeshBridge( + LLPanelObjectInventory* panel, + const LLUUID& uuid, + const std::string& name); + + virtual LLUIImagePtr getIcon() const; + virtual void openItem(); + virtual void performAction(LLInventoryModel* model, std::string action); + virtual void buildContextMenu(LLMenuGL& menu, U32 flags); +}; + +LLTaskMeshBridge::LLTaskMeshBridge( + LLPanelObjectInventory* panel, + const LLUUID& uuid, + const std::string& name) : + LLTaskInvFVBridge(panel, uuid, name) +{ +} + +LLUIImagePtr LLTaskMeshBridge::getIcon() const +{ + return LLInventoryIcon::getIcon(LLAssetType::AT_MESH, LLInventoryType::IT_MESH, 0, FALSE); +} + +void LLTaskMeshBridge::openItem() +{ + // open mesh +} + + +// virtual +void LLTaskMeshBridge::performAction(LLInventoryModel* model, std::string action) +{ + if (action == "mesh action") + { + LLInventoryItem* item = findItem(); + if(item) + { + // do action + } + } + LLTaskInvFVBridge::performAction(model, action); +} + +void LLTaskMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags) +{ + LLInventoryItem* item = findItem(); + if(!item) return; + std::vector<std::string> items; + std::vector<std::string> disabled_items; + + if(item->getPermissions().getOwner() != gAgent.getID() + && item->getSaleInfo().isForSale()) + { + items.push_back(std::string("Task Buy")); + + std::string label= LLTrans::getString("Buy"); + // Check the price of the item. + S32 price = getPrice(); + if (-1 == price) + { + llwarns << "label_buy_task_bridged_item: Invalid price" << llendl; + } + else + { + std::ostringstream info; + info << LLTrans::getString("BuyforL$") << price; + label.assign(info.str()); + } + + const LLView::child_list_t *list = menu.getChildList(); + LLView::child_list_t::const_iterator itor; + for (itor = list->begin(); itor != list->end(); ++itor) + { + std::string name = (*itor)->getName(); + LLMenuItemCallGL* menu_itemp = dynamic_cast<LLMenuItemCallGL*>(*itor); + if (name == "Task Buy" && menu_itemp) + { + menu_itemp->setLabel(label); + } + } + } + else + { + items.push_back(std::string("Task Open")); + if (!isItemCopyable()) + { + disabled_items.push_back(std::string("Task Open")); + } + } + items.push_back(std::string("Task Properties")); + if(isItemRenameable()) + { + items.push_back(std::string("Task Rename")); + } + if(isItemRemovable()) + { + items.push_back(std::string("Task Remove")); + } + + + hide_context_entries(menu, items, disabled_items); +} ///---------------------------------------------------------------------------- /// LLTaskInvFVBridge impl @@ -1307,6 +1418,11 @@ LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory* object->getUUID(), object->getName()); break; + case LLAssetType::AT_MESH: + new_bridge = new LLTaskMeshBridge(panel, + object->getUUID(), + object->getName()); + break; default: llinfos << "Unhandled inventory type (llassetstorage.h): " << (S32)type << llendl; diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 82ff6c3487..933b40ec79 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -61,6 +61,7 @@ #include "llwindow.h" #include "llwindowshade.h" #include "llfloatertools.h" // to enable hide if build tools are up +#include "llvector4a.h" // Functions pulled from pipeline.cpp glh::matrix4f glh_get_current_modelview(); @@ -577,7 +578,9 @@ void LLPanelPrimMediaControls::updateShape() { const LLVolumeFace& vf = volume->getVolumeFace(mTargetObjectFace); - const LLVector3* ext = vf.mExtents; + LLVector3 ext[2]; + ext[0].set(vf.mExtents[0].getF32ptr()); + ext[1].set(vf.mExtents[1].getF32ptr()); LLVector3 center = (ext[0]+ext[1])*0.5f; LLVector3 size = (ext[1]-ext[0])*0.5f; diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index 065c4d0b92..c443814c89 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -71,6 +71,11 @@ #include "lldrawpool.h" #include "lluictrlfactory.h" +// For mesh physics +#include "llagent.h" +#include "llviewercontrol.h" +#include "llmeshrepository.h" + // "Features" Tab BOOL LLPanelVolume::postBuild() @@ -129,6 +134,29 @@ BOOL LLPanelVolume::postBuild() getChild<LLUICtrl>("Light Ambiance")->setValidateBeforeCommit( precommitValidate); } + // PHYSICS Parameters + { + // PhysicsShapeType combobox + mComboPhysicsShapeType = getChild<LLComboBox>("Physics Shape Type Combo Ctrl"); + mComboPhysicsShapeType->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsShapeType, this, _1, mComboPhysicsShapeType)); + + // PhysicsGravity + mSpinPhysicsGravity = getChild<LLSpinCtrl>("Physics Gravity"); + mSpinPhysicsGravity->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsGravity, this, _1, mSpinPhysicsGravity)); + + // PhysicsFriction + mSpinPhysicsFriction = getChild<LLSpinCtrl>("Physics Friction"); + mSpinPhysicsFriction->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsFriction, this, _1, mSpinPhysicsFriction)); + + // PhysicsDensity + mSpinPhysicsDensity = getChild<LLSpinCtrl>("Physics Density"); + mSpinPhysicsDensity->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsDensity, this, _1, mSpinPhysicsDensity)); + + // PhysicsRestitution + mSpinPhysicsRestitution = getChild<LLSpinCtrl>("Physics Restitution"); + mSpinPhysicsRestitution->setCommitCallback(boost::bind(&LLPanelVolume::sendPhysicsRestitution, this, _1, mSpinPhysicsRestitution)); + } + // Start with everyone disabled clearCtrls(); @@ -351,6 +379,54 @@ void LLPanelVolume::getState( ) getChildView("FlexForceZ")->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); + mObject = objectp; mRootObject = root_objectp; } @@ -384,6 +460,17 @@ void LLPanelVolume::refresh() getChildView("Light Ambiance")->setVisible( visible); getChildView("light texture control")->setVisible( visible); + bool enable_mesh = gSavedSettings.getBOOL("MeshEnabled") && + gAgent.getRegion() && + !gAgent.getRegion()->getCapability("GetMesh").empty(); + + getChildView("label physicsshapetype")->setVisible(enable_mesh); + getChildView("Physics Shape Type Combo Ctrl")->setVisible(enable_mesh); + getChildView("Physics Gravity")->setVisible(enable_mesh); + getChildView("Physics Material Override")->setVisible(enable_mesh); + getChildView("Physics Friction")->setVisible(enable_mesh); + getChildView("Physics Density")->setVisible(enable_mesh); + getChildView("Physics Restitution")->setVisible(enable_mesh); } @@ -430,6 +517,11 @@ void LLPanelVolume::clearCtrls() getChildView("FlexForceX")->setEnabled(false); getChildView("FlexForceY")->setEnabled(false); getChildView("FlexForceZ")->setEnabled(false); + + mSpinPhysicsGravity->setEnabled(FALSE); + mSpinPhysicsFriction->setEnabled(FALSE); + mSpinPhysicsDensity->setEnabled(FALSE); + mSpinPhysicsRestitution->setEnabled(FALSE); } // @@ -482,6 +574,48 @@ void LLPanelVolume::sendIsFlexible() llinfos << "update flexible sent" << llendl; } +void LLPanelVolume::sendPhysicsShapeType(LLUICtrl* ctrl, void* userdata) +{ + U8 type = ctrl->getValue().asInteger(); + LLSelectMgr::getInstance()->selectionSetPhysicsType(type); + + refreshCost(); +} + +void LLPanelVolume::sendPhysicsGravity(LLUICtrl* ctrl, void* userdata) +{ + 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); +} + +void LLPanelVolume::sendPhysicsRestitution(LLUICtrl* ctrl, void* userdata) +{ + 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); +} + +void LLPanelVolume::refreshCost() +{ + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + + if (obj) + { + obj->getObjectCost(); + } +} + void LLPanelVolume::onLightCancelColor(const LLSD& data) { LLColorSwatchCtrl* LightColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch"); diff --git a/indra/newview/llpanelvolume.h b/indra/newview/llpanelvolume.h index 90a2abda25..776a2c1f4a 100644 --- a/indra/newview/llpanelvolume.h +++ b/indra/newview/llpanelvolume.h @@ -64,6 +64,8 @@ public: static void onCommitIsFlexible( LLUICtrl* ctrl, void* userdata); static void onCommitFlexible( LLUICtrl* ctrl, void* userdata); + static void onCommitPhysicsParam( LLUICtrl* ctrl, void* userdata); + void onLightCancelColor(const LLSD& data); void onLightSelectColor(const LLSD& data); @@ -73,8 +75,15 @@ public: protected: void getState(); + void refreshCost(); protected: + void sendPhysicsShapeType(LLUICtrl* ctrl, void* userdata); + void sendPhysicsGravity(LLUICtrl* ctrl, void* userdata); + void sendPhysicsFriction(LLUICtrl* ctrl, void* userdata); + void sendPhysicsRestitution(LLUICtrl* ctrl, void* userdata); + void sendPhysicsDensity(LLUICtrl* ctrl, void* userdata); + /* LLTextBox* mLabelSelectSingleMessage; // Light @@ -99,6 +108,12 @@ protected: LLUUID mLightSavedTexture; LLPointer<LLViewerObject> mObject; LLPointer<LLViewerObject> mRootObject; + + LLComboBox* mComboPhysicsShapeType; + LLSpinCtrl* mSpinPhysicsGravity; + LLSpinCtrl* mSpinPhysicsFriction; + LLSpinCtrl* mSpinPhysicsDensity; + LLSpinCtrl* mSpinPhysicsRestitution; }; #endif diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 30a04109bc..e124916c48 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -652,7 +652,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time) const F32 area_for_max_settings = 0.0; const F32 area_for_min_settings = 1400.0; const F32 area_for_this_setting = area_for_max_settings + (area_for_min_settings-area_for_max_settings)*(1.0-lod_factor); - const F32 pixel_area = fsqrtf(mCharacter->getPixelArea()); + const F32 pixel_area = sqrtf(mCharacter->getPixelArea()); const BOOL is_self = (dynamic_cast<LLVOAvatarSelf *>(mCharacter) != NULL); if ((pixel_area > area_for_this_setting) || is_self) diff --git a/indra/newview/llphysicsshapebuilderutil.cpp b/indra/newview/llphysicsshapebuilderutil.cpp new file mode 100644 index 0000000000..5bfe5c9941 --- /dev/null +++ b/indra/newview/llphysicsshapebuilderutil.cpp @@ -0,0 +1,210 @@ +/** + * @file llphysicsshapebuilder.cpp + * @brief Generic system to convert LL(Physics)VolumeParams to physics shapes + * + * $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 "llphysicsshapebuilderutil.h" + +/* static */ +void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut ) +{ + const LLProfileParams& profile_params = volume_params.getProfileParams(); + const LLPathParams& path_params = volume_params.getPathParams(); + + specOut.mScale = scale; + + const F32 avgScale = ( scale[VX] + scale[VY] + scale[VZ] )/3.0f; + + // count the scale elements that are small + S32 min_size_counts = 0; + for (S32 i = 0; i < 3; ++i) + { + if (scale[i] < SHAPE_BUILDER_CONVEXIFICATION_SIZE) + { + ++min_size_counts; + } + } + + const bool profile_complete = ( profile_params.getBegin() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale ) && + ( profile_params.getEnd() >= (1.0f - SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale) ); + + const bool path_complete = ( path_params.getBegin() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale ) && + ( path_params.getEnd() >= (1.0f - SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale) ); + + const bool simple_params = ( volume_params.getHollow() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_HOLLOW/avgScale ) + && ( fabs(path_params.getShearX()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_SHEAR/avgScale ) + && ( fabs(path_params.getShearY()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_SHEAR/avgScale ) + && ( !volume_params.isMeshSculpt() && !volume_params.isSculpt() ); + + if (simple_params && profile_complete) + { + // Try to create an implicit shape or convexified + bool no_taper = ( fabs(path_params.getScaleX() - 1.0f) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TAPER/avgScale ) + && ( fabs(path_params.getScaleY() - 1.0f) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TAPER/avgScale ); + + bool no_twist = ( fabs(path_params.getTwistBegin()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TWIST/avgScale ) + && ( fabs(path_params.getTwistEnd()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TWIST/avgScale); + + // Box + if( + ( profile_params.getCurveType() == LL_PCODE_PROFILE_SQUARE ) + && ( path_params.getCurveType() == LL_PCODE_PATH_LINE ) + && no_taper + && no_twist + ) + { + specOut.mType = PhysicsShapeSpecification::BOX; + if ( path_complete ) + { + return; + } + else + { + // Side lengths + specOut.mScale[VX] = llmax( scale[VX], SHAPE_BUILDER_MIN_GEOMETRY_SIZE ); + specOut.mScale[VY] = llmax( scale[VY], SHAPE_BUILDER_MIN_GEOMETRY_SIZE ); + specOut.mScale[VZ] = llmax( scale[VZ] * (path_params.getEnd() - path_params.getBegin()), SHAPE_BUILDER_MIN_GEOMETRY_SIZE ); + + specOut.mCenter.set( 0.f, 0.f, 0.5f * scale[VZ] * ( path_params.getEnd() + path_params.getBegin() - 1.0f ) ); + return; + } + } + + // Sphere + if( path_complete + && ( profile_params.getCurveType() == LL_PCODE_PROFILE_CIRCLE_HALF ) + && ( path_params.getCurveType() == LL_PCODE_PATH_CIRCLE ) + && ( fabs(volume_params.getTaper()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TAPER/avgScale ) + && no_twist + ) + { + if ( ( scale[VX] == scale[VZ] ) + && ( scale[VY] == scale[VZ] ) ) + { + // perfect sphere + specOut.mType = PhysicsShapeSpecification::SPHERE; + specOut.mScale = scale; + return; + } + else if (min_size_counts > 1) + { + // small or narrow sphere -- we can boxify + for (S32 i=0; i<3; ++i) + { + if (specOut.mScale[i] < SHAPE_BUILDER_CONVEXIFICATION_SIZE) + { + // reduce each small dimension size to split the approximation errors + specOut.mScale[i] *= 0.75f; + } + } + specOut.mType = PhysicsShapeSpecification::BOX; + return; + } + } + + // Cylinder + if( (scale[VX] == scale[VY]) + && ( profile_params.getCurveType() == LL_PCODE_PROFILE_CIRCLE ) + && ( path_params.getCurveType() == LL_PCODE_PATH_LINE ) + && ( volume_params.getBeginS() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale ) + && ( volume_params.getEndS() >= (1.0f - SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale) ) + && no_taper + ) + { + if (min_size_counts > 1) + { + // small or narrow sphere -- we can boxify + for (S32 i=0; i<3; ++i) + { + if (specOut.mScale[i] < SHAPE_BUILDER_CONVEXIFICATION_SIZE) + { + // reduce each small dimension size to split the approximation errors + specOut.mScale[i] *= 0.75f; + } + } + + specOut.mType = PhysicsShapeSpecification::BOX; + } + else + { + specOut.mType = PhysicsShapeSpecification::CYLINDER; + F32 length = (volume_params.getPathParams().getEnd() - volume_params.getPathParams().getBegin()) * scale[VZ]; + + specOut.mScale[VY] = specOut.mScale[VX]; + specOut.mScale[VZ] = length; + // The minus one below fixes the fact that begin and end range from 0 to 1 not -1 to 1. + specOut.mCenter.set( 0.f, 0.f, 0.5f * (volume_params.getPathParams().getBegin() + volume_params.getPathParams().getEnd() - 1.f) * scale[VZ] ); + } + + return; + } + } + + if ( (min_size_counts == 3 ) + // Possible dead code here--who wants to take it out? + || (path_complete + && profile_complete + && ( path_params.getCurveType() == LL_PCODE_PATH_LINE ) + && (min_size_counts > 1 ) ) + ) + { + // it isn't simple but + // we might be able to convexify this shape if the path and profile are complete + // or the path is linear and both path and profile are complete --> we can boxify it + specOut.mType = PhysicsShapeSpecification::BOX; + specOut.mScale = scale; + return; + } + + // Special case for big, very thin objects - bump the small dimensions up to the COLLISION_TOLERANCE + if (min_size_counts == 1 // One dimension is small + && avgScale > 3.f) // ... but others are fairly large + { + for (S32 i = 0; i < 3; ++i) + { + specOut.mScale[i] = llmax( specOut.mScale[i], COLLISION_TOLERANCE ); + } + } + + if ( volume_params.shouldForceConvex() ) + { + specOut.mType = PhysicsShapeSpecification::USER_CONVEX; + } + // Make a simpler convex shape if we can. + else if (volume_params.isConvex() // is convex + || min_size_counts > 1 ) // two or more small dimensions + { + specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; + } + else if ( volume_params.isSculpt() ) // Is a sculpt of any kind (mesh or legacy) + { + specOut.mType = volume_params.isMeshSculpt() ? PhysicsShapeSpecification::USER_MESH : PhysicsShapeSpecification::SCULPT; + } + else // Resort to mesh + { + specOut.mType = PhysicsShapeSpecification::PRIM_MESH; + } +} diff --git a/indra/newview/llphysicsshapebuilderutil.h b/indra/newview/llphysicsshapebuilderutil.h new file mode 100644 index 0000000000..7dedfb05e2 --- /dev/null +++ b/indra/newview/llphysicsshapebuilderutil.h @@ -0,0 +1,138 @@ +/** + * @file llphysicsshapebuilder.h + * @brief Generic system to convert LL(Physics)VolumeParams to physics shapes + * + * $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$ + */ + +#ifndef LL_PHYSICS_SHAPE_BUILDER_H +#define LL_PHYSICS_SHAPE_BUILDER_H + +#include "indra_constants.h" +#include "llvolume.h" + +#define USE_SHAPE_QUANTIZATION 0 + +#define SHAPE_BUILDER_DEFAULT_VOLUME_DETAIL 1 + +#define SHAPE_BUILDER_IMPLICIT_THRESHOLD_HOLLOW 0.10f +#define SHAPE_BUILDER_IMPLICIT_THRESHOLD_HOLLOW_SPHERES 0.90f +#define SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT 0.05f +#define SHAPE_BUILDER_IMPLICIT_THRESHOLD_TAPER 0.05f +#define SHAPE_BUILDER_IMPLICIT_THRESHOLD_TWIST 0.09f +#define SHAPE_BUILDER_IMPLICIT_THRESHOLD_SHEAR 0.05f + +const F32 SHAPE_BUILDER_ENTRY_SNAP_SCALE_BIN_SIZE = 0.15f; +const F32 SHAPE_BUILDER_ENTRY_SNAP_PARAMETER_BIN_SIZE = 0.010f; +const F32 SHAPE_BUILDER_CONVEXIFICATION_SIZE = 2.f * COLLISION_TOLERANCE; +const F32 SHAPE_BUILDER_MIN_GEOMETRY_SIZE = 0.5f * COLLISION_TOLERANCE; + +class LLPhysicsVolumeParams : public LLVolumeParams +{ +public: + + LLPhysicsVolumeParams( const LLVolumeParams& params, bool forceConvex ) : + LLVolumeParams( params ), + mForceConvex(forceConvex) {} + + bool operator==(const LLPhysicsVolumeParams ¶ms) const + { + return ( LLVolumeParams::operator==(params) && (mForceConvex == params.mForceConvex) ); + } + + bool operator!=(const LLPhysicsVolumeParams ¶ms) const + { + return !operator==(params); + } + + bool operator<(const LLPhysicsVolumeParams ¶ms) const + { + if ( LLVolumeParams::operator!=(params) ) + { + return LLVolumeParams::operator<(params); + } + return (params.mForceConvex == false) && (mForceConvex == true); + } + + bool shouldForceConvex() const { return mForceConvex; } + +private: + bool mForceConvex; +}; + + +class LLPhysicsShapeBuilderUtil +{ +public: + + class PhysicsShapeSpecification + { + public: + enum ShapeType + { + // Primitive types + BOX, + SPHERE, + CYLINDER, + + USER_CONVEX, // User specified they wanted the convex hull of the volume + + PRIM_CONVEX, // Either a volume that is inherently convex but not a primitive type, or a shape + // with dimensions such that will convexify it anyway. + + SCULPT, // Special case for traditional sculpts--they are the convex hull of a single particular set of volume params + + USER_MESH, // A user mesh. May or may not contain a convex decomposition. + + PRIM_MESH, // A non-convex volume which we have to represent accurately + + INVALID + }; + + PhysicsShapeSpecification() : + mType( INVALID ), + mScale( 0.f, 0.f, 0.f ), + mCenter( 0.f, 0.f, 0.f ) {} + + bool isConvex() { return (mType != USER_MESH && mType != PRIM_MESH && mType != INVALID); } + bool isMesh() { return (mType == USER_MESH) || (mType == PRIM_MESH); } + + ShapeType getType() { return mType; } + const LLVector3& getScale() { return mScale; } + const LLVector3& getCenter() { return mCenter; } + + private: + friend class LLPhysicsShapeBuilderUtil; + + ShapeType mType; + + // Dimensions of an AABB around the shape + LLVector3 mScale; + + // Offset of shape from origin of primitive's reference frame + LLVector3 mCenter; + }; + + static void determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut ); +}; + +#endif //LL_PHYSICS_SHAPE_BUILDER_H diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp index bacaa0cd76..450f9b2be7 100644 --- a/indra/newview/llpolymesh.cpp +++ b/indra/newview/llpolymesh.cpp @@ -29,7 +29,8 @@ //----------------------------------------------------------------------------- #include "llviewerprecompiledheaders.h" -#include "llpolymesh.h" +#include "llfasttimer.h" +#include "llmemory.h" #include "llviewercontrol.h" #include "llxmltree.h" @@ -39,7 +40,7 @@ #include "llvolume.h" #include "llendianswizzle.h" -#include "llfasttimer.h" +#include "llpolymesh.h" #define HEADER_ASCII "Linden Mesh 1.0" #define HEADER_BINARY "Linden Binary Mesh 1.0" @@ -737,58 +738,52 @@ const LLVector2 &LLPolyMeshSharedData::getUVs(U32 index) //----------------------------------------------------------------------------- LLPolyMesh::LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_mesh) { - LLMemType mt(LLMemType::MTYPE_AVATAR_MESH); - - llassert(shared_data); - - mSharedData = shared_data; - mReferenceMesh = reference_mesh; - mAvatarp = NULL; - mVertexData = NULL; - - mCurVertexCount = 0; - mFaceIndexCount = 0; - mFaceIndexOffset = 0; - mFaceVertexCount = 0; - mFaceVertexOffset = 0; - - if (shared_data->isLOD() && reference_mesh) - { - mCoords = reference_mesh->mCoords; - mNormals = reference_mesh->mNormals; - mScaledNormals = reference_mesh->mScaledNormals; - mBinormals = reference_mesh->mBinormals; - mScaledBinormals = reference_mesh->mScaledBinormals; - mTexCoords = reference_mesh->mTexCoords; - mClothingWeights = reference_mesh->mClothingWeights; - } - else - { -#if 1 // Allocate memory without initializing every vector - // NOTE: This makes asusmptions about the size of LLVector[234] - int nverts = mSharedData->mNumVertices; - int nfloats = nverts * (3*5 + 2 + 4); - mVertexData = new F32[nfloats]; - int offset = 0; - mCoords = (LLVector3*)(mVertexData + offset); offset += 3*nverts; - mNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; - mScaledNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; - mBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; - mScaledBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; - mTexCoords = (LLVector2*)(mVertexData + offset); offset += 2*nverts; - mClothingWeights = (LLVector4*)(mVertexData + offset); offset += 4*nverts; -#else - mCoords = new LLVector3[mSharedData->mNumVertices]; - mNormals = new LLVector3[mSharedData->mNumVertices]; - mScaledNormals = new LLVector3[mSharedData->mNumVertices]; - mBinormals = new LLVector3[mSharedData->mNumVertices]; - mScaledBinormals = new LLVector3[mSharedData->mNumVertices]; - mTexCoords = new LLVector2[mSharedData->mNumVertices]; - mClothingWeights = new LLVector4[mSharedData->mNumVertices]; - memset(mClothingWeights, 0, sizeof(LLVector4) * mSharedData->mNumVertices); -#endif - initializeForMorph(); - } + LLMemType mt(LLMemType::MTYPE_AVATAR_MESH); + + llassert(shared_data); + + mSharedData = shared_data; + mReferenceMesh = reference_mesh; + mAvatarp = NULL; + mVertexData = NULL; + + mCurVertexCount = 0; + mFaceIndexCount = 0; + mFaceIndexOffset = 0; + mFaceVertexCount = 0; + mFaceVertexOffset = 0; + + if (shared_data->isLOD() && reference_mesh) + { + mCoords = reference_mesh->mCoords; + mNormals = reference_mesh->mNormals; + mScaledNormals = reference_mesh->mScaledNormals; + mBinormals = reference_mesh->mBinormals; + mScaledBinormals = reference_mesh->mScaledBinormals; + mTexCoords = reference_mesh->mTexCoords; + mClothingWeights = reference_mesh->mClothingWeights; + } + else + { + // Allocate memory without initializing every vector + // NOTE: This makes asusmptions about the size of LLVector[234] + int nverts = mSharedData->mNumVertices; + int nfloats = nverts * (2*4 + 3*3 + 2 + 4); + //use 16 byte aligned vertex data to make LLPolyMesh SSE friendly + mVertexData = (F32*) ll_aligned_malloc_16(nfloats*4); + int offset = 0; + mCoords = (LLVector4*)(mVertexData + offset); offset += 4*nverts; + mNormals = (LLVector4*)(mVertexData + offset); offset += 4*nverts; + mClothingWeights = (LLVector4*)(mVertexData + offset); offset += 4*nverts; + mTexCoords = (LLVector2*)(mVertexData + offset); offset += 2*nverts; + + // these members don't need to be 16-byte aligned, but the first one might be + // read during an aligned memcpy of mTexCoords + mScaledNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; + mBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; + mScaledBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts; + initializeForMorph(); + } } @@ -803,17 +798,9 @@ LLPolyMesh::~LLPolyMesh() delete mJointRenderData[i]; mJointRenderData[i] = NULL; } -#if 0 // These are now allocated as one big uninitialized chunk - delete [] mCoords; - delete [] mNormals; - delete [] mScaledNormals; - delete [] mBinormals; - delete [] mScaledBinormals; - delete [] mClothingWeights; - delete [] mTexCoords; -#else - delete [] mVertexData; -#endif + + ll_aligned_free_16(mVertexData); + } @@ -919,7 +906,7 @@ void LLPolyMesh::dumpDiagInfo() //----------------------------------------------------------------------------- // getWritableCoords() //----------------------------------------------------------------------------- -LLVector3 *LLPolyMesh::getWritableCoords() +LLVector4 *LLPolyMesh::getWritableCoords() { return mCoords; } @@ -927,7 +914,7 @@ LLVector3 *LLPolyMesh::getWritableCoords() //----------------------------------------------------------------------------- // getWritableNormals() //----------------------------------------------------------------------------- -LLVector3 *LLPolyMesh::getWritableNormals() +LLVector4 *LLPolyMesh::getWritableNormals() { return mNormals; } @@ -979,16 +966,17 @@ LLVector3 *LLPolyMesh::getScaledBinormals() //----------------------------------------------------------------------------- void LLPolyMesh::initializeForMorph() { - if (!mSharedData) - return; - - memcpy(mCoords, mSharedData->mBaseCoords, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ - memcpy(mNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ - memcpy(mScaledNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ - memcpy(mBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ - memcpy(mScaledBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ - memcpy(mTexCoords, mSharedData->mTexCoords, sizeof(LLVector2) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ - memset(mClothingWeights, 0, sizeof(LLVector4) * mSharedData->mNumVertices); + for (U32 i = 0; i < mSharedData->mNumVertices; ++i) + { + mCoords[i] = LLVector4(mSharedData->mBaseCoords[i]); + mNormals[i] = LLVector4(mSharedData->mBaseNormals[i]); + } + + memcpy(mScaledNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ + memcpy(mBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ + memcpy(mScaledBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ + memcpy(mTexCoords, mSharedData->mTexCoords, sizeof(LLVector2) * mSharedData->mNumVertices); /*Flawfinder: ignore*/ + memset(mClothingWeights, 0, sizeof(LLVector4) * mSharedData->mNumVertices); } //----------------------------------------------------------------------------- diff --git a/indra/newview/llpolymesh.h b/indra/newview/llpolymesh.h index 894cd307c4..ba2bf85570 100644 --- a/indra/newview/llpolymesh.h +++ b/indra/newview/llpolymesh.h @@ -217,15 +217,15 @@ public: } // Get coords - const LLVector3 *getCoords() const{ + const LLVector4 *getCoords() const{ return mCoords; } // non const version - LLVector3 *getWritableCoords(); + LLVector4 *getWritableCoords(); // Get normals - const LLVector3 *getNormals() const{ + const LLVector4 *getNormals() const{ return mNormals; } @@ -247,7 +247,7 @@ public: } // intermediate morphed normals and output normals - LLVector3 *getWritableNormals(); + LLVector4 *getWritableNormals(); LLVector3 *getScaledNormals(); LLVector3 *getWritableBinormals(); @@ -341,11 +341,11 @@ protected: // Single array of floats for allocation / deletion F32 *mVertexData; // deformed vertices (resulting from application of morph targets) - LLVector3 *mCoords; + LLVector4 *mCoords; // deformed normals (resulting from application of morph targets) LLVector3 *mScaledNormals; // output normals (after normalization) - LLVector3 *mNormals; + LLVector4 *mNormals; // deformed binormals (resulting from application of morph targets) LLVector3 *mScaledBinormals; // output binormals (after normalization) diff --git a/indra/newview/llpolymorph.cpp b/indra/newview/llpolymorph.cpp index 36f8c8d13e..cefd7df3fe 100644 --- a/indra/newview/llpolymorph.cpp +++ b/indra/newview/llpolymorph.cpp @@ -508,10 +508,10 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) if (delta_weight != 0.f) { llassert(!mMesh->isLOD()); - LLVector3 *coords = mMesh->getWritableCoords(); + LLVector4 *coords = mMesh->getWritableCoords(); LLVector3 *scaled_normals = mMesh->getScaledNormals(); - LLVector3 *normals = mMesh->getWritableNormals(); + LLVector4 *normals = mMesh->getWritableNormals(); LLVector3 *scaled_binormals = mMesh->getScaledBinormals(); LLVector3 *binormals = mMesh->getWritableBinormals(); @@ -531,7 +531,8 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) maskWeight = maskWeightArray[vert_index_morph]; } - coords[vert_index_mesh] += mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight; + coords[vert_index_mesh] += LLVector4(mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight); + if (getInfo()->mIsClothingMorph && clothing_weights) { LLVector3 clothing_offset = mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight; @@ -546,7 +547,7 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) scaled_normals[vert_index_mesh] += mMorphData->mNormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR; LLVector3 normalized_normal = scaled_normals[vert_index_mesh]; normalized_normal.normVec(); - normals[vert_index_mesh] = normalized_normal; + normals[vert_index_mesh] = LLVector4(normalized_normal); // calculate new binormals scaled_binormals[vert_index_mesh] += mMorphData->mBinormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR; @@ -595,7 +596,7 @@ void LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S3 if (maskWeights) { - LLVector3 *coords = mMesh->getWritableCoords(); + LLVector4 *coords = mMesh->getWritableCoords(); LLVector3 *scaled_normals = mMesh->getScaledNormals(); LLVector3 *scaled_binormals = mMesh->getScaledBinormals(); LLVector2 *tex_coords = mMesh->getWritableTexCoords(); @@ -606,7 +607,7 @@ void LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S3 S32 out_vert = mMorphData->mVertexIndices[vert]; // remove effect of existing masked morph - coords[out_vert] -= mMorphData->mCoords[vert] * lastMaskWeight; + coords[out_vert] -= LLVector4(mMorphData->mCoords[vert]) * lastMaskWeight; scaled_normals[out_vert] -= mMorphData->mNormals[vert] * lastMaskWeight * NORMAL_SOFTEN_FACTOR; scaled_binormals[out_vert] -= mMorphData->mBinormals[vert] * lastMaskWeight * NORMAL_SOFTEN_FACTOR; tex_coords[out_vert] -= mMorphData->mTexCoords[vert] * lastMaskWeight; diff --git a/indra/newview/llsceneview.cpp b/indra/newview/llsceneview.cpp new file mode 100644 index 0000000000..8e8fc9dd25 --- /dev/null +++ b/indra/newview/llsceneview.cpp @@ -0,0 +1,429 @@ +/** + * @file llsceneview.cpp + * @brief LLSceneView 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 "llsceneview.h" +#include "llviewerwindow.h" +#include "pipeline.h" +#include "llviewerobjectlist.h" +#include "llviewerregion.h" +#include "llagent.h" +#include "llvolumemgr.h" + +LLSceneView* gSceneView = NULL; + +//borrow this helper function from llfasttimerview.cpp +template <class VEC_TYPE> +void removeOutliers(std::vector<VEC_TYPE>& data, F32 k); + + +LLSceneView::LLSceneView(const LLRect& rect) + : LLFloater(LLSD()) +{ + setRect(rect); + setVisible(FALSE); + + setCanMinimize(false); + setCanClose(true); +} + +void LLSceneView::onClickCloseBtn() +{ + setVisible(false); +} + + +void LLSceneView::draw() +{ + S32 margin = 10; + S32 height = (S32) (gViewerWindow->getWindowRectScaled().getHeight()*0.75f); + S32 width = (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f); + + LLRect new_rect; + new_rect.setLeftTopAndSize(getRect().mLeft, getRect().mTop, width, height); + setRect(new_rect); + + // Draw the window background + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f)); + + + //aggregate some statistics + + //object sizes + std::vector<F32> size[2]; + + //triangle counts + std::vector<S32> triangles[2]; + std::vector<S32> visible_triangles[2]; + S32 total_visible_triangles[] = {0, 0}; + S32 total_triangles[] = {0, 0}; + + //streaming cost + std::vector<F32> streaming_cost[2]; + F32 total_streaming[] = { 0.f, 0.f }; + + //physics cost + std::vector<F32> physics_cost[2]; + F32 total_physics[] = { 0.f, 0.f }; + + + U32 object_count = 0; + + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + for (U32 i = 0; i < gObjectList.getNumObjects(); ++i) + { + LLViewerObject* object = gObjectList.getObject(i); + + if (object && + object->getVolume()&& + object->getRegion() == region) + { + U32 idx = object->isAttachment() ? 1 : 0; + + LLVolume* volume = object->getVolume(); + object_count++; + + F32 radius = object->getScale().magVec(); + size[idx].push_back(radius); + + S32 visible = volume->getNumTriangles(); + S32 high_triangles = object->getHighLODTriangleCount(); + + total_visible_triangles[idx] += visible; + total_triangles[idx] += high_triangles; + + visible_triangles[idx].push_back(visible); + triangles[idx].push_back(high_triangles); + + F32 streaming = object->getStreamingCost(); + total_streaming[idx] += streaming; + streaming_cost[idx].push_back(streaming); + + F32 physics = object->getPhysicsCost(); + total_physics[idx] += physics; + physics_cost[idx].push_back(physics); + } + } + } + + const char* category[] = + { + "Region", + "Attachment" + }; + + S32 graph_pos[4]; + + for (U32 i = 0; i < 4; ++i) + { + graph_pos[i] = new_rect.getHeight()/4*(i+1); + } + + for (U32 idx = 0; idx < 2; idx++) + { + if (!size[idx].empty()) + { //display graph of object sizes + std::sort(size[idx].begin(), size[idx].end()); + + ll_remove_outliers(size[idx], 1.f); + + LLRect size_rect; + + if (idx == 0) + { + size_rect = LLRect(margin, graph_pos[0]-margin, new_rect.getWidth()/2-margin, margin*2); + } + else + { + size_rect = LLRect(margin+new_rect.getWidth()/2, graph_pos[0]-margin, new_rect.getWidth()-margin, margin*2); + } + + gl_rect_2d(size_rect, LLColor4::white, false); + + F32 size_domain[] = { 128.f, 0.f }; + + //get domain of sizes + for (U32 i = 0; i < size[idx].size(); ++i) + { + size_domain[0] = llmin(size_domain[0], size[idx][i]); + size_domain[1] = llmax(size_domain[1], size[idx][i]); + } + + F32 size_range = size_domain[1]-size_domain[0]; + + U32 count = size[idx].size(); + + F32 total = 0.f; + + gGL.begin(LLRender::LINE_STRIP); + + for (U32 i = 0; i < count; ++i) + { + F32 rad = size[idx][i]; + total += rad; + F32 y = (rad-size_domain[0])/size_range*size_rect.getHeight()+size_rect.mBottom; + F32 x = (F32) i / count * size_rect.getWidth() + size_rect.mLeft; + + gGL.vertex2f(x,y); + + if (i%4096 == 0) + { + gGL.end(); + gGL.flush(); + gGL.begin(LLRender::LINE_STRIP); + } + } + + gGL.end(); + gGL.flush(); + + std::string label = llformat("%s Object Sizes (m) -- [%.1f, %.1f] Mean: %.1f Median: %.1f -- %d samples", + category[idx], size_domain[0], size_domain[1], total/count, size[idx][count/2], count); + + LLFontGL::getFontMonospace()->renderUTF8(label, + 0 , size_rect.mLeft, size_rect.mTop+margin, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); + + } + } + + for (U32 idx = 0; idx < 2; ++idx) + { + if (!triangles[idx].empty()) + { //plot graph of visible/total triangles + std::sort(triangles[idx].begin(), triangles[idx].end()); + + ll_remove_outliers(triangles[idx], 1.f); + + LLRect tri_rect; + if (idx == 0) + { + tri_rect = LLRect(margin, graph_pos[1]-margin, new_rect.getWidth()/2-margin, graph_pos[0]+margin); + } + else + { + tri_rect = LLRect(new_rect.getWidth()/2+margin, graph_pos[1]-margin, new_rect.getWidth()-margin, graph_pos[0]+margin); + } + + gl_rect_2d(tri_rect, LLColor4::white, false); + + S32 tri_domain[] = { 65536, 0 }; + + //get domain of triangle counts + for (U32 i = 0; i < triangles[idx].size(); ++i) + { + tri_domain[0] = llmin(tri_domain[0], triangles[idx][i]); + tri_domain[1] = llmax(tri_domain[1], triangles[idx][i]); + } + + U32 triangle_range = tri_domain[1]-tri_domain[0]; + + U32 count = triangles[idx].size(); + + U32 total = 0; + + gGL.begin(LLRender::LINE_STRIP); + //plot triangles + for (U32 i = 0; i < count; ++i) + { + U32 tri_count = triangles[idx][i]; + total += tri_count; + F32 y = (F32) (tri_count-tri_domain[0])/triangle_range*tri_rect.getHeight()+tri_rect.mBottom; + F32 x = (F32) i / count * tri_rect.getWidth() + tri_rect.mLeft; + + gGL.vertex2f(x,y); + + if (i%4096 == 0) + { + gGL.end(); + gGL.flush(); + gGL.begin(LLRender::LINE_STRIP); + } + } + + gGL.end(); + gGL.flush(); + + U32 total_visible = 0; + count = visible_triangles[idx].size(); + + for (U32 i = 0; i < count; ++i) + { + U32 tri_count = visible_triangles[idx][i]; + total_visible += tri_count; + } + + std::string label = llformat("%s Object Triangle Counts (Ktris) -- [%.2f, %.2f] Mean: %.2f Median: %.2f Visible: %.2f/%.2f", + category[idx], tri_domain[0]/1024.f, tri_domain[1]/1024.f, (total/count)/1024.f, triangles[idx][count/2]/1024.f, total_visible_triangles[idx]/1024.f, total_triangles[idx]/1024.f); + + LLFontGL::getFontMonospace()->renderUTF8(label, + 0 , tri_rect.mLeft, tri_rect.mTop+margin, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); + + } + } + + for (U32 idx = 0; idx < 2; ++idx) + { + if (!streaming_cost[idx].empty()) + { //plot graph of streaming cost + std::sort(streaming_cost[idx].begin(), streaming_cost[idx].end()); + + ll_remove_outliers(streaming_cost[idx], 1.f); + + LLRect tri_rect; + if (idx == 0) + { + tri_rect = LLRect(margin, graph_pos[2]-margin, new_rect.getWidth()/2-margin, graph_pos[1]+margin); + } + else + { + tri_rect = LLRect(new_rect.getWidth()/2+margin, graph_pos[2]-margin, new_rect.getWidth()-margin, graph_pos[1]+margin); + } + + gl_rect_2d(tri_rect, LLColor4::white, false); + + F32 streaming_domain[] = { 65536, 0 }; + + //get domain of triangle counts + for (U32 i = 0; i < streaming_cost[idx].size(); ++i) + { + streaming_domain[0] = llmin(streaming_domain[0], streaming_cost[idx][i]); + streaming_domain[1] = llmax(streaming_domain[1], streaming_cost[idx][i]); + } + + F32 cost_range = streaming_domain[1]-streaming_domain[0]; + + U32 count = streaming_cost[idx].size(); + + F32 total = 0; + + gGL.begin(LLRender::LINE_STRIP); + //plot triangles + for (U32 i = 0; i < count; ++i) + { + F32 sc = streaming_cost[idx][i]; + total += sc; + F32 y = (F32) (sc-streaming_domain[0])/cost_range*tri_rect.getHeight()+tri_rect.mBottom; + F32 x = (F32) i / count * tri_rect.getWidth() + tri_rect.mLeft; + + gGL.vertex2f(x,y); + + if (i%4096 == 0) + { + gGL.end(); + gGL.flush(); + gGL.begin(LLRender::LINE_STRIP); + } + } + + gGL.end(); + gGL.flush(); + + std::string label = llformat("%s Object Streaming Cost -- [%.2f, %.2f] Mean: %.2f Total: %.2f", + category[idx], streaming_domain[0], streaming_domain[1], total/count, total_streaming[idx]); + + LLFontGL::getFontMonospace()->renderUTF8(label, + 0 , tri_rect.mLeft, tri_rect.mTop+margin, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); + + } + } + + for (U32 idx = 0; idx < 2; ++idx) + { + if (!physics_cost[idx].empty()) + { //plot graph of physics cost + std::sort(physics_cost[idx].begin(), physics_cost[idx].end()); + + ll_remove_outliers(physics_cost[idx], 1.f); + + LLRect tri_rect; + if (idx == 0) + { + tri_rect = LLRect(margin, graph_pos[3]-margin, new_rect.getWidth()/2-margin, graph_pos[2]+margin); + } + else + { + tri_rect = LLRect(new_rect.getWidth()/2+margin, graph_pos[3]-margin, new_rect.getWidth()-margin, graph_pos[2]+margin); + } + + gl_rect_2d(tri_rect, LLColor4::white, false); + + F32 physics_domain[] = { 65536, 0 }; + + //get domain of triangle counts + for (U32 i = 0; i < physics_cost[idx].size(); ++i) + { + physics_domain[0] = llmin(physics_domain[0], physics_cost[idx][i]); + physics_domain[1] = llmax(physics_domain[1], physics_cost[idx][i]); + } + + F32 cost_range = physics_domain[1]-physics_domain[0]; + + U32 count = physics_cost[idx].size(); + + F32 total = 0; + + gGL.begin(LLRender::LINE_STRIP); + //plot triangles + for (U32 i = 0; i < count; ++i) + { + F32 pc = physics_cost[idx][i]; + total += pc; + F32 y = (F32) (pc-physics_domain[0])/cost_range*tri_rect.getHeight()+tri_rect.mBottom; + F32 x = (F32) i / count * tri_rect.getWidth() + tri_rect.mLeft; + + gGL.vertex2f(x,y); + + if (i%4096 == 0) + { + gGL.end(); + gGL.flush(); + gGL.begin(LLRender::LINE_STRIP); + } + } + + gGL.end(); + gGL.flush(); + + std::string label = llformat("%s Object Physics Cost -- [%.2f, %.2f] Mean: %.2f Total: %.2f", + category[idx], physics_domain[0], physics_domain[1], total/count, total_physics[idx]); + + LLFontGL::getFontMonospace()->renderUTF8(label, + 0 , tri_rect.mLeft, tri_rect.mTop+margin, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); + + } + } + + + + + LLView::draw(); +} + + diff --git a/indra/newview/llsceneview.h b/indra/newview/llsceneview.h new file mode 100644 index 0000000000..2a3a14bbee --- /dev/null +++ b/indra/newview/llsceneview.h @@ -0,0 +1,48 @@ +/** + * @file llsceneview.h + * @brief LLSceneView 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$ + */ + +#ifndef LL_LLSCENEVIEW_H +#define LL_LLSCENEVIEW_H + +#include "llfloater.h" + + +class LLSceneView : public LLFloater +{ +public: + LLSceneView(const LLRect& rect); + + virtual void draw(); + +protected: + virtual void onClickCloseBtn(); + + +}; + +extern LLSceneView* gSceneView; + +#endif // LL_LLSCENEVIEW_H diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index f05892d9b0..9b264b81c7 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -64,6 +64,7 @@ #include "llhudmanager.h" #include "llinventorymodel.h" #include "llmenugl.h" +#include "llmeshrepository.h" #include "llmutelist.h" #include "llnotificationsutil.h" #include "llsidepaneltaskinfo.h" @@ -176,7 +177,6 @@ LLObjectSelection *get_null_object_selection() // Build time optimization, generate this function once here template class LLSelectMgr* LLSingleton<class LLSelectMgr>::getInstance(); - //----------------------------------------------------------------------------- // LLSelectMgr() //----------------------------------------------------------------------------- @@ -1191,8 +1191,8 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 & mGridRotation = first_grid_object->getRenderRotation(); LLVector3 first_grid_obj_pos = first_grid_object->getRenderPosition(); - LLVector3 min_extents(F32_MAX, F32_MAX, F32_MAX); - LLVector3 max_extents(-F32_MAX, -F32_MAX, -F32_MAX); + LLVector4a min_extents(F32_MAX); + LLVector4a max_extents(-F32_MAX); BOOL grid_changed = FALSE; for (LLObjectSelection::iterator iter = mGridObjects.begin(); iter != mGridObjects.end(); ++iter) @@ -1201,7 +1201,7 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 & LLDrawable* drawable = object->mDrawable; if (drawable) { - const LLVector3* ext = drawable->getSpatialExtents(); + 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; @@ -1209,13 +1209,19 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 & } if (grid_changed) { - mGridOrigin = lerp(min_extents, max_extents, 0.5f); + 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 = (max_extents - min_extents) * 0.5f; + mGridScale.set(size.getF32ptr()); } } else // GRID_MODE_WORLD or just plain default @@ -1979,6 +1985,103 @@ BOOL LLSelectMgr::selectionGetGlow(F32 *glow) 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(); + } + 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(); + } + 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(); + } + 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(); + } + 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(); + } + return true; + } + } sendfunc(restitution); + getSelection()->applyToObjects(&sendfunc); +} + + //----------------------------------------------------------------------------- // selectionSetMaterial() //----------------------------------------------------------------------------- @@ -3628,7 +3731,7 @@ void LLSelectMgr::deselectAllIfTooFar() { if (mDebugSelectMgr) { - llinfos << "Selection manager: auto-deselecting, select_dist = " << fsqrtf(select_dist_sq) << llendl; + llinfos << "Selection manager: auto-deselecting, select_dist = " << (F32) sqrt(select_dist_sq) << llendl; llinfos << "agent pos global = " << gAgent.getPositionGlobal() << llendl; llinfos << "selection pos global = " << selectionCenter << llendl; } @@ -3797,6 +3900,26 @@ void LLSelectMgr::sendDelink() 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( @@ -4026,7 +4149,6 @@ void LLSelectMgr::selectionUpdateCastShadows(BOOL cast_shadows) getSelection()->applyToObjects(&func); } - //---------------------------------------------------------------------- // Helpful packing functions for sendObjectMessage() //---------------------------------------------------------------------- @@ -4715,7 +4837,6 @@ void LLSelectMgr::processForceObjectSelect(LLMessageSystem* msg, void**) LLSelectMgr::getInstance()->highlightObjectAndFamily(objects); } - extern LLGLdouble gGLModelView[16]; void LLSelectMgr::updateSilhouettes() @@ -5199,7 +5320,6 @@ LLSelectNode::LLSelectNode(const LLSelectNode& nodep) mSilhouetteVertices = nodep.mSilhouetteVertices; mSilhouetteNormals = nodep.mSilhouetteNormals; - mSilhouetteSegments = nodep.mSilhouetteSegments; mSilhouetteExists = nodep.mSilhouetteExists; mObject = nodep.mObject; @@ -5433,6 +5553,111 @@ BOOL LLSelectNode::allowOperationOnNode(PermissionBit op, U64 group_proxy_power) return (mPermissions->allowOperationBy(op, proxy_agent_id, group_id)); } + +//helper function for pushing relevant vertices from drawable to GL +void pushWireframe(LLDrawable* drawable) +{ + if (drawable->isState(LLDrawable::RIGGED)) + { //render straight from rigged volume if this is a rigged attachment + LLVOVolume* vobj = drawable->getVOVolume(); + if (vobj) + { + vobj->updateRiggedVolume(); + LLRiggedVolume* rigged_volume = vobj->getRiggedVolume(); + if (rigged_volume) + { + LLVertexBuffer::unbind(); + gGL.pushMatrix(); + glMultMatrixf((F32*) vobj->getRelativeXform().mMatrix); + for (S32 i = 0; i < rigged_volume->getNumVolumeFaces(); ++i) + { + const LLVolumeFace& face = rigged_volume->getVolumeFace(i); + glVertexPointer(3, GL_FLOAT, 16, face.mPositions); + glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices); + } + gGL.popMatrix(); + } + } + } + else + { + for (S32 i = 0; i < drawable->getNumFaces(); ++i) + { + LLFace* face = drawable->getFace(i); + if (face->verify()) + { + pushVerts(face, LLVertexBuffer::MAP_VERTEX); + } + } + } +} + +void LLSelectNode::renderOneWireframe(const LLColor4& color) +{ + LLViewerObject* objectp = getObject(); + if (!objectp) + { + return; + } + + LLDrawable* drawable = objectp->mDrawable; + if(!drawable) + { + return; + } + + glMatrixMode(GL_MODELVIEW); + gGL.pushMatrix(); + + BOOL is_hud_object = objectp->isHUDAttachment(); + + if (drawable->isActive()) + { + glLoadMatrixd(gGLModelView); + glMultMatrixf((F32*) objectp->getRenderMatrix().mMatrix); + } + else if (!is_hud_object) + { + glLoadIdentity(); + glMultMatrixd(gGLModelView); + LLVector3 trans = objectp->getRegion()->getOriginAgent(); + glTranslatef(trans.mV[0], trans.mV[1], trans.mV[2]); + } + + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + if (LLSelectMgr::sRenderHiddenSelections) // && gFloaterTools && gFloaterTools->getVisible()) + { + gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE); + LLGLEnable fog(GL_FOG); + glFogi(GL_FOG_MODE, GL_LINEAR); + float d = (LLViewerCamera::getInstance()->getPointOfInterest()-LLViewerCamera::getInstance()->getOrigin()).magVec(); + LLColor4 fogCol = color * (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal()-gAgentCamera.getCameraPositionGlobal()).magVec()/(LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec()*4), 0.0, 1.0); + glFogf(GL_FOG_START, d); + glFogf(GL_FOG_END, d*(1 + (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV()))); + glFogfv(GL_FOG_COLOR, fogCol.mV); + + LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL); + gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + { + glColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f); + pushWireframe(drawable); + } + } + + gGL.flush(); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + + glColor4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2); + LLGLEnable offset(GL_POLYGON_OFFSET_LINE); + glPolygonOffset(3.f, 3.f); + glLineWidth(3.f); + pushWireframe(drawable); + glLineWidth(1.f); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + gGL.popMatrix(); +} + //----------------------------------------------------------------------------- // renderOneSilhouette() //----------------------------------------------------------------------------- @@ -5450,6 +5675,13 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color) return; } + LLVOVolume* vobj = drawable->getVOVolume(); + if (vobj && vobj->isMesh()) + { + renderOneWireframe(color); + return; + } + if (!mSilhouetteExists) { return; @@ -5514,17 +5746,15 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color) gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); gGL.begin(LLRender::LINES); { - S32 i = 0; - for (S32 seg_num = 0; seg_num < (S32)mSilhouetteSegments.size(); seg_num++) + for(S32 i = 0; i < mSilhouetteVertices.size(); i += 2) { - for(; i < mSilhouetteSegments[seg_num]; i++) - { - u_coord += u_divisor * LLSelectMgr::sHighlightUScale; - - gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f); - gGL.texCoord2f( u_coord, v_coord ); - gGL.vertex3fv( mSilhouetteVertices[i].mV ); - } + u_coord += u_divisor * LLSelectMgr::sHighlightUScale; + gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f); + 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(); @@ -5535,51 +5765,50 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color) gGL.setSceneBlendType(LLRender::BT_ALPHA); gGL.begin(LLRender::TRIANGLES); { - S32 i = 0; - for (S32 seg_num = 0; seg_num < (S32)mSilhouetteSegments.size(); seg_num++) + for(S32 i = 0; i < mSilhouetteVertices.size(); i+=2) { - S32 first_i = i; - LLVector3 v; - LLVector2 t; + if (!mSilhouetteNormals[i].isFinite() || + !mSilhouetteNormals[i+1].isFinite()) + { //skip skewed segments + continue; + } - for(; i < mSilhouetteSegments[seg_num]; i++) - { + LLVector3 v[4]; + LLVector2 tc[4]; + v[0] = mSilhouetteVertices[i] + (mSilhouetteNormals[i] * silhouette_thickness); + tc[0].set(u_coord, v_coord + LLSelectMgr::sHighlightVScale); - if (i == first_i) { - LLVector3 vert = (mSilhouetteNormals[i]) * silhouette_thickness; - vert += mSilhouetteVertices[i]; + v[1] = mSilhouetteVertices[i]; + tc[1].set(u_coord, v_coord); - gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.0f); //LLSelectMgr::sHighlightAlpha); - gGL.texCoord2f( u_coord, v_coord + LLSelectMgr::sHighlightVScale ); - gGL.vertex3fv( vert.mV ); - - u_coord += u_divisor * LLSelectMgr::sHighlightUScale; + u_coord += u_divisor * LLSelectMgr::sHighlightUScale; - gGL.color4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2); - gGL.texCoord2f( u_coord, v_coord ); - gGL.vertex3fv( mSilhouetteVertices[i].mV ); + 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); - v = mSilhouetteVertices[i]; - t = LLVector2(u_coord, v_coord); - } - else { - LLVector3 vert = (mSilhouetteNormals[i]) * silhouette_thickness; - vert += mSilhouetteVertices[i]; - - gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.0f); //LLSelectMgr::sHighlightAlpha); - gGL.texCoord2f( u_coord, v_coord + LLSelectMgr::sHighlightVScale ); - gGL.vertex3fv( vert.mV ); - gGL.vertex3fv( vert.mV ); - - gGL.texCoord2fv(t.mV); - u_coord += u_divisor * LLSelectMgr::sHighlightUScale; - gGL.color4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2); - gGL.vertex3fv(v.mV); - gGL.texCoord2f( u_coord, v_coord ); - gGL.vertex3fv( mSilhouetteVertices[i].mV ); + 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*2); + 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*2); + gGL.texCoord2fv( tc[1].mV ); + gGL.vertex3fv( v[1].mV ); + + gGL.texCoord2fv( tc[3].mV ); + gGL.vertex3fv( v[3].mV ); } } gGL.end(); @@ -6147,9 +6376,178 @@ S32 LLObjectSelection::getObjectCount() { cleanupNodes(); S32 count = mList.size(); + + return count; +} + +F32 LLObjectSelection::getSelectedObjectCost() +{ + cleanupNodes(); + 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->getObjectCost(); + } + } + + return cost; +} + +F32 LLObjectSelection::getSelectedLinksetCost() +{ + cleanupNodes(); + F32 cost = 0.f; + + std::set<LLViewerObject*> 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<LLViewerObject*>(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; + + for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + + if (object) + { + cost += object->getPhysicsCost(); + } + } + + return cost; +} + +F32 LLObjectSelection::getSelectedLinksetPhysicsCost() +{ + cleanupNodes(); + F32 cost = 0.f; + + std::set<LLViewerObject*> 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<LLViewerObject*>(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) + { + S32 bytes = 0; + S32 visible = 0; + cost += object->getStreamingCost(&bytes, &visible); + + if (total_bytes) + { + *total_bytes += bytes; + } + + if (visible_bytes) + { + *visible_bytes += visible; + } + } + } + + return cost; +} + +U32 LLObjectSelection::getSelectedObjectTriangleCount() +{ + U32 count = 0; + for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + + if (object) + { + count += object->getTriangleCount(); + } + } + return count; } +/*S32 LLObjectSelection::getSelectedObjectRenderCost() +{ + S32 cost = 0; + LLVOVolume::texture_cost_t textures; + for (list_t::iterator iter = mList.begin(); iter != mList.end(); ++iter) + { + LLSelectNode* node = *iter; + LLVOVolume* object = (LLVOVolume*)node->getObject(); + + if (object) + { + cost += object->getRenderCost(textures); + } + + for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter) + { + // add the cost of each individual texture in the linkset + cost += iter->second; + } + textures.clear(); + } + + + return cost; +}*/ + //----------------------------------------------------------------------------- // getTECount() @@ -6585,7 +6983,7 @@ bool LLSelectMgr::selectionMove(const LLVector3& displ, // 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(fsqrtf(min_dist_squared)) / 2; + 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); diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index cb387f5c3c..166616e13e 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -134,6 +134,7 @@ public: BOOL isTESelected(S32 te_index); S32 getLastSelectedTE(); S32 getTESelectMask() { return mTESelectMask; } + void renderOneWireframe(const LLColor4& color); void renderOneSilhouette(const LLColor4 &color); void setTransient(BOOL transient) { mTransient = transient; } BOOL isTransient() { return mTransient; } @@ -181,7 +182,6 @@ public: std::vector<LLVector3> mTextureScaleRatios; std::vector<LLVector3> mSilhouetteVertices; // array of vertices to render silhouette of object std::vector<LLVector3> mSilhouetteNormals; // array of normals to render silhouette of object - std::vector<S32> mSilhouetteSegments; // array of normals to render silhouette of object BOOL mSilhouetteExists; // need to generate silhouette? protected: @@ -279,6 +279,15 @@ public: // 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 getTECount(); S32 getRootObjectCount(); @@ -500,6 +509,11 @@ public: 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); void selectionSetImage(const LLUUID& imageid); // could be item or asset id void selectionSetColor(const LLColor4 &color); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 94784f3f49..fa329eb0ae 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -32,15 +32,19 @@ #include "llviewerobjectlist.h" #include "llvovolume.h" #include "llvolume.h" +#include "llvolumeoctree.h" #include "llviewercamera.h" #include "llface.h" #include "llviewercontrol.h" #include "llviewerregion.h" #include "llcamera.h" #include "pipeline.h" +#include "llmeshrepository.h" #include "llrender.h" #include "lloctree.h" +#include "llphysicsshapebuilderutil.h" #include "llvoavatar.h" +#include "llvolumemgr.h" #include "lltextureatlas.h" static LLFastTimer::DeclareTimer FTM_FRUSTUM_CULL("Frustum Culling"); @@ -60,6 +64,12 @@ const F32 SG_OCCLUSION_FUDGE = 0.25f; static U32 sZombieGroups = 0; U32 LLSpatialGroup::sNodeCount = 0; + +#define LL_TRACK_PENDING_OCCLUSION_QUERIES 0 + +std::set<GLuint> LLSpatialGroup::sPendingQueries; + + BOOL LLSpatialGroup::sNoDelete = FALSE; static F32 sLastMaxTexPriority = 1.f; @@ -77,6 +87,9 @@ protected: virtual void releaseName(GLuint name) { +#if LL_TRACK_PENDING_OCCLUSION_QUERIES + LLSpatialGroup::sPendingQueries.erase(name); +#endif glDeleteQueriesARB(1, &name); } }; @@ -95,23 +108,6 @@ void sg_assert(BOOL expr) #endif } -#if LL_DEBUG -void validate_drawable(LLDrawable* drawablep) -{ - F64 rad = drawablep->getBinRadius(); - const LLVector3* ext = drawablep->getSpatialExtents(); - - if (rad < 0 || rad > 4096 || - (ext[1]-ext[0]).magVec() > 4096) - { - llwarns << "Invalid drawable found in octree." << llendl; - } -} -#else -#define validate_drawable(x) -#endif - - S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad) { return AABBSphereIntersectR2(min, max, origin, rad*rad); @@ -151,6 +147,55 @@ S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVe } +S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad) +{ + return AABBSphereIntersectR2(min, max, origin, rad*rad); +} + +S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &r) +{ + F32 d = 0.f; + F32 t; + + LLVector4a origina; + origina.load3(origin.mV); + + LLVector4a v; + v.setSub(min, origina); + + if (v.dot3(v) < r) + { + v.setSub(max, origina); + if (v.dot3(v) < r) + { + return 2; + } + } + + + for (U32 i = 0; i < 3; i++) + { + if (origin.mV[i] < min[i]) + { + t = min[i] - origin.mV[i]; + d += t*t; + } + else if (origin.mV[i] > max[i]) + { + t = origin.mV[i] - max[i]; + d += t*t; + } + + if (d > r) + { + return 0; + } + } + + return 1; +} + + typedef enum { b000 = 0x00, @@ -168,76 +213,113 @@ typedef enum //gives you a triangle fan index array static U8 sOcclusionIndices[] = { - // 000 + //000 b111, b110, b010, b011, b001, b101, b100, b110, - //001 - b110, b000, b010, b011, b111, b101, b100, b000, + //001 + b011, b010, b000, b001, b101, b111, b110, b010, //010 b101, b100, b110, b111, b011, b001, b000, b100, //011 - b100, b010, b110, b111, b101, b001, b000, b010, - //100 - b011, b010, b000, b001, b101, b111, b110, b010, + b001, b000, b100, b101, b111, b011, b010, b000, + //100 + b110, b000, b010, b011, b111, b101, b100, b000, //101 b010, b100, b000, b001, b011, b111, b110, b100, //110 - b001, b000, b100, b101, b111, b011, b010, b000, + b100, b010, b110, b111, b101, b001, b000, b010, //111 b000, b110, b100, b101, b001, b011, b010, b110, }; -U8* get_box_fan_indices(LLCamera* camera, const LLVector3& center) +U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center) { - LLVector3 d = center - camera->getOrigin(); + LLVector4a origin; + origin.load3(camera->getOrigin().mV); - U8 cypher = 0; - if (d.mV[0] > 0) - { - cypher |= b100; - } - if (d.mV[1] > 0) - { - cypher |= b010; - } - if (d.mV[2] > 0) - { - cypher |= b001; - } + S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7; + + return cypher*8; +} + +U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center) +{ + LLVector4a origin; + origin.load3(camera->getOrigin().mV); + S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7; + return sOcclusionIndices+cypher*8; } - + + +static LLFastTimer::DeclareTimer FTM_BUILD_OCCLUSION("Build Occlusion"); + void LLSpatialGroup::buildOcclusion() { - if (!mOcclusionVerts) + if (mOcclusionVerts.isNull()) { - mOcclusionVerts = new F32[8*3]; + + mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, + LLVertexBuffer::sUseStreamDraw ? mBufferUsage : 0); //if GL has a hard time with VBOs, don't use them for occlusion culling. + mOcclusionVerts->allocateBuffer(8, 64, true); + + LLStrider<U16> idx; + mOcclusionVerts->getIndexStrider(idx); + for (U32 i = 0; i < 64; i++) + { + *idx++ = sOcclusionIndices[i]; + } } - LLVector3 r = mBounds[1] + LLVector3(SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE); + LLVector4a fudge; + fudge.splat(SG_OCCLUSION_FUDGE); - for (U32 k = 0; k < 3; k++) + LLVector4a r; + r.setAdd(mBounds[1], fudge); + + LLStrider<LLVector3> pos; + { - r.mV[k] = llmin(mBounds[1].mV[k]+0.25f, r.mV[k]); + LLFastTimer t(FTM_BUILD_OCCLUSION); + mOcclusionVerts->getVertexStrider(pos); } - F32* v = mOcclusionVerts; - F32* c = mBounds[0].mV; - F32* s = r.mV; + { + LLVector4a* v = (LLVector4a*) pos.get(); + + const LLVector4a& c = mBounds[0]; + const LLVector4a& s = r; + + static const LLVector4a octant[] = + { + LLVector4a(-1.f, -1.f, -1.f), + LLVector4a(-1.f, -1.f, 1.f), + LLVector4a(-1.f, 1.f, -1.f), + LLVector4a(-1.f, 1.f, 1.f), + + LLVector4a(1.f, -1.f, -1.f), + LLVector4a(1.f, -1.f, 1.f), + LLVector4a(1.f, 1.f, -1.f), + LLVector4a(1.f, 1.f, 1.f), + }; + + //vertex positions are encoded so the 3 bits of their vertex index + //correspond to their axis facing, with bit position 3,2,1 matching + //axis facing x,y,z, bit set meaning positive facing, bit clear + //meaning negative facing + + for (S32 i = 0; i < 8; ++i) + { + LLVector4a p; + p.setMul(s, octant[i]); + p.add(c); + v[i] = p; + } + } - //vertex positions are encoded so the 3 bits of their vertex index - //correspond to their axis facing, with bit position 3,2,1 matching - //axis facing x,y,z, bit set meaning positive facing, bit clear - //meaning negative facing - v[0] = c[0]-s[0]; v[1] = c[1]-s[1]; v[2] = c[2]-s[2]; // 0 - 0000 - v[3] = c[0]-s[0]; v[4] = c[1]-s[1]; v[5] = c[2]+s[2]; // 1 - 0001 - v[6] = c[0]-s[0]; v[7] = c[1]+s[1]; v[8] = c[2]-s[2]; // 2 - 0010 - v[9] = c[0]-s[0]; v[10] = c[1]+s[1]; v[11] = c[2]+s[2]; // 3 - 0011 - - v[12] = c[0]+s[0]; v[13] = c[1]-s[1]; v[14] = c[2]-s[2]; // 4 - 0100 - v[15] = c[0]+s[0]; v[16] = c[1]-s[1]; v[17] = c[2]+s[2]; // 5 - 0101 - v[18] = c[0]+s[0]; v[19] = c[1]+s[1]; v[20] = c[2]-s[2]; // 6 - 0110 - v[21] = c[0]+s[0]; v[22] = c[1]+s[1]; v[23] = c[2]+s[2]; // 7 - 0111 + { + mOcclusionVerts->setBuffer(0); + } clearState(LLSpatialGroup::OCCLUSION_DIRTY); } @@ -281,6 +363,11 @@ LLSpatialGroup::~LLSpatialGroup() llerrs << "Illegal deletion of LLSpatialGroup!" << llendl; }*/ + if (gDebugGL) + { + gPipeline.checkReferences(this); + } + if (isState(DEAD)) { sZombieGroups--; @@ -288,12 +375,17 @@ LLSpatialGroup::~LLSpatialGroup() sNodeCount--; - if (gGLManager.mHasOcclusionQuery && mOcclusionQuery[LLViewerCamera::sCurCameraID]) + if (gGLManager.mHasOcclusionQuery) { - sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]); + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i) + { + if (mOcclusionQuery[i]) + { + sQueryPool.release(mOcclusionQuery[i]); + } + } } - delete [] mOcclusionVerts; mOcclusionVerts = NULL; LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -435,7 +527,7 @@ BOOL LLSpatialGroup::isRecentlyVisible() const BOOL LLSpatialGroup::isVisible() const { - return mVisible[LLViewerCamera::sCurCameraID] == LLDrawable::getCurrentFrame() ? TRUE : FALSE; + return mVisible[LLViewerCamera::sCurCameraID] >= LLDrawable::getCurrentFrame() ? TRUE : FALSE; } void LLSpatialGroup::setVisible() @@ -450,8 +542,10 @@ void LLSpatialGroup::validate() sg_assert(!isState(DIRTY)); sg_assert(!isDead()); - LLVector3 myMin = mBounds[0] - mBounds[1]; - LLVector3 myMax = mBounds[0] + mBounds[1]; + LLVector4a myMin; + myMin.setSub(mBounds[0], mBounds[1]); + LLVector4a myMax; + myMax.setAdd(mBounds[0], mBounds[1]); validateDrawMap(); @@ -483,16 +577,18 @@ void LLSpatialGroup::validate() group->validate(); //ensure all children are enclosed in this node - LLVector3 center = group->mBounds[0]; - LLVector3 size = group->mBounds[1]; + LLVector4a center = group->mBounds[0]; + LLVector4a size = group->mBounds[1]; - LLVector3 min = center - size; - LLVector3 max = center + size; + LLVector4a min; + min.setSub(center, size); + LLVector4a max; + max.setAdd(center, size); for (U32 j = 0; j < 3; j++) { - sg_assert(min.mV[j] >= myMin.mV[j]-0.02f); - sg_assert(max.mV[j] <= myMax.mV[j]+0.02f); + sg_assert(min[j] >= myMin[j]-0.02f); + sg_assert(max[j] <= myMax[j]+0.02f); } } @@ -502,52 +598,8 @@ void LLSpatialGroup::validate() void LLSpatialGroup::checkStates() { #if LL_OCTREE_PARANOIA_CHECK - LLOctreeStateCheck checker; - checker.traverse(mOctreeNode); -#endif -} - -void validate_draw_info(LLDrawInfo& params) -{ -#if LL_OCTREE_PARANOIA_CHECK - if (params.mVertexBuffer.isNull()) - { - llerrs << "Draw batch has no vertex buffer." << llendl; - } - - //bad range - if (params.mStart >= params.mEnd) - { - llerrs << "Draw batch has invalid range." << llendl; - } - - if (params.mEnd >= (U32) params.mVertexBuffer->getNumVerts()) - { - llerrs << "Draw batch has buffer overrun error." << llendl; - } - - if (params.mOffset + params.mCount > (U32) params.mVertexBuffer->getNumIndices()) - { - llerrs << "Draw batch has index buffer ovverrun error." << llendl; - } - - //bad indices - U16* indicesp = (U16*) params.mVertexBuffer->getIndicesPointer(); - if (indicesp) - { - for (U32 i = params.mOffset; i < params.mOffset+params.mCount; i++) - { - if (indicesp[i] < (U16)params.mStart) - { - llerrs << "Draw batch has vertex buffer index out of range error (index too low)." << llendl; - } - - if (indicesp[i] > (U16)params.mEnd) - { - llerrs << "Draw batch has vertex buffer index out of range error (index too high)." << llendl; - } - } - } + //LLOctreeStateCheck checker; + //checker.traverse(mOctreeNode); #endif } @@ -560,8 +612,8 @@ void LLSpatialGroup::validateDrawMap() for (drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j) { LLDrawInfo& params = **j; - - validate_draw_info(params); + + params.validate(); } } #endif @@ -572,19 +624,17 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); drawablep->updateSpatialExtents(); - validate_drawable(drawablep); OctreeNode* parent = mOctreeNode->getOctParent(); if (mOctreeNode->isInside(drawablep->getPositionGroup()) && (mOctreeNode->contains(drawablep) || - (drawablep->getBinRadius() > mOctreeNode->getSize().mdV[0] && + (drawablep->getBinRadius() > mOctreeNode->getSize()[0] && parent && parent->getElementCount() >= LL_OCTREE_MAX_CAPACITY))) { unbound(); setState(OBJECT_DIRTY); //setState(GEOM_DIRTY); - validate_drawable(drawablep); return TRUE; } @@ -602,7 +652,6 @@ BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_oc else { drawablep->setSpatialGroup(this); - validate_drawable(drawablep); setState(OBJECT_DIRTY | GEOM_DIRTY); setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS); gPipeline.markRebuild(this, TRUE); @@ -703,7 +752,7 @@ void LLSpatialPartition::rebuildMesh(LLSpatialGroup* group) } -BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxOut) +BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut) { const OctreeNode* node = mOctreeNode; @@ -716,8 +765,8 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO return FALSE; } - LLVector3& newMin = mObjectExtents[0]; - LLVector3& newMax = mObjectExtents[1]; + LLVector4a& newMin = mObjectExtents[0]; + LLVector4a& newMax = mObjectExtents[1]; if (isState(OBJECT_DIRTY)) { //calculate new bounding box @@ -726,10 +775,10 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO //initialize bounding box to first element OctreeNode::const_element_iter i = node->getData().begin(); LLDrawable* drawablep = *i; - const LLVector3* minMax = drawablep->getSpatialExtents(); + const LLVector4a* minMax = drawablep->getSpatialExtents(); - newMin.setVec(minMax[0]); - newMax.setVec(minMax[1]); + newMin = minMax[0]; + newMax = minMax[1]; for (++i; i != node->getData().end(); ++i) { @@ -753,8 +802,10 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO }*/ } - mObjectBounds[0] = (newMin + newMax) * 0.5f; - mObjectBounds[1] = (newMax - newMin) * 0.5f; + mObjectBounds[0].setAdd(newMin, newMax); + mObjectBounds[0].mul(0.5f); + mObjectBounds[1].setSub(newMax, newMin); + mObjectBounds[1].mul(0.5f); } if (empty) @@ -764,17 +815,8 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO } else { - for (U32 i = 0; i < 3; i++) - { - if (newMin.mV[i] < minOut.mV[i]) - { - minOut.mV[i] = newMin.mV[i]; - } - if (newMax.mV[i] > maxOut.mV[i]) - { - maxOut.mV[i] = newMax.mV[i]; - } - } + minOut.setMin(minOut, newMin); + maxOut.setMax(maxOut, newMax); } return TRUE; @@ -865,18 +907,19 @@ BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) return TRUE; } -void LLSpatialGroup::shift(const LLVector3 &offset) +void LLSpatialGroup::shift(const LLVector4a &offset) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - LLVector3d offsetd(offset); - mOctreeNode->setCenter(mOctreeNode->getCenter()+offsetd); + LLVector4a t = mOctreeNode->getCenter(); + t.add(offset); + mOctreeNode->setCenter(t); mOctreeNode->updateMinMax(); - mBounds[0] += offset; - mExtents[0] += offset; - mExtents[1] += offset; - mObjectBounds[0] += offset; - mObjectExtents[0] += offset; - mObjectExtents[1] += offset; + 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 (!mSpatialPartition->mRenderByGroup) { @@ -884,15 +927,9 @@ void LLSpatialGroup::shift(const LLVector3 &offset) gPipeline.markRebuild(this, TRUE); } - if (mOcclusionVerts) + if (mOcclusionVerts.notNull()) { - for (U32 i = 0; i < 8; i++) - { - F32* v = mOcclusionVerts+i*3; - v[0] += offset.mV[0]; - v[1] += offset.mV[1]; - v[2] += offset.mV[2]; - } + setState(OCCLUSION_DIRTY); } } @@ -1079,12 +1116,23 @@ void LLSpatialGroup::setOcclusionState(U32 state, S32 mode) for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) { mOcclusionState[i] |= state; + + if ((state & DISCARD_QUERY) && mOcclusionQuery[i]) + { + sQueryPool.release(mOcclusionQuery[i]); + mOcclusionQuery[i] = 0; + } } } } else { mOcclusionState[LLViewerCamera::sCurCameraID] |= state; + if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) + { + sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]); + mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; + } } } @@ -1152,13 +1200,11 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : mOctreeNode(node), mSpatialPartition(part), mVertexBuffer(NULL), - mBufferUsage(GL_STATIC_DRAW_ARB), + mBufferUsage(part->mBufferUsage), mDistance(0.f), mDepth(0.f), mLastUpdateDistance(-1.f), mLastUpdateTime(gFrameTimeSeconds), - mViewAngle(0.f), - mLastUpdateViewAngle(-1.f), mAtlasList(4), mCurUpdatingTime(0), mCurUpdatingSlotp(NULL), @@ -1167,13 +1213,18 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : sNodeCount++; LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); + mViewAngle.splat(0.f); + mLastUpdateViewAngle.splat(-1.f); + mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[0] = mObjectBounds[1] = + mObjectExtents[0] = mObjectExtents[1] = mViewAngle; + sg_assert(mOctreeNode->getListenerCount() == 0); mOctreeNode->addListener(this); setState(SG_INITIAL_STATE_MASK); gPipeline.markRebuild(this, TRUE); - mBounds[0] = LLVector3(node->getCenter()); - mBounds[1] = LLVector3(node->getSize()); + mBounds[0] = node->getCenter(); + mBounds[1] = node->getSize(); part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod; mLODHash = part->mLODSeed; @@ -1210,8 +1261,8 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) #endif if (!getData().empty()) { - mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].magVec() : - (F32) mOctreeNode->getSize().magVec(); + mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].getLength3().getF32() : + (F32) mOctreeNode->getSize().getLength3().getF32(); mDistance = mSpatialPartition->calcDistance(this, camera); mPixelArea = mSpatialPartition->calcPixelArea(this, camera); } @@ -1219,24 +1270,31 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) { - LLVector3 eye = group->mObjectBounds[0] - camera.getOrigin(); + 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()) { - LLVector3 v = eye; - dist = eye.normVec(); + LLVector4a v = eye; + + dist = eye.getLength3().getF32(); + eye.normalize3fast(); if (!group->isState(LLSpatialGroup::ALPHA_DIRTY)) { if (!group->mSpatialPartition->isBridge()) { - LLVector3 view_angle = LLVector3(eye * LLVector3(1,0,0), - eye * LLVector3(0,1,0), - eye * LLVector3(0,0,1)); + LLVector4a view_angle = eye; - if ((view_angle-group->mLastUpdateViewAngle).magVec() > 0.64f) + LLVector4a diff; + diff.setSub(view_angle, group->mLastUpdateViewAngle); + + if (diff.getLength3().getF32() > 0.64f) { group->mViewAngle = view_angle; group->mLastUpdateViewAngle = view_angle; @@ -1253,17 +1311,20 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) LLVector3 at = camera.getAtAxis(); - //front of bounding box - for (U32 i = 0; i < 3; i++) - { - v.mV[i] -= group->mObjectBounds[1].mV[i]*0.25f * at.mV[i]; - } + LLVector4a ata; + ata.load3(at.mV); - group->mDepth = v * at; + 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.magVec(); + dist = eye.getLength3().getF32(); } if (dist < 16.f) @@ -1289,7 +1350,8 @@ F32 LLSpatialGroup::getUpdateUrgency() const } else { - return (gFrameTimeSeconds - mLastUpdateTime+4.f)/mDistance; + F32 time = gFrameTimeSeconds-mLastUpdateTime+4.f; + return time + (mObjectBounds[1].dot3(mObjectBounds[1]).getF32()+1.f)/mDistance; } } @@ -1300,8 +1362,8 @@ BOOL LLSpatialGroup::needsUpdate() BOOL LLSpatialGroup::changeLOD() { - if (isState(ALPHA_DIRTY)) - { ///an alpha sort is going to happen, update distance and LOD + if (isState(ALPHA_DIRTY | OBJECT_DIRTY)) + { ///a rebuild is going to happen, update distance and LoD return TRUE; } @@ -1314,7 +1376,7 @@ BOOL LLSpatialGroup::changeLOD() return TRUE; } - if (mDistance > mRadius) + if (mDistance > mRadius*2.f) { return FALSE; } @@ -1416,7 +1478,6 @@ void LLSpatialGroup::destroyGL() } } - delete [] mOcclusionVerts; mOcclusionVerts = NULL; for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i) @@ -1425,8 +1486,7 @@ void LLSpatialGroup::destroyGL() for (S32 j = 0; j < drawable->getNumFaces(); j++) { LLFace* facep = drawable->getFace(j); - facep->mVertexBuffer = NULL; - facep->mLastVertexBuffer = NULL; + facep->clearVertexBuffer(); } } } @@ -1459,8 +1519,8 @@ BOOL LLSpatialGroup::rebound() } else { - LLVector3& newMin = mExtents[0]; - LLVector3& newMax = mExtents[1]; + LLVector4a& newMin = mExtents[0]; + LLVector4a& newMax = mExtents[1]; LLSpatialGroup* group = (LLSpatialGroup*) mOctreeNode->getChild(0)->getListener(0); group->clearState(SKIP_FRUSTUM_CHECK); group->rebound(); @@ -1474,26 +1534,19 @@ BOOL LLSpatialGroup::rebound() group = (LLSpatialGroup*) mOctreeNode->getChild(i)->getListener(0); group->clearState(SKIP_FRUSTUM_CHECK); group->rebound(); - const LLVector3& max = group->mExtents[1]; - const LLVector3& min = group->mExtents[0]; + const LLVector4a& max = group->mExtents[1]; + const LLVector4a& min = group->mExtents[0]; - for (U32 j = 0; j < 3; j++) - { - if (max.mV[j] > newMax.mV[j]) - { - newMax.mV[j] = max.mV[j]; - } - if (min.mV[j] < newMin.mV[j]) - { - newMin.mV[j] = min.mV[j]; - } - } + newMax.setMax(newMax, max); + newMin.setMin(newMin, min); } boundObjects(FALSE, newMin, newMax); - mBounds[0] = (newMin + newMax)*0.5f; - mBounds[1] = (newMax - newMin)*0.5f; + mBounds[0].setAdd(newMin, newMax); + mBounds[0].mul(0.5f); + mBounds[1].setSub(newMax, newMin); + mBounds[1].mul(0.5f); } setState(OCCLUSION_DIRTY); @@ -1516,31 +1569,53 @@ void LLSpatialGroup::checkOcclusion() } else if (isOcclusionState(QUERY_PENDING)) { //otherwise, if a query is pending, read it back - GLuint res = 1; - if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { - glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res); - } - - if (isOcclusionState(DISCARD_QUERY)) - { - res = 2; - } - if (res > 0) + GLuint available = 0; + if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) { - assert_states_valid(this); - clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); - assert_states_valid(this); + glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); } else { - assert_states_valid(this); - setOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); - assert_states_valid(this); + available = 1; } - clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); + if (available) + { //result is available, read it back, otherwise wait until next frame + GLuint res = 1; + if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) + { + glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res); +#if LL_TRACK_PENDING_OCCLUSION_QUERIES + sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]); +#endif + } + else if (mOcclusionQuery[LLViewerCamera::sCurCameraID]) + { //delete the query to avoid holding onto hundreds of pending queries + sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]); + mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0; + } + + if (isOcclusionState(DISCARD_QUERY)) + { + res = 2; + } + + if (res > 0) + { + assert_states_valid(this); + clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); + assert_states_valid(this); + } + else + { + assert_states_valid(this); + setOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); + assert_states_valid(this); + } + + clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); + } } else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLSpatialGroup::OCCLUDED)) { //check occlusion has been issued for occluded node that has not had a query issued @@ -1551,14 +1626,18 @@ void LLSpatialGroup::checkOcclusion() } } +static LLFastTimer::DeclareTimer FTM_PUSH_OCCLUSION_VERTS("Push Occlusion"); +static LLFastTimer::DeclareTimer FTM_SET_OCCLUSION_STATE("Occlusion State"); +static LLFastTimer::DeclareTimer FTM_OCCLUSION_EARLY_FAIL("Occlusion Early Fail"); + void LLSpatialGroup::doOcclusion(LLCamera* camera) { if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1) { // Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension - if ((mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER && !gGLManager.mHasDepthClamp) || - earlyFail(camera, this)) + if (earlyFail(camera, this)) { + LLFastTimer t(FTM_OCCLUSION_EARLY_FAIL); setOcclusionState(LLSpatialGroup::DISCARD_QUERY); assert_states_valid(this); clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); @@ -1566,54 +1645,82 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) } else { + if (!isOcclusionState(QUERY_PENDING) || isOcclusionState(DISCARD_QUERY)) { - LLFastTimer t(FTM_RENDER_OCCLUSION); + { //no query pending, or previous query to be discarded + LLFastTimer t(FTM_RENDER_OCCLUSION); - if (!mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { - mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate(); - } + if (!mOcclusionQuery[LLViewerCamera::sCurCameraID]) + { + mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate(); + } - if (!mOcclusionVerts || isState(LLSpatialGroup::OCCLUSION_DIRTY)) - { - buildOcclusion(); - } - - // Depth clamp all water to avoid it being culled as a result of being - // behind the far clip plane, and in the case of edge water to avoid - // it being culled while still visible. - bool const use_depth_clamp = gGLManager.mHasDepthClamp && - (mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER || - mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER); - if (use_depth_clamp) - { - glEnable(GL_DEPTH_CLAMP); - } - - glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mOcclusionQuery[LLViewerCamera::sCurCameraID]); - glVertexPointer(3, GL_FLOAT, 0, mOcclusionVerts); - if (camera->getOrigin().isExactlyZero()) - { //origin is invalid, draw entire box - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, sOcclusionIndices); - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, sOcclusionIndices+b111*8); - } - else - { - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices(camera, mBounds[0])); + if (mOcclusionVerts.isNull() || isState(LLSpatialGroup::OCCLUSION_DIRTY)) + { + buildOcclusion(); + } + + // Depth clamp all water to avoid it being culled as a result of being + // behind the far clip plane, and in the case of edge water to avoid + // it being culled while still visible. + bool const use_depth_clamp = gGLManager.mHasDepthClamp && + (mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER || + mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER); + + LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0); + +#if !LL_DARWIN + U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB; +#else + U32 mode = GL_SAMPLES_PASSED_ARB; +#endif + +#if LL_TRACK_PENDING_OCCLUSION_QUERIES + sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]); +#endif + + { + LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS); + glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]); + + mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX); + + if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER) + { + LLGLSquashToFarClip squash(glh_get_current_projection(), 1); + if (camera->getOrigin().isExactlyZero()) + { //origin is invalid, draw entire box + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); + } + else + { + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); + } + } + else + { + if (camera->getOrigin().isExactlyZero()) + { //origin is invalid, draw entire box + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); + } + else + { + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); + } + } + + glEndQueryARB(mode); + } } - glEndQueryARB(GL_SAMPLES_PASSED_ARB); - - if (use_depth_clamp) + { - glDisable(GL_DEPTH_CLAMP); + LLFastTimer t(FTM_SET_OCCLUSION_STATE); + setOcclusionState(LLSpatialGroup::QUERY_PENDING); + clearOcclusionState(LLSpatialGroup::DISCARD_QUERY); } } - - setOcclusionState(LLSpatialGroup::QUERY_PENDING); - clearOcclusionState(LLSpatialGroup::DISCARD_QUERY); } } } @@ -1635,8 +1742,11 @@ LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mSlopRatio = 0.25f; mInfiniteFarClip = FALSE; - mOctree = new LLSpatialGroup::OctreeRoot(LLVector3d(0,0,0), - LLVector3d(1,1,1), + LLVector4a center, size; + center.splat(0.f); + size.splat(1.f); + + mOctree = new LLSpatialGroup::OctreeRoot(center,size, NULL); new LLSpatialGroup(mOctree, this); } @@ -1656,7 +1766,6 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); drawablep->updateSpatialExtents(); - validate_drawable(drawablep); //keep drawable from being garbage collected LLPointer<LLDrawable> ptr = drawablep; @@ -1740,16 +1849,16 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL class LLSpatialShift : public LLSpatialGroup::OctreeTraveler { public: - LLSpatialShift(LLVector3 offset) : mOffset(offset) { } + const LLVector4a& mOffset; + + LLSpatialShift(const LLVector4a& offset) : mOffset(offset) { } virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->shift(mOffset); } - - LLVector3 mOffset; }; -void LLSpatialPartition::shift(const LLVector3 &offset) +void LLSpatialPartition::shift(const LLVector4a &offset) { //shift octree node bounding boxes by offset LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); LLSpatialShift shifter(offset); @@ -1911,7 +2020,7 @@ public: class LLOctreeCullVisExtents: public LLOctreeCullShadow { public: - LLOctreeCullVisExtents(LLCamera* camera, LLVector3& min, LLVector3& max) + LLOctreeCullVisExtents(LLCamera* camera, LLVector4a& min, LLVector4a& max) : LLOctreeCullShadow(camera), mMin(min), mMax(max), mEmpty(TRUE) { } virtual bool earlyFail(LLSpatialGroup* group) @@ -1978,8 +2087,8 @@ public: } BOOL mEmpty; - LLVector3& mMin; - LLVector3& mMax; + LLVector4a& mMin; + LLVector4a& mMax; }; class LLOctreeCullDetectVisible: public LLOctreeCullShadow @@ -2048,6 +2157,8 @@ public: 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); @@ -2083,6 +2194,11 @@ void drawBox(const LLVector3& c, const LLVector3& r) gGL.end(); } +void drawBox(const LLVector4a& c, const LLVector4a& r) +{ + drawBox(reinterpret_cast<const LLVector3&>(c), reinterpret_cast<const LLVector3&>(r)); +} + void drawBoxOutline(const LLVector3& pos, const LLVector3& size) { LLVector3 v1 = size.scaledVec(LLVector3( 1, 1,1)); @@ -2129,6 +2245,11 @@ void drawBoxOutline(const LLVector3& pos, const LLVector3& size) gGL.end(); } +void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size) +{ + drawBoxOutline(reinterpret_cast<const LLVector3&>(pos), reinterpret_cast<const LLVector3&>(size)); +} + class LLOctreeDirty : public LLOctreeTraveler<LLDrawable> { public: @@ -2172,14 +2293,21 @@ BOOL LLSpatialPartition::isOcclusionEnabled() BOOL LLSpatialPartition::getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax) { + LLVector4a visMina, visMaxa; + visMina.load3(visMin.mV); + visMaxa.load3(visMax.mV); + { LLFastTimer ftm(FTM_CULL_REBOUND); LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); group->rebound(); } - LLOctreeCullVisExtents vis(&camera, visMin, visMax); + LLOctreeCullVisExtents vis(&camera, visMina, visMaxa); vis.traverse(mOctree); + + visMin.set(visMina.getF32ptr()); + visMax.set(visMaxa.getF32ptr()); return vis.mEmpty; } @@ -2242,25 +2370,36 @@ BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group) } const F32 vel = SG_OCCLUSION_FUDGE*2.f; - LLVector3 c = group->mBounds[0]; - LLVector3 r = group->mBounds[1] + LLVector3(vel,vel,vel); - + LLVector4a fudge; + fudge.splat(vel); + + const LLVector4a& c = group->mBounds[0]; + LLVector4a r; + r.setAdd(group->mBounds[1], fudge); + /*if (r.magVecSquared() > 1024.0*1024.0) { return TRUE; }*/ - LLVector3 e = camera->getOrigin(); + LLVector4a e; + e.load3(camera->getOrigin().mV); - LLVector3 min = c - r; - LLVector3 max = c + r; + LLVector4a min; + min.setSub(c,r); + LLVector4a max; + max.setAdd(c,r); - for (U32 j = 0; j < 3; j++) + S32 lt = e.lessThan(min).getGatheredBits() & 0x7; + if (lt) { - if (e.mV[j] < min.mV[j] || e.mV[j] > max.mV[j]) - { - return FALSE; - } + return FALSE; + } + + S32 gt = e.greaterThan(max).getGatheredBits() & 0x7; + if (gt) + { + return FALSE; } return TRUE; @@ -2291,7 +2430,9 @@ void pushVerts(LLSpatialGroup* group, U32 mask) void pushVerts(LLFace* face, U32 mask) { - LLVertexBuffer* buffer = face->mVertexBuffer; + llassert(face->verify()); + + LLVertexBuffer* buffer = face->getVertexBuffer(); if (buffer) { @@ -2302,7 +2443,25 @@ void pushVerts(LLFace* face, U32 mask) U16 offset = face->getIndicesStart(); buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset); } +} +void pushVerts(LLDrawable* drawable, U32 mask) +{ + for (S32 i = 0; i < drawable->getNumFaces(); ++i) + { + pushVerts(drawable->getFace(i), mask); + } +} + +void pushVerts(LLVolume* volume) +{ + LLVertexBuffer::unbind(); + for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) + { + const LLVolumeFace& face = volume->getVolumeFace(i); + glVertexPointer(3, GL_FLOAT, 16, face.mPositions); + glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices); + } } void pushBufferVerts(LLVertexBuffer* buffer, U32 mask) @@ -2380,7 +2539,6 @@ void renderOctree(LLSpatialGroup* group) { //render solid object bounding box, color //coded by buffer usage and activity - LLGLDepthTest depth(GL_TRUE, GL_FALSE); gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); LLVector4 col; if (group->mBuilt > 0.f) @@ -2421,7 +2579,7 @@ void renderOctree(LLSpatialGroup* group) for (S32 j = 0; j < drawable->getNumFaces(); j++) { LLFace* face = drawable->getFace(j); - if (face->mVertexBuffer.notNull()) + if (face->getVertexBuffer()) { if (gFrameTimeSeconds - face->mLastUpdateTime < 0.5f) { @@ -2436,10 +2594,10 @@ void renderOctree(LLSpatialGroup* group) continue; } - face->mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX); + face->getVertexBuffer()->setBuffer(LLVertexBuffer::MAP_VERTEX); //drawBox((face->mExtents[0] + face->mExtents[1])*0.5f, // (face->mExtents[1]-face->mExtents[0])*0.5f); - face->mVertexBuffer->draw(LLRender::TRIANGLES, face->getIndicesCount(), face->getIndicesStart()); + face->getVertexBuffer()->draw(LLRender::TRIANGLES, face->getIndicesCount(), face->getIndicesStart()); } } @@ -2466,7 +2624,16 @@ void renderOctree(LLSpatialGroup* group) } gGL.color4fv(col.mV); - drawBox(group->mObjectBounds[0], group->mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f)); + LLVector4a fudge; + fudge.splat(0.001f); + LLVector4a size = group->mObjectBounds[1]; + size.mul(1.01f); + size.add(fudge); + + { + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + drawBox(group->mObjectBounds[0], fudge); + } gGL.setSceneBlendType(LLRender::BT_ALPHA); @@ -2497,8 +2664,12 @@ void renderOctree(LLSpatialGroup* group) for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) { LLDrawInfo* draw_info = *j; - LLVector3 center = (draw_info->mExtents[1] + draw_info->mExtents[0])*0.5f; - LLVector3 size = (draw_info->mExtents[1] - draw_info->mExtents[0])*0.5f; + LLVector4a center; + center.setAdd(draw_info->mExtents[1], draw_info->mExtents[0]); + center.mul(0.5f); + LLVector4a size; + size.setSub(draw_info->mExtents[1], draw_info->mExtents[0]); + size.mul(0.5f); drawBoxOutline(center, size); } } @@ -2545,17 +2716,17 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera) gGL.color4f(0.f, 0.75f, 0.f, 0.5f); pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX); } - else if (camera && group->mOcclusionVerts) + else if (camera && group->mOcclusionVerts.notNull()) { LLVertexBuffer::unbind(); - glVertexPointer(3, GL_FLOAT, 0, group->mOcclusionVerts); - + group->mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX); + glColor4f(1.0f, 0.f, 0.f, 0.5f); - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_box_fan_indices(camera, group->mBounds[0])); + group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0])); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glColor4f(1.0f, 1.f, 1.f, 1.0f); - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_box_fan_indices(camera, group->mBounds[0])); + group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0])); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } } @@ -2671,8 +2842,8 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE) } } - const LLVector3* ext; - LLVector3 pos, size; + const LLVector4a* ext; + LLVector4a pos, size; //render face bounding boxes for (S32 i = 0; i < drawable->getNumFaces(); i++) @@ -2681,20 +2852,21 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE) ext = facep->mExtents; - if (ext[0].isExactlyZero() && ext[1].isExactlyZero()) - { - continue; - } - pos = (ext[0] + ext[1]) * 0.5f; - size = (ext[1] - ext[0]) * 0.5f; + 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 = (ext[0] + ext[1]) * 0.5f; - size = (ext[1] - ext[0]) * 0.5f; + 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()) @@ -2711,7 +2883,506 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE) { drawBoxOutline(pos,size); } +} + +void renderNormals(LLDrawable* drawablep) +{ + LLVertexBuffer::unbind(); + + LLVOVolume* vol = drawablep->getVOVolume(); + if (vol) + { + LLVolume* volume = vol->getVolume(); + gGL.pushMatrix(); + glMultMatrixf((F32*) vol->getRelativeXform().mMatrix); + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + LLVector4a scale(gSavedSettings.getF32("RenderDebugNormalScale")); + + for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) + { + const LLVolumeFace& face = volume->getVolumeFace(i); + + gGL.begin(LLRender::LINES); + + for (S32 j = 0; j < face.mNumVertices; ++j) + { + LLVector4a n,p; + + n.setMul(face.mNormals[j], scale); + p.setAdd(face.mPositions[j], n); + + gGL.color4f(1,1,1,1); + gGL.vertex3fv(face.mPositions[j].getF32ptr()); + gGL.vertex3fv(p.getF32ptr()); + + if (face.mBinormals) + { + n.setMul(face.mBinormals[j], scale); + p.setAdd(face.mPositions[j], n); + + gGL.color4f(0,1,1,1); + gGL.vertex3fv(face.mPositions[j].getF32ptr()); + gGL.vertex3fv(p.getF32ptr()); + } + } + + gGL.end(); + } + + gGL.popMatrix(); + } +} + +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; + + 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; + } + } + + return detail; +} + +void renderMeshBaseHull(LLVOVolume* volume, U32 data_mask, LLColor4& color, LLColor4& line_color) +{ + 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); + + if (decomp) + { + if (!decomp->mBaseHullMesh.empty()) + { + glColor4fv(color.mV); + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mBaseHullMesh.mPositions, decomp->mBaseHullMesh.mNormals); + } + else + { + gMeshRepo.buildPhysicsMesh(*decomp); + gGL.color3f(0,1,1); + drawBoxOutline(center, size); + } + + } + else + { + gGL.color3f(1,0,1); + drawBoxOutline(center, size); + } +} + +void render_hull(LLModel::PhysicsMesh& mesh, const LLColor4& color, const LLColor4& line_color) +{ + glColor4fv(color.mV); + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions, mesh.mNormals); + LLGLEnable offset(GL_POLYGON_OFFSET_LINE); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glPolygonOffset(3.f, 3.f); + glLineWidth(3.f); + glColor4fv(line_color.mV); + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions, mesh.mNormals); + glLineWidth(1.f); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +} + +void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume) +{ + if (volume->isSelected()) + { + LLVector3 construct_me(5,5,5); + construct_me.normalize(); + } + + U8 physics_type = volume->getPhysicsShapeType(); + + if (physics_type == LLViewerObject::PHYSICS_SHAPE_NONE || volume->isFlexible()) + { + return; + } + + //not allowed to return at this point without rendering *something* + + F32 threshold = gSavedSettings.getF32("ObjectCostHighThreshold"); + F32 cost = volume->getObjectCost(); + + LLColor4 low = gSavedSettings.getColor4("ObjectCostLowColor"); + LLColor4 mid = gSavedSettings.getColor4("ObjectCostMidColor"); + LLColor4 high = gSavedSettings.getColor4("ObjectCostHighColor"); + + 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 line_color = color*0.5f; + + U32 data_mask = LLVertexBuffer::MAP_VERTEX; + + LLVolumeParams volume_params = volume->getVolume()->getParams(); + + LLPhysicsVolumeParams physics_params(volume_params, + physics_type == LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL); + + LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification physics_spec; + LLPhysicsShapeBuilderUtil::determinePhysicsShape(physics_params, volume->getScale(), physics_spec); + + U32 type = physics_spec.getType(); + + LLVector3 center(0,0,0); + LLVector3 size(0.25f,0.25f,0.25f); + + gGL.pushMatrix(); + glMultMatrixf((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 (!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, line_color); + } + } + else if (!decomp->mPhysicsShapeMesh.empty()) + { + //decomp has physics mesh, render that mesh + glColor4fv(color.mV); + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mPhysicsShapeMesh.mPositions, decomp->mPhysicsShapeMesh.mNormals); + + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glColor4fv(line_color.mV); + LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mPhysicsShapeMesh.mPositions, decomp->mPhysicsShapeMesh.mNormals); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + else + { //no mesh or decomposition, render base hull + renderMeshBaseHull(volume, data_mask, color, line_color); + + if (decomp->mPhysicsShapeMesh.empty()) + { + //attempt to fetch physics shape mesh if available + gMeshRepo.fetchPhysicsShape(mesh_id); + } + } + } + else + { + gGL.color3f(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, line_color); + } +#if LL_WINDOWS + 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<LLVector3> pos; + std::vector<U16> 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 + + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + glColor4fv(line_color.mV); + LLVertexBuffer::unbind(); + + glVertexPointer(3, GL_FLOAT, 16, phys_volume->mHullPoints); + glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices); + + glColor4fv(color.mV); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices); + } + else + { + gGL.color3f(1,0,1); + drawBoxOutline(center, size); + } + + LLPrimitive::sVolumeManager->unrefVolume(phys_volume); + } +#endif //LL_WINDOWS + } + else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::BOX) + { + LLVector3 center = physics_spec.getCenter(); + LLVector3 scale = physics_spec.getScale(); + LLVector3 vscale = volume->getScale()*2.f; + scale.set(scale[0]/vscale[0], scale[1]/vscale[1], scale[2]/vscale[2]); + + gGL.color4fv(color.mV); + drawBox(center, scale); + } + else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::SPHERE) + { + LLVolumeParams volume_params; + volume_params.setType( LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE ); + volume_params.setBeginAndEndS( 0.f, 1.f ); + volume_params.setBeginAndEndT( 0.f, 1.f ); + volume_params.setRatio ( 1, 1 ); + volume_params.setShear ( 0, 0 ); + LLVolume* sphere = LLPrimitive::sVolumeManager->refVolume(volume_params, 3); + + glColor4fv(color.mV); + pushVerts(sphere); + LLPrimitive::sVolumeManager->unrefVolume(sphere); + } + else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::CYLINDER) + { + LLVolumeParams volume_params; + volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE ); + volume_params.setBeginAndEndS( 0.f, 1.f ); + volume_params.setBeginAndEndT( 0.f, 1.f ); + volume_params.setRatio ( 1, 1 ); + volume_params.setShear ( 0, 0 ); + LLVolume* cylinder = LLPrimitive::sVolumeManager->refVolume(volume_params, 3); + + glColor4fv(color.mV); + 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()); + + LLVolume* phys_volume = LLPrimitive::sVolumeManager->refVolume(volume_params, detail); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + glColor4fv(line_color.mV); + pushVerts(phys_volume); + + glColor4fv(color.mV); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + 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()); + + LLVolume* phys_volume = LLPrimitive::sVolumeManager->refVolume(volume_params, detail); + + if (phys_volume->mHullPoints && phys_volume->mHullIndices) + { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + LLVertexBuffer::unbind(); + glVertexPointer(3, GL_FLOAT, 16, phys_volume->mHullPoints); + glColor4fv(line_color.mV); + glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices); + + glColor4fv(color.mV); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices); + } + else + { + gGL.color3f(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 + { + llerrs << "Unhandled type" << llendl; + } + + gGL.popMatrix(); + + /*{ //analytical shape, just push visual rep. + glColor3fv(color.mV); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + pushVerts(drawable, data_mask); + glColor4fv(color.mV); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + pushVerts(drawable, data_mask); + }*/ +} + +void renderPhysicsShapes(LLSpatialGroup* group) +{ + for (LLSpatialGroup::OctreeNode::const_element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + { + LLDrawable* drawable = *i; + LLVOVolume* volume = drawable->getVOVolume(); + if (volume && !volume->isAttachment() && volume->getPhysicsShapeType() != LLViewerObject::PHYSICS_SHAPE_NONE ) + { + if (!group->mSpatialPartition->isBridge()) + { + gGL.pushMatrix(); + LLVector3 trans = drawable->getRegion()->getOriginAgent(); + glTranslatef(trans.mV[0], trans.mV[1], trans.mV[2]); + renderPhysicsShape(drawable, volume); + gGL.popMatrix(); + } + else + { + renderPhysicsShape(drawable, volume); + } + } + else + { + LLViewerObject* object = drawable->getVObj(); + if (object && object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) + { + //push face vertices for terrain + for (S32 i = 0; i < drawable->getNumFaces(); ++i) + { + LLFace* face = drawable->getFace(i); + LLVertexBuffer* buff = face->getVertexBuffer(); + if (buff) + { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + buff->setBuffer(LLVertexBuffer::MAP_VERTEX); + glColor3f(0.2f, 0.5f, 0.3f); + buff->draw(LLRender::TRIANGLES, buff->getRequestedIndices(), 0); + + glColor3f(0.2f, 1.f, 0.3f); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + buff->draw(LLRender::TRIANGLES, buff->getRequestedIndices(), 0); + } + } + } + } + } } void renderTexturePriority(LLDrawable* drawable) @@ -2750,8 +3421,13 @@ void renderTexturePriority(LLDrawable* drawable) // gGL.color4f(1,0,1,1); //} - LLVector3 center = (facep->mExtents[1]+facep->mExtents[0])*0.5f; - LLVector3 size = (facep->mExtents[1]-facep->mExtents[0])*0.5f + LLVector3(0.01f, 0.01f, 0.01f); + 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(); @@ -2775,7 +3451,6 @@ void renderPoints(LLDrawable* drawablep) { gGL.begin(LLRender::POINTS); gGL.color3f(1,1,1); - LLVector3 center(drawablep->getPositionGroup()); for (S32 i = 0; i < drawablep->getNumFaces(); i++) { gGL.vertex3fv(drawablep->getFace(i)->mCenterLocal.mV); @@ -2807,8 +3482,12 @@ void renderShadowFrusta(LLDrawInfo* params) LLGLEnable blend(GL_BLEND); gGL.setSceneBlendType(LLRender::BT_ADD); - LLVector3 center = (params->mExtents[1]+params->mExtents[0])*0.5f; - LLVector3 size = (params->mExtents[1]-params->mExtents[0])*0.5f; + LLVector4a center; + center.setAdd(params->mExtents[1], params->mExtents[0]); + center.mul(0.5f); + LLVector4a size; + size.setSub(params->mExtents[1],params->mExtents[0]); + size.mul(0.5f); if (gPipeline.mShadowCamera[4].AABBInFrustum(center, size)) { @@ -2852,10 +3531,14 @@ void renderLights(LLDrawable* drawablep) pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX); } - const LLVector3* ext = drawablep->getSpatialExtents(); + const LLVector4a* ext = drawablep->getSpatialExtents(); - LLVector3 pos = (ext[0] + ext[1]) * 0.5f; - LLVector3 size = (ext[1] - ext[0]) * 0.5f; + 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); @@ -2865,65 +3548,206 @@ void renderLights(LLDrawable* drawablep) gGL.color4f(1,1,0,1); F32 rad = drawablep->getVOVolume()->getLightRadius(); - drawBoxOutline(pos, LLVector3(rad,rad,rad)); + drawBoxOutline(pos, LLVector4a(rad)); } } - -void renderRaycast(LLDrawable* drawablep) +class LLRenderOctreeRaycast : public LLOctreeTriangleRayIntersect { - if (drawablep->getVObj() != gDebugRaycastObject) +public: + + + LLRenderOctreeRaycast(const LLVector4a& start, const LLVector4a& dir, F32* closest_t) + : LLOctreeTriangleRayIntersect(start, dir, NULL, closest_t, NULL, NULL, NULL, NULL) { - return; + } - + + void visit(const LLOctreeNode<LLVolumeTriangle>* branch) + { + LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) branch->getListener(0); + + LLVector3 center, size; + + if (branch->getData().empty()) + { + gGL.color3f(1.f,0.2f,0.f); + center.set(branch->getCenter().getF32ptr()); + size.set(branch->getSize().getF32ptr()); + } + else + { + gGL.color3f(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.color4f(0,1,1,0.5f); + } + else + { + gGL.color4f(0,0.5f,0.5f, 0.25f); + drawBoxOutline(center, size); + } + + if (i == 1) + { + gGL.flush(); + glLineWidth(3.f); + } + + gGL.begin(LLRender::TRIANGLES); + for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getData().begin(); + iter != branch->getData().end(); + ++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 renderRaycast(LLDrawable* drawablep) +{ if (drawablep->getNumFaces()) { LLGLEnable blend(GL_BLEND); gGL.color4f(0,1,1,0.5f); - if (drawablep->getVOVolume() && gDebugRaycastFaceHit != -1) + if (drawablep->getVOVolume()) { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - pushVerts(drawablep->getFace(gDebugRaycastFaceHit), LLVertexBuffer::MAP_VERTEX); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + //pushVerts(drawablep->getFace(gDebugRaycastFaceHit), LLVertexBuffer::MAP_VERTEX); + //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + LLVOVolume* vobj = drawablep->getVOVolume(); + 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); + if (!face.mOctree) + { + ((LLVolumeFace*) &face)->createOctree(); + } + + gGL.pushMatrix(); + glTranslatef(trans.mV[0], trans.mV[1], trans.mV[2]); + glMultMatrixf((F32*) vobj->getRelativeXform().mMatrix); + + LLVector3 start, end; + if (transform) + { + start = vobj->agentPositionToVolume(gDebugRaycastStart); + end = vobj->agentPositionToVolume(gDebugRaycastEnd); + } + else + { + start = gDebugRaycastStart; + end = gDebugRaycastEnd; + } + + LLVector4a starta, enda; + starta.load3(start.mV); + enda.load3(end.mV); + LLVector4a dir; + dir.setSub(enda, starta); + + F32 t = 1.f; + + LLRenderOctreeRaycast render(starta, dir, &t); + gGL.flush(); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + { + //render face positions + LLVertexBuffer::unbind(); + glColor4f(0,1,1,0.5f); + glVertexPointer(3, GL_FLOAT, sizeof(LLVector4a), face.mPositions); + glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices); + } + + render.traverse(face.mOctree); + gGL.popMatrix(); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + } } else if (drawablep->isAvatar()) { - LLGLDepthTest depth(GL_FALSE); - LLVOAvatar* av = (LLVOAvatar*) drawablep->getVObj().get(); - av->renderCollisionVolumes(); - } - - // draw intersection point - glPushMatrix(); - glLoadMatrixd(gGLModelView); - LLVector3 translate = gDebugRaycastIntersection; - glTranslatef(translate.mV[0], translate.mV[1], translate.mV[2]); - LLCoordFrame orient; - orient.lookDir(gDebugRaycastNormal, gDebugRaycastBinormal); - LLMatrix4 rotation; - orient.getRotMatrixToParent(rotation); - glMultMatrixf((float*)rotation.mMatrix); - - gGL.color4f(1,0,0,0.5f); - drawBox(LLVector3(0, 0, 0), LLVector3(0.1f, 0.022f, 0.022f)); - gGL.color4f(0,1,0,0.5f); - drawBox(LLVector3(0, 0, 0), LLVector3(0.021f, 0.1f, 0.021f)); - gGL.color4f(0,0,1,0.5f); - drawBox(LLVector3(0, 0, 0), LLVector3(0.02f, 0.02f, 0.1f)); - glPopMatrix(); - - // draw bounding box of prim - const LLVector3* ext = drawablep->getSpatialExtents(); - - LLVector3 pos = (ext[0] + ext[1]) * 0.5f; - LLVector3 size = (ext[1] - ext[0]) * 0.5f; + if (drawablep->getVObj() == gDebugRaycastObject) + { + LLGLDepthTest depth(GL_FALSE); + LLVOAvatar* av = (LLVOAvatar*) drawablep->getVObj().get(); + av->renderCollisionVolumes(); + } + } - LLGLDepthTest depth(GL_FALSE, GL_TRUE); - gGL.color4f(0,0.5f,0.5f,1); - drawBoxOutline(pos, size); + if (drawablep->getVObj() == gDebugRaycastObject) + { + // draw intersection point + glPushMatrix(); + glLoadMatrixd(gGLModelView); + LLVector3 translate = gDebugRaycastIntersection; + glTranslatef(translate.mV[0], translate.mV[1], translate.mV[2]); + LLCoordFrame orient; + orient.lookDir(gDebugRaycastNormal, gDebugRaycastBinormal); + LLMatrix4 rotation; + orient.getRotMatrixToParent(rotation); + glMultMatrixf((float*)rotation.mMatrix); + + gGL.color4f(1,0,0,0.5f); + drawBox(LLVector3(0, 0, 0), LLVector3(0.1f, 0.022f, 0.022f)); + gGL.color4f(0,1,0,0.5f); + drawBox(LLVector3(0, 0, 0), LLVector3(0.021f, 0.1f, 0.021f)); + gGL.color4f(0,0,1,0.5f); + drawBox(LLVector3(0, 0, 0), LLVector3(0.02f, 0.02f, 0.1f)); + glPopMatrix(); + + // 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.color4f(0,0.5f,0.5f,1); + drawBoxOutline(pos, size); + } } } @@ -2945,7 +3769,6 @@ void renderAgentTarget(LLVOAvatar* avatar) } } - class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> { public: @@ -3005,8 +3828,8 @@ public: return; } - LLVector3 nodeCenter = group->mBounds[0]; - LLVector3 octCenter = LLVector3(group->mOctreeNode->getCenter()); + LLVector4a nodeCenter = group->mBounds[0]; + LLVector4a octCenter = group->mOctreeNode->getCenter(); group->rebuildGeom(); group->rebuildMesh(); @@ -3029,14 +3852,25 @@ public: { renderBoundingBox(drawable); } + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_NORMALS)) + { + renderNormals(drawable); + } if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BUILD_QUEUE)) { if (drawable->isState(LLDrawable::IN_REBUILD_Q2)) { gGL.color4f(0.6f, 0.6f, 0.1f, 1.f); - const LLVector3* ext = drawable->getSpatialExtents(); - drawBoxOutline((ext[0]+ext[1])*0.5f, (ext[1]-ext[0])*0.5f); + const LLVector4a* ext = drawable->getSpatialExtents(); + LLVector4a center; + center.setAdd(ext[0], ext[1]); + center.mul(0.5f); + LLVector4a size; + size.setSub(ext[1], ext[0]); + size.mul(0.5f); + drawBoxOutline(center, size); } } @@ -3101,6 +3935,41 @@ public: } }; + +class LLOctreeRenderPhysicsShapes : public LLOctreeTraveler<LLDrawable> +{ +public: + LLCamera* mCamera; + LLOctreeRenderPhysicsShapes(LLCamera* camera): mCamera(camera) {} + + virtual void traverse(const LLSpatialGroup::OctreeNode* node) + { + LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); + + if (!mCamera || mCamera->AABBInFrustumNoFarClip(group->mBounds[0], group->mBounds[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); + } + } + + virtual void visit(const LLSpatialGroup::OctreeNode* branch) + { + + } +}; + class LLOctreePushBBoxVerts : public LLOctreeTraveler<LLDrawable> { public: @@ -3219,6 +4088,25 @@ public: }; +void LLSpatialPartition::renderPhysicsShapes() +{ + LLSpatialBridge* bridge = asBridge(); + LLCamera* camera = LLViewerCamera::getInstance(); + + if (bridge) + { + camera = NULL; + } + + gGL.flush(); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + glLineWidth(3.f); + LLOctreeRenderPhysicsShapes render_physics(camera); + render_physics.traverse(mOctree); + gGL.flush(); + glLineWidth(1.f); +} + void LLSpatialPartition::renderDebug() { if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE | @@ -3227,13 +4115,14 @@ void LLSpatialPartition::renderDebug() 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_PRIORITY | LLPipeline::RENDER_DEBUG_TEXTURE_ANIM | LLPipeline::RENDER_DEBUG_RAYCAST | LLPipeline::RENDER_DEBUG_AVATAR_VOLUME | LLPipeline::RENDER_DEBUG_AGENT_TARGET | - LLPipeline::RENDER_DEBUG_BUILD_QUEUE | + //LLPipeline::RENDER_DEBUG_BUILD_QUEUE | LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) { return; @@ -3272,7 +4161,11 @@ void LLSpatialPartition::renderDebug() void LLSpatialGroup::drawObjectBox(LLColor4 col) { gGL.color4fv(col.mV); - drawBox(mObjectBounds[0], mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f)); + LLVector4a size; + size = mObjectBounds[1]; + size.mul(1.01f); + size.add(LLVector4a(0.001f)); + drawBox(mObjectBounds[0], size); } @@ -3332,8 +4225,8 @@ public: LLSpatialGroup* group = (LLSpatialGroup*) child->getListener(0); - LLVector3 size; - LLVector3 center; + LLVector4a size; + LLVector4a center; size = group->mBounds[1]; center = group->mBounds[0]; @@ -3350,7 +4243,11 @@ public: local_end = mEnd * local_matrix; } - if (LLLineSegmentBoxIntersect(local_start, local_end, center, size)) + LLVector4a start, end; + start.load3(local_start.mV); + end.load3(local_end.mV); + + if (LLLineSegmentBoxIntersect(start, end, center, size)) { check(child); } @@ -3440,18 +4337,9 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, mDistance(0.f), mDrawMode(LLRender::TRIANGLES) { + mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); + mDebugColor = (rand() << 16) + rand(); - if (mStart >= mVertexBuffer->getRequestedVerts() || - mEnd >= mVertexBuffer->getRequestedVerts()) - { - llerrs << "Invalid draw info vertex range." << llendl; - } - - if (mOffset >= (U32) mVertexBuffer->getRequestedIndices() || - mOffset + mCount > (U32) mVertexBuffer->getRequestedIndices()) - { - llerrs << "Invalid draw info index range." << llendl; - } } LLDrawInfo::~LLDrawInfo() @@ -3465,6 +4353,16 @@ LLDrawInfo::~LLDrawInfo() { mFace->setDrawInfo(NULL); } + + if (gDebugGL) + { + gPipeline.checkReferences(this); + } +} + +void LLDrawInfo::validate() +{ + mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); } LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage) diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 2b9cf6c630..0d9cad914a 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -39,7 +39,7 @@ #include "lldrawpool.h" #include "llface.h" #include "llviewercamera.h" - +#include "llvector4a.h" #include <queue> #define SG_STATE_INHERIT_MASK (OCCLUDED) @@ -51,11 +51,16 @@ class LLSpatialGroup; class LLTextureAtlas; class LLTextureAtlasSlot; +S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad); +S32 AABBSphereIntersectR2(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &radius_squared); + S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad); S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &radius_squared); +void pushVerts(LLFace* face, U32 mask); // get index buffer for binary encoded axis vertex buffer given a box at center being viewed by given camera -U8* get_box_fan_indices(LLCamera* camera, const LLVector3& center); +U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center); +U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center); class LLDrawInfo : public LLRefCount { @@ -63,11 +68,27 @@ protected: ~LLDrawInfo(); public: + + LLDrawInfo(const LLDrawInfo& rhs) + { + *this = rhs; + } + + const LLDrawInfo& operator=(const LLDrawInfo& rhs) + { + llerrs << "Illegal operation!" << llendl; + return *this; + } + LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, LLViewerTexture* image, LLVertexBuffer* buffer, BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0); + void validate(); + + LLVector4a mExtents[2]; + LLPointer<LLVertexBuffer> mVertexBuffer; LLPointer<LLViewerTexture> mTexture; LLColor4U mGlowColor; @@ -86,7 +107,6 @@ public: LLSpatialGroup* mGroup; LLFace* mFace; //associated face F32 mDistance; - LLVector3 mExtents[2]; U32 mDrawMode; struct CompareTexture @@ -128,6 +148,17 @@ public: }; + struct CompareMatrixTexturePtr + { + bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs) + { + return lhs.get() != rhs.get() + && (lhs.isNull() || (rhs.notNull() && (lhs->mModelMatrix > rhs->mModelMatrix || + (lhs->mModelMatrix == rhs->mModelMatrix && lhs->mTexture.get() > rhs->mTexture.get())))); + } + + }; + struct CompareBump { bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs) @@ -149,11 +180,25 @@ public: }; }; +LL_ALIGN_PREFIX(64) class LLSpatialGroup : public LLOctreeListener<LLDrawable> { friend class LLSpatialPartition; friend class LLOctreeStateCheck; public: + + LLSpatialGroup(const LLSpatialGroup& rhs) + { + *this = rhs; + } + + const LLSpatialGroup& operator=(const LLSpatialGroup& rhs) + { + llerrs << "Illegal operation!" << llendl; + return *this; + } + + static std::set<GLuint> sPendingQueries; //pending occlusion queries static U32 sNodeCount; static BOOL sNoDelete; //deletion of spatial groups and draw info not allowed if TRUE @@ -262,8 +307,8 @@ public: BOOL isVisible() const; BOOL isRecentlyVisible() const; void setVisible(); - void shift(const LLVector3 &offset); - BOOL boundObjects(BOOL empty, LLVector3& newMin, LLVector3& newMax); + void shift(const LLVector4a &offset); + BOOL boundObjects(BOOL empty, LLVector4a& newMin, LLVector4a& newMax); void unbound(); BOOL rebound(); void buildOcclusion(); //rebuild mOcclusionVerts @@ -311,6 +356,27 @@ public: void addAtlas(LLTextureAtlas* atlasp, S8 recursive_level = 3) ; void removeAtlas(LLTextureAtlas* atlasp, BOOL remove_group = TRUE, S8 recursive_level = 3) ; void clearAtlasList() ; + +public: + + typedef enum + { + BOUNDS = 0, + EXTENTS = 2, + OBJECT_BOUNDS = 4, + OBJECT_EXTENTS = 6, + VIEW_ANGLE = 8, + LAST_VIEW_ANGLE = 9, + V4_COUNT = 10 + } eV4Index; + + LLVector4a mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects) + LLVector4a mExtents[2]; // extents (min, max) of this node and all its children + LLVector4a mObjectExtents[2]; // extents (min, max) of objects in this node + LLVector4a mObjectBounds[2]; // bounding box (center, size) of objects in this node + LLVector4a mViewAngle; + LLVector4a mLastUpdateViewAngle; + private: U32 mCurUpdatingTime ; //do not make the below two to use LLPointer @@ -338,14 +404,9 @@ public: F32 mBuilt; OctreeNode* mOctreeNode; LLSpatialPartition* mSpatialPartition; - LLVector3 mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects) - LLVector3 mExtents[2]; // extents (min, max) of this node and all its children - LLVector3 mObjectExtents[2]; // extents (min, max) of objects in this node - LLVector3 mObjectBounds[2]; // bounding box (center, size) of objects in this node - LLPointer<LLVertexBuffer> mVertexBuffer; - F32* mOcclusionVerts; + LLPointer<LLVertexBuffer> mOcclusionVerts; GLuint mOcclusionQuery[LLViewerCamera::NUM_CAMERAS]; U32 mBufferUsage; @@ -356,13 +417,10 @@ public: F32 mDepth; F32 mLastUpdateDistance; F32 mLastUpdateTime; - - LLVector3 mViewAngle; - LLVector3 mLastUpdateViewAngle; F32 mPixelArea; F32 mRadius; -}; +} LL_ALIGN_POSTFIX(64); class LLGeometryManager { @@ -398,7 +456,7 @@ public: // If the drawable moves, move it here. virtual void move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate = FALSE); - virtual void shift(const LLVector3 &offset); + virtual void shift(const LLVector4a &offset); virtual F32 calcDistance(LLSpatialGroup* group, LLCamera& camera); virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera); @@ -414,6 +472,7 @@ public: virtual LLSpatialBridge* asBridge() { return NULL; } virtual BOOL isBridge() { return asBridge() != NULL; } + void renderPhysicsShapes(); void renderDebug(); void renderIntersectingBBoxes(LLCamera* camera); void restoreGL(); @@ -456,7 +515,7 @@ public: virtual void makeActive(); virtual void move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate = FALSE); virtual BOOL updateMove(); - virtual void shiftPos(const LLVector3& vec); + virtual void shiftPos(const LLVector4a& vec); virtual void cleanupReferences(); virtual LLSpatialPartition* asPartition() { return this; } virtual LLSpatialBridge* asBridge() { return this; } @@ -484,6 +543,7 @@ public: sg_list_t::iterator beginAlphaGroups(); sg_list_t::iterator endAlphaGroups(); + bool hasOcclusionGroups() { return mOcclusionGroupsSize > 0; } sg_list_t::iterator beginOcclusionGroups(); sg_list_t::iterator endOcclusionGroups(); @@ -613,6 +673,13 @@ public: class LLVolumeGeometryManager: public LLGeometryManager { public: + typedef enum + { + NONE = 0, + BATCH_SORT, + DISTANCE_SORT + } eSortType; + virtual ~LLVolumeGeometryManager() { } virtual void rebuildGeom(LLSpatialGroup* group); virtual void rebuildMesh(LLSpatialGroup* group); @@ -647,7 +714,7 @@ class LLHUDBridge : public LLVolumeBridge { public: LLHUDBridge(LLDrawable* drawablep); - virtual void shiftPos(const LLVector3& vec); + virtual void shiftPos(const LLVector4a& vec); virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera); }; @@ -664,11 +731,9 @@ class LLHUDPartition : public LLBridgePartition { public: LLHUDPartition(); - virtual void shift(const LLVector3 &offset); + virtual void shift(const LLVector4a &offset); }; -void validate_draw_info(LLDrawInfo& params); - extern const F32 SG_BOX_SIDE; extern const F32 SG_BOX_OFFSET; extern const F32 SG_BOX_RAD; diff --git a/indra/newview/llsprite.cpp b/indra/newview/llsprite.cpp index a69592b61c..4bde2dfcab 100644 --- a/indra/newview/llsprite.cpp +++ b/indra/newview/llsprite.cpp @@ -186,14 +186,15 @@ void LLSprite::updateFace(LLFace &face) U16 index_offset; // Setup face - if (face.mVertexBuffer.isNull()) + if (!face.getVertexBuffer()) { - face.mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | + LLVertexBuffer* buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, GL_STREAM_DRAW_ARB); - face.mVertexBuffer->allocateBuffer(4, 12, TRUE); + buff->allocateBuffer(4, 12, TRUE); face.setGeomIndex(0); face.setIndicesIndex(0); + face.setVertexBuffer(buff); } index_offset = face.getGeometry(verticesp,normalsp,tex_coordsp, indicesp); @@ -242,7 +243,7 @@ void LLSprite::updateFace(LLFace &face) *indicesp++ = 3 + index_offset; } - face.mVertexBuffer->setBuffer(0); + face.getVertexBuffer()->setBuffer(0); face.mCenterAgent = mPosition; } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 078de0cbdf..c6b73dae13 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -421,7 +421,7 @@ bool idle_startup() // // Load autopilot and stats stuff - gAgentPilot.load(gSavedSettings.getString("StatsPilotFile")); + gAgentPilot.load(); //gErrorStream.setTime(gSavedSettings.getBOOL("LogTimestamps")); @@ -995,6 +995,7 @@ bool idle_startup() if(STATE_LOGIN_PROCESS_RESPONSE == LLStartUp::getStartupState()) { + // Generic failure message std::ostringstream emsg; emsg << LLTrans::getString("LoginFailed") << "\n"; if(LLLoginInstance::getInstance()->authFailure()) @@ -1003,25 +1004,33 @@ bool idle_startup() << LLLoginInstance::getInstance()->getResponse() << LL_ENDL; LLSD response = LLLoginInstance::getInstance()->getResponse(); // Still have error conditions that may need some - // sort of handling. + // sort of handling - dig up specific message std::string reason_response = response["reason"]; std::string message_response = response["message"]; - - if(!message_response.empty()) + std::string message_id = response["message_id"]; + std::string message; // actual string to show the user + + if(!message_id.empty() && LLTrans::findString(message, message_id, response["message_args"])) { - // XUI: fix translation for strings returned during login - // We need a generic table for translations - std::string big_reason = LLAgent::sTeleportErrorMessages[ message_response ]; - if ( big_reason.size() == 0 ) - { - emsg << message_response; - } - else - { - emsg << big_reason; - } + // message will be filled in with the template and arguments + } + else if(!message_response.empty()) + { + // *HACK: "no_inventory_host" sent as the message itself. + // Remove this clause when server is sending message_id as well. + message = LLAgent::sTeleportErrorMessages[ message_response ]; + } + + if (message.empty()) + { + // Fallback to server-supplied string; necessary since server + // may add strings that this viewer is not yet aware of + message = message_response; } + emsg << message; + + if(reason_response == "key") { // Couldn't login because user/password is wrong @@ -1957,7 +1966,7 @@ bool idle_startup() } // Start automatic replay if the flag is set. - if (gSavedSettings.getBOOL("StatsAutoRun") || LLAgentPilot::sReplaySession) + if (gSavedSettings.getBOOL("StatsAutoRun") || gAgentPilot.getReplaySession()) { LLUUID id; LL_DEBUGS("AppInit") << "Starting automatic playback" << LL_ENDL; @@ -3068,6 +3077,11 @@ bool process_login_success_response() } // Request the map server url + // Non-agni grids have a different default location. + if (!LLGridManager::getInstance()->isInProductionGrid()) + { + gSavedSettings.setString("MapServerURL", "http://test.map.secondlife.com.s3.amazonaws.com/"); + } std::string map_server_url = response["map-server-url"]; if(!map_server_url.empty()) { diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 1d57e27616..5077c2c7e1 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -854,8 +854,10 @@ void LLSurfacePatch::updateVisibility() F32 stride_per_distance = DEFAULT_DELTA_ANGLE / mSurfacep->getMetersPerGrid(); U32 grids_per_patch_edge = mSurfacep->getGridsPerPatchEdge(); - LLVector3 center = mCenterRegion + mSurfacep->getOriginAgent(); - LLVector3 radius = LLVector3(mRadius, mRadius, mRadius); + 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)) diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 56e9739350..1023a4339b 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -289,7 +289,9 @@ BOOL LLFloaterTexturePicker::handleDragAndDrop( { BOOL handled = FALSE; - if (cargo_type == DAD_TEXTURE) + bool is_mesh = cargo_type == DAD_MESH; + + if ((cargo_type == DAD_TEXTURE) || is_mesh) { LLInventoryItem *item = (LLInventoryItem *)cargo_data; @@ -1206,7 +1208,11 @@ BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, // returns true, then the cast was valid, and we can perform // the third test without problems. LLInventoryItem* item = (LLInventoryItem*)cargo_data; - if (getEnabled() && (cargo_type == DAD_TEXTURE) && allowDrop(item)) + bool is_mesh = cargo_type == DAD_MESH; + + if (getEnabled() && + ((cargo_type == DAD_TEXTURE) || is_mesh) && + allowDrop(item)) { if (drop) { diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 671a334600..d23d2b3abd 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -307,23 +307,24 @@ LLToolDragAndDrop::dragOrDrop3dImpl LLToolDragAndDrop::LLDragAndDropDictionary:: LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary() { - // DT_NONE DT_SELF DT_AVATAR DT_OBJECT DT_LAND - // |--------------|---------------------------|---------------------------|-------------------------------|--------------| + // 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_SOUND, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_TEXTURE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dTextureObject, &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::dad3dUpdateInventoryCategory, &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::dad3dUpdateInventoryCategory, &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_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)); // TODO: animation on self could play it? edit it? // TODO: gesture on self could play it? edit it? }; @@ -396,7 +397,7 @@ void LLToolDragAndDrop::beginDrag(EDragAndDropType type, { folder_ids.push_back(cargo_id); } - gInventory.collectDescendentsIf ( + gInventory.collectDescendentsIf( cargo_id, cats, items, @@ -467,7 +468,7 @@ void LLToolDragAndDrop::beginMultiDrag( { cat_ids.insert(cat->getUUID()); } - gInventory.collectDescendentsIf ( + gInventory.collectDescendentsIf( cat->getUUID(), cats, items, @@ -1027,6 +1028,31 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj, hit_obj->sendTEUpdate(); } +void LLToolDragAndDrop::dropMesh(LLViewerObject* hit_obj, + LLInventoryItem* item, + LLToolDragAndDrop::ESource source, + const LLUUID& src_id) +{ + if (!item) + { + llwarns << "no inventory item." << llendl; + return; + } + LLUUID asset_id = item->getAssetUUID(); + BOOL success = handleDropTextureProtections(hit_obj, item, source, src_id); + if(!success) + { + return; + } + + LLSculptParams sculpt_params; + sculpt_params.setSculptTexture(asset_id); + sculpt_params.setSculptType(LL_SCULPT_TYPE_MESH); + hit_obj->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE); + + dialog_refresh_all(); +} + /* void LLToolDragAndDrop::dropTextureOneFaceAvatar(LLVOAvatar* avatar, S32 hit_face, LLInventoryItem* item) { @@ -1123,9 +1149,9 @@ void LLToolDragAndDrop::dropScript(LLViewerObject* hit_obj, } void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target, - BOOL bypass_sim_raycast, - BOOL from_task_inventory, - BOOL remove_from_inventory) + BOOL bypass_sim_raycast, + BOOL from_task_inventory, + BOOL remove_from_inventory) { LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosGlobal(mLastHitPos); if (!regionp) @@ -1361,7 +1387,7 @@ EAcceptance LLToolDragAndDrop::willObjectAcceptInventory(LLViewerObject* obj, LL // 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()) + if(obj->getID() == item->getParentUUID()) { return ACCEPT_NO; } @@ -1370,17 +1396,19 @@ EAcceptance LLToolDragAndDrop::willObjectAcceptInventory(LLViewerObject* obj, LL // gAgent.getGroupID()) // && (obj->mPermModify || obj->mFlagAllowInventoryAdd)); BOOL worn = FALSE; + LLVOAvatarSelf* my_avatar = NULL; switch(item->getType()) { case LLAssetType::AT_OBJECT: - if (isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(item->getUUID())) + 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())) + if(gAgentWearables.isWearingItem(item->getUUID())) { worn = TRUE; } @@ -1395,7 +1423,7 @@ EAcceptance LLToolDragAndDrop::willObjectAcceptInventory(LLViewerObject* obj, LL const LLPermissions& perm = item->getPermissions(); BOOL modify = (obj->permModify() || obj->flagAllowInventoryAdd()); BOOL transfer = FALSE; - if ((obj->permYouOwner() && (perm.getOwner() == gAgent.getID())) + if((obj->permYouOwner() && (perm.getOwner() == gAgent.getID())) || perm.allowOperationBy(PERM_TRANSFER, gAgent.getID())) { transfer = TRUE; @@ -1403,15 +1431,15 @@ EAcceptance LLToolDragAndDrop::willObjectAcceptInventory(LLViewerObject* obj, LL 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) + if(attached && !unrestricted) { return ACCEPT_NO_LOCKED; } - else if (modify && transfer && volume && !worn) + else if(modify && transfer && volume && !worn) { return ACCEPT_YES_MULTI; } - else if (!modify) + else if(!modify) { return ACCEPT_NO_LOCKED; } @@ -1506,14 +1534,15 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_ case DAD_ANIMATION: case DAD_GESTURE: case DAD_CALLINGCARD: + case DAD_MESH: { LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data; - if (gInventory.getItem(inv_item->getUUID()) + if(gInventory.getItem(inv_item->getUUID()) && LLGiveInventory::isInventoryGiveAcceptable(inv_item)) { // *TODO: get multiple object transfers working *accept = ACCEPT_YES_COPY_SINGLE; - if (drop) + if(drop) { LLIMModel::LLIMSession * session = LLIMModel::instance().findIMSession(session_id); @@ -1553,11 +1582,11 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_ case DAD_CATEGORY: { LLViewerInventoryCategory* inv_cat = (LLViewerInventoryCategory*)cargo_data; - if (gInventory.getCategory(inv_cat->getUUID())) + if( gInventory.getCategory( inv_cat->getUUID() ) ) { // *TODO: get multiple object transfers working *accept = ACCEPT_YES_COPY_SINGLE; - if (drop) + if(drop) { LLGiveInventory::doGiveInventoryCategory(dest_agent, inv_cat, session_id); } @@ -1598,7 +1627,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv( { lldebugs << "LLToolDragAndDrop::dad3dRezAttachmentFromInv()" << llendl; // must be in the user's inventory - if (mSource != SOURCE_AGENT && mSource != SOURCE_LIBRARY) + if(mSource != SOURCE_AGENT && mSource != SOURCE_LIBRARY) { return ACCEPT_NO; } @@ -1610,20 +1639,21 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv( // must not be in the trash const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - if (gInventory.isObjectDescendentOf(item->getUUID(), trash_id)) + if( gInventory.isObjectDescendentOf( item->getUUID(), trash_id ) ) { return ACCEPT_NO; } // must not be already wearing it - if (!isAgentAvatarValid() || gAgentAvatarp->isWearingAttachment(item->getUUID())) + LLVOAvatarSelf* avatar = gAgentAvatarp; + if( !avatar || avatar->isWearingAttachment(item->getUUID()) ) { return ACCEPT_NO; } - if (drop) + if( drop ) { - if (mSource == SOURCE_LIBRARY) + if(mSource == SOURCE_LIBRARY) { LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(0); copy_inventory_item( @@ -1657,7 +1687,8 @@ EAcceptance LLToolDragAndDrop::dad3dRezObjectOnLand( locateInventory(item, cat); if (!item || !item->isFinished()) return ACCEPT_NO; - if (!isAgentAvatarValid() || gAgentAvatarp->isWearingAttachment(item->getUUID())) + LLVOAvatarSelf* my_avatar = gAgentAvatarp; + if( !my_avatar || my_avatar->isWearingAttachment( item->getUUID() ) ) { return ACCEPT_NO; } @@ -1682,7 +1713,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezObjectOnLand( // 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())) + if(!item->getPermissions().allowCopyBy(gAgent.getID())) { accept = ACCEPT_YES_SINGLE; remove_inventory = TRUE; @@ -1690,13 +1721,13 @@ EAcceptance LLToolDragAndDrop::dad3dRezObjectOnLand( // Check if it's in the trash. const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - if (gInventory.isObjectDescendentOf(item->getUUID(), trash_id)) + if(gInventory.isObjectDescendentOf(item->getUUID(), trash_id)) { accept = ACCEPT_YES_SINGLE; remove_inventory = TRUE; } - if (drop) + if(drop) { dropObject(obj, TRUE, FALSE, remove_inventory); } @@ -1718,22 +1749,23 @@ EAcceptance LLToolDragAndDrop::dad3dRezObjectOnObject( LLViewerInventoryCategory* cat; locateInventory(item, cat); if (!item || !item->isFinished()) return ACCEPT_NO; - if (!isAgentAvatarValid() || gAgentAvatarp->isWearingAttachment(item->getUUID())) + LLVOAvatarSelf* my_avatar = gAgentAvatarp; + if( !my_avatar || my_avatar->isWearingAttachment( item->getUUID() ) ) { return ACCEPT_NO; } - if ((mask & MASK_CONTROL)) + 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) + if(mSource == SOURCE_NOTECARD) { return ACCEPT_NO; } EAcceptance rv = willObjectAcceptInventory(obj, item); - if (drop && (ACCEPT_YES_SINGLE <= rv)) + if(drop && (ACCEPT_YES_SINGLE <= rv)) { dropInventory(obj, item, mSource, mSourceID); } @@ -1759,7 +1791,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezObjectOnObject( // 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())) + if(!item->getPermissions().allowCopyBy(gAgent.getID())) { accept = ACCEPT_YES_SINGLE; remove_inventory = TRUE; @@ -1767,13 +1799,13 @@ EAcceptance LLToolDragAndDrop::dad3dRezObjectOnObject( // Check if it's in the trash. const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - if (gInventory.isObjectDescendentOf(item->getUUID(), trash_id)) + if(gInventory.isObjectDescendentOf(item->getUUID(), trash_id)) { accept = ACCEPT_YES_SINGLE; remove_inventory = TRUE; } - if (drop) + if(drop) { dropObject(obj, FALSE, FALSE, remove_inventory); } @@ -1788,7 +1820,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezScript( // *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)) + if((SOURCE_WORLD == mSource) || (SOURCE_NOTECARD == mSource)) { return ACCEPT_NO; } @@ -1798,7 +1830,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezScript( locateInventory(item, cat); if (!item || !item->isFinished()) return ACCEPT_NO; EAcceptance rv = willObjectAcceptInventory(obj, item); - if (drop && (ACCEPT_YES_SINGLE <= rv)) + if(drop && (ACCEPT_YES_SINGLE <= rv)) { // rez in the script active by default, rez in inactive if the // control key is being held down. @@ -1819,14 +1851,14 @@ EAcceptance LLToolDragAndDrop::dad3dRezScript( return rv; } -EAcceptance LLToolDragAndDrop::dad3dTextureObject( - LLViewerObject* obj, S32 face, MASK mask, BOOL drop) +EAcceptance LLToolDragAndDrop::dad3dApplyToObject( + LLViewerObject* obj, S32 face, MASK mask, BOOL drop, EDragAndDropType cargo_type) { - lldebugs << "LLToolDragAndDrop::dad3dTextureObject()" << llendl; + lldebugs << "LLToolDragAndDrop::dad3dApplyToObject()" << llendl; // *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)) + if((SOURCE_WORLD == mSource) || (SOURCE_NOTECARD == mSource)) { return ACCEPT_NO; } @@ -1836,33 +1868,44 @@ EAcceptance LLToolDragAndDrop::dad3dTextureObject( locateInventory(item, cat); if (!item || !item->isFinished()) return ACCEPT_NO; EAcceptance rv = willObjectAcceptInventory(obj, item); - if ((mask & MASK_CONTROL)) + if((mask & MASK_CONTROL)) { - if ((ACCEPT_YES_SINGLE <= rv) && drop) + if((ACCEPT_YES_SINGLE <= rv) && drop) { dropInventory(obj, item, mSource, mSourceID); } return rv; } - if (!obj->permModify()) + if(!obj->permModify()) { return ACCEPT_NO_LOCKED; } //If texture !copyable don't texture or you'll never get it back. - if (!item->getPermissions().allowCopyBy(gAgent.getID())) + if(!item->getPermissions().allowCopyBy(gAgent.getID())) { return ACCEPT_NO; } - if (drop && (ACCEPT_YES_SINGLE <= rv)) + if(drop && (ACCEPT_YES_SINGLE <= rv)) { - if ((mask & MASK_SHIFT)) + if (cargo_type == DAD_TEXTURE) { - dropTextureAllFaces(obj, item, mSource, mSourceID); + if((mask & MASK_SHIFT)) + { + dropTextureAllFaces(obj, item, mSource, mSourceID); + } + else + { + dropTextureOneFace(obj, face, item, mSource, mSourceID); + } + } + else if (cargo_type == DAD_MESH) + { + dropMesh(obj, item, mSource, mSourceID); } else { - dropTextureOneFace(obj, face, item, mSource, mSourceID); + llwarns << "unsupported asset type" << llendl; } // VEFFECT: SetTexture @@ -1876,14 +1919,29 @@ EAcceptance LLToolDragAndDrop::dad3dTextureObject( // enable multi-drop, although last texture will win return ACCEPT_YES_MULTI; } + + +EAcceptance LLToolDragAndDrop::dad3dTextureObject( + LLViewerObject* obj, S32 face, MASK mask, BOOL drop) +{ + return dad3dApplyToObject(obj, face, mask, drop, DAD_TEXTURE); +} + +EAcceptance LLToolDragAndDrop::dad3dMeshObject( + LLViewerObject* obj, S32 face, MASK mask, BOOL drop) +{ + return dad3dApplyToObject(obj, face, mask, drop, DAD_MESH); +} + + /* EAcceptance LLToolDragAndDrop::dad3dTextureSelf( LLViewerObject* obj, S32 face, MASK mask, BOOL drop) { lldebugs << "LLToolDragAndDrop::dad3dTextureAvatar()" << llendl; - if (drop) + if(drop) { - if (!(mask & MASK_SHIFT)) + if( !(mask & MASK_SHIFT) ) { dropTextureOneFaceAvatar( (LLVOAvatar*)obj, face, (LLInventoryItem*)mCargoData); } @@ -1901,16 +1959,16 @@ EAcceptance LLToolDragAndDrop::dad3dWearItem( locateInventory(item, cat); if (!item || !item->isFinished()) return ACCEPT_NO; - if (mSource == SOURCE_AGENT || mSource == SOURCE_LIBRARY) + 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)) + if( gInventory.isObjectDescendentOf( item->getUUID(), trash_id ) ) { return ACCEPT_NO; } - if (drop) + if( drop ) { // TODO: investigate wearables may not be loaded at this point EXT-8231 @@ -1934,19 +1992,19 @@ EAcceptance LLToolDragAndDrop::dad3dActivateGesture( locateInventory(item, cat); if (!item || !item->isFinished()) return ACCEPT_NO; - if (mSource == SOURCE_AGENT || mSource == SOURCE_LIBRARY) + 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)) + if( gInventory.isObjectDescendentOf( item->getUUID(), trash_id ) ) { return ACCEPT_NO; } - if (drop) + if( drop ) { LLUUID item_id; - if (mSource == SOURCE_LIBRARY) + if(mSource == SOURCE_LIBRARY) { // create item based on that one, and put it on if that // was a success. @@ -1981,31 +2039,31 @@ EAcceptance LLToolDragAndDrop::dad3dWearCategory( LLViewerInventoryItem* item; LLViewerInventoryCategory* category; locateInventory(item, category); - if (!category) return ACCEPT_NO; + if(!category) return ACCEPT_NO; if (drop) { // TODO: investigate wearables may not be loaded at this point EXT-8231 } - if (mSource == SOURCE_AGENT) + if(mSource == SOURCE_AGENT) { const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - if (gInventory.isObjectDescendentOf(category->getUUID(), trash_id)) + if( gInventory.isObjectDescendentOf( category->getUUID(), trash_id ) ) { return ACCEPT_NO; } - if (drop) + if(drop) { - BOOL append = ( (mask & MASK_SHIFT) ? TRUE : FALSE ); + BOOL append = ( (mask & MASK_SHIFT) ? TRUE : FALSE ); LLAppearanceMgr::instance().wearInventoryCategory(category, false, append); } return ACCEPT_YES_MULTI; } - else if (mSource == SOURCE_LIBRARY) + else if(mSource == SOURCE_LIBRARY) { - if (drop) + if(drop) { LLAppearanceMgr::instance().wearInventoryCategory(category, true, false); } @@ -2026,7 +2084,7 @@ EAcceptance LLToolDragAndDrop::dad3dUpdateInventory( // *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)) + if((SOURCE_WORLD == mSource) || (SOURCE_NOTECARD == mSource)) { return ACCEPT_NO; } @@ -2046,7 +2104,7 @@ EAcceptance LLToolDragAndDrop::dad3dUpdateInventory( } EAcceptance rv = willObjectAcceptInventory(root_object, item); - if (root_object && drop && (ACCEPT_YES_COPY_SINGLE <= rv)) + if(root_object && drop && (ACCEPT_YES_COPY_SINGLE <= rv)) { dropInventory(root_object, item, mSource, mSourceID); } @@ -2090,7 +2148,7 @@ EAcceptance LLToolDragAndDrop::dad3dUpdateInventoryCategory( LLDroppableItem droppable(!obj->permYouOwner()); LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; - gInventory.collectDescendentsIf (cat->getUUID(), + gInventory.collectDescendentsIf(cat->getUUID(), cats, items, LLInventoryModel::EXCLUDE_TRASH, @@ -2119,7 +2177,7 @@ EAcceptance LLToolDragAndDrop::dad3dUpdateInventoryCategory( { const LLViewerInventoryCategory *cat = (*cat_iter); rv = gInventory.isCategoryComplete(cat->getUUID()) ? ACCEPT_YES_MULTI : ACCEPT_NO; - if (rv < ACCEPT_YES_SINGLE) + if(rv < ACCEPT_YES_SINGLE) { lldebugs << "Category " << cat->getUUID() << "is not complete." << llendl; break; @@ -2187,26 +2245,27 @@ EAcceptance LLToolDragAndDrop::dad3dGiveInventoryObject( lldebugs << "LLToolDragAndDrop::dad3dGiveInventoryObject()" << llendl; // item has to be in agent inventory. - if (mSource != SOURCE_AGENT) return ACCEPT_NO; + 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())) + if(!item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) { // cannot give away no-transfer objects return ACCEPT_NO; } - if (isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(item->getUUID())) + LLVOAvatarSelf* avatar = gAgentAvatarp; + if(avatar && avatar->isWearingAttachment( item->getUUID() ) ) { // You can't give objects that are attached to you return ACCEPT_NO; } - if (obj && isAgentAvatarValid()) + if( obj && avatar ) { - if (drop) + if(drop) { LLGiveInventory::doGiveInventoryItem(obj->getID(), item ); } @@ -2223,7 +2282,7 @@ EAcceptance LLToolDragAndDrop::dad3dGiveInventory( { lldebugs << "LLToolDragAndDrop::dad3dGiveInventory()" << llendl; // item has to be in agent inventory. - if (mSource != SOURCE_AGENT) return ACCEPT_NO; + if(mSource != SOURCE_AGENT) return ACCEPT_NO; LLViewerInventoryItem* item; LLViewerInventoryCategory* cat; locateInventory(item, cat); @@ -2245,12 +2304,12 @@ EAcceptance LLToolDragAndDrop::dad3dGiveInventoryCategory( LLViewerObject* obj, S32 face, MASK mask, BOOL drop) { lldebugs << "LLToolDragAndDrop::dad3dGiveInventoryCategory()" << llendl; - if (drop && obj) + if(drop && obj) { LLViewerInventoryItem* item; LLViewerInventoryCategory* cat; locateInventory(item, cat); - if (!cat) return ACCEPT_NO; + if(!cat) return ACCEPT_NO; LLGiveInventory::doGiveInventoryCategory(obj->getID(), cat); } // *TODO: deal with all the issues surrounding multi-object @@ -2268,12 +2327,12 @@ EAcceptance LLToolDragAndDrop::dad3dRezFromObjectOnLand( locateInventory(item, cat); if (!item || !item->isFinished()) return ACCEPT_NO; - if (!gAgent.allowOperation(PERM_COPY, item->getPermissions()) + if(!gAgent.allowOperation(PERM_COPY, item->getPermissions()) || !item->getPermissions().allowTransferTo(LLUUID::null)) { return ACCEPT_NO_LOCKED; } - if (drop) + if(drop) { dropObject(obj, TRUE, TRUE, FALSE); } @@ -2288,7 +2347,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezFromObjectOnObject( LLViewerInventoryCategory* cat; locateInventory(item, cat); if (!item || !item->isFinished()) return ACCEPT_NO; - if ((mask & MASK_CONTROL)) + if((mask & MASK_CONTROL)) { // *HACK: In order to resolve SL-22177, we need to block drags // from notecards and objects onto other objects. @@ -2296,19 +2355,19 @@ EAcceptance LLToolDragAndDrop::dad3dRezFromObjectOnObject( // *HACK: uncomment this when appropriate //EAcceptance rv = willObjectAcceptInventory(obj, item); - //if (drop && (ACCEPT_YES_SINGLE <= rv)) + //if(drop && (ACCEPT_YES_SINGLE <= rv)) //{ // dropInventory(obj, item, mSource, mSourceID); //} //return rv; } - if (!item->getPermissions().allowCopyBy(gAgent.getID(), + if(!item->getPermissions().allowCopyBy(gAgent.getID(), gAgent.getGroupID()) || !item->getPermissions().allowTransferTo(LLUUID::null)) { return ACCEPT_NO_LOCKED; } - if (drop) + if(drop) { dropObject(obj, FALSE, TRUE, FALSE); } @@ -2324,23 +2383,23 @@ EAcceptance LLToolDragAndDrop::dad3dCategoryOnLand( LLInventoryItem* item; LLInventoryCategory* cat; locateInventory(item, cat); - if (!cat) return ACCEPT_NO; + 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(), + gInventory.collectDescendentsIf(cat->getUUID(), cats, items, LLInventoryModel::EXCLUDE_TRASH, droppable); - if (items.count() > 0) + if(items.count() > 0) { rv = ACCEPT_YES_SINGLE; } - if ((rv >= ACCEPT_YES_COPY_SINGLE) && drop) + if((rv >= ACCEPT_YES_COPY_SINGLE) && drop) { createContainer(items, cat->getName()); return ACCEPT_NO; @@ -2363,19 +2422,19 @@ EAcceptance LLToolDragAndDrop::dad3dAssetOnLand( LLViewerInventoryItem::item_array_t items; LLViewerInventoryItem::item_array_t copyable_items; locateMultipleInventory(items, cats); - if (!items.count()) return ACCEPT_NO; + if(!items.count()) return ACCEPT_NO; EAcceptance rv = ACCEPT_NO; for (S32 i = 0; i < items.count(); i++) { LLInventoryItem* item = items[i]; - if (item->getPermissions().allowCopyBy(gAgent.getID())) + if(item->getPermissions().allowCopyBy(gAgent.getID())) { copyable_items.put(item); rv = ACCEPT_YES_SINGLE; } } - if ((rv >= ACCEPT_YES_COPY_SINGLE) && drop) + if((rv >= ACCEPT_YES_COPY_SINGLE) && drop) { createContainer(copyable_items, NULL); } @@ -2390,20 +2449,20 @@ LLInventoryObject* LLToolDragAndDrop::locateInventory( { item = NULL; cat = NULL; - if (mCargoIDs.empty()) return NULL; - if ((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY)) + if(mCargoIDs.empty()) 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) + else if(mSource == SOURCE_WORLD) { // This object is in some task inventory somewhere. LLViewerObject* obj = gObjectList.findObject(mSourceID); - if (obj) + if(obj) { - if ((mCargoTypes[mCurItemIndex] == DAD_CATEGORY) + if((mCargoTypes[mCurItemIndex] == DAD_CATEGORY) || (mCargoTypes[mCurItemIndex] == DAD_ROOT_CATEGORY)) { cat = (LLViewerInventoryCategory*)obj->getInventoryObject(mCargoIDs[mCurItemIndex]); @@ -2414,16 +2473,16 @@ LLInventoryObject* LLToolDragAndDrop::locateInventory( } } } - else if (mSource == SOURCE_NOTECARD) + else if(mSource == SOURCE_NOTECARD) { LLPreviewNotecard* preview = LLFloaterReg::findTypedInstance<LLPreviewNotecard>("preview_notecard", mSourceID); - if (preview) + if(preview) { item = (LLViewerInventoryItem*)preview->getDragItem(); } } - if (item) return item; - if (cat) return cat; + if(item) return item; + if(cat) return cat; return NULL; } @@ -2431,8 +2490,8 @@ LLInventoryObject* LLToolDragAndDrop::locateInventory( LLInventoryObject* LLToolDragAndDrop::locateMultipleInventory(LLViewerInventoryCategory::cat_array_t& cats, LLViewerInventoryItem::item_array_t& items) { - if (mCargoIDs.count() == 0) return NULL; - if ((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY)) + if(mCargoIDs.count() == 0) return NULL; + if((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY)) { // The object should be in user inventory. for (S32 i = 0; i < mCargoIDs.count(); i++) @@ -2449,13 +2508,13 @@ LLInventoryObject* LLToolDragAndDrop::locateMultipleInventory(LLViewerInventoryC } } } - else if (mSource == SOURCE_WORLD) + else if(mSource == SOURCE_WORLD) { // This object is in some task inventory somewhere. LLViewerObject* obj = gObjectList.findObject(mSourceID); - if (obj) + if(obj) { - if ((mCargoType == DAD_CATEGORY) + if((mCargoType == DAD_CATEGORY) || (mCargoType == DAD_ROOT_CATEGORY)) { // The object should be in user inventory. @@ -2481,17 +2540,17 @@ LLInventoryObject* LLToolDragAndDrop::locateMultipleInventory(LLViewerInventoryC } } } - else if (mSource == SOURCE_NOTECARD) + else if(mSource == SOURCE_NOTECARD) { LLPreviewNotecard* card; card = (LLPreviewNotecard*)LLPreview::find(mSourceID); - if (card) + if(card) { items.put((LLInventoryItem*)card->getDragItem()); } } - if (items.count()) return items[0]; - if (cats.count()) return cats[0]; + if(items.count()) return items[0]; + if(cats.count()) return cats[0]; return NULL; } */ diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h index a13b775699..7b8cce3dc7 100644 --- a/indra/newview/lltooldraganddrop.h +++ b/indra/newview/lltooldraganddrop.h @@ -148,6 +148,8 @@ protected: MASK mask, BOOL drop); EAcceptance dad3dTextureObject(LLViewerObject* obj, S32 face, MASK mask, BOOL drop); + EAcceptance dad3dMeshObject(LLViewerObject* obj, S32 face, + MASK mask, BOOL drop); // EAcceptance dad3dTextureSelf(LLViewerObject* obj, S32 face, // MASK mask, BOOL drop); EAcceptance dad3dWearItem(LLViewerObject* obj, S32 face, @@ -179,6 +181,11 @@ protected: EAcceptance dad3dActivateGesture(LLViewerObject *obj, S32 face, MASK mask, BOOL drop); + // helper called by methods above to handle "application" of an item + // to an object (texture applied to face, mesh applied to shape, etc.) + EAcceptance dad3dApplyToObject(LLViewerObject* obj, S32 face, MASK mask, BOOL drop, EDragAndDropType cargo_type); + + // set the LLToolDragAndDrop's cursor based on the given acceptance ECursorType acceptanceToCursor( EAcceptance acceptance ); @@ -229,6 +236,11 @@ public: LLInventoryItem* item, ESource source, const LLUUID& src_id); + static void dropMesh(LLViewerObject* hit_obj, + LLInventoryItem* item, + ESource source, + const LLUUID& src_id); + //static void dropTextureOneFaceAvatar(LLVOAvatar* avatar,S32 hit_face, // LLInventoryItem* item) diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp index 7024b2c785..e621cf647e 100644 --- a/indra/newview/llviewerassetstats.cpp +++ b/indra/newview/llviewerassetstats.cpp @@ -525,7 +525,7 @@ asset_type_to_category(const LLViewerAssetType::EType at, bool with_http, bool i // - gestures // - everything else. // - llassert_always(26 == LLViewerAssetType::AT_COUNT); + llassert_always(50 == LLViewerAssetType::AT_COUNT); // Multiple asset definitions are floating around so this requires some // maintenance and attention. @@ -557,9 +557,7 @@ asset_type_to_category(const LLViewerAssetType::EType at, bool with_http, bool i LLViewerAssetStats::EVACOtherGet, // AT_FAVORITE LLViewerAssetStats::EVACOtherGet, // AT_LINK LLViewerAssetStats::EVACOtherGet, // AT_LINK_FOLDER -#if 0 - // When LLViewerAssetType::AT_COUNT == 49 - LLViewerAssetStats::EVACOtherGet, // AT_FOLDER_ENSEMBLE_START + LLViewerAssetStats::EVACOtherGet, // LLViewerAssetStats::EVACOtherGet, // LLViewerAssetStats::EVACOtherGet, // LLViewerAssetStats::EVACOtherGet, // @@ -578,11 +576,12 @@ asset_type_to_category(const LLViewerAssetType::EType at, bool with_http, bool i LLViewerAssetStats::EVACOtherGet, // LLViewerAssetStats::EVACOtherGet, // LLViewerAssetStats::EVACOtherGet, // - LLViewerAssetStats::EVACOtherGet, // AT_FOLDER_ENSEMBLE_END - LLViewerAssetStats::EVACOtherGet, // AT_CURRENT_OUTFIT - LLViewerAssetStats::EVACOtherGet, // AT_OUTFIT - LLViewerAssetStats::EVACOtherGet // AT_MY_OUTFITS -#endif + LLViewerAssetStats::EVACOtherGet, // + LLViewerAssetStats::EVACOtherGet, // + LLViewerAssetStats::EVACOtherGet, // + LLViewerAssetStats::EVACOtherGet, // + LLViewerAssetStats::EVACOtherGet, // AT_MESH + // (50) }; if (at < 0 || at >= LLViewerAssetType::AT_COUNT) diff --git a/indra/newview/llviewerassettype.cpp b/indra/newview/llviewerassettype.cpp index 9a52422641..b103f11597 100644 --- a/indra/newview/llviewerassettype.cpp +++ b/indra/newview/llviewerassettype.cpp @@ -79,6 +79,8 @@ LLViewerAssetDictionary::LLViewerAssetDictionary() addEntry(LLViewerAssetType::AT_LINK, new ViewerAssetEntry(DAD_LINK)); addEntry(LLViewerAssetType::AT_LINK_FOLDER, new ViewerAssetEntry(DAD_LINK)); + addEntry(LLViewerAssetType::AT_MESH, new ViewerAssetEntry(DAD_MESH)); + addEntry(LLViewerAssetType::AT_NONE, new ViewerAssetEntry(DAD_NONE)); }; diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index cbb1d25f78..7f7366dd3d 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -32,6 +32,7 @@ // Viewer includes #include "llagent.h" #include "llagentcamera.h" +#include "llmatrix4a.h" #include "llviewercontrol.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" @@ -755,6 +756,10 @@ LLVector3 LLViewerCamera::roundToPixel(const LLVector3 &pos_agent) BOOL LLViewerCamera::cameraUnderWater() const { + if(!gAgent.getRegion()) + { + return FALSE ; + } return getOrigin().mV[VZ] < gAgent.getRegion()->getWaterHeight(); } @@ -781,21 +786,29 @@ BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts) 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.mVertices.size(); v++) + for (U32 v = 0; v < face.mNumVertices; v++) { - LLVector4 vec = LLVector4(face.mVertices[v].mPosition) * mat; + const LLVector4a& src_vec = face.mPositions[v]; + LLVector4a vec; + mata.affineTransform(src_vec, vec); if (drawablep->isActive()) { - vec = vec * render_mat; + LLVector4a t = vec; + render_mata.affineTransform(t, vec); } - BOOL in_frustum = pointInFrustum(LLVector3(vec)) > 0; + BOOL in_frustum = pointInFrustum(LLVector3(vec.getF32ptr())) > 0; if (( !in_frustum && all_verts) || (in_frustum && !all_verts)) diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 06c1520314..379bbe614d 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -128,6 +128,45 @@ static bool handleSetShaderChanged(const LLSD& newvalue) return true; } +static bool handleRenderPerfTestChanged(const LLSD& newvalue) +{ + bool status = !newvalue.asBoolean(); + if (!status) + { + gPipeline.clearRenderTypeMask(LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::RENDER_TYPE_GROUND, + LLPipeline::RENDER_TYPE_TERRAIN, + LLPipeline::RENDER_TYPE_GRASS, + LLPipeline::RENDER_TYPE_TREE, + LLPipeline::RENDER_TYPE_WATER, + LLPipeline::RENDER_TYPE_PASS_GRASS, + LLPipeline::RENDER_TYPE_HUD, + LLPipeline::RENDER_TYPE_PARTICLES, + LLPipeline::RENDER_TYPE_CLOUDS, + LLPipeline::RENDER_TYPE_HUD_PARTICLES, + LLPipeline::END_RENDER_TYPES); + gPipeline.setRenderDebugFeatureControl(LLPipeline::RENDER_DEBUG_FEATURE_UI, false); + } + else + { + gPipeline.setRenderTypeMask(LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::RENDER_TYPE_GROUND, + LLPipeline::RENDER_TYPE_TERRAIN, + LLPipeline::RENDER_TYPE_GRASS, + LLPipeline::RENDER_TYPE_TREE, + LLPipeline::RENDER_TYPE_WATER, + LLPipeline::RENDER_TYPE_PASS_GRASS, + LLPipeline::RENDER_TYPE_HUD, + LLPipeline::RENDER_TYPE_PARTICLES, + LLPipeline::RENDER_TYPE_CLOUDS, + LLPipeline::RENDER_TYPE_HUD_PARTICLES, + LLPipeline::END_RENDER_TYPES); + gPipeline.setRenderDebugFeatureControl(LLPipeline::RENDER_DEBUG_FEATURE_UI, true); + } + + return true; +} + bool handleRenderTransparentWaterChanged(const LLSD& newvalue) { LLWorld::getInstance()->updateWaterObjects(); @@ -300,24 +339,6 @@ static bool handleNumpadControlChanged(const LLSD& newvalue) return true; } -static bool handleRenderUseVBOChanged(const LLSD& newvalue) -{ - if (gPipeline.isInit()) - { - gPipeline.setUseVBO(newvalue.asBoolean()); - } - return true; -} - -static bool handleRenderUseVBOMappingChanged(const LLSD& newvalue) -{ - if (gPipeline.isInit()) - { - gPipeline.setDisableVBOMapping(newvalue.asBoolean()); - } - return true; -} - static bool handleWLSkyDetailChanged(const LLSD&) { if (gSky.mVOWLSkyp.notNull()) @@ -342,13 +363,21 @@ static bool handleRenderDynamicLODChanged(const LLSD& newvalue) return true; } -static bool handleRenderUseFBOChanged(const LLSD& newvalue) +static bool handleRenderLocalLightsChanged(const LLSD& newvalue) +{ + gPipeline.setLightingDetail(-1); + return true; +} + +static bool handleRenderDeferredChanged(const LLSD& newvalue) { LLRenderTarget::sUseFBO = newvalue.asBoolean(); if (gPipeline.isInit()) { + gPipeline.updateRenderDeferred(); gPipeline.releaseGLBuffers(); gPipeline.createGLBuffers(); + gPipeline.resetVertexBuffers(); if (LLPipeline::sRenderDeferred && LLRenderTarget::sUseFBO) { LLViewerShaderMgr::instance()->setShaders(); @@ -560,21 +589,22 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderFogRatio")->getSignal()->connect(boost::bind(&handleFogRatioChanged, _2)); gSavedSettings.getControl("RenderMaxPartCount")->getSignal()->connect(boost::bind(&handleMaxPartCountChanged, _2)); gSavedSettings.getControl("RenderDynamicLOD")->getSignal()->connect(boost::bind(&handleRenderDynamicLODChanged, _2)); + gSavedSettings.getControl("RenderLocalLights")->getSignal()->connect(boost::bind(&handleRenderLocalLightsChanged, _2)); gSavedSettings.getControl("RenderDebugTextureBind")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderAutoMaskAlphaDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderAutoMaskAlphaNonDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderUseFBO")->getSignal()->connect(boost::bind(&handleRenderUseFBOChanged, _2)); gSavedSettings.getControl("RenderDeferredNoise")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); gSavedSettings.getControl("RenderUseImpostors")->getSignal()->connect(boost::bind(&handleRenderUseImpostorsChanged, _2)); gSavedSettings.getControl("RenderDebugGL")->getSignal()->connect(boost::bind(&handleRenderDebugGLChanged, _2)); gSavedSettings.getControl("RenderDebugPipeline")->getSignal()->connect(boost::bind(&handleRenderDebugPipelineChanged, _2)); gSavedSettings.getControl("RenderResolutionDivisor")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _2)); - gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); + gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleRenderDeferredChanged, _2)); gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); gSavedSettings.getControl("RenderDeferredGI")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); + gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2)); gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _2)); gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _2)); gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _2)); @@ -597,9 +627,10 @@ void settings_setup_listeners() gSavedSettings.getControl("MuteVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleRenderUseVBOChanged, _2)); - gSavedSettings.getControl("RenderVBOMappingDisable")->getSignal()->connect(boost::bind(&handleRenderUseVBOMappingChanged, _2)); + gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); + gSavedSettings.getControl("RenderVBOMappingDisable")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("RenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); + gSavedSettings.getControl("RenderPreferStreamDraw")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _2)); gSavedSettings.getControl("NumpadControl")->getSignal()->connect(boost::bind(&handleNumpadControlChanged, _2)); gSavedSettings.getControl("JoystickAxis0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index d94ec291a3..e619ef101c 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -616,10 +616,10 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) && gSavedSettings.getBOOL("UseOcclusion") && gGLManager.mHasOcclusionQuery) ? 2 : 0; - if (LLPipeline::sUseOcclusion && LLPipeline::sRenderDeferred) - { //force occlusion on for all render types if doing deferred render + /*if (LLPipeline::sUseOcclusion && LLPipeline::sRenderDeferred) + { //force occlusion on for all render types if doing deferred render (tighter shadow frustum) LLPipeline::sUseOcclusion = 3; - } + }*/ LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred"); LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred"); @@ -754,7 +754,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; LLMemType mt_ss(LLMemType::MTYPE_DISPLAY_STATE_SORT); - gPipeline.sAllowRebuildPriorityGroup = TRUE ; gPipeline.stateSort(*LLViewerCamera::getInstance(), result); stop_glerror(); @@ -826,13 +825,14 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) //} LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE; - LLPipeline::updateRenderDeferred(); + LLPipeline::refreshRenderDeferred(); stop_glerror(); if (to_texture) { gGL.setColorMask(true, true); + if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) { gPipeline.mDeferredScreen.bindTarget(); @@ -885,10 +885,26 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) { gPipeline.mDeferredScreen.flush(); + if(LLRenderTarget::sUseFBO) + { + LLRenderTarget::copyContentsToFramebuffer(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), + gPipeline.mDeferredScreen.getHeight(), 0, 0, + gPipeline.mDeferredScreen.getWidth(), + gPipeline.mDeferredScreen.getHeight(), + GL_DEPTH_BUFFER_BIT, GL_NEAREST); + } } else { gPipeline.mScreen.flush(); + if(LLRenderTarget::sUseFBO) + { + LLRenderTarget::copyContentsToFramebuffer(gPipeline.mScreen, 0, 0, gPipeline.mScreen.getWidth(), + gPipeline.mScreen.getHeight(), 0, 0, + gPipeline.mScreen.getWidth(), + gPipeline.mScreen.getHeight(), + GL_DEPTH_BUFFER_BIT, GL_NEAREST); + } } } @@ -906,9 +922,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) render_ui(); } - gPipeline.rebuildGroups(); - + LLSpatialGroup::sNoDelete = FALSE; + gPipeline.clearReferences(); + + gPipeline.rebuildGroups(); } LLAppViewer::instance()->pingMainloopTimeout("Display:FrameStats"); @@ -1006,6 +1024,7 @@ void render_hud_attachments() gPipeline.renderGeom(hud_cam); LLSpatialGroup::sNoDelete = FALSE; + //gPipeline.clearReferences(); render_hud_elements(); diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index d4464a2915..670b35aa71 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -78,6 +78,7 @@ #include "llfloaterlandholdings.h" #include "llfloatermap.h" #include "llfloatermemleak.h" +#include "llfloatermodelwizard.h" #include "llfloaternamedesc.h" #include "llfloaternotificationsconsole.h" #include "llfloateropenobject.h" @@ -128,8 +129,34 @@ #include "llpreviewtexture.h" #include "llsyswellwindow.h" #include "llscriptfloater.h" +#include "llfloatermodelpreview.h" +#include "llcommandhandler.h" + // *NOTE: Please add files in alphabetical order to keep merges easy. +// handle secondlife:///app/floater/{NAME} URLs +class LLFloaterOpenHandler : public LLCommandHandler +{ +public: + // requires trusted browser to trigger + LLFloaterOpenHandler() : LLCommandHandler("floater", UNTRUSTED_THROTTLE) { } + + bool handle(const LLSD& params, const LLSD& query_map, + LLMediaCtrl* web) + { + if (params.size() != 1) + { + return false; + } + + const std::string floater_name = LLURI::unescape(params[0].asString()); + LLFloaterReg::showInstance(floater_name); + + return true; + } +}; + +LLFloaterOpenHandler gFloaterOpenHandler; void LLViewerFloaterReg::registerFloaters() { @@ -261,7 +288,9 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("upload_anim", "floater_animation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAnimPreview>, "upload"); LLFloaterReg::add("upload_image", "floater_image_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterImagePreview>, "upload"); LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundPreview>, "upload"); - + LLFloaterReg::add("upload_model", "floater_model_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterModelPreview>, "upload"); + LLFloaterReg::add("upload_model_wizard", "floater_model_wizard.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterModelWizard>); + LLFloaterReg::add("voice_controls", "floater_voice_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLCallFloater>); LLFloaterReg::add("voice_effect", "floater_voice_effect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterVoiceEffect>); diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp index de1c8d14a8..42f780a8a3 100644 --- a/indra/newview/llviewerfoldertype.cpp +++ b/indra/newview/llviewerfoldertype.cpp @@ -126,6 +126,9 @@ LLViewerFolderDictionary::LLViewerFolderDictionary() addEntry(LLFolderType::FT_CURRENT_OUTFIT, new ViewerFolderEntry("Current Outfit", "Inv_SysOpen", "Inv_SysClosed", TRUE)); addEntry(LLFolderType::FT_OUTFIT, new ViewerFolderEntry("New Outfit", "Inv_LookFolderOpen", "Inv_LookFolderClosed", TRUE)); addEntry(LLFolderType::FT_MY_OUTFITS, new ViewerFolderEntry("My Outfits", "Inv_SysOpen", "Inv_SysClosed", TRUE)); + addEntry(LLFolderType::FT_MESH, new ViewerFolderEntry("Meshes", "Inv_SysOpen", "Inv_SysClosed", FALSE)); + + addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Inbox", "Inv_SysOpen", "Inv_SysClosed", FALSE)); addEntry(LLFolderType::FT_NONE, new ViewerFolderEntry("New Folder", "Inv_FolderOpen", "Inv_FolderClosed", FALSE, "default")); diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index e59e685f53..77c8bb0329 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -55,6 +55,7 @@ #include "v4math.h" #include "m3math.h" #include "m4math.h" +#include "llmatrix4a.h" #if !LL_DARWIN && !LL_LINUX && !LL_SOLARIS extern PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB; @@ -375,6 +376,7 @@ const S32 NUM_AXES = 3; // pivot parent 0-n -- child = n+1 static LLMatrix4 gJointMatUnaligned[32]; +static LLMatrix4a gJointMatAligned[32]; static LLMatrix3 gJointRotUnaligned[32]; static LLVector4 gJointPivot[32]; @@ -460,6 +462,14 @@ void LLViewerJointMesh::uploadJointMatrices() glUniform4fvARB(gAvatarMatrixParam, 45, mat); stop_glerror(); } + else + { + //load gJointMatUnaligned into gJointMatAligned + for (joint_num = 0; joint_num < reference_mesh->mJointRenderData.count(); ++joint_num) + { + gJointMatAligned[joint_num].loadu(gJointMatUnaligned[joint_num]); + } + } } //-------------------------------------------------------------------- @@ -501,7 +511,7 @@ int compare_int(const void *a, const void *b) U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) { if (!mValid || !mMesh || !mFace || !mVisible || - mFace->mVertexBuffer.isNull() || + !mFace->getVertexBuffer() || mMesh->getNumFaces() == 0) { return 0; @@ -509,6 +519,8 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) U32 triangle_count = 0; + S32 diffuse_channel = LLDrawPoolAvatar::sDiffuseChannel; + stop_glerror(); //---------------------------------------------------------------- @@ -521,7 +533,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) stop_glerror(); - LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), mShiny && !(mFace->getPool()->getVertexShaderLevel() > 0)); + LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), mFace->getPool()->getVertexShaderLevel() > 0 ? 0.f : mShiny); //---------------------------------------------------------------- // setup current texture @@ -531,7 +543,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) LLTexUnit::eTextureAddressMode old_mode = LLTexUnit::TAM_WRAP; if (mTestImageName) { - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTestImageName); + gGL.getTexUnit(diffuse_channel)->bindManual(LLTexUnit::TT_TEXTURE, mTestImageName); if (mIsTransparent) { @@ -540,24 +552,18 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) else { glColor4f(0.7f, 0.6f, 0.3f, 1.f); - gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_LERP_TEX_ALPHA, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); + gGL.getTexUnit(diffuse_channel)->setTextureColorBlend(LLTexUnit::TBO_LERP_TEX_ALPHA, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); } } else if( !is_dummy && mLayerSet ) { if( mLayerSet->hasComposite() ) { - gGL.getTexUnit(0)->bind(mLayerSet->getComposite()); + gGL.getTexUnit(diffuse_channel)->bind(mLayerSet->getComposite()); } else { - // This warning will always trigger if you've hacked the avatar to show as incomplete. - // Ignore the warning if that's the case. - if (!gSavedSettings.getBOOL("RenderUnloadedAvatar")) - { - //llwarns << "Layerset without composite" << llendl; - } - gGL.getTexUnit(0)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT)); + gGL.getTexUnit(diffuse_channel)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT)); } } else @@ -567,16 +573,16 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) { old_mode = mTexture->getAddressMode(); } - gGL.getTexUnit(0)->bind(mTexture.get()); - gGL.getTexUnit(0)->bind(mTexture); - gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + gGL.getTexUnit(diffuse_channel)->bind(mTexture.get()); + gGL.getTexUnit(diffuse_channel)->bind(mTexture); + gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); } else { - gGL.getTexUnit(0)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT)); + gGL.getTexUnit(diffuse_channel)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT)); } - mFace->mVertexBuffer->setBuffer(sRenderMask); + mFace->getVertexBuffer()->setBuffer(sRenderMask); U32 start = mMesh->mFaceVertexOffset; U32 end = start + mMesh->mFaceVertexCount - 1; @@ -593,14 +599,14 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) } } - mFace->mVertexBuffer->drawRange(LLRender::TRIANGLES, start, end, count, offset); + mFace->getVertexBuffer()->drawRange(LLRender::TRIANGLES, start, end, count, offset); } else { glPushMatrix(); LLMatrix4 jointToWorld = getWorldMatrix(); glMultMatrixf((GLfloat*)jointToWorld.mMatrix); - mFace->mVertexBuffer->drawRange(LLRender::TRIANGLES, start, end, count, offset); + mFace->getVertexBuffer()->drawRange(LLRender::TRIANGLES, start, end, count, offset); glPopMatrix(); } gPipeline.addTrianglesDrawn(count); @@ -609,13 +615,13 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) if (mTestImageName) { - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + gGL.getTexUnit(diffuse_channel)->setTextureBlendType(LLTexUnit::TB_MULT); } if (mTexture.notNull() && !is_dummy) { - gGL.getTexUnit(0)->bind(mTexture); - gGL.getTexUnit(0)->setTextureAddressMode(old_mode); + gGL.getTexUnit(diffuse_channel)->bind(mTexture); + gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(old_mode); } return triangle_count; @@ -626,6 +632,9 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) //----------------------------------------------------------------------------- void LLViewerJointMesh::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area) { + //bump num_vertices to next multiple of 4 + num_vertices = (num_vertices + 0x3) & ~0x3; + // Do a pre-alloc pass to determine sizes of data. if (mMesh && mValid) { @@ -648,13 +657,25 @@ static LLFastTimer::DeclareTimer FTM_AVATAR_FACE("Avatar Face"); void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update) { + //IF THIS FUNCTION BREAKS, SEE LLPOLYMESH CONSTRUCTOR AND CHECK ALIGNMENT OF INPUT ARRAYS + mFace = face; - if (mFace->mVertexBuffer.isNull()) + if (!mFace->getVertexBuffer()) { return; } + LLDrawPool *poolp = mFace->getPool(); + BOOL hardware_skinning = (poolp && poolp->getVertexShaderLevel() > 0) ? TRUE : FALSE; + + if (!hardware_skinning && terse_update) + { //no need to do terse updates if we're doing software vertex skinning + // since mMesh is being copied into mVertexBuffer every frame + return; + } + + LLFastTimer t(FTM_AVATAR_FACE); LLStrider<LLVector3> verticesp; @@ -667,111 +688,59 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w // Copy data into the faces from the polymesh data. if (mMesh && mValid) { - if (mMesh->getNumVertices()) + const U32 num_verts = mMesh->getNumVertices(); + + if (num_verts) { - stop_glerror(); face->getGeometryAvatar(verticesp, normalsp, tex_coordsp, vertex_weightsp, clothing_weightsp); - stop_glerror(); - face->mVertexBuffer->getIndexStrider(indicesp); - stop_glerror(); + face->getVertexBuffer()->getIndexStrider(indicesp); verticesp += mMesh->mFaceVertexOffset; - tex_coordsp += mMesh->mFaceVertexOffset; normalsp += mMesh->mFaceVertexOffset; - vertex_weightsp += mMesh->mFaceVertexOffset; - clothing_weightsp += mMesh->mFaceVertexOffset; - - const U32* __restrict coords = (U32*) mMesh->getCoords(); - const U32* __restrict tex_coords = (U32*) mMesh->getTexCoords(); - const U32* __restrict normals = (U32*) mMesh->getNormals(); - const U32* __restrict weights = (U32*) mMesh->getWeights(); - const U32* __restrict cloth_weights = (U32*) mMesh->getClothingWeights(); - - const U32 num_verts = mMesh->getNumVertices(); - - U32 i = 0; - - const U32 skip = verticesp.getSkip()/sizeof(U32); + + F32* v = (F32*) verticesp.get(); + F32* n = (F32*) normalsp.get(); + + U32 words = num_verts*4; - U32* __restrict v = (U32*) verticesp.get(); - U32* __restrict n = (U32*) normalsp.get(); + LLVector4a::memcpyNonAliased16(v, (F32*) mMesh->getCoords(), words*sizeof(F32)); + LLVector4a::memcpyNonAliased16(n, (F32*) mMesh->getNormals(), words*sizeof(F32)); + - if (terse_update) + if (!terse_update) { - for (S32 i = num_verts; i > 0; --i) - { - //morph target application only, only update positions and normals - v[0] = coords[0]; - v[1] = coords[1]; - v[2] = coords[2]; - coords += 3; - v += skip; - } + vertex_weightsp += mMesh->mFaceVertexOffset; + clothing_weightsp += mMesh->mFaceVertexOffset; + tex_coordsp += mMesh->mFaceVertexOffset; + + F32* tc = (F32*) tex_coordsp.get(); + F32* vw = (F32*) vertex_weightsp.get(); + F32* cw = (F32*) clothing_weightsp.get(); - for (S32 i = num_verts; i > 0; --i) - { - n[0] = normals[0]; - n[1] = normals[1]; - n[2] = normals[2]; - normals += 3; - n += skip; - } + LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), num_verts*2*sizeof(F32)); + LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), num_verts*sizeof(F32)); + LLVector4a::memcpyNonAliased16(cw, (F32*) mMesh->getClothingWeights(), num_verts*4*sizeof(F32)); } - else - { - U32* __restrict tc = (U32*) tex_coordsp.get(); - U32* __restrict vw = (U32*) vertex_weightsp.get(); - U32* __restrict cw = (U32*) clothing_weightsp.get(); - - do - { - v[0] = *(coords++); - v[1] = *(coords++); - v[2] = *(coords++); - v += skip; - - tc[0] = *(tex_coords++); - tc[1] = *(tex_coords++); - tc += skip; - - n[0] = *(normals++); - n[1] = *(normals++); - n[2] = *(normals++); - n += skip; - - vw[0] = *(weights++); - vw += skip; - - cw[0] = *(cloth_weights++); - cw[1] = *(cloth_weights++); - cw[2] = *(cloth_weights++); - cw[3] = *(cloth_weights++); - cw += skip; - } - while (++i < num_verts); + const U32 idx_count = mMesh->getNumFaces()*3; - const U32 idx_count = mMesh->getNumFaces()*3; + indicesp += mMesh->mFaceIndexOffset; - indicesp += mMesh->mFaceIndexOffset; + U16* __restrict idx = indicesp.get(); + S32* __restrict src_idx = (S32*) mMesh->getFaces(); - U16* __restrict idx = indicesp.get(); - S32* __restrict src_idx = (S32*) mMesh->getFaces(); + const S32 offset = (S32) mMesh->mFaceVertexOffset; - i = 0; - - const S32 offset = (S32) mMesh->mFaceVertexOffset; - - do - { - *(idx++) = *(src_idx++)+offset; - } - while (++i < idx_count); + for (S32 i = 0; i < idx_count; ++i) + { + *(idx++) = *(src_idx++)+offset; } } } } + + //----------------------------------------------------------------------------- // updateLOD() //----------------------------------------------------------------------------- @@ -789,89 +758,49 @@ void LLViewerJointMesh::updateGeometryOriginal(LLFace *mFace, LLPolyMesh *mMesh) LLStrider<LLVector3> o_normals; //get vertex and normal striders - LLVertexBuffer *buffer = mFace->mVertexBuffer; + LLVertexBuffer* buffer = mFace->getVertexBuffer(); buffer->getVertexStrider(o_vertices, 0); buffer->getNormalStrider(o_normals, 0); - F32 last_weight = F32_MAX; - LLMatrix4 gBlendMat; - LLMatrix3 gBlendRotMat; + F32* __restrict vert = o_vertices[0].mV; + F32* __restrict norm = o_normals[0].mV; + + const F32* __restrict weights = mMesh->getWeights(); + const LLVector4a* __restrict coords = (LLVector4a*) mMesh->getCoords(); + const LLVector4a* __restrict normals = (LLVector4a*) mMesh->getNormals(); + + U32 offset = mMesh->mFaceVertexOffset*4; + vert += offset; + norm += offset; - const F32* weights = mMesh->getWeights(); - const LLVector3* coords = mMesh->getCoords(); - const LLVector3* normals = mMesh->getNormals(); for (U32 index = 0; index < mMesh->getNumVertices(); index++) { - U32 bidx = index + mMesh->mFaceVertexOffset; - - // blend by first matrix - F32 w = weights[index]; - - // Maybe we don't have to change gBlendMat. - // Profiles of a single-avatar scene on a Mac show this to be a very - // common case. JC - if (w == last_weight) - { - o_vertices[bidx] = coords[index] * gBlendMat; - o_normals[bidx] = normals[index] * gBlendRotMat; - continue; - } - - last_weight = w; + // equivalent to joint = floorf(weights[index]); + S32 joint = _mm_cvtt_ss2si(_mm_load_ss(weights+index)); + F32 w = weights[index] - joint; - S32 joint = llfloor(w); - w -= joint; - - // No lerp required in this case. - if (w == 1.0f) + LLMatrix4a gBlendMat; + + if (w != 0.f) { - gBlendMat = gJointMatUnaligned[joint+1]; - o_vertices[bidx] = coords[index] * gBlendMat; - gBlendRotMat = gJointRotUnaligned[joint+1]; - o_normals[bidx] = normals[index] * gBlendRotMat; - continue; + // blend between matrices and apply + gBlendMat.setLerp(gJointMatAligned[joint+0], + gJointMatAligned[joint+1], w); + + LLVector4a res; + gBlendMat.affineTransform(coords[index], res); + res.store4a(vert+index*4); + gBlendMat.rotate(normals[index], res); + res.store4a(norm+index*4); + } + else + { // No lerp required in this case. + LLVector4a res; + gJointMatAligned[joint].affineTransform(coords[index], res); + res.store4a(vert+index*4); + gJointMatAligned[joint].rotate(normals[index], res); + res.store4a(norm+index*4); } - - // Try to keep all the accesses to the matrix data as close - // together as possible. This function is a hot spot on the - // Mac. JC - LLMatrix4 &m0 = gJointMatUnaligned[joint+1]; - LLMatrix4 &m1 = gJointMatUnaligned[joint+0]; - - gBlendMat.mMatrix[VX][VX] = lerp(m1.mMatrix[VX][VX], m0.mMatrix[VX][VX], w); - gBlendMat.mMatrix[VX][VY] = lerp(m1.mMatrix[VX][VY], m0.mMatrix[VX][VY], w); - gBlendMat.mMatrix[VX][VZ] = lerp(m1.mMatrix[VX][VZ], m0.mMatrix[VX][VZ], w); - - gBlendMat.mMatrix[VY][VX] = lerp(m1.mMatrix[VY][VX], m0.mMatrix[VY][VX], w); - gBlendMat.mMatrix[VY][VY] = lerp(m1.mMatrix[VY][VY], m0.mMatrix[VY][VY], w); - gBlendMat.mMatrix[VY][VZ] = lerp(m1.mMatrix[VY][VZ], m0.mMatrix[VY][VZ], w); - - gBlendMat.mMatrix[VZ][VX] = lerp(m1.mMatrix[VZ][VX], m0.mMatrix[VZ][VX], w); - gBlendMat.mMatrix[VZ][VY] = lerp(m1.mMatrix[VZ][VY], m0.mMatrix[VZ][VY], w); - gBlendMat.mMatrix[VZ][VZ] = lerp(m1.mMatrix[VZ][VZ], m0.mMatrix[VZ][VZ], w); - - gBlendMat.mMatrix[VW][VX] = lerp(m1.mMatrix[VW][VX], m0.mMatrix[VW][VX], w); - gBlendMat.mMatrix[VW][VY] = lerp(m1.mMatrix[VW][VY], m0.mMatrix[VW][VY], w); - gBlendMat.mMatrix[VW][VZ] = lerp(m1.mMatrix[VW][VZ], m0.mMatrix[VW][VZ], w); - - o_vertices[bidx] = coords[index] * gBlendMat; - - LLMatrix3 &n0 = gJointRotUnaligned[joint+1]; - LLMatrix3 &n1 = gJointRotUnaligned[joint+0]; - - gBlendRotMat.mMatrix[VX][VX] = lerp(n1.mMatrix[VX][VX], n0.mMatrix[VX][VX], w); - gBlendRotMat.mMatrix[VX][VY] = lerp(n1.mMatrix[VX][VY], n0.mMatrix[VX][VY], w); - gBlendRotMat.mMatrix[VX][VZ] = lerp(n1.mMatrix[VX][VZ], n0.mMatrix[VX][VZ], w); - - gBlendRotMat.mMatrix[VY][VX] = lerp(n1.mMatrix[VY][VX], n0.mMatrix[VY][VX], w); - gBlendRotMat.mMatrix[VY][VY] = lerp(n1.mMatrix[VY][VY], n0.mMatrix[VY][VY], w); - gBlendRotMat.mMatrix[VY][VZ] = lerp(n1.mMatrix[VY][VZ], n0.mMatrix[VY][VZ], w); - - gBlendRotMat.mMatrix[VZ][VX] = lerp(n1.mMatrix[VZ][VX], n0.mMatrix[VZ][VX], w); - gBlendRotMat.mMatrix[VZ][VY] = lerp(n1.mMatrix[VZ][VY], n0.mMatrix[VZ][VY], w); - gBlendRotMat.mMatrix[VZ][VZ] = lerp(n1.mMatrix[VZ][VZ], n0.mMatrix[VZ][VZ], w); - - o_normals[bidx] = normals[index] * gBlendRotMat; } buffer->setBuffer(0); @@ -940,7 +869,7 @@ void LLViewerJointMesh::updateJointGeometry() && mMesh && mFace && mMesh->hasWeights() - && mFace->mVertexBuffer.notNull() + && mFace->getVertexBuffer() && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) == 0)) { return; diff --git a/indra/newview/llviewerjointmesh_sse.cpp b/indra/newview/llviewerjointmesh_sse.cpp index 174b6eae29..400b49d046 100644 --- a/indra/newview/llviewerjointmesh_sse.cpp +++ b/indra/newview/llviewerjointmesh_sse.cpp @@ -83,13 +83,13 @@ void LLViewerJointMesh::updateGeometrySSE(LLFace *face, LLPolyMesh *mesh) LLStrider<LLVector3> o_vertices; LLStrider<LLVector3> o_normals; - LLVertexBuffer *buffer = face->mVertexBuffer; + LLVertexBuffer *buffer = face->getVertexBuffer(); buffer->getVertexStrider(o_vertices, mesh->mFaceVertexOffset); buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset); const F32* weights = mesh->getWeights(); - const LLVector3* coords = mesh->getCoords(); - const LLVector3* normals = mesh->getNormals(); + const LLVector3* coords = (const LLVector3*)mesh->getCoords(); + const LLVector3* normals = (const LLVector3*)mesh->getNormals(); for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index) { if( weight != weights[index]) diff --git a/indra/newview/llviewerjointmesh_sse2.cpp b/indra/newview/llviewerjointmesh_sse2.cpp index a374ba2471..c2296dd569 100644 --- a/indra/newview/llviewerjointmesh_sse2.cpp +++ b/indra/newview/llviewerjointmesh_sse2.cpp @@ -90,13 +90,13 @@ void LLViewerJointMesh::updateGeometrySSE2(LLFace *face, LLPolyMesh *mesh) LLStrider<LLVector3> o_vertices; LLStrider<LLVector3> o_normals; - LLVertexBuffer *buffer = face->mVertexBuffer; + LLVertexBuffer *buffer = face->getVertexBuffer(); buffer->getVertexStrider(o_vertices, mesh->mFaceVertexOffset); buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset); const F32* weights = mesh->getWeights(); - const LLVector3* coords = mesh->getCoords(); - const LLVector3* normals = mesh->getNormals(); + const LLVector3* coords = (const LLVector3*)mesh->getCoords(); + const LLVector3* normals = (const LLVector3*)mesh->getNormals(); for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index) { if( weight != weights[index]) diff --git a/indra/newview/llviewerjointmesh_vec.cpp b/indra/newview/llviewerjointmesh_vec.cpp index c9371030ad..6600d01d17 100644 --- a/indra/newview/llviewerjointmesh_vec.cpp +++ b/indra/newview/llviewerjointmesh_vec.cpp @@ -46,6 +46,7 @@ // static void LLViewerJointMesh::updateGeometryVectorized(LLFace *face, LLPolyMesh *mesh) { +#if 0 static LLV4Matrix4 sJointMat[32]; LLDynamicArray<LLJointRenderData*>& joint_data = mesh->getReferenceMesh()->mJointRenderData; S32 j, joint_num, joint_end = joint_data.count(); @@ -92,4 +93,5 @@ void LLViewerJointMesh::updateGeometryVectorized(LLFace *face, LLPolyMesh *mesh) } buffer->setBuffer(0); +#endif } diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp index e1dd72dddc..fbf11f20db 100644 --- a/indra/newview/llviewerjoystick.cpp +++ b/indra/newview/llviewerjoystick.cpp @@ -758,7 +758,7 @@ void LLViewerJoystick::moveAvatar(bool reset) sDelta[RX_I] += (cur_delta[RX_I] - sDelta[RX_I]) * time * feather; sDelta[RY_I] += (cur_delta[RY_I] - sDelta[RY_I]) * time * feather; - handleRun(fsqrtf(sDelta[Z_I]*sDelta[Z_I] + sDelta[X_I]*sDelta[X_I])); + handleRun((F32) sqrt(sDelta[Z_I]*sDelta[Z_I] + sDelta[X_I]*sDelta[X_I])); // Allow forward/backward movement some priority if (dom_axis == Z_I) diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index bc326540e6..79c6c8db75 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -914,7 +914,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg) // Set the low priority size for downsampling to approximately the size the texture is displayed at. { - F32 approximate_interest_dimension = fsqrtf(pimpl->getInterest()); + F32 approximate_interest_dimension = (F32) sqrt(pimpl->getInterest()); pimpl->setLowPrioritySizeLimit(llround(approximate_interest_dimension)); } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index f5b9b533a5..36c14ca938 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -78,6 +78,7 @@ #include "llmoveview.h" #include "llparcel.h" #include "llrootview.h" +#include "llsceneview.h" #include "llselectmgr.h" #include "llsidetray.h" #include "llstatusbar.h" @@ -169,7 +170,6 @@ LLMenuItemCallGL* gBusyMenu = NULL; // Local prototypes // File Menu -const char* upload_pick(void* data); void handle_compress_image(void*); @@ -456,7 +456,7 @@ void init_menus() gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", upload_cost); gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", upload_cost); gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", upload_cost); - + gAFKMenu = gMenuBarView->getChild<LLMenuItemCallGL>("Set Away", TRUE); gBusyMenu = gMenuBarView->getChild<LLMenuItemCallGL>("Set Busy", TRUE); gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", TRUE); @@ -518,6 +518,11 @@ class LLAdvancedToggleConsole : public view_listener_t { toggle_visibility( (void*)gDebugView->mFastTimerView ); } + else if ("scene view" == console_type) + { + toggle_visibility( (void*)gSceneView); + } + #if MEM_TRACK_MEM else if ("memory view" == console_type) { @@ -553,6 +558,10 @@ class LLAdvancedCheckConsole : public view_listener_t { new_value = get_visibility( (void*)gDebugView->mFastTimerView ); } + else if ("scene view" == console_type) + { + new_value = get_visibility( (void*) gSceneView); + } #if MEM_TRACK_MEM else if ("memory view" == console_type) { @@ -700,7 +709,7 @@ U32 render_type_from_string(std::string render_type) { return LLPipeline::RENDER_TYPE_AVATAR; } - else if ("surfacePath" == render_type) + else if ("surfacePatch" == render_type) { return LLPipeline::RENDER_TYPE_TERRAIN; } @@ -904,6 +913,10 @@ U32 info_display_from_string(std::string 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; @@ -916,6 +929,10 @@ U32 info_display_from_string(std::string 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; @@ -948,6 +965,14 @@ U32 info_display_from_string(std::string info_display) { return LLPipeline::RENDER_DEBUG_FACE_AREA; } + else if ("lod info" == info_display) + { + return LLPipeline::RENDER_DEBUG_LOD_INFO; + } + else if ("build queue" == info_display) + { + return LLPipeline::RENDER_DEBUG_BUILD_QUEUE; + } else if ("lights" == info_display) { return LLPipeline::RENDER_DEBUG_LIGHTS; @@ -976,6 +1001,10 @@ U32 info_display_from_string(std::string info_display) { return LLPipeline::RENDER_DEBUG_AGENT_TARGET; } + else if ("sculpt" == info_display) + { + return LLPipeline::RENDER_DEBUG_SCULPTED; + } else { return 0; @@ -1908,19 +1937,20 @@ class LLAdvancedAgentPilot : public view_listener_t std::string command = userdata.asString(); if ("start playback" == command) { - LLAgentPilot::startPlayback(NULL); + gAgentPilot.setNumRuns(-1); + gAgentPilot.startPlayback(); } else if ("stop playback" == command) { - LLAgentPilot::stopPlayback(NULL); + gAgentPilot.stopPlayback(); } else if ("start record" == command) { - LLAgentPilot::startRecord(NULL); + gAgentPilot.startRecord(); } else if ("stop record" == command) { - LLAgentPilot::saveRecord(NULL); + gAgentPilot.stopRecord(); } return true; @@ -1938,7 +1968,7 @@ class LLAdvancedToggleAgentPilotLoop : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLAgentPilot::sLoop = !(LLAgentPilot::sLoop); + gAgentPilot.setLoop(!gAgentPilot.getLoop()); return true; } }; @@ -1947,7 +1977,7 @@ class LLAdvancedCheckAgentPilotLoop : public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = LLAgentPilot::sLoop; + bool new_value = gAgentPilot.getLoop(); return new_value; } }; @@ -2075,7 +2105,7 @@ class LLAdvancedEnableRenderDeferred: public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = gSavedSettings.getBOOL("RenderUseFBO") && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT > 0) && + bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0; return new_value; } @@ -2088,7 +2118,8 @@ class LLAdvancedEnableRenderDeferredOptions: public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = gSavedSettings.getBOOL("RenderUseFBO") && gSavedSettings.getBOOL("RenderDeferred"); + bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 && + LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0 && gSavedSettings.getBOOL("RenderDeferred"); return new_value; } }; diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 2cf8dbec89..37640ad0d4 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -34,6 +34,7 @@ #include "llfilepicker.h" #include "llfloaterreg.h" #include "llbuycurrencyhtml.h" +#include "llfloatermodelpreview.h" #include "llfloatersnapshot.h" #include "llimage.h" #include "llimagebmp.h" @@ -52,13 +53,14 @@ #include "llvfs.h" #include "llviewerinventory.h" #include "llviewermenu.h" // gMenuHolder +#include "llviewerparcelmgr.h" #include "llviewerregion.h" #include "llviewerstats.h" #include "llviewerwindow.h" #include "llappviewer.h" #include "lluploaddialog.h" #include "lltrans.h" - +#include "llfloaterbuycurrency.h" // linden libraries #include "llassetuploadresponders.h" @@ -66,6 +68,7 @@ #include "llhttpclient.h" #include "llnotificationsutil.h" #include "llsdserialize.h" +#include "llsdutil.h" #include "llstring.h" #include "lltransactiontypes.h" #include "lluuid.h" @@ -84,6 +87,99 @@ class LLFileEnableUpload : public view_listener_t } }; +class LLFileEnableUploadModel : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + return true; + } +}; + +class LLMeshEnabled : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + return gSavedSettings.getBOOL("MeshEnabled"); + } +}; + +class LLMeshUploadVisible : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + return gSavedSettings.getBOOL("MeshEnabled") && + LLViewerParcelMgr::getInstance()->allowAgentBuild() && + !gAgent.getRegion()->getCapability("ObjectAdd").empty(); + } +}; + +LLMutex* LLFilePickerThread::sMutex = NULL; +std::queue<LLFilePickerThread*> LLFilePickerThread::sDeadQ; + +void LLFilePickerThread::getFile() +{ +#if LL_WINDOWS + start(); +#else + run(); +#endif +} + +//virtual +void LLFilePickerThread::run() +{ + LLFilePicker picker; +#if LL_WINDOWS + if (picker.getOpenFile(mFilter, false)) + { + mFile = picker.getFirstFile(); + } +#else + if (picker.getOpenFile(mFilter, true)) + { + mFile = picker.getFirstFile(); + } +#endif + + { + LLMutexLock lock(sMutex); + sDeadQ.push(this); + } + +} + +//static +void LLFilePickerThread::initClass() +{ + sMutex = new LLMutex(NULL); +} + +//static +void LLFilePickerThread::cleanupClass() +{ + 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->mFile); + delete thread; + sDeadQ.pop(); + } + } +} + + //============================================================================ #if LL_WINDOWS @@ -97,6 +193,7 @@ static std::string XML_EXTENSIONS = "xml"; static std::string SLOBJECT_EXTENSIONS = "slobject"; #endif static std::string ALL_FILE_EXTENSIONS = "*.*"; +static std::string MODEL_EXTENSIONS = "dae"; std::string build_extensions_string(LLFilePicker::ELoadFilter filter) { @@ -111,6 +208,8 @@ std::string build_extensions_string(LLFilePicker::ELoadFilter filter) return ANIM_EXTENSIONS; case LLFilePicker::FFLOAD_SLOBJECT: return SLOBJECT_EXTENSIONS; + case LLFilePicker::FFLOAD_MODEL: + return MODEL_EXTENSIONS; #ifdef _CORY_TESTING case LLFilePicker::FFLOAD_GEOMETRY: return GEOMETRY_EXTENSIONS; @@ -254,6 +353,20 @@ class LLFileUploadImage : public view_listener_t } }; +class LLFileUploadModel : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) LLFloaterReg::getInstance("upload_model"); + if (fmp) + { + fmp->loadModel(3); + } + + return TRUE; + } +}; + class LLFileUploadSound : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -315,10 +428,21 @@ class LLFileUploadBulk : public view_listener_t LLAssetStorage::LLStoreAssetCallback callback = NULL; S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); void *userdata = NULL; - upload_new_resource(filename, asset_name, asset_name, 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE, - LLFloaterPerms::getNextOwnerPerms(), LLFloaterPerms::getGroupPerms(), LLFloaterPerms::getEveryonePerms(), - display_name, - callback, expected_upload_cost, userdata); + + upload_new_resource( + filename, + asset_name, + asset_name, + 0, + LLFolderType::FT_NONE, + LLInventoryType::IT_NONE, + LLFloaterPerms::getNextOwnerPerms(), + LLFloaterPerms::getGroupPerms(), + LLFloaterPerms::getEveryonePerms(), + display_name, + callback, + expected_upload_cost, + userdata); // *NOTE: Ew, we don't iterate over the file list here, // we handle the next files in upload_done_callback() @@ -473,17 +597,20 @@ void handle_compress_image(void*) } } -void 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) +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) { // Generate the temporary UUID. std::string filename = gDirUtilp->getTempFilename(); @@ -509,7 +636,7 @@ void upload_new_resource(const std::string& src_filename, std::string name, short_name.c_str()); args["FILE"] = short_name; upload_error(error_message, "NoFileExtension", filename, args); - return; + return LLUUID(); } else if (codec != IMG_CODEC_INVALID) { @@ -522,7 +649,7 @@ void upload_new_resource(const std::string& src_filename, std::string name, args["FILE"] = src_filename; args["ERROR"] = LLImage::getLastError(); upload_error(error_message, "ProblemWithFile", filename, args); - return; + return LLUUID(); } } else if(exten == "wav") @@ -550,7 +677,7 @@ void upload_new_resource(const std::string& src_filename, std::string name, upload_error(error_message, "UnknownVorbisEncodeFailure", filename, args); break; } - return; + return LLUUID(); } } else if(exten == "tmp") @@ -590,7 +717,7 @@ void upload_new_resource(const std::string& src_filename, std::string name, error_message = llformat("corrupt resource file: %s", src_filename.c_str()); args["FILE"] = src_filename; upload_error(error_message, "CorruptResourceFile", filename, args); - return; + return LLUUID(); } if (2 == tokens_read) @@ -618,7 +745,7 @@ void upload_new_resource(const std::string& src_filename, std::string name, error_message = llformat("unknown linden resource file version in file: %s", src_filename.c_str()); args["FILE"] = src_filename; upload_error(error_message, "UnknownResourceFileVersion", filename, args); - return; + return LLUUID(); } } else @@ -660,7 +787,7 @@ void upload_new_resource(const std::string& src_filename, std::string name, error_message = llformat( "Unable to create output file: %s", filename.c_str()); args["FILE"] = filename; upload_error(error_message, "UnableToCreateOutputFile", filename, args); - return; + return LLUUID(); } fclose(in); @@ -674,7 +801,7 @@ void upload_new_resource(const std::string& src_filename, std::string name, { error_message = llformat("We do not currently support bulk upload of animation files\n"); upload_error(error_message, "DoNotSupportBulkAnimationUpload", filename, args); - return; + return LLUUID(); } else { @@ -720,9 +847,21 @@ void upload_new_resource(const std::string& src_filename, std::string name, { t_disp_name = src_filename; } - upload_new_resource(tid, asset_type, name, desc, compression_info, // tid - destination_folder_type, inv_type, next_owner_perms, group_perms, everyone_perms, - display_name, callback, expected_upload_cost, userdata); + upload_new_resource( + tid, + asset_type, + name, + desc, + compression_info, // tid + destination_folder_type, + inv_type, + next_owner_perms, + group_perms, + everyone_perms, + display_name, + callback, + expected_upload_cost, + userdata); } else { @@ -736,9 +875,15 @@ void upload_new_resource(const std::string& src_filename, std::string name, } LLFilePicker::instance().reset(); } + + return uuid; } -void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExtStat ext_status) // StoreAssetData callback (fixed) +void upload_done_callback( + 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; @@ -843,35 +988,102 @@ void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExt std::string display_name = LLStringUtil::null; LLAssetStorage::LLStoreAssetCallback callback = NULL; void *userdata = NULL; - upload_new_resource(next_file, asset_name, asset_name, // file - 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE, - PERM_NONE, PERM_NONE, PERM_NONE, - 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); + upload_new_resource( + next_file, + asset_name, + asset_name, // file + 0, + LLFolderType::FT_NONE, + LLInventoryType::IT_NONE, + PERM_NONE, + PERM_NONE, + PERM_NONE, + 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(const LLTransactionID &tid, LLAssetType::EType asset_type, - 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) +static LLAssetID upload_new_resource_prep( + const LLTransactionID& tid, + LLAssetType::EType asset_type, + LLInventoryType::EType& inventory_type, + std::string& name, + const std::string& display_name, + std::string& description) +{ + LLAssetID uuid = generate_asset_id_for_new_upload(tid); + + increase_new_upload_stats(asset_type); + + assign_defaults_and_show_upload_message( + asset_type, + inventory_type, + name, + display_name, + description); + + return uuid; +} + +LLSD generate_new_resource_upload_capability_body( + LLAssetType::EType asset_type, + const std::string& name, + const std::string& desc, + LLFolderType::EType destination_folder_type, + LLInventoryType::EType inv_type, + U32 next_owner_perms, + U32 group_perms, + U32 everyone_perms) +{ + LLSD body; + + body["folder_id"] = gInventory.findCategoryUUIDForType( + (destination_folder_type == LLFolderType::FT_NONE) ? + (LLFolderType::EType) asset_type : + destination_folder_type); + + body["asset_type"] = LLAssetType::lookup(asset_type); + body["inventory_type"] = LLInventoryType::lookup(inv_type); + body["name"] = name; + body["description"] = desc; + body["next_owner_mask"] = LLSD::Integer(next_owner_perms); + body["group_mask"] = LLSD::Integer(group_perms); + body["everyone_mask"] = LLSD::Integer(everyone_perms); + + return body; +} + +void upload_new_resource( + const LLTransactionID &tid, + LLAssetType::EType asset_type, + 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) { if(gDisconnected) { return ; } - - LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID()); + + LLAssetID uuid = + upload_new_resource_prep( + tid, + asset_type, + inv_type, + name, + display_name, + desc); if( LLAssetType::AT_SOUND == asset_type ) { @@ -916,26 +1128,32 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty llinfos << "Expected Upload Cost: " << expected_upload_cost << llendl; lldebugs << "Folder: " << gInventory.findCategoryUUIDForType((destination_folder_type == LLFolderType::FT_NONE) ? LLFolderType::assetTypeToFolderType(asset_type) : destination_folder_type) << llendl; lldebugs << "Asset Type: " << LLAssetType::lookup(asset_type) << llendl; - std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory"); - if (!url.empty()) + + std::string url = gAgent.getRegion()->getCapability( + "NewFileAgentInventory"); + + if ( !url.empty() ) { llinfos << "New Agent Inventory via capability" << llendl; - LLSD body; - body["folder_id"] = gInventory.findCategoryUUIDForType((destination_folder_type == LLFolderType::FT_NONE) ? LLFolderType::assetTypeToFolderType(asset_type) : destination_folder_type); - body["asset_type"] = LLAssetType::lookup(asset_type); - body["inventory_type"] = LLInventoryType::lookup(inv_type); - body["name"] = name; - body["description"] = desc; - body["next_owner_mask"] = LLSD::Integer(next_owner_perms); - body["group_mask"] = LLSD::Integer(group_perms); - body["everyone_mask"] = LLSD::Integer(everyone_perms); - body["expected_upload_cost"] = LLSD::Integer(expected_upload_cost); - - //std::ostringstream llsdxml; - //LLSDSerialize::toPrettyXML(body, llsdxml); - //llinfos << "posting body to capability: " << llsdxml.str() << llendl; - LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, uuid, asset_type)); + LLSD body; + body = generate_new_resource_upload_capability_body( + asset_type, + name, + desc, + destination_folder_type, + inv_type, + next_owner_perms, + group_perms, + everyone_perms); + + LLHTTPClient::post( + url, + body, + new LLNewAgentInventoryResponder( + body, + uuid, + asset_type)); } else { @@ -949,10 +1167,10 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty S32 balance = gStatusBar->getBalance(); if (balance < expected_upload_cost) { + // insufficient funds, bail on this upload LLStringUtil::format_map_t args; args["NAME"] = name; args["AMOUNT"] = llformat("%d", expected_upload_cost); - // insufficient funds, bail on this upload LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("UploadingCosts", args), expected_upload_cost ); return; } @@ -976,18 +1194,157 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty { asset_callback = callback; } - gAssetStorage->storeAssetData(data->mAssetInfo.mTransactionID, data->mAssetInfo.mType, - asset_callback, - (void*)data, - FALSE); + gAssetStorage->storeAssetData( + data->mAssetInfo.mTransactionID, + data->mAssetInfo.mType, + asset_callback, + (void*)data, + FALSE); + } +} + +BOOL upload_new_variable_price_resource( + const LLTransactionID &tid, + LLAssetType::EType asset_type, + std::string name, + std::string desc, + LLFolderType::EType destination_folder_type, + LLInventoryType::EType inv_type, + U32 next_owner_perms, + U32 group_perms, + U32 everyone_perms, + const std::string& display_name, + const LLSD& asset_resources) +{ + LLAssetID uuid = + upload_new_resource_prep( + tid, + asset_type, + inv_type, + name, + display_name, + desc); + + llinfos << "*** Uploading: " << llendl; + llinfos << "Type: " << LLAssetType::lookup(asset_type) << llendl; + llinfos << "UUID: " << uuid << llendl; + llinfos << "Name: " << name << llendl; + llinfos << "Desc: " << desc << llendl; + lldebugs << "Folder: " + << gInventory.findCategoryUUIDForType((destination_folder_type == LLFolderType::FT_NONE) ? (LLFolderType::EType)asset_type : destination_folder_type) << llendl; + lldebugs << "Asset Type: " << LLAssetType::lookup(asset_type) << llendl; + + std::string url = gAgent.getRegion()->getCapability( + "NewFileAgentInventoryVariablePrice"); + + if ( !url.empty() ) + { + lldebugs + << "New Agent Inventory variable price upload" << llendl; + + // Each of the two capabilities has similar data, so + // let's reuse that code + + LLSD body; + + body = generate_new_resource_upload_capability_body( + asset_type, + name, + desc, + destination_folder_type, + inv_type, + next_owner_perms, + group_perms, + everyone_perms); + + body["asset_resources"] = asset_resources; + + LLHTTPClient::post( + url, + body, + new LLNewAgentInventoryVariablePriceResponder( + uuid, + asset_type, + body)); + + return TRUE; + } + else + { + return FALSE; + } +} + +LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid) +{ + if ( gDisconnected ) + { + LLAssetID rv; + + rv.setNull(); + return rv; + } + + LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID()); + + return uuid; +} + +void increase_new_upload_stats(LLAssetType::EType asset_type) +{ + if ( LLAssetType::AT_SOUND == asset_type ) + { + LLViewerStats::getInstance()->incStat( + LLViewerStats::ST_UPLOAD_SOUND_COUNT ); + } + else if ( LLAssetType::AT_TEXTURE == asset_type ) + { + LLViewerStats::getInstance()->incStat( + LLViewerStats::ST_UPLOAD_TEXTURE_COUNT ); + } + else if ( LLAssetType::AT_ANIMATION == asset_type ) + { + LLViewerStats::getInstance()->incStat( + LLViewerStats::ST_UPLOAD_ANIM_COUNT ); + } +} + +void assign_defaults_and_show_upload_message( + LLAssetType::EType asset_type, + LLInventoryType::EType& inventory_type, + std::string& name, + const std::string& display_name, + std::string& description) +{ + if ( LLInventoryType::IT_NONE == inventory_type ) + { + inventory_type = LLInventoryType::defaultForAssetType(asset_type); + } + LLStringUtil::stripNonprintable(name); + LLStringUtil::stripNonprintable(description); + + if ( name.empty() ) + { + name = "(No Name)"; + } + if ( description.empty() ) + { + description = "(No Description)"; } + + // At this point, we're ready for the upload. + std::string upload_message = "Uploading...\n\n"; + upload_message.append(display_name); + LLUploadDialog::modalUploadDialog(upload_message); } + 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 LLFileUploadBulk(), "File.UploadBulk"); view_listener_t::addCommit(new LLFileCloseWindow(), "File.CloseWindow"); view_listener_t::addCommit(new LLFileCloseAllWindows(), "File.CloseAllWindows"); @@ -997,6 +1354,9 @@ void init_menu_file() 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::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. } diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h index 56b9e19049..1597821504 100644 --- a/indra/newview/llviewermenufile.h +++ b/indra/newview/llviewermenufile.h @@ -30,39 +30,118 @@ #include "llfoldertype.h" #include "llassetstorage.h" #include "llinventorytype.h" +#include "llfilepicker.h" class LLTransactionID; void init_menu_file(); -void 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); - -void upload_new_resource(const LLTransactionID &tid, - LLAssetType::EType type, - 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); +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); + +void upload_new_resource( + const LLTransactionID &tid, + LLAssetType::EType type, + 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); + +// TODO* : Move all uploads to use this new function +// since at some point, that upload path will be deprecated and no longer +// used + +// We make a new function here to ensure that previous code is not broken +BOOL upload_new_variable_price_resource( + const LLTransactionID& tid, + LLAssetType::EType type, + std::string name, + std::string desc, + LLFolderType::EType destination_folder_type, + LLInventoryType::EType inv_type, + U32 next_owner_perms, + U32 group_perms, + U32 everyone_perms, + const std::string& display_name, + const LLSD& asset_resources); + +LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid); +void increase_new_upload_stats(LLAssetType::EType asset_type); +void assign_defaults_and_show_upload_message( + LLAssetType::EType asset_type, + LLInventoryType::EType& inventory_type, + std::string& name, + const std::string& display_name, + std::string& description); + +LLSD generate_new_resource_upload_capability_body( + LLAssetType::EType asset_type, + const std::string& name, + const std::string& desc, + LLFolderType::EType destination_folder_type, + LLInventoryType::EType inv_type, + U32 next_owner_perms, + U32 group_perms, + U32 everyone_perms); + +void on_new_single_inventory_upload_complete( + LLAssetType::EType asset_type, + LLInventoryType::EType inventory_type, + const std::string inventory_type_string, + const LLUUID& item_folder_id, + const std::string& item_name, + const std::string& item_description, + const LLSD& server_response, + S32 upload_price); + +class LLFilePickerThread : public LLThread +{ //multi-threaded file picker (runs system specific file picker in background and calls "notify" from main thread) +public: + + static std::queue<LLFilePickerThread*> sDeadQ; + static LLMutex* sMutex; + + static void initClass(); + static void cleanupClass(); + static void clearDead(); + + std::string mFile; + + LLFilePicker::ELoadFilter mFilter; + + LLFilePickerThread(LLFilePicker::ELoadFilter filter) + : LLThread("file picker"), mFilter(filter) + { + + } + + void getFile(); + + virtual void run(); + + virtual void notify(const std::string& filename) = 0; +}; + #endif diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 298e789f65..fdd1199b78 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -2603,6 +2603,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) args["NAME"] = LLSLURL("agent", from_id, "completename").getSLURLString();; LLSD payload; payload["from_id"] = from_id; + // Passing the "SESSION_NAME" to use it for IM notification logging + // in LLTipHandler::processNotification(). See STORM-941. + payload["SESSION_NAME"] = name; LLNotificationsUtil::add("InventoryAccepted", args, payload); break; } @@ -2802,7 +2805,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) { LLVector3 pos, look_at; U64 region_handle; - U8 region_access = SIM_ACCESS_MIN; + U8 region_access; std::string region_info = ll_safe_string((char*)binary_bucket, binary_bucket_size); std::string region_access_str = LLStringUtil::null; std::string region_access_icn = LLStringUtil::null; @@ -5373,10 +5376,10 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem) { // notification was specified using the new mechanism, so we can just handle it here std::string notificationID; - msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, notificationID);
- if (!LLNotifications::getInstance()->templateExists(notificationID))
- {
- return false;
+ msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, notificationID); + if (!LLNotifications::getInstance()->templateExists(notificationID)) + { + return false; } std::string llsdRaw; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index e8828e63a9..6d493bfcd5 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -47,6 +47,7 @@ #include "llprimitive.h" #include "llquantize.h" #include "llregionhandle.h" +#include "llsdserialize.h" #include "lltree_common.h" #include "llxfermanager.h" #include "message.h" @@ -62,6 +63,7 @@ #include "lldrawable.h" #include "llface.h" #include "llfloaterproperties.h" +#include "llfloatertools.h" #include "llfollowcam.h" #include "llhudtext.h" #include "llselectmgr.h" @@ -202,6 +204,11 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mGLName(0), mbCanSelect(TRUE), mFlags(0), + mPhysicsShapeType(0), + mPhysicsGravity(0), + mPhysicsFriction(0), + mPhysicsDensity(0), + mPhysicsRestitution(0), mDrawable(), mCreateSelected(FALSE), mRenderMedia(FALSE), @@ -233,6 +240,12 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mState(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) @@ -845,6 +858,13 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, #ifdef DEBUG_UPDATE_TYPE llinfos << "Full:" << getID() << llendl; #endif + //clear cost and linkset cost + mCostStale = true; + if (isSelected()) + { + gFloaterTools->dirty(); + } + LLUUID audio_uuid; LLUUID owner_id; // only valid if audio_uuid or particle system is not null F32 gain; @@ -1410,6 +1430,13 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, #ifdef DEBUG_UPDATE_TYPE llinfos << "CompFull:" << getID() << llendl; #endif + mCostStale = true; + + if (isSelected()) + { + gFloaterTools->dirty(); + } + dp->unpackU32(crc, "CRC"); mTotalCRC = crc; dp->unpackU8(material, "Material"); @@ -3014,21 +3041,126 @@ void LLViewerObject::setScale(const LLVector3 &scale, BOOL damped) } } -void LLViewerObject::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax) +void LLViewerObject::setObjectCost(F32 cost) { - LLVector3 center = getRenderPosition(); - LLVector3 size = getScale(); - newMin.setVec(center-size); - newMax.setVec(center+size); - mDrawable->setPositionGroup((newMin + newMax) * 0.5f); + mObjectCost = cost; + mCostStale = false; + + if (isSelected()) + { + gFloaterTools->dirty(); + } +} + +void LLViewerObject::setLinksetCost(F32 cost) +{ + mLinksetCost = cost; + mCostStale = false; + + if (isSelected()) + { + gFloaterTools->dirty(); + } +} + +void LLViewerObject::setPhysicsCost(F32 cost) +{ + mPhysicsCost = cost; + mCostStale = false; + + if (isSelected()) + { + gFloaterTools->dirty(); + } +} + +void LLViewerObject::setLinksetPhysicsCost(F32 cost) +{ + mLinksetPhysicsCost = cost; + mCostStale = false; + + if (isSelected()) + { + gFloaterTools->dirty(); + } +} + + +F32 LLViewerObject::getObjectCost() +{ + if (mCostStale) + { + gObjectList.updateObjectCost(this); + } + + return mObjectCost; +} + +F32 LLViewerObject::getLinksetCost() +{ + if (mCostStale) + { + gObjectList.updateObjectCost(this); + } + + return mLinksetCost; +} + +F32 LLViewerObject::getPhysicsCost() +{ + if (mCostStale) + { + gObjectList.updateObjectCost(this); + } + + return mPhysicsCost; +} + +F32 LLViewerObject::getLinksetPhysicsCost() +{ + if (mCostStale) + { + gObjectList.updateObjectCost(this); + } + + return mLinksetPhysicsCost; +} + +F32 LLViewerObject::getStreamingCost(S32* bytes, S32* visible_bytes) +{ + return 0.f; +} + +U32 LLViewerObject::getTriangleCount() +{ + return 0; +} + +U32 LLViewerObject::getHighLODTriangleCount() +{ + return 0; +} + +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); } F32 LLViewerObject::getBinRadius() { if (mDrawable.notNull()) { - const LLVector3* ext = mDrawable->getSpatialExtents(); - return (ext[1]-ext[0]).magVec(); + const LLVector4a* ext = mDrawable->getSpatialExtents(); + LLVector4a diff; + diff.setSub(ext[1], ext[0]); + return diff.getLength3().getF32(); } return getScale().magVec(); @@ -3094,7 +3226,7 @@ void LLViewerObject::boostTexturePriority(BOOL boost_children /* = TRUE */) getTEImage(i)->setBoostLevel(LLViewerTexture::BOOST_SELECTED); } - if (isSculpted()) + if (isSculpted() && !isMesh()) { LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); LLUUID sculpt_id = sculpt_params->getSculptTexture(); @@ -3334,6 +3466,15 @@ const LLVector3 LLViewerObject::getPositionEdit() const const LLVector3 LLViewerObject::getRenderPosition() const { + if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED)) + { + LLVOAvatar* avatar = getAvatar(); + if (avatar) + { + return avatar->getPositionAgent(); + } + } + if (mDrawable.isNull() || mDrawable->getGeneration() < 0) { return getPositionAgent(); @@ -3352,6 +3493,11 @@ const LLVector3 LLViewerObject::getPivotPositionAgent() const const LLQuaternion LLViewerObject::getRenderRotation() const { LLQuaternion ret; + if (mDrawable.notNull() && mDrawable->isState(LLDrawable::RIGGED)) + { + return ret; + } + if (mDrawable.isNull() || mDrawable->isStatic()) { ret = getRotationEdit(); @@ -3620,12 +3766,21 @@ BOOL LLViewerObject::lineSegmentBoundingBox(const LLVector3& start, const LLVect return FALSE; } - const LLVector3* ext = mDrawable->getSpatialExtents(); + const LLVector4a* ext = mDrawable->getSpatialExtents(); - LLVector3 center = (ext[1]+ext[0])*0.5f; - LLVector3 size = (ext[1]-ext[0])*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); + LLVector4a starta, enda; + starta.load3(start.mV); + enda.load3(end.mV); + + return LLLineSegmentBoxIntersect(starta, enda, center, size); } U8 LLViewerObject::getMediaType() const @@ -5140,6 +5295,12 @@ void LLViewerObject::updateFlags() gMessageSystem->addBOOL("IsTemporary", flagTemporaryOnRez() ); gMessageSystem->addBOOL("IsPhantom", flagPhantom() ); gMessageSystem->addBOOL("CastsShadows", flagCastShadows() ); + 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() ); } @@ -5172,6 +5333,44 @@ BOOL LLViewerObject::setFlags(U32 flags, BOOL state) return setit; } +void LLViewerObject::setPhysicsShapeType(U8 type) +{ + mPhysicsShapeUnknown = false; + mPhysicsShapeType = type; + mCostStale = true; +} + +void LLViewerObject::setPhysicsGravity(F32 gravity) +{ + mPhysicsGravity = gravity; +} + +void LLViewerObject::setPhysicsFriction(F32 friction) +{ + mPhysicsFriction = friction; +} + +void LLViewerObject::setPhysicsDensity(F32 density) +{ + mPhysicsDensity = density; +} + +void LLViewerObject::setPhysicsRestitution(F32 restitution) +{ + mPhysicsRestitution = restitution; +} + +U8 LLViewerObject::getPhysicsShapeType() const +{ + if (mPhysicsShapeUnknown) + { + mPhysicsShapeUnknown = false; + gObjectList.updatePhysicsFlags(this); + } + + return mPhysicsShapeType; +} + void LLViewerObject::applyAngularVelocity(F32 dt) { //do target omega here @@ -5428,3 +5627,75 @@ const LLUUID &LLViewerObject::extractAttachmentItemID() setAttachmentItemID(item_id); return getAttachmentItemID(); } + +//virtual +LLVOAvatar* LLViewerObject::getAvatar() const +{ + if (isAttachment()) + { + LLViewerObject* vobj = (LLViewerObject*) getParent(); + + while (vobj && !vobj->asAvatar()) + { + vobj = (LLViewerObject*) vobj->getParent(); + } + + return (LLVOAvatar*) vobj; + } + + return NULL; +} + + +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(); + }; +}; + +LLHTTPRegistration<ObjectPhysicsProperties> + gHTTPRegistrationObjectPhysicsProperties("/message/ObjectPhysicsProperties"); diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 7afb7f464b..e417343bec 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -176,6 +176,7 @@ public: void setOnActiveList(BOOL on_active) { mOnActiveList = on_active; } virtual BOOL isAttachment() const { return FALSE; } + virtual LLVOAvatar* getAvatar() const; //get the avatar this object is attached to, or NULL if object is not an attachment virtual BOOL isHUDAttachment() const { return FALSE; } virtual void updateRadius() {}; virtual F32 getVObjRadius() const; // default implemenation is mDrawable->getRadius() @@ -224,6 +225,7 @@ public: virtual BOOL isFlexible() const { return FALSE; } virtual BOOL isSculpted() const { return FALSE; } + virtual BOOL isMesh() const { return FALSE; } virtual BOOL hasLightTexture() const { return FALSE; } // This method returns true if the object is over land owned by @@ -324,6 +326,22 @@ public: virtual void setScale(const LLVector3 &scale, BOOL damped = FALSE); + virtual F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL); + virtual U32 getTriangleCount(); + virtual U32 getHighLODTriangleCount(); + + 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 getState() { return mState; } @@ -363,7 +381,7 @@ public: void markForUpdate(BOOL priority); void updateVolume(const LLVolumeParams& volume_params); - virtual void updateSpatialExtents(LLVector3& min, LLVector3& max); + virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max); virtual F32 getBinRadius(); LLBBox getBoundingBoxAgent() const; @@ -376,7 +394,7 @@ public: void clearDrawableState(U32 state, BOOL recursive = TRUE); // Called when the drawable shifts - virtual void onShift(const LLVector3 &shift_vector) { } + virtual void onShift(const LLVector4a &shift_vector) { } ////////////////////////////////////// // @@ -451,6 +469,12 @@ public: inline BOOL flagCameraDecoupled() const { return ((mFlags & FLAGS_CAMERA_DECOUPLED) != 0); } inline BOOL flagObjectMove() const { return ((mFlags & FLAGS_OBJECT_MOVE) != 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 getIncludeInSearch() const; void setIncludeInSearch(bool include_in_search); @@ -466,6 +490,11 @@ public: void updateFlags(); BOOL setFlags(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; } @@ -530,6 +559,13 @@ public: 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; // unique within region, not unique across regions @@ -548,6 +584,14 @@ public: // Grabbed from UPDATE_FLAGS U32 mFlags; + // Sent to sim in UPDATE_FLAGS, received in ObjectPhysicsProperties + U8 mPhysicsShapeType; + F32 mPhysicsGravity; + F32 mPhysicsFriction; + F32 mPhysicsDensity; + F32 mPhysicsRestitution; + + // Pipeline classes LLPointer<LLDrawable> mDrawable; @@ -656,6 +700,13 @@ protected: U8 mState; // legacy 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; + + bool mCostStale; + mutable bool mPhysicsShapeUnknown; static U32 sNumZombieObjects; // Objects which are dead, but not deleted diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index da95bacc41..ab2e07e4df 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -54,6 +54,7 @@ #include "llviewercamera.h" #include "llselectmgr.h" #include "llresmgr.h" +#include "llsdutil.h" #include "llviewerregion.h" #include "llviewerstats.h" #include "llviewerstatsrecorder.h" @@ -692,6 +693,189 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent) LLVOAvatar::cullAvatarsByPixelArea(); } +class LLObjectCostResponder : public LLCurl::Responder +{ +public: + LLObjectCostResponder(const LLSD& object_ids) + : mObjectIDs(object_ids) + { + } + + // Clear's the global object list's pending + // request list for all objects requested + void clear_object_list_pending_requests() + { + // TODO*: No more hard coding + for ( + LLSD::array_iterator iter = mObjectIDs.beginArray(); + iter != mObjectIDs.endArray(); + ++iter) + { + gObjectList.onObjectCostFetchFailure(iter->asUUID()); + } + } + + void error(U32 statusNum, const std::string& reason) + { + llwarns + << "Transport error requesting object cost " + << "HTTP status: " << statusNum << ", reason: " + << reason << "." << llendl; + + // TODO*: Error message to user + // For now just clear the request from the pending list + clear_object_list_pending_requests(); + } + + void result(const LLSD& content) + { + if ( !content.isMap() || content.has("error") ) + { + // Improper response or the request had an error, + // show an error to the user? + llwarns + << "Application level error when fetching object " + << "cost. Message: " << content["error"]["message"].asString() + << ", identifier: " << content["error"]["identifier"].asString() + << llendl; + + // TODO*: Adaptively adjust request size if the + // service says we've requested too many and retry + + // TODO*: Error message if not retrying + clear_object_list_pending_requests(); + return; + } + + // Success, grab the resource cost and linked set costs + // for an object if one was returned + for ( + LLSD::array_iterator iter = mObjectIDs.beginArray(); + iter != mObjectIDs.endArray(); + ++iter) + { + LLUUID object_id = iter->asUUID(); + + // Check to see if the request contains data for the object + if ( content.has(iter->asString()) ) + { + F32 link_cost = + content[iter->asString()]["linked_set_resource_cost"].asReal(); + F32 object_cost = + content[iter->asString()]["resource_cost"].asReal(); + + F32 physics_cost = content[iter->asString()]["physics_cost"].asReal(); + F32 link_physics_cost = content[iter->asString()]["linked_set_physics_cost"].asReal(); + + gObjectList.updateObjectCost(object_id, object_cost, link_cost, physics_cost, link_physics_cost); + } + else + { + // TODO*: Give user feedback about the missing data? + gObjectList.onObjectCostFetchFailure(object_id); + } + } + } + +private: + LLSD mObjectIDs; +}; + + +class LLPhysicsFlagsResponder : public LLCurl::Responder +{ +public: + LLPhysicsFlagsResponder(const LLSD& object_ids) + : mObjectIDs(object_ids) + { + } + + // Clear's the global object list's pending + // request list for all objects requested + void clear_object_list_pending_requests() + { + // TODO*: No more hard coding + for ( + LLSD::array_iterator iter = mObjectIDs.beginArray(); + iter != mObjectIDs.endArray(); + ++iter) + { + gObjectList.onPhysicsFlagsFetchFailure(iter->asUUID()); + } + } + + void error(U32 statusNum, const std::string& reason) + { + llwarns + << "Transport error requesting object physics flags " + << "HTTP status: " << statusNum << ", reason: " + << reason << "." << llendl; + + // TODO*: Error message to user + // For now just clear the request from the pending list + clear_object_list_pending_requests(); + } + + void result(const LLSD& content) + { + if ( !content.isMap() || content.has("error") ) + { + // Improper response or the request had an error, + // show an error to the user? + llwarns + << "Application level error when fetching object " + << "physics flags. Message: " << content["error"]["message"].asString() + << ", identifier: " << content["error"]["identifier"].asString() + << llendl; + + // TODO*: Adaptively adjust request size if the + // service says we've requested too many and retry + + // TODO*: Error message if not retrying + clear_object_list_pending_requests(); + return; + } + + // Success, grab the resource cost and linked set costs + // for an object if one was returned + for ( + LLSD::array_iterator iter = mObjectIDs.beginArray(); + iter != mObjectIDs.endArray(); + ++iter) + { + LLUUID object_id = iter->asUUID(); + + // Check to see if the request contains data for the object + if ( content.has(iter->asString()) ) + { + const LLSD& data = content[iter->asString()]; + + S32 shape_type = data["PhysicsShapeType"].asInteger(); + + gObjectList.updatePhysicsShapeType(object_id, shape_type); + + if (data.has("Density")) + { + F32 density = data["Density"].asReal(); + F32 friction = data["Friction"].asReal(); + F32 restitution = data["Restitution"].asReal(); + F32 gravity_multiplier = data["GravityMultiplier"].asReal(); + + gObjectList.updatePhysicsProperties(object_id, + density, friction, restitution, gravity_multiplier); + } + } + else + { + // TODO*: Give user feedback about the missing data? + gObjectList.onPhysicsFlagsFetchFailure(object_id); + } + } + } + +private: + LLSD mObjectIDs; +}; void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) { @@ -804,6 +988,9 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) } } + fetchObjectCosts(); + fetchPhysicsFlags(); + mNumSizeCulled = 0; mNumVisCulled = 0; @@ -869,6 +1056,119 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) LLViewerStats::getInstance()->mNumVisCulledStat.addValue(mNumVisCulled); } +void LLViewerObjectList::fetchObjectCosts() +{ + // issue http request for stale object physics costs + if (!mStaleObjectCost.empty()) + { + LLViewerRegion* regionp = gAgent.getRegion(); + + if (regionp) + { + std::string url = regionp->getCapability("GetObjectCost"); + + if (!url.empty()) + { + LLSD id_list; + U32 object_index = 0; + + for ( + std::set<LLUUID>::iterator iter = mStaleObjectCost.begin(); + iter != mStaleObjectCost.end(); + ++iter) + { + // Check to see if a request for this object + // has already been made. + if ( mPendingObjectCost.find(*iter) == + mPendingObjectCost.end() ) + { + mPendingObjectCost.insert(*iter); + id_list[object_index++] = *iter; + } + } + + // id_list should now contain all + // requests in mStaleObjectCost before, so clear + // it now + mStaleObjectCost.clear(); + + if ( id_list.size() > 0 ) + { + LLSD post_data = LLSD::emptyMap(); + + post_data["object_ids"] = id_list; + LLHTTPClient::post( + url, + post_data, + new LLObjectCostResponder(id_list)); + } + } + else + { + mStaleObjectCost.clear(); + mPendingObjectCost.clear(); + } + } + } +} + +void LLViewerObjectList::fetchPhysicsFlags() +{ + // issue http request for stale object physics flags + if (!mStalePhysicsFlags.empty()) + { + LLViewerRegion* regionp = gAgent.getRegion(); + + if (regionp) + { + std::string url = regionp->getCapability("GetObjectPhysicsData"); + + if (!url.empty()) + { + LLSD id_list; + U32 object_index = 0; + + for ( + std::set<LLUUID>::iterator iter = mStalePhysicsFlags.begin(); + iter != mStalePhysicsFlags.end(); + ++iter) + { + // Check to see if a request for this object + // has already been made. + if ( mPendingPhysicsFlags.find(*iter) == + mPendingPhysicsFlags.end() ) + { + mPendingPhysicsFlags.insert(*iter); + id_list[object_index++] = *iter; + } + } + + // id_list should now contain all + // requests in mStalePhysicsFlags before, so clear + // it now + mStalePhysicsFlags.clear(); + + if ( id_list.size() > 0 ) + { + LLSD post_data = LLSD::emptyMap(); + + post_data["object_ids"] = id_list; + LLHTTPClient::post( + url, + post_data, + new LLPhysicsFlagsResponder(id_list)); + } + } + else + { + mStalePhysicsFlags.clear(); + mPendingPhysicsFlags.clear(); + } + } + } +} + + void LLViewerObjectList::clearDebugText() { for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) @@ -923,8 +1223,12 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp) mNumDeadObjects++; } +static LLFastTimer::DeclareTimer FTM_REMOVE_DRAWABLE("Remove Drawable"); + void LLViewerObjectList::removeDrawable(LLDrawable* drawablep) { + LLFastTimer t(FTM_REMOVE_DRAWABLE); + if (!drawablep) { return; @@ -1089,7 +1393,69 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp) } } +void LLViewerObjectList::updateObjectCost(LLViewerObject* object) +{ + mStaleObjectCost.insert(object->getID()); +} + +void LLViewerObjectList::updateObjectCost(const LLUUID& object_id, F32 object_cost, F32 link_cost, F32 physics_cost, F32 link_physics_cost) +{ + mPendingObjectCost.erase(object_id); + LLViewerObject* object = findObject(object_id); + if (object) + { + object->setObjectCost(object_cost); + object->setLinksetCost(link_cost); + object->setPhysicsCost(physics_cost); + object->setLinksetPhysicsCost(link_physics_cost); + } +} + +void LLViewerObjectList::onObjectCostFetchFailure(const LLUUID& object_id) +{ + //llwarns << "Failed to fetch object cost for object: " << object_id << llendl; + mPendingObjectCost.erase(object_id); +} + +void LLViewerObjectList::updatePhysicsFlags(const LLViewerObject* object) +{ + mStalePhysicsFlags.insert(object->getID()); +} + +void LLViewerObjectList::updatePhysicsShapeType(const LLUUID& object_id, S32 type) +{ + mPendingPhysicsFlags.erase(object_id); + LLViewerObject* object = findObject(object_id); + if (object) + { + object->setPhysicsShapeType(type); + } +} + +void LLViewerObjectList::updatePhysicsProperties(const LLUUID& object_id, + F32 density, + F32 friction, + F32 restitution, + F32 gravity_multiplier) +{ + mPendingPhysicsFlags.erase(object_id); + + LLViewerObject* object = findObject(object_id); + if (object) + { + object->setPhysicsDensity(density); + object->setPhysicsFriction(friction); + object->setPhysicsGravity(gravity_multiplier); + object->setPhysicsRestitution(restitution); + } +} + +void LLViewerObjectList::onPhysicsFlagsFetchFailure(const LLUUID& object_id) +{ + //llwarns << "Failed to fetch physics flags for object: " << object_id << llendl; + mPendingPhysicsFlags.erase(object_id); +} void LLViewerObjectList::shiftObjects(const LLVector3 &offset) { diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 22a7f97c38..65374bca70 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -85,6 +85,22 @@ public: void updateApparentAngles(LLAgent &agent); void update(LLAgent &agent, LLWorld &world); + void fetchObjectCosts(); + void fetchPhysicsFlags(); + + void updateObjectCost(LLViewerObject* object); + void updateObjectCost(const LLUUID& object_id, F32 object_cost, F32 link_cost, F32 physics_cost, F32 link_physics_cost); + void onObjectCostFetchFailure(const LLUUID& object_id); + + void updatePhysicsFlags(const LLViewerObject* object); + void onPhysicsFlagsFetchFailure(const LLUUID& object_id); + void updatePhysicsShapeType(const LLUUID& object_id, S32 type); + void updatePhysicsProperties(const LLUUID& object_id, + F32 density, + F32 friction, + F32 restitution, + F32 gravity_multiplier); + void shiftObjects(const LLVector3 &offset); bool hasMapObjectInRegion(LLViewerRegion* regionp) ; @@ -186,6 +202,14 @@ protected: std::map<LLUUID, LLPointer<LLViewerObject> > mUUIDObjectMap; + //set of objects that need to update their cost + std::set<LLUUID> mStaleObjectCost; + std::set<LLUUID> mPendingObjectCost; + + //set of objects that need to update their physics flags + std::set<LLUUID> mStalePhysicsFlags; + std::set<LLUUID> mPendingPhysicsFlags; + std::vector<LLDebugBeacon> mDebugBeacons; S32 mCurLazyUpdateIndex; diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 5ae4e872f3..8db72da1ee 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -2202,9 +2202,9 @@ bool LLViewerParcelMgr::canAgentBuyParcel(LLParcel* parcel, bool forGroup) const = parcelOwner == (forGroup ? gAgent.getGroupID() : gAgent.getID()); bool isAuthorized - = (authorizeBuyer.isNull()
- || (gAgent.getID() == authorizeBuyer)
- || (gAgent.hasPowerInGroup(authorizeBuyer,GP_LAND_DEED)
+ = (authorizeBuyer.isNull() + || (gAgent.getID() == authorizeBuyer) + || (gAgent.hasPowerInGroup(authorizeBuyer,GP_LAND_DEED) && gAgent.hasPowerInGroup(authorizeBuyer,GP_LAND_SET_SALE_INFO))); return isForSale && !isOwner && isAuthorized && isEmpowered; diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index 4fee85e45c..6b3e04348a 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -155,8 +155,8 @@ LLViewerPartGroup::LLViewerPartGroup(const LLVector3 ¢er_agent, const F32 bo if (group != NULL) { - LLVector3 center(group->mOctreeNode->getCenter()); - LLVector3 size(group->mOctreeNode->getSize()); + LLVector3 center(group->mOctreeNode->getCenter().getF32ptr()); + LLVector3 size(group->mOctreeNode->getSize().getF32ptr()); size += LLVector3(0.01f, 0.01f, 0.01f); mMinObjPos = center - size; mMaxObjPos = center + size; diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h index 45c9b3e91f..faa86d43dd 100644 --- a/indra/newview/llviewerprecompiledheaders.h +++ b/indra/newview/llviewerprecompiledheaders.h @@ -118,8 +118,8 @@ // Library includes from llvfs #include "lldir.h" -
-// Library includes from llmessage project
+ +// Library includes from llmessage project #include "llcachename.h" #endif diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 9a49132ce6..65fb74f1f0 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -349,7 +349,6 @@ LLViewerRegion::~LLViewerRegion() // Can't do this on destruction, because the neighbor pointers might be invalid. // This should be reference counted... disconnectAllNeighbors(); - mCloudLayer.destroy(); LLViewerPartSim::getInstance()->cleanupRegion(this); gObjectList.killObjects(this); @@ -1185,7 +1184,7 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec // AND the CRC matches. JC LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type) { - llassert(mCacheLoaded); + //llassert(mCacheLoaded); This assert failes often, changing to early-out -- davep, 2010/10/18 LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL); @@ -1196,22 +1195,23 @@ LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type) { // Record a hit entry->recordHit(); - cache_miss_type = CACHE_MISS_TYPE_NONE; + cache_miss_type = CACHE_MISS_TYPE_NONE; return entry->getDP(crc); } else { // llinfos << "CRC miss for " << local_id << llendl; - cache_miss_type = CACHE_MISS_TYPE_CRC; + cache_miss_type = CACHE_MISS_TYPE_CRC; mCacheMissCRC.put(local_id); } } else { // llinfos << "Cache miss for " << local_id << llendl; - cache_miss_type = CACHE_MISS_TYPE_FULL; + cache_miss_type = CACHE_MISS_TYPE_FULL; mCacheMissFull.put(local_id); } + return NULL; } @@ -1500,12 +1500,17 @@ void LLViewerRegion::setSeedCapability(const std::string& url) capabilityNames.append("GetDisplayNames"); capabilityNames.append("GetTexture"); + capabilityNames.append("GetMesh"); + capabilityNames.append("GetObjectCost"); + capabilityNames.append("GetObjectPhysicsData"); capabilityNames.append("GroupProposalBallot"); capabilityNames.append("HomeLocation"); capabilityNames.append("LandResources"); capabilityNames.append("MapLayer"); capabilityNames.append("MapLayerGod"); capabilityNames.append("NewFileAgentInventory"); + capabilityNames.append("NewFileAgentInventoryVariablePrice"); + capabilityNames.append("ObjectAdd"); capabilityNames.append("ParcelPropertiesUpdate"); capabilityNames.append("ParcelMediaURLFilterList"); capabilityNames.append("ParcelNavigateMedia"); @@ -1520,6 +1525,8 @@ void LLViewerRegion::setSeedCapability(const std::string& url) capabilityNames.append("SendUserReport"); capabilityNames.append("SendUserReportWithScreenshot"); capabilityNames.append("ServerReleaseNotes"); + capabilityNames.append("SimConsole"); + capabilityNames.append("SimulatorFeatures"); capabilityNames.append("SetDisplayName"); capabilityNames.append("SimConsoleAsync"); capabilityNames.append("StartGroupProposal"); @@ -1534,6 +1541,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url) capabilityNames.append("UpdateNotecardTaskInventory"); capabilityNames.append("UpdateScriptTask"); capabilityNames.append("UploadBakedTexture"); + capabilityNames.append("UploadObjectAsset"); capabilityNames.append("ViewerMetrics"); capabilityNames.append("ViewerStartAuction"); capabilityNames.append("ViewerStats"); @@ -1580,6 +1588,7 @@ std::string LLViewerRegion::getCapability(const std::string& name) const { return ""; } + return iter->second; } diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index eae04b2f0c..4bc487e4cb 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -34,7 +34,6 @@ #include "lldarray.h" #include "llwind.h" -#include "llcloud.h" #include "llstat.h" #include "v3dmath.h" #include "llstring.h" @@ -334,7 +333,6 @@ protected: public: LLWind mWind; - LLCloudLayer mCloudLayer; LLViewerParcelOverlay *mParcelOverlay; LLStat mBitStat; diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 09325a8c1b..d1888e43f5 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -68,9 +68,21 @@ LLGLSLShader gObjectFullbrightProgram; LLGLSLShader gObjectFullbrightWaterProgram; LLGLSLShader gObjectFullbrightShinyProgram; +LLGLSLShader gObjectFullbrightShinyWaterProgram; LLGLSLShader gObjectShinyProgram; LLGLSLShader gObjectShinyWaterProgram; +//object hardware skinning shaders +LLGLSLShader gSkinnedObjectSimpleProgram; +LLGLSLShader gSkinnedObjectFullbrightProgram; +LLGLSLShader gSkinnedObjectFullbrightShinyProgram; +LLGLSLShader gSkinnedObjectShinySimpleProgram; + +LLGLSLShader gSkinnedObjectSimpleWaterProgram; +LLGLSLShader gSkinnedObjectFullbrightWaterProgram; +LLGLSLShader gSkinnedObjectFullbrightShinyWaterProgram; +LLGLSLShader gSkinnedObjectShinySimpleWaterProgram; + //environment shaders LLGLSLShader gTerrainProgram; LLGLSLShader gTerrainWaterProgram; @@ -101,6 +113,9 @@ LLGLSLShader gDeferredImpostorProgram; LLGLSLShader gDeferredEdgeProgram; LLGLSLShader gDeferredWaterProgram; LLGLSLShader gDeferredDiffuseProgram; +LLGLSLShader gDeferredSkinnedDiffuseProgram; +LLGLSLShader gDeferredSkinnedBumpProgram; +LLGLSLShader gDeferredSkinnedAlphaProgram; LLGLSLShader gDeferredBumpProgram; LLGLSLShader gDeferredTerrainProgram; LLGLSLShader gDeferredTreeProgram; @@ -115,12 +130,14 @@ LLGLSLShader gDeferredBlurLightProgram; LLGLSLShader gDeferredSoftenProgram; LLGLSLShader gDeferredShadowProgram; LLGLSLShader gDeferredAvatarShadowProgram; +LLGLSLShader gDeferredAttachmentShadowProgram; LLGLSLShader gDeferredAlphaProgram; LLGLSLShader gDeferredFullbrightProgram; LLGLSLShader gDeferredGIProgram; LLGLSLShader gDeferredGIFinalProgram; LLGLSLShader gDeferredPostGIProgram; LLGLSLShader gDeferredPostProgram; +LLGLSLShader gDeferredPostNoDoFProgram; LLGLSLShader gLuminanceGatherProgram; @@ -142,6 +159,15 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gObjectSimpleProgram); mShaderList.push_back(&gObjectFullbrightProgram); mShaderList.push_back(&gObjectFullbrightShinyProgram); + mShaderList.push_back(&gObjectFullbrightShinyWaterProgram); + mShaderList.push_back(&gSkinnedObjectSimpleProgram); + mShaderList.push_back(&gSkinnedObjectFullbrightProgram); + mShaderList.push_back(&gSkinnedObjectFullbrightShinyProgram); + mShaderList.push_back(&gSkinnedObjectShinySimpleProgram); + mShaderList.push_back(&gSkinnedObjectSimpleWaterProgram); + mShaderList.push_back(&gSkinnedObjectFullbrightWaterProgram); + mShaderList.push_back(&gSkinnedObjectFullbrightShinyWaterProgram); + mShaderList.push_back(&gSkinnedObjectShinySimpleWaterProgram); mShaderList.push_back(&gTerrainProgram); mShaderList.push_back(&gTerrainWaterProgram); mShaderList.push_back(&gObjectSimpleWaterProgram); @@ -155,6 +181,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredLightProgram); mShaderList.push_back(&gDeferredMultiLightProgram); mShaderList.push_back(&gDeferredAlphaProgram); + mShaderList.push_back(&gDeferredSkinnedAlphaProgram); mShaderList.push_back(&gDeferredFullbrightProgram); mShaderList.push_back(&gDeferredPostGIProgram); mShaderList.push_back(&gDeferredEdgeProgram); @@ -189,6 +216,7 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void) mReservedAttribs.push_back("materialColor"); mReservedAttribs.push_back("specularColor"); mReservedAttribs.push_back("binormal"); + mReservedAttribs.push_back("object_weight"); mAvatarAttribs.reserve(5); mAvatarAttribs.push_back("weight"); @@ -370,7 +398,9 @@ void LLViewerShaderMgr::setShaders() S32 deferred_class = 0; if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && - gSavedSettings.getBOOL("RenderDeferred")) + gSavedSettings.getBOOL("RenderDeferred") && + gSavedSettings.getBOOL("RenderAvatarVP") && + gSavedSettings.getBOOL("WindLightUseAtmosShaders")) { if (gSavedSettings.getS32("RenderShadowDetail") > 0) { @@ -388,14 +418,11 @@ void LLViewerShaderMgr::setShaders() deferred_class = 1; } - //make sure framebuffer objects are enabled - gSavedSettings.setBOOL("RenderUseFBO", TRUE); - //make sure hardware skinning is enabled - gSavedSettings.setBOOL("RenderAvatarVP", TRUE); + //gSavedSettings.setBOOL("RenderAvatarVP", TRUE); //make sure atmospheric shaders are enabled - gSavedSettings.setBOOL("WindLightUseAtmosShaders", TRUE); + //gSavedSettings.setBOOL("WindLightUseAtmosShaders", TRUE); } @@ -438,7 +465,6 @@ void LLViewerShaderMgr::setShaders() // Load all shaders to set max levels loadShadersEnvironment(); loadShadersWater(); - loadShadersObject(); loadShadersWindLight(); loadShadersEffects(); loadShadersInterface(); @@ -446,14 +472,9 @@ void LLViewerShaderMgr::setShaders() // Load max avatar shaders to set the max level mVertexShaderLevel[SHADER_AVATAR] = 3; mMaxAvatarShaderLevel = 3; - loadShadersAvatar(); - -#if 0 && LL_DARWIN // force avatar shaders off for mac - mVertexShaderLevel[SHADER_AVATAR] = 0; - sMaxAvatarShaderLevel = 0; -#else - if (gSavedSettings.getBOOL("RenderAvatarVP")) - { + + if (gSavedSettings.getBOOL("RenderAvatarVP") && loadShadersObject()) + { //hardware skinning is enabled and rigged attachment shaders loaded correctly BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth"); S32 avatar_class = 1; @@ -484,17 +505,28 @@ void LLViewerShaderMgr::setShaders() } } else - { + { //hardware skinning not possible, neither is deferred rendering mVertexShaderLevel[SHADER_AVATAR] = 0; - gSavedSettings.setBOOL("RenderAvatarCloth", FALSE); + mVertexShaderLevel[SHADER_DEFERRED] = 0; + + if (gSavedSettings.getBOOL("RenderAvatarVP")) + { + gSavedSettings.setBOOL("RenderDeferred", FALSE); + gSavedSettings.setBOOL("RenderAvatarCloth", FALSE); + gSavedSettings.setBOOL("RenderAvatarVP", FALSE); + } + loadShadersAvatar(); // unloads + loadShadersObject(); } if (!loadShadersDeferred()) { gSavedSettings.setBOOL("RenderDeferred", FALSE); + reentrance = false; + setShaders(); + return; } -#endif } else { @@ -542,7 +574,20 @@ void LLViewerShaderMgr::unloadShaders() gObjectShinyProgram.unload(); gObjectFullbrightShinyProgram.unload(); + gObjectFullbrightShinyWaterProgram.unload(); gObjectShinyWaterProgram.unload(); + + gSkinnedObjectSimpleProgram.unload(); + gSkinnedObjectFullbrightProgram.unload(); + gSkinnedObjectFullbrightShinyProgram.unload(); + gSkinnedObjectShinySimpleProgram.unload(); + + gSkinnedObjectSimpleWaterProgram.unload(); + gSkinnedObjectFullbrightWaterProgram.unload(); + gSkinnedObjectFullbrightShinyWaterProgram.unload(); + gSkinnedObjectShinySimpleWaterProgram.unload(); + + gWaterProgram.unload(); gUnderWaterProgram.unload(); gTerrainProgram.unload(); @@ -562,6 +607,9 @@ void LLViewerShaderMgr::unloadShaders() gPostNightVisionProgram.unload(); gDeferredDiffuseProgram.unload(); + gDeferredSkinnedDiffuseProgram.unload(); + gDeferredSkinnedBumpProgram.unload(); + gDeferredSkinnedAlphaProgram.unload(); mVertexShaderLevel[SHADER_LIGHTING] = 0; mVertexShaderLevel[SHADER_OBJECT] = 0; @@ -620,6 +668,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders() shaders.push_back( make_pair( "lighting/lightSpecularV.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); shaders.push_back( make_pair( "windlight/atmosphericsV.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) ); shaders.push_back( make_pair( "avatar/avatarSkinV.glsl", 1 ) ); + shaders.push_back( make_pair( "avatar/objectSkinV.glsl", 1 ) ); // 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++) @@ -635,7 +684,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders() // (in order of shader function call depth for reference purposes, deepest level first) shaders.clear(); - shaders.reserve(12); + shaders.reserve(13); shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) ); shaders.push_back( make_pair( "windlight/gammaF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT]) ); shaders.push_back( make_pair( "windlight/atmosphericsF.glsl", mVertexShaderLevel[SHADER_WINDLIGHT] ) ); @@ -648,6 +697,7 @@ BOOL LLViewerShaderMgr::loadBasicShaders() shaders.push_back( make_pair( "lighting/lightShinyF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); + shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterF.glsl", mVertexShaderLevel[SHADER_LIGHTING] ) ); for (U32 i = 0; i < shaders.size(); i++) { @@ -875,6 +925,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { gDeferredTreeProgram.unload(); gDeferredDiffuseProgram.unload(); + gDeferredSkinnedDiffuseProgram.unload(); + gDeferredSkinnedBumpProgram.unload(); + gDeferredSkinnedAlphaProgram.unload(); gDeferredBumpProgram.unload(); gDeferredImpostorProgram.unload(); gDeferredTerrainProgram.unload(); @@ -887,6 +940,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSoftenProgram.unload(); gDeferredShadowProgram.unload(); gDeferredAvatarShadowProgram.unload(); + gDeferredAttachmentShadowProgram.unload(); gDeferredAvatarProgram.unload(); gDeferredAvatarAlphaProgram.unload(); gDeferredAlphaProgram.unload(); @@ -898,7 +952,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredGIProgram.unload(); gDeferredGIFinalProgram.unload(); gDeferredWaterProgram.unload(); - return FALSE; + return TRUE; } mVertexShaderLevel[SHADER_AVATAR] = 1; @@ -917,6 +971,44 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { + gDeferredSkinnedDiffuseProgram.mName = "Deferred Skinned Diffuse Shader"; + gDeferredSkinnedDiffuseProgram.mFeatures.hasObjectSkinning = true; + gDeferredSkinnedDiffuseProgram.mShaderFiles.clear(); + gDeferredSkinnedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSkinnedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSkinnedDiffuseProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredSkinnedDiffuseProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredSkinnedBumpProgram.mName = "Deferred Skinned Bump Shader"; + gDeferredSkinnedBumpProgram.mFeatures.hasObjectSkinning = true; + gDeferredSkinnedBumpProgram.mShaderFiles.clear(); + gDeferredSkinnedBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSkinnedBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSkinnedBumpProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredSkinnedBumpProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredSkinnedAlphaProgram.mName = "Deferred Skinned Alpha Shader"; + gDeferredSkinnedAlphaProgram.mFeatures.hasObjectSkinning = true; + gDeferredSkinnedAlphaProgram.mFeatures.calculatesLighting = true; + gDeferredSkinnedAlphaProgram.mFeatures.calculatesAtmospherics = true; + gDeferredSkinnedAlphaProgram.mFeatures.hasGamma = true; + gDeferredSkinnedAlphaProgram.mFeatures.hasAtmospherics = true; + gDeferredSkinnedAlphaProgram.mFeatures.hasLighting = true; + gDeferredSkinnedAlphaProgram.mShaderFiles.clear(); + gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSkinnedAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSkinnedAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredSkinnedAlphaProgram.createShader(NULL, NULL); + } + + if (success) + { gDeferredBumpProgram.mName = "Deferred Bump Shader"; gDeferredBumpProgram.mShaderFiles.clear(); gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpV.glsl", GL_VERTEX_SHADER_ARB)); @@ -959,7 +1051,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { gDeferredMultiLightProgram.mName = "Deferred MultiLight Shader"; gDeferredMultiLightProgram.mShaderFiles.clear(); - gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredMultiLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredMultiLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredMultiLightProgram.createShader(NULL, NULL); @@ -1065,7 +1157,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSoftenProgram.mShaderFiles.clear(); gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSoftenProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + + 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); + } + success = gDeferredSoftenProgram.createShader(NULL, NULL); } @@ -1092,6 +1191,17 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { + gDeferredAttachmentShadowProgram.mName = "Deferred Attachment Shadow Shader"; + gDeferredAttachmentShadowProgram.mFeatures.hasObjectSkinning = true; + gDeferredAttachmentShadowProgram.mShaderFiles.clear(); + gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredAttachmentShadowProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredAttachmentShadowProgram.createShader(NULL, NULL); + } + + if (success) + { gTerrainProgram.mName = "Deferred Terrain Shader"; gDeferredTerrainProgram.mShaderFiles.clear(); gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER_ARB)); @@ -1122,11 +1232,31 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true; gDeferredAvatarAlphaProgram.mShaderFiles.clear(); gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredAvatarAlphaProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; success = gDeferredAvatarAlphaProgram.createShader(&mAvatarAttribs, &mAvatarUniforms); } + if (success) + { + gDeferredPostProgram.mName = "Deferred Post Shader"; + gDeferredPostProgram.mShaderFiles.clear(); + gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredPostProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredPostProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredPostNoDoFProgram.mName = "Deferred Post Shader"; + gDeferredPostNoDoFProgram.mShaderFiles.clear(); + gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredPostNoDoFProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredPostNoDoFProgram.createShader(NULL, NULL); + } + if (mVertexShaderLevel[SHADER_DEFERRED] > 1) { if (success) @@ -1142,15 +1272,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (mVertexShaderLevel[SHADER_DEFERRED] > 2) { - if (success) - { - gDeferredPostProgram.mName = "Deferred Post Shader"; - gDeferredPostProgram.mShaderFiles.clear(); - gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB)); - gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER_ARB)); - gDeferredPostProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; - success = gDeferredPostProgram.createShader(NULL, NULL); - } + if (success) { @@ -1204,12 +1326,22 @@ BOOL LLViewerShaderMgr::loadShadersObject() { gObjectShinyProgram.unload(); gObjectFullbrightShinyProgram.unload(); + gObjectFullbrightShinyWaterProgram.unload(); gObjectShinyWaterProgram.unload(); gObjectSimpleProgram.unload(); gObjectSimpleWaterProgram.unload(); gObjectFullbrightProgram.unload(); gObjectFullbrightWaterProgram.unload(); - return FALSE; + gSkinnedObjectSimpleProgram.unload(); + gSkinnedObjectFullbrightProgram.unload(); + gSkinnedObjectFullbrightShinyProgram.unload(); + gSkinnedObjectShinySimpleProgram.unload(); + gSkinnedObjectSimpleWaterProgram.unload(); + gSkinnedObjectFullbrightWaterProgram.unload(); + gSkinnedObjectFullbrightShinyWaterProgram.unload(); + gSkinnedObjectShinySimpleWaterProgram.unload(); + + return TRUE; } if (success) @@ -1318,6 +1450,159 @@ BOOL LLViewerShaderMgr::loadShadersObject() success = gObjectFullbrightShinyProgram.createShader(NULL, &mShinyUniforms); } + if (success) + { + gObjectFullbrightShinyWaterProgram.mName = "Fullbright Shiny Water Shader"; + gObjectFullbrightShinyWaterProgram.mFeatures.calculatesAtmospherics = true; + gObjectFullbrightShinyWaterProgram.mFeatures.isFullbright = true; + gObjectFullbrightShinyWaterProgram.mFeatures.isShiny = true; + gObjectFullbrightShinyWaterProgram.mFeatures.hasGamma = true; + gObjectFullbrightShinyWaterProgram.mFeatures.hasTransport = true; + gObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true; + gObjectFullbrightShinyWaterProgram.mShaderFiles.clear(); + gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB)); + gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gObjectFullbrightShinyWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; + gObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + success = gObjectFullbrightShinyWaterProgram.createShader(NULL, &mShinyUniforms); + } + + if (mVertexShaderLevel[SHADER_AVATAR] > 0) + { //load hardware skinned attachment shaders + if (success) + { + gSkinnedObjectSimpleProgram.mName = "Skinned Simple Shader"; + gSkinnedObjectSimpleProgram.mFeatures.calculatesLighting = true; + gSkinnedObjectSimpleProgram.mFeatures.calculatesAtmospherics = true; + gSkinnedObjectSimpleProgram.mFeatures.hasGamma = true; + gSkinnedObjectSimpleProgram.mFeatures.hasAtmospherics = true; + gSkinnedObjectSimpleProgram.mFeatures.hasLighting = true; + gSkinnedObjectSimpleProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectSimpleProgram.mShaderFiles.clear(); + gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gSkinnedObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSkinnedObjectSimpleProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; + success = gSkinnedObjectSimpleProgram.createShader(NULL, NULL); + } + + if (success) + { + gSkinnedObjectFullbrightProgram.mName = "Skinned Fullbright Shader"; + gSkinnedObjectFullbrightProgram.mFeatures.calculatesAtmospherics = true; + gSkinnedObjectFullbrightProgram.mFeatures.hasGamma = true; + gSkinnedObjectFullbrightProgram.mFeatures.hasTransport = true; + gSkinnedObjectFullbrightProgram.mFeatures.isFullbright = true; + gSkinnedObjectFullbrightProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectFullbrightProgram.mShaderFiles.clear(); + gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gSkinnedObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSkinnedObjectFullbrightProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; + success = gSkinnedObjectFullbrightProgram.createShader(NULL, NULL); + } + + if (success) + { + gSkinnedObjectFullbrightShinyProgram.mName = "Skinned Fullbright Shiny Shader"; + gSkinnedObjectFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true; + gSkinnedObjectFullbrightShinyProgram.mFeatures.hasGamma = true; + gSkinnedObjectFullbrightShinyProgram.mFeatures.hasTransport = true; + gSkinnedObjectFullbrightShinyProgram.mFeatures.isShiny = true; + gSkinnedObjectFullbrightShinyProgram.mFeatures.isFullbright = true; + gSkinnedObjectFullbrightShinyProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectFullbrightShinyProgram.mShaderFiles.clear(); + gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gSkinnedObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSkinnedObjectFullbrightShinyProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; + success = gSkinnedObjectFullbrightShinyProgram.createShader(NULL, &mShinyUniforms); + } + + if (success) + { + gSkinnedObjectShinySimpleProgram.mName = "Skinned Shiny Simple Shader"; + gSkinnedObjectShinySimpleProgram.mFeatures.calculatesLighting = true; + gSkinnedObjectShinySimpleProgram.mFeatures.calculatesAtmospherics = true; + gSkinnedObjectShinySimpleProgram.mFeatures.hasGamma = true; + gSkinnedObjectShinySimpleProgram.mFeatures.hasAtmospherics = true; + gSkinnedObjectShinySimpleProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectShinySimpleProgram.mFeatures.isShiny = true; + gSkinnedObjectShinySimpleProgram.mShaderFiles.clear(); + gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gSkinnedObjectShinySimpleProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSkinnedObjectShinySimpleProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; + success = gSkinnedObjectShinySimpleProgram.createShader(NULL, &mShinyUniforms); + } + + if (success) + { + gSkinnedObjectSimpleWaterProgram.mName = "Skinned Simple Water Shader"; + gSkinnedObjectSimpleWaterProgram.mFeatures.calculatesLighting = true; + gSkinnedObjectSimpleWaterProgram.mFeatures.calculatesAtmospherics = true; + gSkinnedObjectSimpleWaterProgram.mFeatures.hasGamma = true; + gSkinnedObjectSimpleWaterProgram.mFeatures.hasAtmospherics = true; + gSkinnedObjectSimpleWaterProgram.mFeatures.hasLighting = true; + gSkinnedObjectSimpleWaterProgram.mFeatures.hasWaterFog = true; + gSkinnedObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gSkinnedObjectSimpleWaterProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectSimpleWaterProgram.mShaderFiles.clear(); + gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSkinnedObjectSimpleWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; + success = gSkinnedObjectSimpleWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gSkinnedObjectFullbrightWaterProgram.mName = "Skinned Fullbright Water Shader"; + gSkinnedObjectFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true; + gSkinnedObjectFullbrightWaterProgram.mFeatures.hasGamma = true; + gSkinnedObjectFullbrightWaterProgram.mFeatures.hasTransport = true; + gSkinnedObjectFullbrightWaterProgram.mFeatures.isFullbright = true; + gSkinnedObjectFullbrightWaterProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true; + gSkinnedObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gSkinnedObjectFullbrightWaterProgram.mShaderFiles.clear(); + gSkinnedObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gSkinnedObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSkinnedObjectFullbrightWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; + success = gSkinnedObjectFullbrightWaterProgram.createShader(NULL, NULL); + } + + if (success) + { + gSkinnedObjectFullbrightShinyWaterProgram.mName = "Skinned Fullbright Shiny Water Shader"; + gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.calculatesAtmospherics = true; + gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasGamma = true; + gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasTransport = true; + gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isShiny = true; + gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.isFullbright = true; + gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true; + gSkinnedObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.clear(); + gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinySkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gSkinnedObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSkinnedObjectFullbrightShinyWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; + success = gSkinnedObjectFullbrightShinyWaterProgram.createShader(NULL, &mShinyUniforms); + } + + if (success) + { + gSkinnedObjectShinySimpleWaterProgram.mName = "Skinned Shiny Simple Water Shader"; + gSkinnedObjectShinySimpleWaterProgram.mFeatures.calculatesLighting = true; + gSkinnedObjectShinySimpleWaterProgram.mFeatures.calculatesAtmospherics = true; + gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasGamma = true; + gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasAtmospherics = true; + gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasObjectSkinning = true; + gSkinnedObjectShinySimpleWaterProgram.mFeatures.isShiny = true; + gSkinnedObjectShinySimpleWaterProgram.mFeatures.hasWaterFog = true; + gSkinnedObjectShinySimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER; + gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.clear(); + gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinySimpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB)); + gSkinnedObjectShinySimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSkinnedObjectShinySimpleWaterProgram.mShaderLevel = mVertexShaderLevel[SHADER_OBJECT]; + success = gSkinnedObjectShinySimpleWaterProgram.createShader(NULL, &mShinyUniforms); + } + } if( !success ) { diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index e958cf1172..514ff14cbd 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -76,6 +76,7 @@ public: MATERIAL_COLOR = 0, SPECULAR_COLOR, BINORMAL, + OBJECT_WEIGHT, END_RESERVED_ATTRIBS } eGLSLReservedAttribs; @@ -296,9 +297,20 @@ extern LLGLSLShader gObjectSimpleLODProgram; extern LLGLSLShader gObjectFullbrightLODProgram; extern LLGLSLShader gObjectFullbrightShinyProgram; +extern LLGLSLShader gObjectFullbrightShinyWaterProgram; extern LLGLSLShader gObjectShinyProgram; extern LLGLSLShader gObjectShinyWaterProgram; +extern LLGLSLShader gSkinnedObjectSimpleProgram; +extern LLGLSLShader gSkinnedObjectFullbrightProgram; +extern LLGLSLShader gSkinnedObjectFullbrightShinyProgram; +extern LLGLSLShader gSkinnedObjectShinySimpleProgram; + +extern LLGLSLShader gSkinnedObjectSimpleWaterProgram; +extern LLGLSLShader gSkinnedObjectFullbrightWaterProgram; +extern LLGLSLShader gSkinnedObjectFullbrightShinyWaterProgram; +extern LLGLSLShader gSkinnedObjectShinySimpleWaterProgram; + //environment shaders extern LLGLSLShader gTerrainProgram; extern LLGLSLShader gTerrainWaterProgram; @@ -329,6 +341,9 @@ extern LLGLSLShader gDeferredImpostorProgram; extern LLGLSLShader gDeferredEdgeProgram; extern LLGLSLShader gDeferredWaterProgram; extern LLGLSLShader gDeferredDiffuseProgram; +extern LLGLSLShader gDeferredSkinnedDiffuseProgram; +extern LLGLSLShader gDeferredSkinnedBumpProgram; +extern LLGLSLShader gDeferredSkinnedAlphaProgram; extern LLGLSLShader gDeferredBumpProgram; extern LLGLSLShader gDeferredTerrainProgram; extern LLGLSLShader gDeferredTreeProgram; @@ -345,7 +360,9 @@ extern LLGLSLShader gDeferredSoftenProgram; extern LLGLSLShader gDeferredShadowProgram; extern LLGLSLShader gDeferredPostGIProgram; extern LLGLSLShader gDeferredPostProgram; +extern LLGLSLShader gDeferredPostNoDoFProgram; extern LLGLSLShader gDeferredAvatarShadowProgram; +extern LLGLSLShader gDeferredAttachmentShadowProgram; extern LLGLSLShader gDeferredAlphaProgram; extern LLGLSLShader gDeferredFullbrightProgram; extern LLGLSLShader gDeferredAvatarAlphaProgram; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index fa60e572ac..0fb94bc44b 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -59,6 +59,7 @@ #include "llworld.h" #include "llfeaturemanager.h" #include "llviewernetwork.h" +#include "llmeshrepository.h" //for LLMeshRepository::sBytesReceived class StatAttributes @@ -794,6 +795,7 @@ void send_stats() download["world_kbytes"] = gTotalWorldBytes / 1024.0; download["object_kbytes"] = gTotalObjectBytes / 1024.0; download["texture_kbytes"] = gTotalTextureBytes / 1024.0; + download["mesh_kbytes"] = LLMeshRepository::sBytesReceived/1024.0; LLSD &in = body["stats"]["net"]["in"]; diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index 3f9cfb9d9b..f91a1241fe 100644 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -196,8 +196,15 @@ public: S32 mCount; F32 mSum; F32 mSumOfSquares; + F32 mMinValue; + F32 mMaxValue; U32 mCountOfNextUpdatesToIgnore; + inline StatsAccumulator() + { + reset(); + } + inline void push( F32 val ) { if ( mCountOfNextUpdatesToIgnore > 0 ) @@ -209,13 +216,31 @@ public: mCount++; mSum += val; mSumOfSquares += val * val; + if (mCount == 1 || val > mMaxValue) + { + mMaxValue = val; + } + if (mCount == 1 || val < mMinValue) + { + mMinValue = val; + } } inline F32 getMean() const { return (mCount == 0) ? 0.f : ((F32)mSum)/mCount; } - + + inline F32 getMinValue() const + { + return mMinValue; + } + + inline F32 getMaxValue() const + { + return mMaxValue; + } + inline F32 getStdDev() const { const F32 mean = getMean(); @@ -231,6 +256,8 @@ public: { mCount = 0; mSum = mSumOfSquares = 0.f; + mMinValue = 0.0f; + mMaxValue = 0.0f; mCountOfNextUpdatesToIgnore = 0; } @@ -240,6 +267,8 @@ public: data["mean"] = getMean(); data["std_dev"] = getStdDev(); data["count"] = (S32)mCount; + data["min"] = getMinValue(); + data["max"] = getMaxValue(); return data; } }; diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 0c36970878..4798bb536f 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -537,6 +537,7 @@ LLUIImagePtr LLEmbeddedItems::getItemImage(llwchar ext_char) const case LLAssetType::AT_BODYPART: img_name = "Inv_Skin"; break; case LLAssetType::AT_ANIMATION: img_name = "Inv_Animation"; break; case LLAssetType::AT_GESTURE: img_name = "Inv_Gesture"; break; + case LLAssetType::AT_MESH: img_name = "Inv_Mesh"; break; default: llassert(0); } @@ -846,17 +847,18 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask, { switch( cargo_type ) { - case DAD_CALLINGCARD: - case DAD_TEXTURE: - case DAD_SOUND: - case DAD_LANDMARK: - case DAD_SCRIPT: - case DAD_CLOTHING: - case DAD_OBJECT: - case DAD_NOTECARD: - case DAD_BODYPART: - case DAD_ANIMATION: - case DAD_GESTURE: + case DAD_CALLINGCARD: + case DAD_TEXTURE: + case DAD_SOUND: + case DAD_LANDMARK: + case DAD_SCRIPT: + case DAD_CLOTHING: + case DAD_OBJECT: + case DAD_NOTECARD: + case DAD_BODYPART: + case DAD_ANIMATION: + case DAD_GESTURE: + case DAD_MESH: { LLInventoryItem *item = (LLInventoryItem *)cargo_data; if( item && allowsEmbeddedItems() ) diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index f5fb074992..af06421bf9 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -835,7 +835,7 @@ BOOL LLViewerTexture::createGLTexture(S32 discard_level, const LLImageRaw* image llassert(mGLTexturep.notNull()) ; BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category) ; - + if(ret) { mFullWidth = mGLTexturep->getCurrentWidth() ; @@ -1422,8 +1422,15 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/) mOrigWidth = mRawImage->getWidth(); mOrigHeight = mRawImage->getHeight(); - // leave black border, do not scale image content - mRawImage->expandToPowerOfTwo(MAX_IMAGE_SIZE, FALSE); + + if (mBoostLevel == BOOST_PREVIEW) + { + mRawImage->biasedScaleToPowerOfTwo(1024); + } + else + { // leave black border, do not scale image content + mRawImage->expandToPowerOfTwo(MAX_IMAGE_SIZE, FALSE); + } mFullWidth = mRawImage->getWidth(); mFullHeight = mRawImage->getHeight(); @@ -1583,7 +1590,7 @@ F32 LLViewerFetchedTexture::calcDecodePriority() S32 cur_discard = getCurrentDiscardLevelForFetching(); bool have_all_data = (cur_discard >= 0 && (cur_discard <= mDesiredDiscardLevel)); - F32 pixel_priority = fsqrtf(mMaxVirtualSize); + F32 pixel_priority = (F32) sqrt(mMaxVirtualSize); F32 priority = 0.f; @@ -2711,6 +2718,9 @@ void LLViewerFetchedTexture::forceToSaveRawImage(S32 desired_discard) } void LLViewerFetchedTexture::destroySavedRawImage() { + mForceToSaveRawImage = FALSE ; + mSaveRawImage = FALSE ; + clearCallbackEntryList() ; mSavedRawImage = NULL ; @@ -2870,7 +2880,7 @@ BOOL LLViewerFetchedTexture::insertToAtlas() } //process the waiting_list - for(ll_face_list_t::iterator iter = waiting_list.begin(); iter != waiting_list.end(); ++iter) + for(std::vector<LLFace*>::iterator iter = waiting_list.begin(); iter != waiting_list.end(); ++iter) { facep = (LLFace*)*iter ; groupp = facep->getDrawable()->getSpatialGroup() ; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 33e7328cd7..cd6653b0c7 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -110,8 +110,8 @@ void LLViewerTextureList::doPreloadImages() { LL_DEBUGS("ViewerImages") << "Preloading images..." << LL_ENDL; - llassert_always(mInitialized) ;
- llassert_always(mImageList.empty()) ;
+ llassert_always(mInitialized) ; + llassert_always(mImageList.empty()) ; llassert_always(mUUIDMap.empty()) ; // Set the "missing asset" image @@ -835,7 +835,7 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) for (entries_list_t::iterator iter3 = entries.begin(); iter3 != entries.end(); ) { - LLPointer<LLViewerFetchedTexture> imagep = *iter3++; + LLViewerFetchedTexture* imagep = *iter3++; bool fetching = imagep->updateFetch(); if (fetching) diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 7728958ed8..6fe79c2e85 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -25,7 +25,6 @@ */ #include "llviewerprecompiledheaders.h" - #include "llviewerwindow.h" #if LL_WINDOWS @@ -41,6 +40,7 @@ #include "llagent.h" #include "llagentcamera.h" #include "llfloaterreg.h" +#include "llmeshrepository.h" #include "llpanellogin.h" #include "llviewerkeyboard.h" #include "llviewermenu.h" @@ -228,6 +228,8 @@ LLVector2 gDebugRaycastTexCoord; LLVector3 gDebugRaycastNormal; LLVector3 gDebugRaycastBinormal; S32 gDebugRaycastFaceHit; +LLVector3 gDebugRaycastStart; +LLVector3 gDebugRaycastEnd; // HUD display lines in lower right BOOL gDisplayWindInfo = FALSE; @@ -325,7 +327,7 @@ public: mTextColor = LLColor4( 0.86f, 0.86f, 0.86f, 1.f ); // Draw stuff growing up from right lower corner of screen - U32 xpos = mWindow->getWindowWidthScaled() - 350; + U32 xpos = mWindow->getWorldViewWidthScaled() - 350; U32 ypos = 64; const U32 y_inc = 20; @@ -459,6 +461,79 @@ public: addText(xpos, ypos, "Shaders Disabled"); ypos += y_inc; } + + if (gGLManager.mHasATIMemInfo) + { + S32 meminfo[4]; + glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo); + + addText(xpos, ypos, llformat("%.2f MB Texture Memory Free", meminfo[0]/1024.f)); + ypos += y_inc; + + if (gGLManager.mHasVertexBufferObject) + { + glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, meminfo); + addText(xpos, ypos, llformat("%.2f MB VBO Memory Free", meminfo[0]/1024.f)); + ypos += y_inc; + } + } + else if (gGLManager.mHasNVXMemInfo) + { + S32 free_memory; + glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory); + addText(xpos, ypos, llformat("%.2f MB Video Memory Free", free_memory/1024.f)); + ypos += y_inc; + } + + //show streaming cost/triangle count of known prims in current region OR selection + { + F32 cost = 0.f; + S32 count = 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(&bytes, &visible); + count += object->getTriangleCount(); + total_bytes += bytes; + visible_bytes += visible; + } + } + } + } + else + { + label = "Selection"; + cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectStreamingCost(&total_bytes, &visible_bytes); + count = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectTriangleCount(); + object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + } + + addText(xpos,ypos, llformat("%s streaming cost: %.1f", label, cost)); + ypos += y_inc; + + addText(xpos, ypos, llformat(" %.1f KTris, %.1f/%.1f KB, %d objects", + count/1024.f, visible_bytes/1024.f, total_bytes/1024.f, object_count)); + ypos += y_inc; + + } + addText(xpos, ypos, llformat("%d MB Vertex Data", LLVertexBuffer::sAllocatedBytes/(1024*1024))); ypos += y_inc; @@ -511,6 +586,12 @@ public: ypos += y_inc; + if (!LLSpatialGroup::sPendingQueries.empty()) + { + addText(xpos,ypos, llformat("%d Queries pending", LLSpatialGroup::sPendingQueries.size())); + ypos += y_inc; + } + addText(xpos,ypos, llformat("%d Avatars visible", LLVOAvatar::sNumVisibleAvatars)); @@ -520,6 +601,22 @@ public: ypos += y_inc; + if (gSavedSettings.getBOOL("MeshEnabled")) + { + 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("%.3f/%.3f MB Mesh Cache Read/Write ", LLMeshRepository::sCacheBytesRead/(1024.f*1024.f), LLMeshRepository::sCacheBytesWritten/(1024.f*1024.f))); + + ypos += y_inc; + } + LLVertexBuffer::sBindCount = LLImageGL::sBindCount = LLVertexBuffer::sSetCount = LLImageGL::sUniqueCount = gPipeline.mNumVisibleNodes = LLPipeline::sVisibleLightCount = 0; @@ -610,6 +707,7 @@ public: ypos += y_inc; } } + if(log_texture_traffic) { U32 old_y = ypos ; @@ -626,6 +724,52 @@ public: addText(xpos, ypos, "Network traffic for textures:"); ypos += y_inc; } + } + + if (gSavedSettings.getBOOL("DebugShowUploadCost")) + { + addText(xpos, ypos, llformat(" Meshes: L$%d", gPipeline.mDebugMeshUploadCost)); + ypos += y_inc/2; + addText(xpos, ypos, llformat(" Sculpties: L$%d", gPipeline.mDebugSculptUploadCost)); + ypos += y_inc/2; + addText(xpos, ypos, llformat(" Textures: L$%d", gPipeline.mDebugTextureUploadCost)); + ypos += y_inc/2; + addText(xpos, ypos, "Upload Cost: "); + + ypos += y_inc; + } + + //temporary hack to give feedback on mesh upload progress + if (!gMeshRepo.mUploads.empty()) + { + for (std::vector<LLMeshUploadThread*>::iterator iter = gMeshRepo.mUploads.begin(); + iter != gMeshRepo.mUploads.end(); ++iter) + { + LLMeshUploadThread* thread = *iter; + + addText(xpos, ypos, llformat("Mesh Upload -- price quote: %d:%d | upload: %d:%d | create: %d", + thread->mPendingConfirmations, thread->mUploadQ.size()+thread->mTextureQ.size(), + thread->mPendingUploads, thread->mConfirmedQ.size()+thread->mConfirmedTextureQ.size(), + thread->mInstanceQ.size())); + ypos += y_inc; + } + } + + if (!gMeshRepo.mPendingRequests.empty() || + !gMeshRepo.mThread->mHeaderReqQ.empty() || + !gMeshRepo.mThread->mLODReqQ.empty()) + { + LLMutexLock lock(gMeshRepo.mThread->mMutex); + S32 pending = (S32) gMeshRepo.mPendingRequests.size(); + S32 header = (S32) gMeshRepo.mThread->mHeaderReqQ.size(); + S32 lod = (S32) gMeshRepo.mThread->mLODReqQ.size(); + + addText(xpos, ypos, llformat ("Mesh Queue - %d pending (%d:%d header | %d:%d LOD)", + pending, + LLMeshRepoThread::sActiveHeaderRequests, header, + LLMeshRepoThread::sActiveLODRequests, lod)); + + ypos += y_inc; } if (gSavedSettings.getBOOL("DebugShowTextureInfo")) @@ -1432,7 +1576,7 @@ LLViewerWindow::LLViewerWindow( gSavedSettings.getBOOL("DisableVerticalSync"), !gHeadlessClient, ignore_pixel_depth, - gSavedSettings.getBOOL("RenderUseFBO") ? 0 : gSavedSettings.getU32("RenderFSAASamples")); //don't use window level anti-aliasing if FBOs are enabled + gSavedSettings.getBOOL("RenderDeferred") ? 0 : gSavedSettings.getU32("RenderFSAASamples")); //don't use window level anti-aliasing if FBOs are enabled if (!LLAppViewer::instance()->restoreErrorTrap()) { @@ -2604,7 +2748,9 @@ void LLViewerWindow::updateUI() &gDebugRaycastIntersection, &gDebugRaycastTexCoord, &gDebugRaycastNormal, - &gDebugRaycastBinormal); + &gDebugRaycastBinormal, + &gDebugRaycastStart, + &gDebugRaycastEnd); } updateMouseDelta(); @@ -3539,7 +3685,9 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de LLVector3 *intersection, LLVector2 *uv, LLVector3 *normal, - LLVector3 *binormal) + LLVector3 *binormal, + LLVector3* start, + LLVector3* end) { S32 x = mouse_x; S32 y = mouse_y; @@ -3571,7 +3719,22 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de 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 = mouse_world_end; + } + + if (start) + { + *start = mouse_world_start; + } + + if (end) + { + *end = mouse_world_end; + } + LLViewerObject* found = NULL; if (this_object) // check only this object @@ -3583,8 +3746,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de { found = this_object; } - } - + } else // is a world object { if (this_object->lineSegmentIntersect(mouse_world_start, mouse_world_end, this_face, pick_transparent, @@ -3592,21 +3754,22 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de { found = this_object; } - } - } - + } + } else // check ALL objects - { + { found = gPipeline.lineSegmentIntersectInHUD(mouse_hud_start, mouse_hud_end, pick_transparent, face_hit, intersection, uv, normal, binormal); if (!found) // if not found in HUD, look in world: - - { + { found = gPipeline.lineSegmentIntersectInWorld(mouse_world_start, mouse_world_end, pick_transparent, face_hit, intersection, uv, normal, binormal); + if (found && !pick_transparent) + { + gDebugRaycastIntersection = *intersection; } - + } } return found; @@ -4573,6 +4736,7 @@ BOOL LLViewerWindow::changeDisplaySettings(LLCoordScreen size, BOOL disable_vsyn //gResizeScreenTexture = TRUE; + //U32 fsaa = gSavedSettings.getU32("RenderFSAASamples"); //U32 old_fsaa = mWindow->getFSAASamples(); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index bb0023b787..df6928aa1d 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -346,7 +346,9 @@ public: LLVector3 *intersection = NULL, LLVector2 *uv = NULL, LLVector3 *normal = NULL, - LLVector3 *binormal = NULL); + LLVector3 *binormal = NULL, + LLVector3* start = NULL, + LLVector3* end = NULL); // Returns a pointer to the last object hit @@ -480,6 +482,8 @@ extern LLVector2 gDebugRaycastTexCoord; extern LLVector3 gDebugRaycastNormal; extern LLVector3 gDebugRaycastBinormal; extern S32 gDebugRaycastFaceHit; +extern LLVector3 gDebugRaycastStart; +extern LLVector3 gDebugRaycastEnd; extern BOOL gDisplayCameraPos; extern BOOL gDisplayWindInfo; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 79866dc5d2..ec2b5a4c98 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -64,6 +64,8 @@ #include "llkeyframefallmotion.h" #include "llkeyframestandmotion.h" #include "llkeyframewalkmotion.h" +#include "llmanipscale.h" // for get_default_max_prim_scale() +#include "llmeshrepository.h" #include "llmutelist.h" #include "llmoveview.h" #include "llnotificationsutil.h" @@ -81,6 +83,7 @@ #include "llviewermenu.h" #include "llviewerobjectlist.h" #include "llviewerparcelmgr.h" +#include "llviewershadermgr.h" #include "llviewerstats.h" #include "llvoavatarself.h" #include "llvovolume.h" @@ -679,12 +682,14 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mTexHairColor( NULL ), mTexEyeColor( NULL ), mNeedsSkin(FALSE), + mLastSkinTime(0.f), mUpdatePeriod(1), mFullyLoaded(FALSE), mPreviousFullyLoaded(FALSE), mFullyLoadedInitialized(FALSE), mSupportsAlphaLayers(FALSE), - mLoadedCallbacksPaused(FALSE) + mLoadedCallbacksPaused(FALSE), + mHasPelvisOffset( FALSE ) { LLMemType mt(LLMemType::MTYPE_AVATAR); //VTResume(); // VTune @@ -759,6 +764,10 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mRuthTimer.reset(); mRuthDebugTimer.reset(); mDebugExistenceTimer.reset(); + mPelvisOffset = LLVector3(0.0f,0.0f,0.0f); + mLastPelvisToFoot = 0.0f; + mPelvisFixup = 0.0f; + mLastPelvisFixup = 0.0f; } //------------------------------------------------------------------------ @@ -1322,7 +1331,17 @@ const LLVector3 LLVOAvatar::getRenderPosition() const } else if (isRoot()) { - return mDrawable->getPositionAgent(); + if ( !mHasPelvisOffset ) + { + return mDrawable->getPositionAgent(); + } + else + { + //Apply a pelvis fixup (as defined by the avs skin) + LLVector3 pos = mDrawable->getPositionAgent(); + pos[VZ] += mPelvisFixup; + return pos; + } } else { @@ -1335,42 +1354,47 @@ void LLVOAvatar::updateDrawable(BOOL force_damped) clearChanged(SHIFTED); } -void LLVOAvatar::onShift(const LLVector3& shift_vector) +void LLVOAvatar::onShift(const LLVector4a& shift_vector) { - mLastAnimExtents[0] += shift_vector; - mLastAnimExtents[1] += shift_vector; + const LLVector3& shift = reinterpret_cast<const LLVector3&>(shift_vector); + mLastAnimExtents[0] += shift; + mLastAnimExtents[1] += shift; mNeedsImpostorUpdate = TRUE; mNeedsAnimUpdate = TRUE; } -void LLVOAvatar::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax) +void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) { if (isImpostor() && !needsImpostorUpdate()) { LLVector3 delta = getRenderPosition() - - ((LLVector3(mDrawable->getPositionGroup())-mImpostorOffset)); + ((LLVector3(mDrawable->getPositionGroup().getF32ptr())-mImpostorOffset)); - newMin = mLastAnimExtents[0] + delta; - newMax = mLastAnimExtents[1] + delta; + newMin.load3( (mLastAnimExtents[0] + delta).mV); + newMax.load3( (mLastAnimExtents[1] + delta).mV); } else { getSpatialExtents(newMin,newMax); - mLastAnimExtents[0] = newMin; - mLastAnimExtents[1] = newMax; - LLVector3 pos_group = (newMin+newMax)*0.5f; - mImpostorOffset = pos_group-getRenderPosition(); + mLastAnimExtents[0].set(newMin.getF32ptr()); + mLastAnimExtents[1].set(newMax.getF32ptr()); + LLVector4a pos_group; + pos_group.setAdd(newMin,newMax); + pos_group.mul(0.5f); + mImpostorOffset = LLVector3(pos_group.getF32ptr())-getRenderPosition(); mDrawable->setPositionGroup(pos_group); } } -void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax) +void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { - LLVector3 buffer(0.25f, 0.25f, 0.25f); - LLVector3 pos = getRenderPosition(); - newMin = pos - buffer; - newMax = pos + buffer; - float max_attachment_span = DEFAULT_MAX_PRIM_SCALE * 5.0f; + LLVector4a buffer(0.25f); + LLVector4a pos; + pos.load3(getRenderPosition().mV); + newMin.setSub(pos, buffer); + newMax.setAdd(pos, buffer); + + float max_attachment_span = get_default_max_prim_scale() * 5.0f; //stretch bounding box by joint positions for (polymesh_map_t::iterator i = mMeshes.begin(); i != mMeshes.end(); ++i) @@ -1378,12 +1402,20 @@ void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax) LLPolyMesh* mesh = i->second; for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.count(); joint_num++) { - update_min_max(newMin, newMax, - mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation()); + LLVector4a trans; + trans.load3( mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation().mV); + update_min_max(newMin, newMax, trans); } } - mPixelArea = LLPipeline::calcPixelArea((newMin+newMax)*0.5f, (newMax-newMin)*0.5f, *LLViewerCamera::getInstance()); + 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()); //stretch bounding box by attachments for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); @@ -1405,20 +1437,22 @@ void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax) if (attached_object && !attached_object->isHUDAttachment()) { LLDrawable* drawable = attached_object->mDrawable; - if (drawable) + if (drawable && !drawable->isState(LLDrawable::RIGGED)) { LLSpatialBridge* bridge = drawable->getSpatialBridge(); if (bridge) { - const LLVector3* ext = bridge->getSpatialExtents(); - LLVector3 distance = (ext[1] - ext[0]); + const LLVector4a* ext = bridge->getSpatialExtents(); + LLVector4a distance; + distance.setSub(ext[1], ext[0]); + 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) - if (distance.mV[0] < max_attachment_span - && distance.mV[1] < max_attachment_span - && distance.mV[2] < max_attachment_span) + if (lt == 0x7) { update_min_max(newMin,newMax,ext[0]); update_min_max(newMin,newMax,ext[1]); @@ -1430,8 +1464,9 @@ void LLVOAvatar::getSpatialExtents(LLVector3& newMin, LLVector3& newMax) } //pad bounding box - newMin -= buffer; - newMax += buffer; + + newMin.sub(buffer); + newMax.add(buffer); } //----------------------------------------------------------------------------- @@ -1606,7 +1641,8 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent info->mRot.mV[VZ], LLQuaternion::XYZ)); joint->setScale(info->mScale); - + joint->setDefaultFromCurrentXform(); + if (info->mIsJoint) { joint->setSkinOffset( info->mPivot ); @@ -1984,26 +2020,29 @@ void LLVOAvatar::updateMeshData() bool terse_update = false; - if(facep->mVertexBuffer.isNull()) + facep->setGeomIndex(0); + facep->setIndicesIndex(0); + + LLVertexBuffer* buff = facep->getVertexBuffer(); + if(!facep->getVertexBuffer()) { - facep->mVertexBuffer = new LLVertexBufferAvatar(); - facep->mVertexBuffer->allocateBuffer(num_vertices, num_indices, TRUE); + buff = new LLVertexBufferAvatar(); + buff->allocateBuffer(num_vertices, num_indices, TRUE); + facep->setVertexBuffer(buff); } else { - if (facep->mVertexBuffer->getRequestedIndices() == num_indices && - facep->mVertexBuffer->getRequestedVerts() == num_vertices) + if (buff->getRequestedIndices() == num_indices && + buff->getRequestedVerts() == num_vertices) { terse_update = true; } else { - facep->mVertexBuffer->resizeBuffer(num_vertices, num_indices) ; - } + buff->resizeBuffer(num_vertices, num_indices); + } } - - facep->setGeomIndex(0); - facep->setIndicesIndex(0); + // 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) @@ -2018,7 +2057,7 @@ void LLVOAvatar::updateMeshData() } stop_glerror(); - facep->mVertexBuffer->setBuffer(0); + buff->setBuffer(0); if(!f_num) { @@ -2386,9 +2425,19 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled) // here we get the approximate head position and set as sound source for the voice symbol // (the following version uses a tweak of "mHeadOffset" which handle sitting vs. standing) //-------------------------------------------------------------------------------------------- - LLVector3 headOffset = LLVector3( 0.0f, 0.0f, mHeadOffset.mV[2] ); - mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot.getWorldPosition() + headOffset ); + if ( mIsSitting ) + { + LLVector3 headOffset = LLVector3( 0.0f, 0.0f, mHeadOffset.mV[2] ); + mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot.getWorldPosition() + headOffset ); + } + else + { + LLVector3 tagPos = mRoot.getWorldPosition(); + tagPos[VZ] -= mPelvisToFoot; + tagPos[VZ] += ( mBodySize[VZ] + 0.125f ); + mVoiceVisualizer->setVoiceSourceWorldPosition( tagPos ); + } }//if ( voiceEnabled ) } @@ -2452,7 +2501,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) if (isImpostor() && !mNeedsImpostorUpdate) { - LLVector3 ext[2]; + LLVector4a ext[2]; F32 distance; LLVector3 angle; @@ -2481,12 +2530,22 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) } else { + //VECTORIZE THIS getSpatialExtents(ext[0], ext[1]); - if ((ext[1]-mImpostorExtents[1]).length() > 0.05f || - (ext[0]-mImpostorExtents[0]).length() > 0.05f) + LLVector4a diff; + diff.setSub(ext[1], mImpostorExtents[1]); + if (diff.getLength3().getF32() > 0.05f) { mNeedsImpostorUpdate = TRUE; } + else + { + diff.setSub(ext[0], mImpostorExtents[0]); + if (diff.getLength3().getF32() > 0.05f) + { + mNeedsImpostorUpdate = TRUE; + } + } } } } @@ -2825,10 +2884,8 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) } LLVector3 name_position = idleUpdateNameTagPosition(root_pos_last); - mNameText->setPositionAgent(name_position); - - idleUpdateNameTagText(new_name); - + mNameText->setPositionAgent(name_position); + idleUpdateNameTagText(new_name); idleUpdateNameTagAlpha(new_name, alpha); } @@ -3114,8 +3171,9 @@ void LLVOAvatar::invalidateNameTags() if (avatar->isDead()) continue; avatar->clearNameTag(); - } - } + + } +} // Compute name tag position during idle update LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last) @@ -3134,12 +3192,14 @@ LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last) local_camera_up.scaleVec(mBodySize * 0.5f); local_camera_at.scaleVec(mBodySize * 0.5f); - LLVector3 name_position = mRoot.getWorldPosition() + - (local_camera_up * root_rot) - - (projected_vec(local_camera_at * root_rot, camera_to_av)); + LLVector3 name_position = mRoot.getWorldPosition(); + name_position[VZ] -= mPelvisToFoot; + name_position[VZ] += (mBodySize[VZ]* 0.55f); + name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av)); name_position += pixel_up_vec * 15.f; + return name_position; - } +} void LLVOAvatar::idleUpdateNameTagAlpha(BOOL new_name, F32 alpha) { @@ -3260,20 +3320,28 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) mTimeVisible.reset(); } - + //-------------------------------------------------------------------- // the rest should only be done occasionally for far away avatars //-------------------------------------------------------------------- if (visible && !isSelf() && !mIsDummy && sUseImpostors && !mNeedsAnimUpdate && !sFreezeCounter) { + const LLVector4a* ext = mDrawable->getSpatialExtents(); + LLVector4a size; + size.setSub(ext[1],ext[0]); + F32 mag = size.getLength3().getF32()*0.5f; + F32 impostor_area = 256.f*512.f*(8.125f - LLVOAvatar::sLODFactor*8.f); if (LLMuteList::getInstance()->isMuted(getID())) { // muted avatars update at 16 hz mUpdatePeriod = 16; } - else if (mVisibilityRank <= LLVOAvatar::sMaxVisible) + else if (mVisibilityRank <= LLVOAvatar::sMaxVisible || + 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 (mVisibilityRank > LLVOAvatar::sMaxVisible * 4) @@ -3384,7 +3452,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) root_pos = gAgent.getPosGlobalFromAgent(getRenderPosition()); resolveHeightGlobal(root_pos, ground_under_pelvis, normal); - F32 foot_to_ground = (F32) (root_pos.mdV[VZ] - mPelvisToFoot - ground_under_pelvis.mdV[VZ]); + 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); @@ -3398,13 +3466,12 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) // of the agent's physical representation root_pos.mdV[VZ] -= (0.5f * mBodySize.mV[VZ]) - mPelvisToFoot; - LLVector3 newPosition = gAgent.getPosAgentFromGlobal(root_pos); if (newPosition != mRoot.getXform()->getWorldPosition()) { mRoot.touch(); - mRoot.setWorldPosition(newPosition ); // regular update + mRoot.setWorldPosition( newPosition ); // regular update } @@ -3680,7 +3747,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) return TRUE; } - //----------------------------------------------------------------------------- // updateHeadOffset() //----------------------------------------------------------------------------- @@ -3705,7 +3771,41 @@ void LLVOAvatar::updateHeadOffset() mHeadOffset = lerp(midEyePt, mHeadOffset, u); } } - +//------------------------------------------------------------------------ +// setPelvisOffset +//------------------------------------------------------------------------ +void LLVOAvatar::setPelvisOffset( bool hasOffset, const LLVector3& offsetAmount, F32 pelvisFixup ) +{ + mHasPelvisOffset = hasOffset; + if ( mHasPelvisOffset ) + { + //Store off last pelvis to foot value + mLastPelvisToFoot = mPelvisToFoot; + mPelvisOffset = offsetAmount; + mLastPelvisFixup = mPelvisFixup; + mPelvisFixup = pelvisFixup; + } +} +//------------------------------------------------------------------------ +// postPelvisSetRecalc +//------------------------------------------------------------------------ +void LLVOAvatar::postPelvisSetRecalc( void ) +{ + computeBodySize(); + mRoot.touch(); + mRoot.updateWorldMatrixChildren(); + dirtyMesh(); + updateHeadOffset(); +} +//------------------------------------------------------------------------ +// pelisPoke +//------------------------------------------------------------------------ +void LLVOAvatar::setPelvisOffset( F32 pelvisFixupAmount ) +{ + mHasPelvisOffset = true; + mLastPelvisFixup = mPelvisFixup; + mPelvisFixup = pelvisFixupAmount; +} //------------------------------------------------------------------------ // updateVisibility() //------------------------------------------------------------------------ @@ -3855,6 +3955,46 @@ bool LLVOAvatar::shouldAlphaMask() } +U32 LLVOAvatar::renderSkinnedAttachments() +{ + /*U32 num_indices = 0; + + const U32 data_mask = LLVertexBuffer::MAP_VERTEX | + LLVertexBuffer::MAP_NORMAL | + LLVertexBuffer::MAP_TEXCOORD0 | + LLVertexBuffer::MAP_COLOR | + LLVertexBuffer::MAP_WEIGHT4; + + for (attachment_map_t::const_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) + { + const LLViewerObject* attached_object = (*attachment_iter); + if (attached_object && !attached_object->isHUDAttachment()) + { + const LLDrawable* drawable = attached_object->mDrawable; + if (drawable) + { + for (S32 i = 0; i < drawable->getNumFaces(); ++i) + { + LLFace* face = drawable->getFace(i); + if (face->isState(LLFace::RIGGED)) + { + + } + } + } + } + + return num_indices;*/ + return 0; +} + //----------------------------------------------------------------------------- // renderSkinned() //----------------------------------------------------------------------------- @@ -3869,7 +4009,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) LLFace* face = mDrawable->getFace(0); - bool needs_rebuild = !face || face->mVertexBuffer.isNull() || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY); + 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 @@ -3902,8 +4042,9 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) mMeshLOD[MESH_ID_HAIR]->updateJointGeometry(); } mNeedsSkin = FALSE; - - LLVertexBuffer* vb = mDrawable->getFace(0)->mVertexBuffer; + mLastSkinTime = gFrameTimeSeconds; + + LLVertexBuffer* vb = mDrawable->getFace(0)->getVertexBuffer(); if (vb) { vb->setBuffer(0); @@ -4250,7 +4391,7 @@ void LLVOAvatar::updateTextures() if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) { - setDebugText(llformat("%4.0f:%4.0f", fsqrtf(mMinPixelArea),fsqrtf(mMaxPixelArea))); + setDebugText(llformat("%4.0f:%4.0f", (F32) sqrt(mMinPixelArea),(F32) sqrt(mMaxPixelArea))); } } @@ -4392,7 +4533,6 @@ void LLVOAvatar::resolveRayCollisionAgent(const LLVector3d start_pt, const LLVec 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); @@ -4789,6 +4929,80 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name ) } //----------------------------------------------------------------------------- +// resetJointPositions +//----------------------------------------------------------------------------- +void LLVOAvatar::resetJointPositions( void ) +{ + for(S32 i = 0; i < (S32)mNumJoints; ++i) + { + mSkeleton[i].restoreOldXform(); + mSkeleton[i].setId( LLUUID::null ); + } + mHasPelvisOffset = false; + mPelvisFixup = mLastPelvisFixup; +} +//----------------------------------------------------------------------------- +// resetSpecificJointPosition +//----------------------------------------------------------------------------- +void LLVOAvatar::resetSpecificJointPosition( const std::string& name ) +{ + LLJoint* pJoint = mRoot.findJoint( name ); + + if ( pJoint && pJoint->doesJointNeedToBeReset() ) + { + pJoint->restoreOldXform(); + pJoint->setId( LLUUID::null ); + //If we're reseting the pelvis position make sure not to apply offset + if ( name == "mPelvis" ) + { + mHasPelvisOffset = false; + } + } + else + { + llinfos<<"Did not find "<< name.c_str()<<llendl; + } +} +//----------------------------------------------------------------------------- +// resetJointPositionsToDefault +//----------------------------------------------------------------------------- +void LLVOAvatar::resetJointPositionsToDefault( void ) +{ + const LLVector3& avPos = getCharacterPosition(); + + //Reposition the pelvis + LLJoint* pPelvis = mRoot.findJoint("mPelvis"); + if ( pPelvis ) + { + pPelvis->setPosition( avPos + pPelvis->getPosition() ); + } + else + { + llwarns<<"Can't get pelvis joint."<<llendl; + return; + } + + //Subsequent joints are relative to pelvis + for( S32 i = 0; i < (S32)mNumJoints; ++i ) + { + LLJoint* pJoint = (LLJoint*)&mSkeleton[i]; + if ( pJoint->doesJointNeedToBeReset() ) + { + + pJoint->setId( LLUUID::null ); + //restore joints to default positions, however skip over the pelvis + if ( pJoint && pPelvis != pJoint ) + { + pJoint->restoreOldXform(); + } + } + } + //make sure we don't apply the joint offset + mHasPelvisOffset = false; + mPelvisFixup = mLastPelvisFixup; + postPelvisSetRecalc(); +} +//----------------------------------------------------------------------------- // getCharacterPosition() //----------------------------------------------------------------------------- LLVector3 LLVOAvatar::getCharacterPosition() @@ -5445,9 +5659,13 @@ void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent) return; } - const LLVector3* ext = mDrawable->getSpatialExtents(); - LLVector3 center = (ext[1] + ext[0]) * 0.5f; - LLVector3 size = (ext[1]-ext[0])*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()); @@ -5459,7 +5677,7 @@ void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent) } else { - F32 radius = size.length(); + F32 radius = size.getLength3().getF32(); mAppAngle = (F32) atan2( radius, range) * RAD_TO_DEG; } @@ -5770,6 +5988,52 @@ void LLVOAvatar::resetHUDAttachments() } } +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); + } + } + } +} +//----------------------------------------------------------------------------- +// cleanupAttachedMesh() +//----------------------------------------------------------------------------- +void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO ) +{ + //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 = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID() ); + if ( pSkinData ) + { + const int jointCnt = pSkinData->mJointNames.size(); + bool fullRig = ( jointCnt>=20 ) ? true : false; + if ( fullRig ) + { + const int bindCnt = pSkinData->mAlternateBindMatrix.size(); + if ( bindCnt > 0 ) + { + LLVOAvatar::resetJointPositionsToDefault(); + } + } + } + } + } +} //----------------------------------------------------------------------------- // detachObject() //----------------------------------------------------------------------------- @@ -5780,14 +6044,23 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) ++iter) { LLViewerJointAttachment* attachment = iter->second; - + if (attachment->isObjectAttached(viewer_object)) { + cleanupAttachedMesh( viewer_object ); attachment->removeObject(viewer_object); lldebugs << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << llendl; return TRUE; } } + + std::vector<LLPointer<LLViewerObject> >::iterator iter = std::find(mPendingAttachment.begin(), mPendingAttachment.end(), viewer_object); + if (iter != mPendingAttachment.end()) + { + mPendingAttachment.erase(iter); + return TRUE; + } + return FALSE; } @@ -7864,7 +8137,7 @@ BOOL LLVOAvatar::updateLOD() BOOL res = updateJointLODs(); LLFace* facep = mDrawable->getFace(0); - if (facep->mVertexBuffer.isNull()) + if (!facep->getVertexBuffer()) { dirtyMesh(2); } @@ -7876,12 +8149,16 @@ BOOL LLVOAvatar::updateLOD() mNeedsSkin = TRUE; mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); } - updateVisibility(); return res; } +void LLVOAvatar::updateLODRiggedAttachments( void ) +{ + updateLOD(); + rebuildRiggedAttachments(); +} U32 LLVOAvatar::getPartitionType() const { // Avatars merely exist as drawables in the bridge partition @@ -7933,9 +8210,9 @@ void LLVOAvatar::cacheImpostorValues() getImpostorValues(mImpostorExtents, mImpostorAngle, mImpostorDistance); } -void LLVOAvatar::getImpostorValues(LLVector3* extents, LLVector3& angle, F32& distance) const +void LLVOAvatar::getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& distance) const { - const LLVector3* ext = mDrawable->getSpatialExtents(); + const LLVector4a* ext = mDrawable->getSpatialExtents(); extents[0] = ext[0]; extents[1] = ext[1]; @@ -7998,7 +8275,9 @@ void LLVOAvatar::idleUpdateRenderCost() } } } + } + // Diagnostic output to identify all avatar-related textures. // Does not affect rendering cost calculation. // Could be wrapped in a debug option if output becomes problematic. @@ -8038,6 +8317,7 @@ void LLVOAvatar::idleUpdateRenderCost() } } } + cost += textures.size() * LLVOVolume::ARC_TEXTURE_COST; setDebugText(llformat("%d", cost)); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 3659fb055f..295799fd24 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -123,10 +123,11 @@ public: virtual BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); virtual BOOL updateLOD(); BOOL updateJointLODs(); + void updateLODRiggedAttachments( void ); virtual BOOL isActive() const; // Whether this object needs to do an idleUpdate. virtual void updateTextures(); virtual S32 setTETexture(const U8 te, const LLUUID& uuid); // If setting a baked texture, need to request it from a non-local sim. - virtual void onShift(const LLVector3& shift_vector); + virtual void onShift(const LLVector4a& shift_vector); virtual U32 getPartitionType() const; virtual const LLVector3 getRenderPosition() const; virtual void updateDrawable(BOOL force_damped); @@ -134,8 +135,8 @@ public: virtual BOOL updateGeometry(LLDrawable *drawable); virtual void setPixelAreaAndAngle(LLAgent &agent); virtual void updateRegion(LLViewerRegion *regionp); - virtual void updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax); - virtual void getSpatialExtents(LLVector3& newMin, LLVector3& newMax); + virtual void updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax); + virtual void getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); virtual BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face = -1, // which face to check, -1 = ALL_SIDES BOOL pick_transparent = FALSE, @@ -167,7 +168,11 @@ public: virtual LLJoint* getJoint(const std::string &name); virtual LLJoint* getRootJoint() { return &mRoot; } - + + void resetJointPositions( void ); + void resetJointPositionsToDefault( void ); + void resetSpecificJointPosition( const std::string& name ); + virtual const char* getAnimationPrefix() { return "avatar"; } virtual const LLUUID& getID(); virtual LLVector3 getVolumePos(S32 joint_index, LLVector3& volume_offset); @@ -196,6 +201,10 @@ public: public: virtual bool isSelf() const { return false; } // True if this avatar is for this viewer's agent bool isBuilt() const { return mIsBuilt; } + +private: //aligned members + LLVector4a mImpostorExtents[2]; + private: BOOL mSupportsAlphaLayers; // For backwards compatibility, TRUE for 1.23+ clients @@ -285,6 +294,16 @@ protected: public: void updateHeadOffset(); F32 getPelvisToFoot() const { return mPelvisToFoot; } + void setPelvisOffset( bool hasOffset, const LLVector3& translation, F32 offset ) ; + bool hasPelvisOffset( void ) { return mHasPelvisOffset; } + void postPelvisSetRecalc( void ); + void setPelvisOffset( F32 pelvixFixupAmount ); + + bool mHasPelvisOffset; + LLVector3 mPelvisOffset; + F32 mLastPelvisToFoot; + F32 mPelvisFixup; + F32 mLastPelvisFixup; LLVector3 mHeadOffset; // current head position LLViewerJoint mRoot; @@ -352,6 +371,8 @@ public: U32 renderImpostor(LLColor4U color = LLColor4U(255,255,255,255), S32 diffuse_channel = 0); U32 renderRigid(); U32 renderSkinned(EAvatarRenderPass pass); + F32 getLastSkinTime() { return mLastSkinTime; } + U32 renderSkinnedAttachments(); U32 renderTransparent(BOOL first_pass); void renderCollisionVolumes(); static void deleteCachedImages(bool clearAll=true); @@ -363,6 +384,8 @@ private: bool shouldAlphaMask(); BOOL mNeedsSkin; // avatar has been animated and verts have not been updated + F32 mLastSkinTime; //value of gFrameTimeSeconds at last skin update + S32 mUpdatePeriod; S32 mNumInitFaces; //number of faces generated when creating the avatar drawable, does not inculde splitted faces due to long vertex buffer. @@ -402,7 +425,7 @@ public: BOOL needsImpostorUpdate() const; const LLVector3& getImpostorOffset() const; const LLVector2& getImpostorDim() const; - void getImpostorValues(LLVector3* extents, LLVector3& angle, F32& distance) const; + void getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& distance) const; void cacheImpostorValues(); void setImpostorDim(const LLVector2& dim); static void resetImpostors(); @@ -413,7 +436,6 @@ private: LLVector3 mImpostorOffset; LLVector2 mImpostorDim; BOOL mNeedsAnimUpdate; - LLVector3 mImpostorExtents[2]; LLVector3 mImpostorAngle; F32 mImpostorDistance; F32 mImpostorPixelArea; @@ -671,10 +693,12 @@ public: void clampAttachmentPositions(); virtual const LLViewerJointAttachment* attachObject(LLViewerObject *viewer_object); virtual BOOL detachObject(LLViewerObject *viewer_object); + void cleanupAttachedMesh( LLViewerObject* pVO ); static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj); protected: LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object); void lazyAttach(); + void rebuildRiggedAttachments( void ); //-------------------------------------------------------------------- // Map of attachment points, by ID @@ -786,6 +810,7 @@ protected: //-------------------------------------------------------------------- public: void resolveHeightGlobal(const LLVector3d &inPos, LLVector3d &outPos, LLVector3 &outNorm); + bool distanceToGround( const LLVector3d &startPoint, LLVector3d &collisionPoint, F32 distToIntersectionAlongRay ); void resolveHeightAgent(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm); void resolveRayCollisionAgent(const LLVector3d start_pt, const LLVector3d end_pt, LLVector3d &out_pos, LLVector3 &out_norm); void slamPosition(); // Slam position to transmitted position (for teleport); diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 3b4066e3ca..59883e0bb1 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -56,6 +56,8 @@ #include "llviewerstats.h" #include "llviewerregion.h" #include "llappearancemgr.h" +#include "llmeshrepository.h" +#include "llvovolume.h" #if LL_MSVC // disable boost::lexical_cast warning @@ -623,6 +625,7 @@ BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent) mScreenp->updateWorldMatrixChildren(); resetHUDAttachments(); } + return LLVOAvatar::updateCharacter(agent); } @@ -648,7 +651,11 @@ LLJoint *LLVOAvatarSelf::getJoint(const std::string &name) } return LLVOAvatar::getJoint(name); } - +//virtual +void LLVOAvatarSelf::resetJointPositions( void ) +{ + return LLVOAvatar::resetJointPositions(); +} // virtual BOOL LLVOAvatarSelf::setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake ) { @@ -1139,6 +1146,7 @@ const LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *view LLAppearanceMgr::instance().registerAttachment(attachment_id); // Clear any pending requests once the attachment arrives. removeAttachmentRequest(attachment_id); + updateLODRiggedAttachments(); } return attachment; @@ -1148,8 +1156,10 @@ const LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *view BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object) { const LLUUID attachment_id = viewer_object->getAttachmentItemID(); - if (LLVOAvatar::detachObject(viewer_object)) + if ( LLVOAvatar::detachObject(viewer_object) ) { + LLVOAvatar::cleanupAttachedMesh( viewer_object ); + // the simulator should automatically handle permission revocation stopMotionFromSource(attachment_id); diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index d13cf5ba38..51f06dee5f 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -83,7 +83,9 @@ public: /*virtual*/ void stopMotionFromSource(const LLUUID& source_id); /*virtual*/ void requestStopMotion(LLMotion* motion); /*virtual*/ LLJoint* getJoint(const std::string &name); - + + void resetJointPositions( void ); + /*virtual*/ BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE ); /*virtual*/ BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake = FALSE ); /*virtual*/ BOOL setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake = FALSE ); diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index b888a263d0..c605ddb1c8 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -76,6 +76,7 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file) S32 size = -1; BOOL success; + mDP.assignBuffer(mBuffer, 0); success = check_read(apr_file, &mLocalID, sizeof(U32)); if(success) { @@ -136,10 +137,11 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file) LLVOCacheEntry::~LLVOCacheEntry() { - if(mBuffer) + if(mBuffer != mDP.getBuffer()) { - delete[] mBuffer; + delete[] mBuffer ; //just in case } + mDP.freeBuffer(); } diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index f57f7b67ea..32822e1181 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -340,7 +340,7 @@ void LLVOGrass::updateTextures() { if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) { - setDebugText(llformat("%4.0f", fsqrtf(mPixelArea))); + setDebugText(llformat("%4.0f", (F32) sqrt(mPixelArea))); } getTEImage(0)->addTextureStats(mPixelArea); } @@ -453,7 +453,7 @@ void LLVOGrass::plantBlades() face->setTexture(getTEImage(0)); face->setState(LLFace::GLOBAL); face->setSize(mNumBlades * 8, mNumBlades * 12); - face->mVertexBuffer = NULL; + face->setVertexBuffer(NULL); face->setTEOffset(0); face->mCenterLocal = mPosition + mRegionp->getOriginAgent(); @@ -640,7 +640,7 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en LLVector2 tc[4]; LLVector3 v[4]; - // LLVector3 n[4]; // unused! + //LLVector3 n[4]; F32 closest_t = 1.f; @@ -686,7 +686,6 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en position.mV[2] += blade_height; v[3] = v1 = position + mRegionp->getOriginAgent(); - F32 a,b,t; BOOL hit = FALSE; @@ -694,23 +693,23 @@ BOOL LLVOGrass::lineSegmentIntersect(const LLVector3& start, const LLVector3& en U32 idx0 = 0,idx1 = 0,idx2 = 0; - if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, &a, &b, &t, FALSE)) + if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE)) { hit = TRUE; idx0 = 0; idx1 = 1; idx2 = 2; } - else if (LLTriangleRayIntersect(v[1], v[3], v[2], start, dir, &a, &b, &t, FALSE)) + else if (LLTriangleRayIntersect(v[1], v[3], v[2], start, dir, a, b, t, FALSE)) { hit = TRUE; idx0 = 1; idx1 = 3; idx2 = 2; } - else if (LLTriangleRayIntersect(v[2], v[1], v[0], start, dir, &a, &b, &t, FALSE)) + else if (LLTriangleRayIntersect(v[2], v[1], v[0], start, dir, a, b, t, FALSE)) { normal1 = -normal1; hit = TRUE; idx0 = 2; idx1 = 1; idx2 = 0; } - else if (LLTriangleRayIntersect(v[2], v[3], v[1], start, dir, &a, &b, &t, FALSE)) + else if (LLTriangleRayIntersect(v[2], v[3], v[1], start, dir, a, b, t, FALSE)) { normal1 = -normal1; hit = TRUE; diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp index f032ae8780..ce256fdedf 100644 --- a/indra/newview/llvoground.cpp +++ b/indra/newview/llvoground.cpp @@ -97,13 +97,14 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable) drawable->addFace(poolp, NULL); face = drawable->getFace(0); - if (face->mVertexBuffer.isNull()) + if (!face->getVertexBuffer()) { face->setSize(5, 12); - face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolGround::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); - face->mVertexBuffer->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); + LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolGround::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); + buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); face->setGeomIndex(0); face->setIndicesIndex(0); + face->setVertexBuffer(buff); } index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp); @@ -161,7 +162,7 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable) *(texCoordsp++) = LLVector2(0.f, 1.f); *(texCoordsp++) = LLVector2(0.5f, 0.5f); - face->mVertexBuffer->setBuffer(0); + face->getVertexBuffer()->setBuffer(0); LLPipeline::sCompiles++; return TRUE; } diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 08581be38b..6ee6822e2f 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -6979,13 +6979,6 @@ void LLVivoxProtocolParser::reset() alias.clear(); numberOfAliases = 0; applicationString.clear(); - id = 0; - nameString.clear(); - descriptionString.clear(); - expirationDate = LLDate(); - hasExpired = false; - fontType = 0; - fontStatus = 0; } //virtual diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 40833ad259..6f354b78b1 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -73,12 +73,14 @@ F32 LLVOPartGroup::getBinRadius() return mScale.mV[0]*2.f; } -void LLVOPartGroup::updateSpatialExtents(LLVector3& newMin, LLVector3& newMax) +void LLVOPartGroup::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { const LLVector3& pos_agent = getPositionAgent(); - newMin = pos_agent - mScale; - newMax = pos_agent + mScale; - mDrawable->setPositionGroup(pos_agent); + newMin.load3( (pos_agent - mScale).mV); + newMax.load3( (pos_agent + mScale).mV); + LLVector4a pos; + pos.load3(pos_agent.mV); + mDrawable->setPositionGroup(pos); } BOOL LLVOPartGroup::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) @@ -358,7 +360,7 @@ U32 LLVOPartGroup::getPartitionType() const } LLParticlePartition::LLParticlePartition() -: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB) +: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK, TRUE, GL_STREAM_DRAW_ARB) { mRenderPass = LLRenderPass::PASS_ALPHA; mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES; @@ -461,7 +463,7 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject(); facep->setGeomIndex(vertex_count); facep->setIndicesIndex(index_count); - facep->mVertexBuffer = buffer; + facep->setVertexBuffer(buffer); facep->setPoolType(LLDrawPool::POOL_ALPHA); object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, indicesp); diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h index b136f2cbfa..4db893b4ef 100644 --- a/indra/newview/llvopartgroup.h +++ b/indra/newview/llvopartgroup.h @@ -51,7 +51,7 @@ public: BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); virtual F32 getBinRadius(); - virtual void updateSpatialExtents(LLVector3& newMin, LLVector3& newMax); + virtual void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); virtual U32 getPartitionType() const; /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index e28179a789..447e60a38c 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -304,7 +304,7 @@ void LLSkyTex::createGLImage(S32 which) void LLSkyTex::bindTexture(BOOL curr) { - gGL.getTexUnit(0)->bind(mTexture[getWhich(curr)]); + gGL.getTexUnit(0)->bind(mTexture[getWhich(curr)], true); } /*************************************** @@ -1182,7 +1182,7 @@ BOOL LLVOSky::updateSky() } } - if (mDrawable.notNull() && mDrawable->getFace(0) && mDrawable->getFace(0)->mVertexBuffer.isNull()) + if (mDrawable.notNull() && mDrawable->getFace(0) && !mDrawable->getFace(0)->getVertexBuffer()) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); } @@ -1233,10 +1233,11 @@ void LLVOSky::createDummyVertexBuffer() mFace[FACE_DUMMY] = mDrawable->addFace(poolp, NULL); } - if(mFace[FACE_DUMMY]->mVertexBuffer.isNull()) + if(!mFace[FACE_DUMMY]->getVertexBuffer()) { - mFace[FACE_DUMMY]->mVertexBuffer = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB); - mFace[FACE_DUMMY]->mVertexBuffer->allocateBuffer(1, 1, TRUE); + LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB); + buff->allocateBuffer(1, 1, TRUE); + mFace[FACE_DUMMY]->setVertexBuffer(buff); } } @@ -1255,13 +1256,13 @@ void LLVOSky::updateDummyVertexBuffer() LLFastTimer t(FTM_RENDER_FAKE_VBO_UPDATE) ; - if(!mFace[FACE_DUMMY] || mFace[FACE_DUMMY]->mVertexBuffer.isNull()) + if(!mFace[FACE_DUMMY] || !mFace[FACE_DUMMY]->getVertexBuffer()) createDummyVertexBuffer() ; LLStrider<LLVector3> vertices ; - mFace[FACE_DUMMY]->mVertexBuffer->getVertexStrider(vertices, 0); + mFace[FACE_DUMMY]->getVertexBuffer()->getVertexStrider(vertices, 0); *vertices = mCameraPosAgent ; - mFace[FACE_DUMMY]->mVertexBuffer->setBuffer(0) ; + mFace[FACE_DUMMY]->getVertexBuffer()->setBuffer(0) ; } //---------------------------------- //end of fake vertex buffer updating @@ -1304,14 +1305,15 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable) { face = mFace[FACE_SIDE0 + side]; - if (face->mVertexBuffer.isNull()) + if (!face->getVertexBuffer()) { face->setSize(4, 6); face->setGeomIndex(0); face->setIndicesIndex(0); - face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); - face->mVertexBuffer->allocateBuffer(4, 6, TRUE); - + LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); + buff->allocateBuffer(4, 6, TRUE); + face->setVertexBuffer(buff); + index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp); S32 vtx = 0; @@ -1344,7 +1346,7 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable) *indicesp++ = index_offset + 3; *indicesp++ = index_offset + 2; - face->mVertexBuffer->setBuffer(0); + buff->setBuffer(0); } } @@ -1471,13 +1473,14 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons facep = mFace[f]; - if (facep->mVertexBuffer.isNull()) + if (!facep->getVertexBuffer()) { - facep->setSize(4, 6); - facep->mVertexBuffer = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); - facep->mVertexBuffer->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount(), TRUE); + facep->setSize(4, 6); + LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); + buff->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount(), TRUE); facep->setGeomIndex(0); facep->setIndicesIndex(0); + facep->setVertexBuffer(buff); } index_offset = facep->getGeometry(verticesp,normalsp,texCoordsp, indicesp); @@ -1506,7 +1509,7 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons *indicesp++ = index_offset + 2; *indicesp++ = index_offset + 3; - facep->mVertexBuffer->setBuffer(0); + facep->getVertexBuffer()->setBuffer(0); if (is_sun) { @@ -1875,13 +1878,14 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, LLFace *face = mFace[FACE_REFLECTION]; - if (face->mVertexBuffer.isNull() || quads*4 != face->getGeomCount()) + if (!face->getVertexBuffer() || quads*4 != face->getGeomCount()) { face->setSize(quads * 4, quads * 6); - face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); - face->mVertexBuffer->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); + LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); + buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); face->setIndicesIndex(0); face->setGeomIndex(0); + face->setVertexBuffer(buff); } LLStrider<LLVector3> verticesp; @@ -2019,7 +2023,7 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, } } - face->mVertexBuffer->setBuffer(0); + face->getVertexBuffer()->setBuffer(0); } diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 2eb4398488..dbcd4f50ca 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -54,27 +54,77 @@ public: LLVertexBuffer(MAP_VERTEX | MAP_NORMAL | MAP_TEXCOORD0 | MAP_TEXCOORD1 | MAP_COLOR, GL_DYNAMIC_DRAW_ARB) { //texture coordinates 2 and 3 exist, but use the same data as texture coordinate 1 - mOffsets[TYPE_TEXCOORD3] = mOffsets[TYPE_TEXCOORD2] = mOffsets[TYPE_TEXCOORD1]; - mTypeMask |= MAP_TEXCOORD2 | MAP_TEXCOORD3; }; - /*// virtual + // virtual void setupVertexBuffer(U32 data_mask) const - { - if (LLDrawPoolTerrain::getDetailMode() == 0 || LLPipeline::sShadowRender) + { + U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData; + + //assume tex coords 2 and 3 are present + U32 type_mask = mTypeMask | MAP_TEXCOORD2 | MAP_TEXCOORD3; + + if ((data_mask & type_mask) != data_mask) { - LLVertexBuffer::setupVertexBuffer(data_mask); + llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl; + } + + if (data_mask & MAP_NORMAL) + { + glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL])); + } + if (data_mask & MAP_TEXCOORD3) + { //substitute tex coord 0 for tex coord 3 + glClientActiveTextureARB(GL_TEXTURE3_ARB); + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + if (data_mask & MAP_TEXCOORD2) + { //substitute tex coord 0 for tex coord 2 + glClientActiveTextureARB(GL_TEXTURE2_ARB); + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); } - else if (data_mask & LLVertexBuffer::MAP_TEXCOORD1) + if (data_mask & MAP_TEXCOORD1) { - LLVertexBuffer::setupVertexBuffer(data_mask); + glClientActiveTextureARB(GL_TEXTURE1_ARB); + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); } - else + if (data_mask & MAP_BINORMAL) { - LLVertexBuffer::setupVertexBuffer(data_mask); + glClientActiveTextureARB(GL_TEXTURE2_ARB); + glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); } - llglassertok(); - }*/ + if (data_mask & MAP_TEXCOORD0) + { + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0])); + } + if (data_mask & MAP_COLOR) + { + glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR])); + } + + if (data_mask & MAP_WEIGHT) + { + glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], (void*)(base + mOffsets[TYPE_WEIGHT])); + } + + if (data_mask & MAP_WEIGHT4 && sWeight4Loc != -1) + { + glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], (void*)(base+mOffsets[TYPE_WEIGHT4])); + } + + if (data_mask & MAP_CLOTHWEIGHT) + { + glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], (void*)(base + mOffsets[TYPE_CLOTHWEIGHT])); + } + if (data_mask & MAP_VERTEX) + { + glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); + } + } }; //============================================================================ @@ -840,7 +890,7 @@ void LLVOSurfacePatch::dirtyGeom() if (mDrawable) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); - mDrawable->getFace(0)->mVertexBuffer = NULL; + mDrawable->getFace(0)->setVertexBuffer(NULL); mDrawable->movePartition(); } } @@ -939,7 +989,13 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect //step one meter at a time until intersection point found - const LLVector3* ext = mDrawable->getSpatialExtents(); + //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; @@ -1001,13 +1057,16 @@ BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector3& start, const LLVect return FALSE; } -void LLVOSurfacePatch::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax) +void LLVOSurfacePatch::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) { LLVector3 posAgent = getPositionAgent(); LLVector3 scale = getScale(); - newMin = posAgent-scale*0.5f; // Changing to 2.f makes the culling a -little- better, but still wrong - newMax = posAgent+scale*0.5f; - mDrawable->setPositionGroup((newMin+newMax)*0.5f); + 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 @@ -1060,7 +1119,7 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) facep->setIndicesIndex(indices_index); facep->setGeomIndex(index_offset); - facep->mVertexBuffer = buffer; + facep->setVertexBuffer(buffer); LLVOSurfacePatch* patchp = (LLVOSurfacePatch*) facep->getViewerObject(); patchp->getGeometry(vertices, normals, colors, texcoords, texcoords2, indices); diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index bd80e1dbe6..8e75ff2e6e 100644 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -72,7 +72,7 @@ public: /*virtual*/ void updateTextures(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area - /*virtual*/ void updateSpatialExtents(LLVector3& newMin, LLVector3& newMax); + /*virtual*/ void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. void setPatch(LLSurfacePatch *patchp); diff --git a/indra/newview/llvotextbubble.cpp b/indra/newview/llvotextbubble.cpp index b61dae53ba..a92172fe23 100644 --- a/indra/newview/llvotextbubble.cpp +++ b/indra/newview/llvotextbubble.cpp @@ -39,6 +39,7 @@ #include "llviewertexturelist.h" #include "llvolume.h" #include "pipeline.h" +#include "llvector4a.h" #include "llviewerregion.h" LLVOTextBubble::LLVOTextBubble(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) @@ -211,7 +212,7 @@ void LLVOTextBubble::updateFaceSize(S32 idx) else { const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx); - face->setSize(vol_face.mVertices.size(), vol_face.mIndices.size()); + face->setSize(vol_face.mNumVertices, vol_face.mNumIndices); } } @@ -229,19 +230,37 @@ void LLVOTextBubble::getGeometry(S32 idx, const LLVolumeFace& face = getVolume()->getVolumeFace(idx); - LLVector3 pos = getPositionAgent(); + LLVector4a pos; + pos.load3(getPositionAgent().mV); + + LLVector4a scale; + scale.load3(getScale().mV); + LLColor4U color = LLColor4U(getTE(idx)->getColor()); U32 offset = mDrawable->getFace(idx)->getGeomIndex(); - for (U32 i = 0; i < face.mVertices.size(); i++) + LLVector4a* dst_pos = (LLVector4a*) verticesp.get(); + LLVector4a* src_pos = (LLVector4a*) face.mPositions; + + LLVector4a* dst_norm = (LLVector4a*) normalsp.get(); + LLVector4a* src_norm = (LLVector4a*) face.mNormals; + + LLVector2* dst_tc = (LLVector2*) texcoordsp.get(); + LLVector2* src_tc = (LLVector2*) face.mTexCoords; + + LLVector4a::memcpyNonAliased16((F32*) dst_norm, (F32*) src_norm, face.mNumVertices*4*sizeof(F32)); + LLVector4a::memcpyNonAliased16((F32*) dst_tc, (F32*) src_tc, face.mNumVertices*2*sizeof(F32)); + + + for (U32 i = 0; i < face.mNumVertices; i++) { - *verticesp++ = face.mVertices[i].mPosition.scaledVec(getScale()) + pos; - *normalsp++ = face.mVertices[i].mNormal; - *texcoordsp++ = face.mVertices[i].mTexCoord; + LLVector4a t; + t.setMul(src_pos[i], scale); + dst_pos[i].setAdd(t, pos); *colorsp++ = color; } - for (U32 i = 0; i < face.mIndices.size(); i++) + for (U32 i = 0; i < face.mNumIndices; i++) { *indicesp++ = face.mIndices[i] + offset; } diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 46025b46be..8946d4e0b6 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -486,7 +486,7 @@ void LLVOTree::updateTextures() { if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) { - setDebugText(llformat("%4.0f", fsqrtf(mPixelArea))); + setDebugText(llformat("%4.0f", (F32) sqrt(mPixelArea))); } mTreeImagep->addTextureStats(mPixelArea); } @@ -526,11 +526,11 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable) if(mTrunkLOD >= sMAX_NUM_TREE_LOD_LEVELS) //do not display the tree. { mReferenceBuffer = NULL ; - mDrawable->getFace(0)->mVertexBuffer = NULL ; + mDrawable->getFace(0)->setVertexBuffer(NULL); return TRUE ; } - if (mReferenceBuffer.isNull() || mDrawable->getFace(0)->mVertexBuffer.isNull()) + if (mReferenceBuffer.isNull() || !mDrawable->getFace(0)->getVertexBuffer()) { const F32 SRR3 = 0.577350269f; // sqrt(1/3) const F32 SRR2 = 0.707106781f; // sqrt(1/2) @@ -864,7 +864,7 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable) if (gSavedSettings.getBOOL("RenderAnimateTrees")) { - mDrawable->getFace(0)->mVertexBuffer = mReferenceBuffer; + mDrawable->getFace(0)->setVertexBuffer(mReferenceBuffer); } else { @@ -922,8 +922,9 @@ void LLVOTree::updateMesh() calcNumVerts(vert_count, index_count, mTrunkLOD, stop_depth, mDepth, mTrunkDepth, mBranches); LLFace* facep = mDrawable->getFace(0); - facep->mVertexBuffer = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); - facep->mVertexBuffer->allocateBuffer(vert_count, index_count, TRUE); + LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); + buff->allocateBuffer(vert_count, index_count, TRUE); + facep->setVertexBuffer(buff); LLStrider<LLVector3> vertices; LLStrider<LLVector3> normals; @@ -931,16 +932,15 @@ void LLVOTree::updateMesh() LLStrider<U16> indices; U16 idx_offset = 0; - facep->mVertexBuffer->getVertexStrider(vertices); - facep->mVertexBuffer->getNormalStrider(normals); - facep->mVertexBuffer->getTexCoord0Strider(tex_coords); - facep->mVertexBuffer->getIndexStrider(indices); + buff->getVertexStrider(vertices); + buff->getNormalStrider(normals); + buff->getTexCoord0Strider(tex_coords); + buff->getIndexStrider(indices); genBranchPipeline(vertices, normals, tex_coords, indices, idx_offset, scale_mat, mTrunkLOD, stop_depth, mDepth, mTrunkDepth, 1.0, mTwist, droop, mBranches, alpha); mReferenceBuffer->setBuffer(0); - facep->mVertexBuffer->setBuffer(0); - + buff->setBuffer(0); } void LLVOTree::appendMesh(LLStrider<LLVector3>& vertices, @@ -1261,7 +1261,7 @@ void LLVOTree::updateRadius() mDrawable->setRadius(32.0f); } -void LLVOTree::updateSpatialExtents(LLVector3& newMin, LLVector3& newMax) +void LLVOTree::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { F32 radius = getScale().length()*0.05f; LLVector3 center = getRenderPosition(); @@ -1271,9 +1271,11 @@ void LLVOTree::updateSpatialExtents(LLVector3& newMin, LLVector3& newMax) center += LLVector3(0, 0, size.mV[2]) * getRotation(); - newMin.set(center-size); - newMax.set(center+size); - mDrawable->setPositionGroup(center); + newMin.load3((center-size).mV); + newMax.load3((center+size).mV); + LLVector4a pos; + pos.load3(center.mV); + mDrawable->setPositionGroup(pos); } BOOL LLVOTree::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face, BOOL pick_transparent, S32 *face_hitp, @@ -1286,8 +1288,13 @@ BOOL LLVOTree::lineSegmentIntersect(const LLVector3& start, const LLVector3& end return FALSE; } - const LLVector3* ext = mDrawable->getSpatialExtents(); + const LLVector4a* exta = mDrawable->getSpatialExtents(); + //VECTORIZE THIS + LLVector3 ext[2]; + ext[0].set(exta[0].getF32ptr()); + ext[1].set(exta[1].getF32ptr()); + LLVector3 center = (ext[1]+ext[0])*0.5f; LLVector3 size = (ext[1]-ext[0]); @@ -1324,7 +1331,7 @@ U32 LLVOTree::getPartitionType() const } LLTreePartition::LLTreePartition() -: LLSpatialPartition(0, FALSE, 0) +: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB) { mDrawableType = LLPipeline::RENDER_TYPE_TREE; mPartitionType = LLViewerRegion::PARTITION_TREE; diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h index fd0ebdf8e2..1e1deede26 100644 --- a/indra/newview/llvotree.h +++ b/indra/newview/llvotree.h @@ -68,7 +68,7 @@ public: /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); - /*virtual*/ void updateSpatialExtents(LLVector3 &min, LLVector3 &max); + /*virtual*/ void updateSpatialExtents(LLVector4a &min, LLVector4a &max); virtual U32 getPartitionType() const; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index ee54a938ba..e9a8c9b80a 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -30,12 +30,16 @@ #include "llvovolume.h" +#include <sstream> + #include "llviewercontrol.h" #include "lldir.h" #include "llflexibleobject.h" +#include "llfloatertools.h" #include "llmaterialtable.h" #include "llprimitive.h" #include "llvolume.h" +#include "llvolumeoctree.h" #include "llvolumemgr.h" #include "llvolumemessage.h" #include "material_codes.h" @@ -44,6 +48,7 @@ #include "object_flags.h" #include "llagentconstants.h" #include "lldrawable.h" +#include "lldrawpoolavatar.h" #include "lldrawpoolbump.h" #include "llface.h" #include "llspatialpartition.h" @@ -51,19 +56,24 @@ #include "llflexibleobject.h" #include "llsky.h" #include "lltexturefetch.h" +#include "llvector4a.h" #include "llviewercamera.h" #include "llviewertexturelist.h" +#include "llviewerobjectlist.h" #include "llviewerregion.h" #include "llviewertextureanim.h" #include "llworld.h" #include "llselectmgr.h" #include "pipeline.h" #include "llsdutil.h" +#include "llmatrix4a.h" #include "llmediaentry.h" #include "llmediadataclient.h" +#include "llmeshrepository.h" #include "llagent.h" #include "llviewermediafocus.h" #include "lldatapacker.h" +#include "llvoavatar.h" #include "llvocache.h" const S32 MIN_QUIET_FRAMES_COALESCE = 30; @@ -84,6 +94,7 @@ LLPointer<LLObjectMediaNavigateClient> LLVOVolume::sObjectMediaNavigateClient = static LLFastTimer::DeclareTimer FTM_GEN_TRIANGLES("Generate Triangles"); static LLFastTimer::DeclareTimer FTM_GEN_VOLUME("Generate Volumes"); +static LLFastTimer::DeclareTimer FTM_VOLUME_TEXTURES("Volume Textures"); // Implementation class of LLMediaDataClientObject. See llmediadataclient.h class LLMediaDataClientObjectImpl : public LLMediaDataClientObject @@ -694,6 +705,7 @@ BOOL LLVOVolume::isVisible() const void LLVOVolume::updateTextureVirtualSize() { + LLFastTimer ftm(FTM_VOLUME_TEXTURES); // Update the pixel area of all faces if(!isVisible()) @@ -727,7 +739,7 @@ void LLVOVolume::updateTextureVirtualSize() const LLTextureEntry *te = face->getTextureEntry(); LLViewerTexture *imagep = face->getTexture(); if (!imagep || !te || - face->mExtents[0] == face->mExtents[1]) + face->mExtents[0].equals3(face->mExtents[1])) { continue; } @@ -786,10 +798,12 @@ void LLVOVolume::updateTextureVirtualSize() if (isSculpted()) { LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); - LLUUID id = sculpt_params->getSculptTexture(); + LLUUID id = sculpt_params->getSculptTexture(); updateSculptTexture(); + + if (mSculptTexture.notNull()) { mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(), @@ -830,6 +844,7 @@ void LLVOVolume::updateTextureVirtualSize() mSculptTexture->getHeight(), mSculptTexture->getWidth())); } } + } if (getLightTextureID().notNull()) @@ -845,18 +860,18 @@ void LLVOVolume::updateTextureVirtualSize() *camera)); } } - + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) { - setDebugText(llformat("%.0f:%.0f", fsqrtf(min_vsize),fsqrtf(max_vsize))); + 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", fsqrtf(min_vsize),fsqrtf(max_vsize))); + setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize))); } else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA)) { - setDebugText(llformat("%.0f:%.0f", fsqrtf(min_vsize),fsqrtf(max_vsize))); + setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize))); } if (mPixelArea == 0) @@ -867,7 +882,8 @@ void LLVOVolume::updateTextureVirtualSize() BOOL LLVOVolume::isActive() const { - return !mStatic || mTextureAnimp || (mVolumeImpl && mVolumeImpl->isActive()); + return !mStatic || mTextureAnimp || (mVolumeImpl && mVolumeImpl->isActive()) || + (mDrawable.notNull() && mDrawable->isActive()); } BOOL LLVOVolume::setMaterial(const U8 material) @@ -941,8 +957,35 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline) return mDrawable; } -BOOL LLVOVolume::setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume) +BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bool unique_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 + + LLUUID mesh_id = volume_params.getSculptID(); + + //profile and path params don't matter for meshes + volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); + + 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) @@ -970,29 +1013,53 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &volume_params, const S32 detail } } - if ((LLPrimitive::setVolume(volume_params, mLOD, (mVolumeImpl && mVolumeImpl->isVolumeUnique()))) || mSculptChanged) + if (is404) + { + setIcon(LLViewerTextureManager::getFetchedTextureFromFile("icons/Inv_Mesh.png", TRUE, LLViewerTexture::BOOST_UI)); + } + + if ((LLPrimitive::setVolume(volume_params, lod, (mVolumeImpl && mVolumeImpl->isVolumeUnique()))) || mSculptChanged) { mFaceMappingChanged = TRUE; if (mVolumeImpl) { - mVolumeImpl->onSetVolume(volume_params, detail); + mVolumeImpl->onSetVolume(volume_params, mLOD); } updateSculptTexture(); + if (isSculpted()) { updateSculptTexture(); - - if (mSculptTexture.notNull()) + // if it's a mesh + if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) { - sculpt(); + if (getVolume()->getNumVolumeFaces() == 0 || getVolume()->isTetrahedron()) + { + //load request not yet issued, request pipeline load this mesh + LLUUID asset_id = volume_params.getSculptID(); + S32 available_lod = gMeshRepo.loadMesh(this, volume_params, lod, last_lod); + if (available_lod != lod) + { + LLPrimitive::setVolume(volume_params, available_lod); + } + } + + } + else // otherwise is sculptie + { + if (mSculptTexture.notNull()) + { + sculpt(); + } } } return TRUE; } + return FALSE; } @@ -1000,7 +1067,7 @@ void LLVOVolume::updateSculptTexture() { LLPointer<LLViewerFetchedTexture> old_sculpt = mSculptTexture; - if (isSculpted()) + if (isSculpted() && !isMesh()) { LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); LLUUID id = sculpt_params->getSculptTexture(); @@ -1028,6 +1095,14 @@ void LLVOVolume::updateSculptTexture() } + + +void LLVOVolume::notifyMeshLoaded() +{ + mSculptChanged = TRUE; + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE); +} + // sculpt replaces generate() for sculpted surfaces void LLVOVolume::sculpt() { @@ -1131,10 +1206,26 @@ BOOL LLVOVolume::calcLOD() S32 cur_detail = 0; - F32 radius = getVolume()->mLODScaleBias.scaledVec(getScale()).length(); - F32 distance = mDrawable->mDistanceWRTCamera; //llmin(mDrawable->mDistanceWRTCamera, MAX_LOD_DISTANCE); + F32 radius; + F32 distance; + + if (mDrawable->isState(LLDrawable::RIGGED)) + { + LLVOAvatar* avatar = getAvatar(); + distance = avatar->mDrawable->mDistanceWRTCamera; + radius = avatar->getBinRadius(); + } + else + { + distance = mDrawable->mDistanceWRTCamera; + radius = getVolume()->mLODScaleBias.scaledVec(getScale()).length(); + } + + //hold onto unmodified distance for debugging + F32 debug_distance = distance; + distance *= sDistanceFactor; - + F32 rampDist = LLVOVolume::sLODFactor * 2; if (distance < rampDist) @@ -1151,6 +1242,12 @@ BOOL LLVOVolume::calcLOD() cur_detail = computeLODDetail(llround(distance, 0.01f), llround(radius, 0.01f)); + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO)) + { + setDebugText(llformat("%.2f:%.2f, %d", debug_distance, radius, cur_detail)); + } + if (cur_detail != mLOD) { mAppAngle = llround((F32) atan2( mDrawable->getRadius(), mDrawable->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f); @@ -1178,7 +1275,7 @@ BOOL LLVOVolume::updateLOD() mLODChanged = TRUE; } - lod_changed |= LLViewerObject::updateLOD(); + lod_changed = lod_changed || LLViewerObject::updateLOD(); return lod_changed; } @@ -1214,6 +1311,11 @@ void LLVOVolume::updateFaceFlags() for (S32 i = 0; i < getVolume()->getNumFaces(); i++) { LLFace *face = mDrawable->getFace(i); + if (!face) + { + return; + } + BOOL fullbright = getTE(i)->getFullbright(); face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT); @@ -1293,14 +1395,28 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) { BOOL res = TRUE; - LLVector3 min,max; + LLVector4a min,max; - BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION); + min.clear(); + max.clear(); - for (S32 i = 0; i < getVolume()->getNumFaces(); i++) + BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED); + +// bool rigged = false; + LLVolume* volume = mRiggedVolume; + if (!volume) + { + volume = getVolume(); + } + + for (S32 i = 0; i < getVolume()->getNumVolumeFaces(); i++) { LLFace *face = mDrawable->getFace(i); - res &= face->genVolumeBBoxes(*getVolume(), i, + if (!face) + { + continue; + } + res &= face->genVolumeBBoxes(*volume, i, mRelativeXform, mRelativeXformInvTrans, (mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global); @@ -1313,17 +1429,8 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) } else { - for (U32 i = 0; i < 3; i++) - { - if (face->mExtents[0].mV[i] < min.mV[i]) - { - min.mV[i] = face->mExtents[0].mV[i]; - } - if (face->mExtents[1].mV[i] > max.mV[i]) - { - max.mV[i] = face->mExtents[1].mV[i]; - } - } + min.setMin(min, face->mExtents[0]); + max.setMax(max, face->mExtents[1]); } } } @@ -1331,7 +1438,9 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) if (rebuild) { mDrawable->setSpatialExtents(min,max); - mDrawable->setPositionGroup((min+max)*0.5f); + min.add(max); + min.mul(0.5f); + mDrawable->setPositionGroup(min); } updateRadius(); @@ -1358,7 +1467,21 @@ void LLVOVolume::updateRelativeXform() LLDrawable* drawable = mDrawable; - if (drawable->isActive()) + 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()) { // setup relative transforms LLQuaternion delta_rot; @@ -1440,11 +1563,22 @@ void LLVOVolume::updateRelativeXform() static LLFastTimer::DeclareTimer FTM_GEN_FLEX("Generate Flexies"); static LLFastTimer::DeclareTimer FTM_UPDATE_PRIMITIVES("Update Primitives"); +static LLFastTimer::DeclareTimer FTM_UPDATE_RIGGED_VOLUME("Update Rigged"); BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) { LLFastTimer t(FTM_UPDATE_PRIMITIVES); + if (mDrawable->isState(LLDrawable::REBUILD_RIGGED)) + { + { + LLFastTimer t(FTM_UPDATE_RIGGED_VOLUME); + updateRiggedVolume(); + } + genBBoxes(FALSE); + mDrawable->clearState(LLDrawable::REBUILD_RIGGED); + } + if (mVolumeImpl != NULL) { BOOL res; @@ -1521,6 +1655,17 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) regenFaces(); } genBBoxes(FALSE); + + 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(); + } + } } } } @@ -1540,12 +1685,12 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) { LLPipeline::sCompiles++; } - + mVolumeChanged = FALSE; mLODChanged = FALSE; mSculptChanged = FALSE; mFaceMappingChanged = FALSE; - + return LLViewerObject::updateGeometry(drawable); } @@ -1554,19 +1699,14 @@ void LLVOVolume::updateFaceSize(S32 idx) LLFace* facep = mDrawable->getFace(idx); if (idx >= getVolume()->getNumVolumeFaces()) { - facep->setSize(0,0); + facep->setSize(0,0, true); } else { const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx); - if (LLPipeline::sUseTriStrips) - { - facep->setSize(vol_face.mVertices.size(), vol_face.mTriStrip.size()); - } - else - { - facep->setSize(vol_face.mVertices.size(), vol_face.mIndices.size()); - } + facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices, + true); // <--- volume faces should be padded for 16-byte alignment + } } @@ -1821,21 +1961,25 @@ bool LLVOVolume::hasMedia() const LLVector3 LLVOVolume::getApproximateFaceNormal(U8 face_id) { LLVolume* volume = getVolume(); - LLVector3 result; + LLVector4a result; + result.clear(); + + LLVector3 ret; if (volume && face_id < volume->getNumVolumeFaces()) { const LLVolumeFace& face = volume->getVolumeFace(face_id); - for (S32 i = 0; i < (S32)face.mVertices.size(); ++i) + for (S32 i = 0; i < (S32)face.mNumVertices; ++i) { - result += face.mVertices[i].mNormal; + result.add(face.mNormals[i]); } - result = volumeDirectionToAgent(result); - result.normVec(); + LLVector3 ret(result.getF32ptr()); + ret = volumeDirectionToAgent(ret); + ret.normVec(); } - return result; + return ret; } void LLVOVolume::requestMediaDataUpdate(bool isNew) @@ -2632,6 +2776,23 @@ BOOL LLVOVolume::isSculpted() const return FALSE; } +BOOL LLVOVolume::isMesh() const +{ + 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; + } + } + + return FALSE; +} + BOOL LLVOVolume::hasLightTexture() const { if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) @@ -2648,6 +2809,11 @@ BOOL LLVOVolume::isVolumeGlobal() const { return mVolumeImpl->isVolumeGlobal() ? TRUE : FALSE; } + else if (mRiggedVolume.notNull()) + { + return TRUE; + } + return FALSE; } @@ -2732,7 +2898,7 @@ void LLVOVolume::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_p trans_mat.translate(getRegion()->getOriginAgent()); } - volume->generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, nodep->mSilhouetteSegments, view_vector, trans_mat, mRelativeXformInvTrans, nodep->getTESelectMask()); + volume->generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, view_vector, trans_mat, mRelativeXformInvTrans, nodep->getTESelectMask()); nodep->mSilhouetteExists = TRUE; } @@ -2918,6 +3084,62 @@ U32 LLVOVolume::getRenderCost(std::set<LLUUID> &textures) const } +F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes) +{ + if (isMesh()) + { + LLSD& header = gMeshRepo.getMeshHeader(getVolume()->getParams().getSculptID()); + + F32 radius = getScale().length(); + + return LLMeshRepository::getStreamingCost(header, radius, bytes, visible_bytes, mLOD); + } + + return 0.f; +} + +U32 LLVOVolume::getTriangleCount() +{ + U32 count = 0; + LLVolume* volume = getVolume(); + if (volume) + { + count = volume->getNumTriangles(); + } + + 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->isTetrahedron() || 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() { @@ -2955,7 +3177,7 @@ void LLVOVolume::setSelected(BOOL sel) } } -void LLVOVolume::updateSpatialExtents(LLVector3& newMin, LLVector3& newMax) +void LLVOVolume::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { } @@ -2963,7 +3185,9 @@ F32 LLVOVolume::getBinRadius() { F32 radius; - const LLVector3* ext = mDrawable->getSpatialExtents(); + F32 scale = 1.f; + + const LLVector4a* ext = mDrawable->getSpatialExtents(); BOOL shrink_wrap = mDrawable->isAnimating(); BOOL alpha_wrap = FALSE; @@ -2995,7 +3219,10 @@ F32 LLVOVolume::getBinRadius() } else if (shrink_wrap) { - radius = (ext[1]-ext[0]).length()*0.5f; + LLVector4a rad; + rad.setSub(ext[1], ext[0]); + + radius = rad.getLength3().getF32()*0.5f; } else if (mDrawable->isStatic()) { @@ -3019,7 +3246,7 @@ F32 LLVOVolume::getBinRadius() radius = 8.f; } - return llclamp(radius, 0.5f, 256.f); + return llclamp(radius*scale, 0.5f, 256.f); } const LLVector3 LLVOVolume::getPivotPositionAgent() const @@ -3031,7 +3258,7 @@ const LLVector3 LLVOVolume::getPivotPositionAgent() const return LLViewerObject::getPivotPositionAgent(); } -void LLVOVolume::onShift(const LLVector3 &shift_vector) +void LLVOVolume::onShift(const LLVector4a &shift_vector) { if (mVolumeImpl) { @@ -3108,12 +3335,37 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e BOOL ret = FALSE; LLVolume* volume = getVolume(); + + bool transform = true; + + if (mDrawable->isState(LLDrawable::RIGGED)) + { + if (LLFloater::isVisible(gFloaterTools) && getAvatar()->isSelf()) + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_RIGGED, TRUE); + volume = mRiggedVolume; + transform = false; + } + else + { //cannot pick rigged attachments on other avatars or when not in build mode + return FALSE; + } + } + if (volume) { LLVector3 v_start, v_end, v_dir; - v_start = agentPositionToVolume(start); - v_end = agentPositionToVolume(end); + if (transform) + { + v_start = agentPositionToVolume(start); + v_end = agentPositionToVolume(end); + } + else + { + v_start = start; + v_end = end; + } LLVector3 p; LLVector3 n; @@ -3154,8 +3406,15 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e end_face = face+1; } + bool special_cursor = specialHoverCursor(); for (S32 i = start_face; i < end_face; ++i) { + if (!special_cursor && !pick_transparent && getTE(i)->getColor().mV[3] == 0.f) + { //don't attempt to pick completely transparent faces unless + //pick_transparent is true + continue; + } + face_hit = volume->lineSegmentIntersect(v_start, v_end, i, &p, &tc, &n, &bn); @@ -3173,18 +3432,40 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e if (intersection != NULL) { - *intersection = volumePositionToAgent(p); // must map back to agent space + if (transform) + { + *intersection = volumePositionToAgent(p); // must map back to agent space + } + else + { + *intersection = p; + } } if (normal != NULL) { - *normal = volumeDirectionToAgent(n); + if (transform) + { + *normal = volumeDirectionToAgent(n); + } + else + { + *normal = n; + } + (*normal).normVec(); } if (bi_normal != NULL) { - *bi_normal = volumeDirectionToAgent(bn); + if (transform) + { + *bi_normal = volumeDirectionToAgent(bn); + } + else + { + *bi_normal = bn; + } (*bi_normal).normVec(); } @@ -3202,6 +3483,201 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e return ret; } +bool LLVOVolume::treatAsRigged() +{ + return LLFloater::isVisible(gFloaterTools) && + isAttachment() && + getAvatar() && + getAvatar()->isSelf() && + mDrawable.notNull() && + mDrawable->isState(LLDrawable::RIGGED); +} + +LLRiggedVolume* LLVOVolume::getRiggedVolume() +{ + return mRiggedVolume; +} + +void LLVOVolume::clearRiggedVolume() +{ + if (mRiggedVolume.notNull()) + { + mRiggedVolume = NULL; + updateRelativeXform(); + } +} + +void LLVOVolume::updateRiggedVolume() +{ + //Update mRiggedVolume to match current animation frame of avatar. + //Also update position/size in octree. + + if (!treatAsRigged()) + { + clearRiggedVolume(); + + return; + } + + LLVolume* volume = getVolume(); + + const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(volume->getParams().getSculptID()); + + 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); + +} + +static LLFastTimer::DeclareTimer FTM_SKIN_RIGGED("Skin"); +static LLFastTimer::DeclareTimer FTM_RIGGED_OCTREE("Octree"); + +void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* 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); + } + + //build matrix palette + LLMatrix4a mp[64]; + LLMatrix4* mat = (LLMatrix4*) mp; + + for (U32 j = 0; j < skin->mJointNames.size(); ++j) + { + LLJoint* joint = avatar->getJoint(skin->mJointNames[j]); + if (joint) + { + mat[j] = skin->mInvBindMatrix[j]; + mat[j] *= joint->getWorldMatrix(); + } + } + + for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) + { + const LLVolumeFace& vol_face = volume->getVolumeFace(i); + + LLVolumeFace& dst_face = mVolumeFaces[i]; + + LLVector4a* weight = vol_face.mWeights; + + LLMatrix4a bind_shape_matrix; + bind_shape_matrix.loadu(skin->mBindShapeMatrix); + + LLVector4a* pos = dst_face.mPositions; + + { + LLFastTimer t(FTM_SKIN_RIGGED); + + for (U32 j = 0; j < dst_face.mNumVertices; ++j) + { + LLMatrix4a final_mat; + final_mat.clear(); + + S32 idx[4]; + + LLVector4 wght; + + F32 scale = 0.f; + for (U32 k = 0; k < 4; k++) + { + F32 w = weight[j][k]; + + idx[k] = (S32) floorf(w); + wght[k] = w - floorf(w); + scale += wght[k]; + } + + wght *= 1.f/scale; + + for (U32 k = 0; k < 4; k++) + { + F32 w = wght[k]; + + LLMatrix4a src; + src.setMul(mp[idx[k]], w); + + final_mat.add(src); + } + + + 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 + LLVector4a& min = dst_face.mExtents[0]; + LLVector4a& max = dst_face.mExtents[1]; + + min = pos[0]; + max = pos[1]; + + for (U32 j = 1; j < dst_face.mNumVertices; ++j) + { + min.setMin(min, pos[j]); + max.setMax(max, pos[j]); + } + + dst_face.mCenter->setAdd(dst_face.mExtents[0], dst_face.mExtents[1]); + dst_face.mCenter->mul(0.5f); + + } + + { + LLFastTimer t(FTM_RIGGED_OCTREE); + delete dst_face.mOctree; + dst_face.mOctree = NULL; + + LLVector4a size; + size.setSub(dst_face.mExtents[1], dst_face.mExtents[0]); + size.splat(size.getLength3().getF32()*0.5f); + + dst_face.createOctree(1.f); + } + } +} + U32 LLVOVolume::getPartitionType() const { if (isHUDAttachment()) @@ -3254,7 +3730,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, (type == LLRenderPass::PASS_INVISIBLE) || (type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)); - if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL)) + if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_NORMAL)) { llwarns << "Non fullbright face has no normals!" << llendl; return; @@ -3276,22 +3752,20 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, else { model_mat = &(drawable->getRegion()->mRenderMatrix); + if (model_mat->isIdentity()) + { + model_mat = NULL; + } } - U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? facep->getTextureEntry()->getBumpmap() : 0; LLViewerTexture* tex = facep->getTexture(); U8 glow = (U8) (facep->getTextureEntry()->getGlow() * 255); - if (facep->mVertexBuffer.isNull()) - { - llerrs << "WTF?" << llendl; - } - if (idx >= 0 && - draw_vec[idx]->mVertexBuffer == facep->mVertexBuffer && + draw_vec[idx]->mVertexBuffer == facep->getVertexBuffer() && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 && (LLPipeline::sTextureBindTest || draw_vec[idx]->mTexture == tex) && #if LL_DARWIN @@ -3307,7 +3781,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_vec[idx]->mCount += facep->getIndicesCount(); draw_vec[idx]->mEnd += facep->getGeomCount(); draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize()); - validate_draw_info(*draw_vec[idx]); + draw_vec[idx]->validate(); update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[0]); update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[1]); } @@ -3318,7 +3792,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 offset = facep->getIndicesStart(); U32 count = facep->getIndicesCount(); LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset, tex, - facep->mVertexBuffer, fullbright, bump); + facep->getVertexBuffer(), fullbright, bump); draw_info->mGroup = group; draw_info->mVSize = facep->getVirtualSize(); draw_vec.push_back(draw_info); @@ -3331,12 +3805,13 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, } draw_info->mExtents[0] = facep->mExtents[0]; draw_info->mExtents[1] = facep->mExtents[1]; - validate_draw_info(*draw_info); if (LLPipeline::sUseTriStrips) { draw_info->mDrawMode = LLRender::TRIANGLE_STRIP; } + + draw_info->validate(); } } @@ -3348,6 +3823,32 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group) static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume"); static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt"); +static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj) +{ + LLVOAvatar* avatar = vobj->getAvatar(); + + if (avatar) + { + LLDrawable* drawable = avatar->mDrawable; + if (drawable && drawable->getNumFaces() > 0) + { + LLFace* face = drawable->getFace(0); + if (face) + { + LLDrawPool* drawpool = face->getPool(); + if (drawpool) + { + if (drawpool->getType() == LLDrawPool::POOL_AVATAR) + { + return (LLDrawPoolAvatar*) drawpool; + } + } + } + } + } + + return NULL; +} void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { @@ -3386,8 +3887,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) std::vector<LLFace*> alpha_faces; U32 useage = group->mSpatialPartition->mBufferUsage; - U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask); - U32 max_total = (gSavedSettings.getS32("RenderMaxNodeSize")*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask); + U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); + U32 max_total = (gSavedSettings.getS32("RenderMaxNodeSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); max_vertices = llmin(max_vertices, (U32) 65535); U32 cur_total = 0; @@ -3408,29 +3909,210 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } LLVOVolume* vobj = drawablep->getVOVolume(); + + if (vobj->getVolume() && vobj->getVolume()->isTetrahedron()) + { + continue; + } + llassert_always(vobj); vobj->updateTextureVirtualSize(); vobj->preRebuild(); drawablep->clearState(LLDrawable::HAS_ALPHA); + bool rigged = vobj->isAttachment() && + vobj->isMesh() && + gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID()); + + bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic(); + + bool is_rigged = false; + //for each face for (S32 i = 0; i < drawablep->getNumFaces(); i++) { + LLFace* facep = drawablep->getFace(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); - LLFace* facep = drawablep->getFace(i); + + + + if (rigged) + { + if (!facep->isState(LLFace::RIGGED)) + { //completely reset vertex buffer + facep->clearVertexBuffer(); + } + + facep->setState(LLFace::RIGGED); + is_rigged = true; + + //get drawpool of avatar with rigged face + LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj); + + //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. + LLVOAvatar* pAvatarVO = vobj->getAvatar(); + bool pelvisGotSet = false; + + if ( pAvatarVO ) + { + LLUUID currentId = vobj->getVolume()->getParams().getSculptID(); + const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId ); + + if ( pSkinData ) + { + const int bindCnt = pSkinData->mAlternateBindMatrix.size(); + if ( bindCnt > 0 ) + { + const int jointCnt = pSkinData->mJointNames.size(); + const F32 pelvisZOffset = pSkinData->mPelvisOffset; + bool fullRig = (jointCnt>=20) ? true : false; + if ( fullRig ) + { + for ( int i=0; i<jointCnt; ++i ) + { + std::string lookingForJoint = pSkinData->mJointNames[i].c_str(); + //llinfos<<"joint name "<<lookingForJoint.c_str()<<llendl; + LLJoint* pJoint = pAvatarVO->getJoint( lookingForJoint ); + if ( pJoint && pJoint->getId() != currentId ) + { + pJoint->setId( currentId ); + const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation(); + //Set the joint position + pJoint->storeCurrentXform( jointPos ); + //If joint is a pelvis then handle old/new pelvis to foot values + if ( lookingForJoint == "mPelvis" ) + { + pJoint->storeCurrentXform( jointPos ); + if ( !pAvatarVO->hasPelvisOffset() ) + { + pAvatarVO->setPelvisOffset( true, jointPos, pelvisZOffset ); + //Trigger to rebuild viewer AV + pelvisGotSet = true; + } + } + } + } + } + } + } + } + //If we've set the pelvis to a new position we need to also rebuild some information that the + //viewer does at launch (e.g. body size etc.) + if ( pelvisGotSet ) + { + pAvatarVO->postPelvisSetRecalc(); + } + + if (pool) + { + const LLTextureEntry* te = facep->getTextureEntry(); + + //remove face from old pool if it exists + LLDrawPool* old_pool = facep->getPool(); + if (old_pool && old_pool->getType() == LLDrawPool::POOL_AVATAR) + { + ((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep); + } + + //add face to new pool + LLViewerTexture* tex = facep->getTexture(); + U32 type = gPipeline.getPoolTypeFromTE(te, tex); + + if (type == LLDrawPool::POOL_ALPHA) + { + if (te->getFullbright()) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA); + } + } + else if (te->getShiny()) + { + if (te->getFullbright()) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY); + } + else + { + if (LLPipeline::sRenderDeferred) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY); + } + } + } + else + { + if (te->getFullbright()) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE); + } + } + + if (te->getGlow()) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW); + } + + if (LLPipeline::sRenderDeferred) + { + if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright()) + { + if (te->getBumpmap()) + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP); + } + else + { + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE); + } + } + } + } + + continue; + } + 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) + { + pool->removeRiggedFace(facep); + } + facep->clearState(LLFace::RIGGED); + } + } if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0) { - facep->mVertexBuffer = NULL; - facep->mLastVertexBuffer = NULL; + facep->clearVertexBuffer(); continue; } cur_total += facep->getGeomCount(); - if (facep->hasGeometry() && facep->mPixelArea > FORCE_CULL_AREA) + if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA) { const LLTextureEntry* te = facep->getTextureEntry(); LLViewerTexture* tex = facep->getTexture(); @@ -3443,7 +4125,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } } - BOOL force_simple = (facep->mPixelArea < FORCE_SIMPLE_RENDER_AREA); + BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA); U32 type = gPipeline.getPoolTypeFromTE(te, tex); if (type != LLDrawPool::POOL_ALPHA && force_simple) { @@ -3515,7 +4197,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) bump_faces.push_back(facep); } else if ((te->getShiny() && LLPipeline::sRenderBump) || - !te->getFullbright()) + !(te->getFullbright() || bake_sunlight)) { //needs normal simple_faces.push_back(facep); } @@ -3529,10 +4211,18 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } else { //face has no renderable geometry - facep->mVertexBuffer = NULL; - facep->mLastVertexBuffer = NULL; + facep->clearVertexBuffer(); } } + + if (is_rigged) + { + drawablep->setState(LLDrawable::RIGGED); + } + else + { + drawablep->clearState(LLDrawable::RIGGED); + } } group->mBufferUsage = useage; @@ -3547,7 +4237,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { bump_mask |= LLVertexBuffer::MAP_BINORMAL; } - + genDrawInfo(group, simple_mask, simple_faces); genDrawInfo(group, bump_mask, bump_faces); genDrawInfo(group, fullbright_mask, fullbright_faces); @@ -3593,24 +4283,25 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) LLFastTimer t(FTM_VOLUME_GEOM_PARTIAL); LLDrawable* drawablep = *drawable_iter; - if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) - { - continue; - } - - if (drawablep->isState(LLDrawable::REBUILD_ALL)) + if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) ) { LLVOVolume* vobj = drawablep->getVOVolume(); vobj->preRebuild(); + LLVolume* volume = vobj->getVolume(); for (S32 i = 0; i < drawablep->getNumFaces(); ++i) { LLFace* face = drawablep->getFace(i); - if (face && face->mVertexBuffer.notNull()) + if (face && face->getVertexBuffer()) { face->getGeometryVolume(*volume, face->getTEOffset(), vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()); } + + if (!face) + { + llerrs << "WTF?" << llendl; + } } drawablep->clearState(LLDrawable::REBUILD_ALL); @@ -3653,9 +4344,10 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) for (S32 i = 0; i < drawablep->getNumFaces(); ++i) { LLFace* face = drawablep->getFace(i); - if (face && face->mVertexBuffer.notNull() && face->mVertexBuffer->isLocked()) + LLVertexBuffer* buff = face->getVertexBuffer(); + if (face && buff && buff->isLocked()) { - face->mVertexBuffer->setBuffer(0) ; + buff->setBuffer(0) ; } } } @@ -3673,7 +4365,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort) { //calculate maximum number of vertices to store in a single buffer - U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask); + U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask); max_vertices = llmin(max_vertices, (U32) 65535); if (!distance_sort) @@ -3720,10 +4412,12 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: buffer_index = 0; } + bool bake_sunlight = LLPipeline::sBakeSunlight && facep->getDrawable()->isStatic(); + U32 index_count = facep->getIndicesCount(); U32 geom_count = facep->getGeomCount(); - //sum up vertices needed for this texture + //sum up vertices needed for this render batch std::vector<LLFace*>::iterator i = face_iter; ++i; @@ -3733,7 +4427,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: facep = *i; if (geom_count + facep->getGeomCount() > max_vertices) - { //cut vertex buffers on geom count too big + { //cut batches on geom count too big break; } @@ -3761,10 +4455,11 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: buffer->allocateBuffer(geom_count, index_count, TRUE); } else - { - if (LLVertexBuffer::sEnableVBOs && buffer->getUsage() != group->mBufferUsage) + { //resize pre-existing buffer + if (LLVertexBuffer::sEnableVBOs && buffer->getUsage() != group->mBufferUsage || + buffer->getTypeMask() != mask) { - buffer = createVertexBuffer(group->mSpatialPartition->mVertexDataMask, + buffer = createVertexBuffer(mask, group->mBufferUsage); buffer->allocateBuffer(geom_count, index_count, TRUE); } @@ -3782,15 +4477,18 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: U16 index_offset = 0; while (face_iter < i) - { + { //update face indices for new buffer facep = *face_iter; - facep->mIndicesIndex = indices_index; - facep->mGeomIndex = index_offset; - facep->mVertexBuffer = buffer; + facep->setIndicesIndex(indices_index); + facep->setGeomIndex(index_offset); + facep->setVertexBuffer(buffer); + { + //for debugging, set last time face was updated vs moved facep->updateRebuildFlags(); + if (!LLPipeline::sDelayVBUpdate) - { + { //copy face geometry into vertex buffer LLDrawable* drawablep = facep->getDrawable(); LLVOVolume* vobj = drawablep->getVOVolume(); LLVolume* volume = vobj->getVolume(); @@ -3807,9 +4505,12 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } index_offset += facep->getGeomCount(); - indices_index += facep->mIndicesCount; + indices_index += facep->getIndicesCount(); + - BOOL force_simple = facep->mPixelArea < FORCE_SIMPLE_RENDER_AREA; + //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 @@ -3825,7 +4526,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: // can we safely treat this as an alpha mask? if (facep->canRenderAsMask()) { - if (te->getFullbright()) + if (te->getFullbright() || LLPipeline::sNoAlpha) { registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); } @@ -3889,7 +4590,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: { //invisiprim registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); } - else if (fullbright) + else if (fullbright || bake_sunlight) { //fullbright registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && te->getBumpmap()) @@ -3976,7 +4677,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun //sum up face verts and indices drawablep->updateFaceSize(i); LLFace* facep = drawablep->getFace(i); - if (facep->hasGeometry() && facep->mPixelArea > FORCE_CULL_AREA) + if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA) { vertex_count += facep->getGeomCount(); index_count += facep->getIndicesCount(); @@ -3986,8 +4687,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun } else { - facep->mVertexBuffer = NULL; - facep->mLastVertexBuffer = NULL; + facep->clearVertexBuffer(); } } } @@ -4003,7 +4703,7 @@ LLHUDPartition::LLHUDPartition() mLODPeriod = 1; } -void LLHUDPartition::shift(const LLVector3 &offset) +void LLHUDPartition::shift(const LLVector4a &offset) { //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 8b68e7c78a..fc00f0c0d0 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -40,6 +40,8 @@ class LLDrawPool; class LLSelectNode; class LLObjectMediaDataClient; class LLObjectMediaNavigateClient; +class LLVOAvatar; +class LLMeshSkinInfo; typedef std::vector<viewer_media_t> media_list_t; @@ -48,6 +50,18 @@ enum LLVolumeInterfaceType INTERFACE_FLEXIBLE = 1, }; + +class LLRiggedVolume : public LLVolume +{ +public: + LLRiggedVolume(const LLVolumeParams& params) + : LLVolume(params, 0.f) + { + } + + void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume); +}; + // Base class for implementations of the volume - Primitive, Flexible Object, etc. class LLVolumeInterface { @@ -60,7 +74,7 @@ public: 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 LLVector3 &shift_vector) = 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? @@ -116,7 +130,9 @@ public: const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; } /*virtual*/ const LLMatrix4 getRenderMatrix() const; U32 getRenderCost(std::set<LLUUID> &textures) const; - + /*virtual*/ F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL); + /*virtual*/ U32 getTriangleCount(); + /*virtual*/ U32 getHighLODTriangleCount(); /*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, S32 face = -1, // which face to check, -1 = ALL_SIDES BOOL pick_transparent = FALSE, @@ -140,7 +156,7 @@ public: void markForUpdate(BOOL priority) { LLViewerObject::markForUpdate(priority); mVolumeChanged = TRUE; } - /*virtual*/ void onShift(const LLVector3 &shift_vector); // Called when the drawable shifts + /*virtual*/ void onShift(const LLVector4a &shift_vector); // Called when the drawable shifts /*virtual*/ void parameterChanged(U16 param_type, bool local_origin); /*virtual*/ void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin); @@ -179,6 +195,11 @@ public: void updateSculptTexture(); void setIndexInTex(S32 index) { mIndexInTex = index ;} void sculpt(); + static void rebuildMeshAssetCallback(LLVFS *vfs, + const LLUUID& asset_uuid, + LLAssetType::EType type, + void* user_data, S32 status, LLExtStat ext_status); + void updateRelativeXform(); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); /*virtual*/ void updateFaceSize(S32 idx); @@ -191,7 +212,7 @@ public: void regenFaces(); BOOL genBBoxes(BOOL force_global); void preRebuild(); - virtual void updateSpatialExtents(LLVector3& min, LLVector3& max); + virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max); virtual F32 getBinRadius(); virtual U32 getPartitionType() const; @@ -225,6 +246,7 @@ public: U32 getVolumeInterfaceID() const; virtual BOOL isFlexible() const; virtual BOOL isSculpted() const; + virtual BOOL isMesh() const; virtual BOOL hasLightTexture() const; BOOL isVolumeGlobal() const; @@ -249,6 +271,7 @@ public: 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); @@ -264,9 +287,11 @@ public: LLVector3 getApproximateFaceNormal(U8 face_id); + void notifyMeshLoaded(); + // 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; } @@ -274,6 +299,21 @@ public: void removeMDCImpl() { --mMDCImplCount; } S32 getMDCImplCount() { return mMDCImplCount; } + + //rigged volume update (for raycasting) + void updateRiggedVolume(); + 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(); + + //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); BOOL calcLOD(); @@ -307,6 +347,9 @@ private: S32 mLastFetchedMediaVersion; // as fetched from the server, starts as -1 S32 mIndexInTex; S32 mMDCImplCount; + + LLPointer<LLRiggedVolume> mRiggedVolume; + // statics public: static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index 71f08ec36d..69ebad61ac 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -166,16 +166,18 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) face->setSize(vertices_per_quad * num_quads, indices_per_quad * num_quads); - if (face->mVertexBuffer.isNull()) + LLVertexBuffer* buff = face->getVertexBuffer(); + if (!buff) { - face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB); - face->mVertexBuffer->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); + buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB); + buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); face->setIndicesIndex(0); face->setGeomIndex(0); + face->setVertexBuffer(buff); } else { - face->mVertexBuffer->resizeBuffer(face->getGeomCount(), face->getIndicesCount()); + buff->resizeBuffer(face->getGeomCount(), face->getIndicesCount()); } index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp); @@ -229,7 +231,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) } } - face->mVertexBuffer->setBuffer(0); + buff->setBuffer(0); mDrawable->movePartition(); LLPipeline::sCompiles++; @@ -261,15 +263,21 @@ void LLVOWater::setIsEdgePatch(const BOOL edge_patch) mIsEdgePatch = edge_patch; } -void LLVOWater::updateSpatialExtents(LLVector3 &newMin, LLVector3& newMax) +void LLVOWater::updateSpatialExtents(LLVector4a &newMin, LLVector4a& newMax) { - LLVector3 pos = getPositionAgent(); - LLVector3 scale = getScale(); - - newMin = pos - scale * 0.5f; - newMax = pos + scale * 0.5f; + LLVector4a pos; + pos.load3(getPositionAgent().mV); + LLVector4a scale; + scale.load3(getScale().mV); + scale.mul(0.5f); + + newMin.setSub(pos, scale); + newMax.setAdd(pos, scale); + + pos.setAdd(newMin,newMax); + pos.mul(0.5f); - mDrawable->setPositionGroup((newMin + newMax) * 0.5f); + mDrawable->setPositionGroup(pos); } U32 LLVOWater::getPartitionType() const @@ -283,7 +291,7 @@ U32 LLVOVoidWater::getPartitionType() const } LLWaterPartition::LLWaterPartition() -: LLSpatialPartition(0, FALSE, 0) +: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB) { mInfiniteFarClip = TRUE; mDrawableType = LLPipeline::RENDER_TYPE_WATER; diff --git a/indra/newview/llvowater.h b/indra/newview/llvowater.h index cb9584cabf..ed709dd840 100644 --- a/indra/newview/llvowater.h +++ b/indra/newview/llvowater.h @@ -61,7 +61,7 @@ public: /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); - /*virtual*/ void updateSpatialExtents(LLVector3& newMin, LLVector3& newMax); + /*virtual*/ void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax); /*virtual*/ void updateTextures(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index 5cb61b8734..7b1c725483 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -332,7 +332,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) { const U32 max_buffer_bytes = gSavedSettings.getS32("RenderMaxVBOSize")*1024; const U32 data_mask = LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK; - const U32 max_verts = max_buffer_bytes / LLVertexBuffer::calcStride(data_mask); + const U32 max_verts = max_buffer_bytes / LLVertexBuffer::calcVertexSize(data_mask); const U32 total_stacks = getNumStacks(); diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index b060c9f076..a8a5ef3117 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -396,7 +396,6 @@ protected: */ class LLWearableItemsList : public LLInventoryItemsList { - LOG_CLASS(LLWearableItemsList); public: /** * Context menu. diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index fd42058c8a..3af62d537c 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -61,6 +61,8 @@ #include <map> #include <cstring> +#define TMP_WL_REMOVE_CLOUDS /* disables code for classic clouds */ + // // Globals // @@ -91,8 +93,11 @@ LLWorld::LLWorld() : mLastPacketsIn(0), mLastPacketsOut(0), mLastPacketsLost(0), - mSpaceTimeUSec(0), - mClassicCloudsEnabled(TRUE) + mSpaceTimeUSec(0) +#ifndef TMP_WL_REMOVE_CLOUDS + , + mClassicCloudsEnabled(FALSE) +#endif { for (S32 i = 0; i < 8; i++) { @@ -597,7 +602,7 @@ void LLWorld::updateVisibilities() region_list_t::iterator curiter = iter++; LLViewerRegion* regionp = *curiter; F32 height = regionp->getLand().getMaxZ() - regionp->getLand().getMinZ(); - F32 radius = 0.5f*fsqrtf(height * height + diagonal_squared); + F32 radius = 0.5f*(F32) sqrt(height * height + diagonal_squared); if (!regionp->getLand().hasZData() || LLViewerCamera::getInstance()->sphereInFrustum(regionp->getCenterAgent(), radius)) { @@ -618,7 +623,7 @@ void LLWorld::updateVisibilities() } F32 height = regionp->getLand().getMaxZ() - regionp->getLand().getMinZ(); - F32 radius = 0.5f*fsqrtf(height * height + diagonal_squared); + F32 radius = 0.5f*(F32) sqrt(height * height + diagonal_squared); if (LLViewerCamera::getInstance()->sphereInFrustum(regionp->getCenterAgent(), radius)) { regionp->calculateCameraDistance(); @@ -661,6 +666,7 @@ void LLWorld::updateParticles() LLViewerPartSim::getInstance()->updateSimulation(); } +#ifndef TMP_WL_REMOVE_CLOUDS void LLWorld::updateClouds(const F32 dt) { static LLFastTimer::DeclareTimer ftm("World Clouds"); @@ -672,33 +678,6 @@ void LLWorld::updateClouds(const F32 dt) return; } - if ( - mClassicCloudsEnabled != - gSavedSettings.getBOOL("SkyUseClassicClouds") ) - { - // The classic cloud toggle has been flipped - // gotta update all of the cloud layers - mClassicCloudsEnabled = - gSavedSettings.getBOOL("SkyUseClassicClouds"); - - if ( !mClassicCloudsEnabled && mActiveRegionList.size() ) - { - // We've transitioned to having classic clouds disabled - // reset all cloud layers. - for ( - region_list_t::iterator iter = mActiveRegionList.begin(); - iter != mActiveRegionList.end(); - ++iter) - { - LLViewerRegion* regionp = *iter; - regionp->mCloudLayer.reset(); - } - - return; - } - } - else if ( !mClassicCloudsEnabled ) return; - if (mActiveRegionList.size()) { for (region_list_t::iterator iter = mActiveRegionList.begin(); @@ -745,7 +724,7 @@ LLCloudGroup* LLWorld::findCloudGroup(const LLCloudPuff &puff) } return NULL; } - +#endif // TMP_WL_REMOVE_CLOUDS void LLWorld::renderPropertyLines() { @@ -867,42 +846,6 @@ void LLWorld::waterHeightRegionInfo(std::string const& sim_name, F32 water_heigh } } -// There are three types of water objects: -// Region water objects: the water in a region. -// Hole water objects: water in the void but within current draw distance. -// Edge water objects: the water outside the draw distance, up till the horizon. -// -// For example: -// -// -----------------------horizon------------------------- -// | | | | -// | Edge Water | | | -// | | | | -// | | | | -// | | | | -// | | | | -// | | rwidth | | -// | | <-----> | | -// ------------------------------------------------------- -// | |Hole |other| | | -// | |Water|reg. | | | -// | |-----------------| | -// | |other|cur. |<--> | | -// | |reg. | reg.| \__|_ draw distance | -// | |-----------------| | -// | | | |<--->| | -// | | | | \__|_ range | -// ------------------------------------------------------- -// | |<----width------>|<--horizon ext.->| -// | | | | -// | | | | -// | | | | -// | | | | -// | | | | -// | | | | -// | | | | -// ------------------------------------------------------- -// void LLWorld::updateWaterObjects() { if (!gAgent.getRegion()) @@ -915,265 +858,128 @@ void LLWorld::updateWaterObjects() return; } - // Region width in meters. - S32 const rwidth = (S32)REGION_WIDTH_U32; - - // The distance we might see into the void - // when standing on the edge of a region, in meters. - S32 const draw_distance = llceil(mLandFarClip); - - // We can only have "holes" in the water (where there no region) if we - // can have existing regions around it. Taking into account that this - // code is only executed when we enter a region, and not when we walk - // around in it, we (only) need to take into account regions that fall - // within the draw_distance. - // - // Set 'range' to draw_distance, rounded up to the nearest multiple of rwidth. - S32 const nsims = (draw_distance + rwidth - 1) / rwidth; - S32 const range = nsims * rwidth; - - // Get South-West corner of current region. - LLViewerRegion const* regionp = gAgent.getRegion(); + // First, determine the min and max "box" of water objects + S32 min_x = 0; + S32 min_y = 0; + S32 max_x = 0; + S32 max_y = 0; U32 region_x, region_y; + + S32 rwidth = 256; + + // We only want to fill in water for stuff that's near us, say, within 256 or 512m + S32 range = LLViewerCamera::getInstance()->getFar() > 256.f ? 512 : 256; + + LLViewerRegion* regionp = gAgent.getRegion(); from_region_handle(regionp->getHandle(), ®ion_x, ®ion_y); - // The min. and max. coordinates of the South-West corners of the Hole water objects. - S32 const min_x = (S32)region_x - range; - S32 const min_y = (S32)region_y - range; - S32 const max_x = (S32)region_x + range; - S32 const max_y = (S32)region_y + range; - - // Attempt to determine a sensible water height for all the - // Hole Water objects. - // - // It make little sense to try to guess what the best water - // height should be when that isn't completely obvious: if it's - // impossible to satisfy every region's water height without - // getting a jump in the water height. - // - // In order to keep the reasoning simple, we assume something - // logical as a group of connected regions, where the coastline - // is at the outer edge. Anything more complex that would "break" - // under such an assumption would probably break anyway (would - // depend on terrain editing and existing mega prims, say, if - // anything would make sense at all). - // - // So, what we do is find all connected regions within the - // draw distance that border void, and then pick the lowest - // water height of those (coast) regions. - S32 const n = 2 * nsims + 1; - S32 const origin = nsims + nsims * n; - std::vector<F32> water_heights(n * n); - std::vector<U8> checked(n * n, 0); // index = nx + ny * n + origin; - U8 const region_bit = 1; - U8 const hole_bit = 2; - U8 const bordering_hole_bit = 4; - U8 const bordering_edge_bit = 8; - // Use the legacy waterheight for the Edge water in the case - // that we don't find any Hole water at all. - F32 water_height = DEFAULT_WATER_HEIGHT; - int max_count = 0; - LL_DEBUGS("WaterHeight") << "Current region: " << regionp->getName() << "; water height: " << regionp->getWaterHeight() << " m." << LL_ENDL; - std::map<S32, int> water_height_counts; - typedef std::queue<std::pair<S32, S32>, std::deque<std::pair<S32, S32> > > nxny_pairs_type; - nxny_pairs_type nxny_pairs; - nxny_pairs.push(nxny_pairs_type::value_type(0, 0)); - water_heights[origin] = regionp->getWaterHeight(); - checked[origin] = region_bit; - // For debugging purposes. - int number_of_connected_regions = 1; - int uninitialized_regions = 0; - int bordering_hole = 0; - int bordering_edge = 0; - while(!nxny_pairs.empty()) - { - S32 const nx = nxny_pairs.front().first; - S32 const ny = nxny_pairs.front().second; - LL_DEBUGS("WaterHeight") << "nx,ny = " << nx << "," << ny << LL_ENDL; - S32 const index = nx + ny * n + origin; - nxny_pairs.pop(); - for (S32 dir = 0; dir < 4; ++dir) - { - S32 const cnx = nx + gDirAxes[dir][0]; - S32 const cny = ny + gDirAxes[dir][1]; - LL_DEBUGS("WaterHeight") << "dir = " << dir << "; cnx,cny = " << cnx << "," << cny << LL_ENDL; - S32 const cindex = cnx + cny * n + origin; - bool is_hole = false; - bool is_edge = false; - LLViewerRegion* new_region_found = NULL; - if (cnx < -nsims || cnx > nsims || - cny < -nsims || cny > nsims) - { - LL_DEBUGS("WaterHeight") << " Edge Water!" << LL_ENDL; - // Bumped into Edge water object. - is_edge = true; - } - else if (checked[cindex]) - { - LL_DEBUGS("WaterHeight") << " Already checked before!" << LL_ENDL; - // Already checked. - is_hole = (checked[cindex] & hole_bit); - } - else - { - S32 x = (S32)region_x + cnx * rwidth; - S32 y = (S32)region_y + cny * rwidth; - U64 region_handle = to_region_handle(x, y); - new_region_found = getRegionFromHandle(region_handle); - is_hole = !new_region_found; - checked[cindex] = is_hole ? hole_bit : region_bit; - } - if (is_hole) - { - // This was a region that borders at least one 'hole'. - // Count the found coastline. - F32 new_water_height = water_heights[index]; - LL_DEBUGS("WaterHeight") << " This is void; counting coastline with water height of " << new_water_height << LL_ENDL; - S32 new_water_height_cm = llround(new_water_height * 100); - int count = (water_height_counts[new_water_height_cm] += 1); - // Just use the lowest water height: this is mainly about the horizon water, - // and whatever we do, we don't want it to be possible to look under the water - // when looking in the distance: it is better to make a step downwards in water - // height when going away from the avie than a step upwards. However, since - // everyone is used to DEFAULT_WATER_HEIGHT, don't allow a single region - // to drag the water level below DEFAULT_WATER_HEIGHT on it's own. - if (bordering_hole == 0 || // First time we get here. - (new_water_height >= DEFAULT_WATER_HEIGHT && - new_water_height < water_height) || - (new_water_height < DEFAULT_WATER_HEIGHT && - count > max_count) - ) - { - water_height = new_water_height; - } - if (count > max_count) - { - max_count = count; - } - if (!(checked[index] & bordering_hole_bit)) - { - checked[index] |= bordering_hole_bit; - ++bordering_hole; - } - } - else if (is_edge && !(checked[index] & bordering_edge_bit)) - { - checked[index] |= bordering_edge_bit; - ++bordering_edge; - } - if (!new_region_found) - { - // Dead end, there is no region here. - continue; - } - // Found a new connected region. - ++number_of_connected_regions; - if (new_region_found->getName().empty()) - { - // Uninitialized LLViewerRegion, don't use it's water height. - LL_DEBUGS("WaterHeight") << " Uninitialized region." << LL_ENDL; - ++uninitialized_regions; - continue; - } - nxny_pairs.push(nxny_pairs_type::value_type(cnx, cny)); - water_heights[cindex] = new_region_found->getWaterHeight(); - LL_DEBUGS("WaterHeight") << " Found a new region (name: " << new_region_found->getName() << "; water height: " << water_heights[cindex] << " m)!" << LL_ENDL; - } - } - llinfos << "Number of connected regions: " << number_of_connected_regions << " (" << uninitialized_regions << - " uninitialized); number of regions bordering Hole water: " << bordering_hole << - "; number of regions bordering Edge water: " << bordering_edge << llendl; - llinfos << "Coastline count (height, count): "; - bool first = true; - for (std::map<S32, int>::iterator iter = water_height_counts.begin(); iter != water_height_counts.end(); ++iter) - { - if (!first) llcont << ", "; - llcont << "(" << (iter->first / 100.f) << ", " << iter->second << ")"; - first = false; - } - llcont << llendl; - llinfos << "Water height used for Hole and Edge water objects: " << water_height << llendl; + min_x = (S32)region_x - range; + min_y = (S32)region_y - range; + max_x = (S32)region_x + range; + max_y = (S32)region_y + range; - // Update all Region water objects. - for (region_list_t::iterator iter = mRegionList.begin(); iter != mRegionList.end(); ++iter) + F32 height = 0.f; + + for (region_list_t::iterator iter = mRegionList.begin(); + iter != mRegionList.end(); ++iter) { LLViewerRegion* regionp = *iter; LLVOWater* waterp = regionp->getLand().getWaterObj(); + height += regionp->getWaterHeight(); if (waterp) { gObjectList.updateActive(waterp); } } - // Clean up all existing Hole water objects. for (std::list<LLVOWater*>::iterator iter = mHoleWaterObjects.begin(); - iter != mHoleWaterObjects.end(); ++iter) + iter != mHoleWaterObjects.end(); ++ iter) { LLVOWater* waterp = *iter; gObjectList.killObject(waterp); } mHoleWaterObjects.clear(); - // Let the Edge and Hole water boxes be 1024 meter high so that they - // are never too small to be drawn (A LL_VO_*_WATER box has water - // rendered on it's bottom surface only), and put their bottom at - // the current regions water height. - F32 const box_height = 1024; - F32 const water_center_z = water_height + box_height / 2; - - // Create new Hole water objects within 'range' where there is no region. - for (S32 x = min_x; x <= max_x; x += rwidth) + // Now, get a list of the holes + S32 x, y; + for (x = min_x; x <= max_x; x += rwidth) { - for (S32 y = min_y; y <= max_y; y += rwidth) + for (y = min_y; y <= max_y; y += rwidth) { U64 region_handle = to_region_handle(x, y); if (!getRegionFromHandle(region_handle)) { - LLVOWater* waterp = (LLVOWater*)gObjectList.createObjectViewer(LLViewerObject::LL_VO_VOID_WATER, gAgent.getRegion()); + LLVOWater* waterp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, gAgent.getRegion()); waterp->setUseTexture(FALSE); - waterp->setPositionGlobal(LLVector3d(x + rwidth / 2, y + rwidth / 2, water_center_z)); - waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, box_height)); + waterp->setPositionGlobal(LLVector3d(x + rwidth/2, + y + rwidth/2, + 256.f+DEFAULT_WATER_HEIGHT)); + waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, 512.f)); gPipeline.createObject(waterp); mHoleWaterObjects.push_back(waterp); } } } - // Center of the region. - S32 const center_x = region_x + rwidth / 2; - S32 const center_y = region_y + rwidth / 2; - // Width of the area with Hole water objects. - S32 const width = rwidth + 2 * range; - S32 const horizon_extend = 2048 + 512 - range; // Legacy value. - // The overlap is needed to get rid of sky pixels being visible between the - // Edge and Hole water object at greater distances (due to floating point - // round off errors). - S32 const edge_hole_overlap = 1; // Twice the actual overlap. + // Update edge water objects + S32 wx, wy; + S32 center_x, center_y; + wx = (max_x - min_x) + rwidth; + wy = (max_y - min_y) + rwidth; + center_x = min_x + (wx >> 1); + center_y = min_y + (wy >> 1); + + S32 add_boundary[4] = { + 512 - (max_x - region_x), + 512 - (max_y - region_y), + 512 - (region_x - min_x), + 512 - (region_y - min_y) }; - for (S32 dir = 0; dir < 8; ++dir) + S32 dir; + for (dir = 0; dir < 8; dir++) { - // Size of the Edge water objects. - S32 const dim_x = (gDirAxes[dir][0] == 0) ? width : (horizon_extend + edge_hole_overlap); - S32 const dim_y = (gDirAxes[dir][1] == 0) ? width : (horizon_extend + edge_hole_overlap); - // And their position. - S32 const water_center_x = center_x + (width + horizon_extend) / 2 * gDirAxes[dir][0]; - S32 const water_center_y = center_y + (width + horizon_extend) / 2 * gDirAxes[dir][1]; + S32 dim[2] = { 0 }; + switch (gDirAxes[dir][0]) + { + case -1: dim[0] = add_boundary[2]; break; + case 0: dim[0] = wx; break; + default: dim[0] = add_boundary[0]; break; + } + switch (gDirAxes[dir][1]) + { + case -1: dim[1] = add_boundary[3]; break; + case 0: dim[1] = wy; break; + default: dim[1] = add_boundary[1]; break; + } + // Resize and reshape the water objects + const S32 water_center_x = center_x + llround((wx + dim[0]) * 0.5f * gDirAxes[dir][0]); + const S32 water_center_y = center_y + llround((wy + dim[1]) * 0.5f * gDirAxes[dir][1]); + LLVOWater* waterp = mEdgeWaterObjects[dir]; if (!waterp || waterp->isDead()) { // The edge water objects can be dead because they're attached to the region that the // agent was in when they were originally created. - mEdgeWaterObjects[dir] = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_VOID_WATER, gAgent.getRegion()); + mEdgeWaterObjects[dir] = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_VOID_WATER, + gAgent.getRegion()); waterp = mEdgeWaterObjects[dir]; waterp->setUseTexture(FALSE); - waterp->setIsEdgePatch(TRUE); // Mark that this is edge water and not hole water. + waterp->setIsEdgePatch(TRUE); gPipeline.createObject(waterp); } waterp->setRegion(gAgent.getRegion()); - LLVector3d water_pos(water_center_x, water_center_y, water_center_z); - LLVector3 water_scale((F32) dim_x, (F32) dim_y, box_height); + LLVector3d water_pos(water_center_x, water_center_y, + DEFAULT_WATER_HEIGHT+256.f); + LLVector3 water_scale((F32) dim[0], (F32) dim[1], 512.f); + + //stretch out to horizon + water_scale.mV[0] += fabsf(2048.f * gDirAxes[dir][0]); + water_scale.mV[1] += fabsf(2048.f * gDirAxes[dir][1]); + + water_pos.mdV[0] += 1024.f * gDirAxes[dir][0]; + water_pos.mdV[1] += 1024.f * gDirAxes[dir][1]; waterp->setPositionGlobal(water_pos); waterp->setScale(water_scale); @@ -1182,6 +988,7 @@ void LLWorld::updateWaterObjects() } } + void LLWorld::shiftRegions(const LLVector3& offset) { for (region_list_t::const_iterator i = getRegionList().begin(); i != getRegionList().end(); ++i) diff --git a/indra/newview/llxmlrpclistener.cpp b/indra/newview/llxmlrpclistener.cpp index 2596f239ca..97a9eb7f5f 100644 --- a/indra/newview/llxmlrpclistener.cpp +++ b/indra/newview/llxmlrpclistener.cpp @@ -499,6 +499,13 @@ private: // 'array' as the value of this 'key'. responses.insert(key, array); } + else if (xmlrpc_type_struct == type) + { + LLSD submap = parseValues(status_string, + STRINGIZE(key_pfx << key << ':'), + current); + responses.insert(key, submap); + } else { // whoops - unrecognized type diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 6dc8f28265..f64eb89866 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -67,6 +67,7 @@ #include "llhudnametag.h" #include "llhudtext.h" #include "lllightconstants.h" +#include "llmeshrepository.h" #include "llresmgr.h" #include "llselectmgr.h" #include "llsky.h" @@ -74,6 +75,7 @@ #include "lltool.h" #include "lltoolmgr.h" #include "llviewercamera.h" +#include "llviewermediafocus.h" #include "llviewertexturelist.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" @@ -100,8 +102,29 @@ #include "llspatialpartition.h" #include "llmutelist.h" #include "lltoolpie.h" +#include "llcurl.h" +void check_stack_depth(S32 stack_depth) +{ + if (gDebugGL || gDebugSession) + { + GLint depth; + glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); + if (depth != stack_depth) + { + if (gDebugSession) + { + ll_fail("GL matrix stack corrupted."); + } + else + { + llerrs << "GL matrix stack corrupted!" << llendl; + } + } + } +} + #ifdef _DEBUG // Debug indices is disabled for now for debug performance - djs 4/24/02 //#define DEBUG_INDICES @@ -169,19 +192,20 @@ std::string gPoolNames[] = // Correspond to LLDrawpool enum render type "NONE", "POOL_SIMPLE", - "POOL_TERRAIN", + "POOL_GROUND", + "POOL_FULLBRIGHT", "POOL_BUMP", - "POOL_TREE", + "POOL_TERRAIN," "POOL_SKY", "POOL_WL_SKY", - "POOL_GROUND", + "POOL_TREE", + "POOL_GRASS", "POOL_INVISIBLE", "POOL_AVATAR", + "POOL_VOIDWATER", "POOL_WATER", - "POOL_GRASS", - "POOL_FULLBRIGHT", "POOL_GLOW", - "POOL_ALPHA", + "POOL_ALPHA" }; void drawBox(const LLVector3& c, const LLVector3& r); @@ -216,6 +240,16 @@ glh::matrix4f glh_get_current_projection() return glh_copy_matrix(gGLProjection); } +glh::matrix4f glh_get_last_modelview() +{ + return glh_copy_matrix(gGLLastModelView); +} + +glh::matrix4f glh_get_last_projection() +{ + return glh_copy_matrix(gGLLastProjection); +} + void glh_copy_matrix(const glh::matrix4f& src, GLdouble* dst) { for (U32 i = 0; i < 16; i++) @@ -268,6 +302,8 @@ BOOL LLPipeline::sAutoMaskAlphaDeferred = TRUE; BOOL LLPipeline::sAutoMaskAlphaNonDeferred = FALSE; BOOL LLPipeline::sDisableShaders = FALSE; BOOL LLPipeline::sRenderBump = TRUE; +BOOL LLPipeline::sBakeSunlight = FALSE; +BOOL LLPipeline::sNoAlpha = FALSE; BOOL LLPipeline::sUseTriStrips = TRUE; BOOL LLPipeline::sUseFarClip = TRUE; BOOL LLPipeline::sShadowRender = FALSE; @@ -281,7 +317,6 @@ BOOL LLPipeline::sRenderFrameTest = FALSE; BOOL LLPipeline::sRenderAttachedLights = TRUE; BOOL LLPipeline::sRenderAttachedParticles = TRUE; BOOL LLPipeline::sRenderDeferred = FALSE; -BOOL LLPipeline::sAllowRebuildPriorityGroup = FALSE ; S32 LLPipeline::sVisibleLightCount = 0; F32 LLPipeline::sMinRenderSize = 0.f; @@ -328,6 +363,8 @@ LLPipeline::LLPipeline() : mRenderDebugFeatureMask(0), mRenderDebugMask(0), mOldRenderDebugMask(0), + mGroupQ1Locked(false), + mGroupQ2Locked(false), mLastRebuildPool(NULL), mAlphaPool(NULL), mSkyPool(NULL), @@ -359,6 +396,7 @@ void LLPipeline::init() sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO"); + LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw"); sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights"); sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles"); @@ -393,6 +431,14 @@ void LLPipeline::init() toggleRenderType(RENDER_TYPE_GROUND); } + // 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; @@ -526,6 +572,22 @@ void LLPipeline::resizeScreenTexture() } } +void LLPipeline::allocatePhysicsBuffer() +{ + GLuint resX = gViewerWindow->getWorldViewWidthRaw(); + GLuint resY = gViewerWindow->getWorldViewHeightRaw(); + + if (mPhysicsDisplay.getWidth() != resX || mPhysicsDisplay.getHeight() != resY) + { + mPhysicsDisplay.allocate(resX, resY, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + if (mSampleBuffer.getWidth() == mPhysicsDisplay.getWidth() && + mSampleBuffer.getHeight() == mPhysicsDisplay.getHeight()) + { + mPhysicsDisplay.setSampleBuffer(&mSampleBuffer); + } + } +} + void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) { // remember these dimensions @@ -534,6 +596,11 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) //never use more than 4 samples for render targets U32 samples = llmin(gSavedSettings.getU32("RenderFSAASamples"), (U32) 4); + if (gGLManager.mIsATI) + { //disable multisampling of render targets where ATI is involved + samples = 0; + } + U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor"); if (res_mod > 1 && res_mod < resX && res_mod < resY) @@ -549,6 +616,10 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) if (LLPipeline::sRenderDeferred) { + S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail"); + BOOL ssao = gSavedSettings.getBOOL("RenderDeferredSSAO"); + bool gi = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED); + //allocate deferred rendering color buffers mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); @@ -557,14 +628,40 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); mEdgeMap.allocate(resX, resY, GL_ALPHA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); - for (U32 i = 0; i < 3; i++) + if (shadow_detail > 0 || ssao) + { //only need mDeferredLight[0] for shadows OR ssao + mDeferredLight[0].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + } + else { - mDeferredLight[i].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + mDeferredLight[0].release(); } - for (U32 i = 0; i < 2; i++) + if (ssao) + { //only need mDeferredLight[1] for ssao + mDeferredLight[1].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + } + else + { + mDeferredLight[1].release(); + } + + if (gi) + { //only need mDeferredLight[2] and mGIMapPost for gi + mDeferredLight[2].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + for (U32 i = 0; i < 2; i++) + { + mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + } + } + else { - mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + mDeferredLight[2].release(); + + for (U32 i = 0; i < 2; i++) + { + mGIMapPost[i].release(); + } } F32 scale = gSavedSettings.getF32("RenderShadowResolutionScale"); @@ -572,18 +669,37 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) //HACK: make alpha masking work on ATI depth shadows (work around for ATI driver bug) U32 shadow_fmt = gGLManager.mIsATI ? GL_ALPHA : 0; - for (U32 i = 0; i < 4; i++) + if (shadow_detail > 0) + { //allocate 4 sun shadow maps + for (U32 i = 0; i < 4; i++) + { + mShadow[i].allocate(U32(resX*scale),U32(resY*scale), shadow_fmt, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + } + } + else { - mShadow[i].allocate(U32(resX*scale),U32(resY*scale), shadow_fmt, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + for (U32 i = 0; i < 4; i++) + { + mShadow[i].release(); + } } - U32 width = nhpo2(U32(resX*scale))/2; U32 height = width; - for (U32 i = 4; i < 6; i++) + if (shadow_detail > 1) + { //allocate two spot shadow maps + for (U32 i = 4; i < 6; i++) + { + mShadow[i].allocate(width, height, shadow_fmt, TRUE, FALSE); + } + } + else { - mShadow[i].allocate(width, height, shadow_fmt, TRUE, FALSE); + for (U32 i = 4; i < 6; i++) + { + mShadow[i].release(); + } } width = nhpo2(resX)/2; @@ -592,30 +708,55 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) } else { + for (U32 i = 0; i < 3; i++) + { + mDeferredLight[i].release(); + } + for (U32 i = 0; i < 2; i++) + { + mGIMapPost[i].release(); + } + for (U32 i = 0; i < 6; i++) + { + mShadow[i].release(); + } + mScreen.release(); + mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first + mDeferredDepth.release(); + mEdgeMap.release(); + mLuminanceMap.release(); + mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); } - - if (LLRenderTarget::sUseFBO && gGLManager.mHasFramebufferMultisample && samples > 1) - { + if (LLRenderTarget::sUseFBO && samples > 1) + { mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples); if (LLPipeline::sRenderDeferred) { addDeferredAttachments(mSampleBuffer); mDeferredScreen.setSampleBuffer(&mSampleBuffer); + mEdgeMap.setSampleBuffer(&mSampleBuffer); } mScreen.setSampleBuffer(&mSampleBuffer); stop_glerror(); } + else + { + mSampleBuffer.release(); + } if (LLPipeline::sRenderDeferred) { //share depth buffer between deferred targets mDeferredScreen.shareDepthBuffer(mScreen); for (U32 i = 0; i < 3; i++) { //share stencil buffer with screen space lightmap to stencil out sky - mDeferredScreen.shareDepthBuffer(mDeferredLight[i]); + if (mDeferredLight[i].getTexture(0)) + { + mDeferredScreen.shareDepthBuffer(mDeferredLight[i]); + } } } @@ -636,7 +777,26 @@ void LLPipeline::updateRenderDeferred() gSavedSettings.getBOOL("WindLightUseAtmosShaders")) ? TRUE : FALSE) && !gUseWireframe; - sRenderDeferred = deferred; + sRenderDeferred = deferred; + if (deferred) + { //must render glow when rendering deferred since post effect pass is needed to present any lighting at all + sRenderGlow = TRUE; + } +} + +//static +void LLPipeline::refreshRenderDeferred() +{ + if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) + { + //turn the deferred rendering and glow off when draw physics shapes. + sRenderDeferred = FALSE ; + sRenderGlow = FALSE ; + } + else + { + updateRenderDeferred() ; + } } void LLPipeline::releaseGLBuffers() @@ -664,8 +824,9 @@ void LLPipeline::releaseGLBuffers() mWaterRef.release(); mWaterDis.release(); mScreen.release(); + mPhysicsDisplay.release(); mUIScreen.release(); - mSampleBuffer.releaseSampleBuffer(); + mSampleBuffer.release(); mDeferredScreen.release(); mDeferredDepth.release(); for (U32 i = 0; i < 3; i++) @@ -690,6 +851,7 @@ void LLPipeline::releaseGLBuffers() mGlow[i].release(); } + gBumpImageList.destroyGL(); LLVOAvatar::resetImpostors(); } @@ -728,7 +890,6 @@ void LLPipeline::createGLBuffers() allocateScreenBuffer(resX,resY); mScreenWidth = 0; mScreenHeight = 0; - } if (sRenderDeferred) @@ -813,6 +974,8 @@ void LLPipeline::createGLBuffers() addDeferredAttachments(mGIMap); } } + + gBumpImageList.restoreGL(); } void LLPipeline::restoreGL() @@ -872,7 +1035,7 @@ BOOL LLPipeline::canUseWindLightShadersOnObjects() const BOOL LLPipeline::canUseAntiAliasing() const { - return TRUE; //(gSavedSettings.getBOOL("RenderUseFBO")); + return TRUE; } void LLPipeline::unloadShaders() @@ -910,11 +1073,10 @@ S32 LLPipeline::getMaxLightingDetail() const S32 LLPipeline::setLightingDetail(S32 level) { LLMemType mt_ld(LLMemType::MTYPE_PIPELINE_LIGHTING_DETAIL); - assertInitialized(); if (level < 0) { - if (gSavedSettings.getBOOL("VertexShaderEnable")) + if (gSavedSettings.getBOOL("RenderLocalLights")) { level = 1; } @@ -924,15 +1086,8 @@ S32 LLPipeline::setLightingDetail(S32 level) } } level = llclamp(level, 0, getMaxLightingDetail()); - if (level != mLightingDetail) - { - mLightingDetail = level; - - if (mVertexShadersLoaded == 1) - { - LLViewerShaderMgr::instance()->setShaders(); - } - } + mLightingDetail = level; + return mLightingDetail; } @@ -1158,9 +1313,15 @@ void LLPipeline::allocDrawable(LLViewerObject *vobj) } +static LLFastTimer::DeclareTimer FTM_UNLINK("Unlink"); +static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_MOVE_LIST("Movelist"); +static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_SPATIAL_PARTITION("Spatial Partition"); +static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_LIGHT_SET("Light Set"); +static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_HIGHLIGHT_SET("Highlight Set"); + void LLPipeline::unlinkDrawable(LLDrawable *drawable) { - LLFastTimer t(FTM_PIPELINE); + LLFastTimer t(FTM_UNLINK); assertInitialized(); @@ -1169,6 +1330,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) // Based on flags, remove the drawable from the queues that it's on. if (drawablep->isState(LLDrawable::ON_MOVE_LIST)) { + LLFastTimer t(FTM_REMOVE_FROM_MOVE_LIST); LLDrawable::drawable_vector_t::iterator iter = std::find(mMovedList.begin(), mMovedList.end(), drawablep); if (iter != mMovedList.end()) { @@ -1178,6 +1340,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) if (drawablep->getSpatialGroup()) { + LLFastTimer t(FTM_REMOVE_FROM_SPATIAL_PARTITION); if (!drawablep->getSpatialGroup()->mSpatialPartition->remove(drawablep, drawablep->getSpatialGroup())) { #ifdef LL_RELEASE_FOR_DOWNLOAD @@ -1188,18 +1351,23 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) } } - mLights.erase(drawablep); - for (light_set_t::iterator iter = mNearbyLights.begin(); - iter != mNearbyLights.end(); iter++) { - if (iter->drawable == drawablep) + LLFastTimer t(FTM_REMOVE_FROM_LIGHT_SET); + mLights.erase(drawablep); + + for (light_set_t::iterator iter = mNearbyLights.begin(); + iter != mNearbyLights.end(); iter++) { - mNearbyLights.erase(iter); - break; + if (iter->drawable == drawablep) + { + mNearbyLights.erase(iter); + break; + } } } { + LLFastTimer t(FTM_REMOVE_FROM_HIGHLIGHT_SET); HighlightItem item(drawablep); mHighlightSet.erase(item); @@ -1492,11 +1660,214 @@ F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera 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 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; + } + + //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; } +void LLPipeline::clearReferences() +{ + sCull = NULL; +} + +void check_references(LLSpatialGroup* group, LLDrawable* drawable) +{ + for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + { + if (drawable == *i) + { + llerrs << "LLDrawable deleted while actively reference by LLPipeline." << llendl; + } + } +} + +void check_references(LLDrawable* drawable, LLFace* face) +{ + for (S32 i = 0; i < drawable->getNumFaces(); ++i) + { + if (drawable->getFace(i) == face) + { + llerrs << "LLFace deleted while actively referenced by LLPipeline." << llendl; + } + } +} + +void check_references(LLSpatialGroup* group, LLFace* face) +{ + for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + { + LLDrawable* drawable = *i; + check_references(drawable, face); + } +} + +void LLPipeline::checkReferences(LLFace* face) +{ +#if 0 + if (sCull) + { + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, face); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, face); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, face); + } + + for (LLCullResult::drawable_list_t::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_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, drawable); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, drawable); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, drawable); + } + + for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) + { + if (drawable == *iter) + { + llerrs << "LLDrawable deleted while actively referenced by LLPipeline." << llendl; + } + } + } +#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) + { + llerrs << "LLDrawInfo deleted while actively referenced by LLPipeline." << llendl; + } + } + } +} + + +void LLPipeline::checkReferences(LLDrawInfo* draw_info) +{ +#if 0 + if (sCull) + { + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, draw_info); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, draw_info); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, draw_info); + } + } +#endif +} + +void LLPipeline::checkReferences(LLSpatialGroup* group) +{ +#if 0 + if (sCull) + { + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + if (group == *iter) + { + llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl; + } + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + if (group == *iter) + { + llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl; + } + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + if (group == *iter) + { + llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl; + } + } + } +#endif +} + + BOOL LLPipeline::visibleObjectsInFrustum(LLCamera& camera) { for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); @@ -1563,7 +1934,7 @@ BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& static LLFastTimer::DeclareTimer FTM_CULL("Object Culling"); -void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip) +void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip, LLPlane* planep) { LLFastTimer t(FTM_CULL); LLMemType mt_uc(LLMemType::MTYPE_PIPELINE_UPDATE_CULL); @@ -1583,6 +1954,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl mScreen.bindTarget(); } + if (sUseOcclusion > 1) + { + gGL.setColorMask(false, false); + } + glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadMatrixd(gGLLastProjection); @@ -1597,10 +1973,37 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl LLGLDisable test(GL_ALPHA_TEST); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - if (sUseOcclusion > 1) + + //setup a clip plane in projection matrix for reflection renders (prevents flickering from occlusion culling) + LLViewerRegion* region = gAgent.getRegion(); + LLPlane plane; + + if (planep) { - gGL.setColorMask(false, false); + plane = *planep; + } + else + { + if (region) + { + LLVector3 pnorm; + F32 height = region->getWaterHeight(); + if (water_clip < 0) + { //camera is above water, clip plane points up + pnorm.setVec(0,0,1); + plane.setVec(pnorm, -height); + } + else if (water_clip > 0) + { //camera is below water, clip plane points down + pnorm = LLVector3(0,0,-1); + plane.setVec(pnorm, height); + } + } } + + glh::matrix4f modelview = glh_get_last_modelview(); + glh::matrix4f proj = glh_get_last_projection(); + LLGLUserClipPlane clip(plane, modelview, proj, water_clip != 0 && LLPipeline::sReflectionRender); LLGLDepthTest depth(GL_TRUE, GL_FALSE); @@ -1692,7 +2095,7 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) } if (sMinRenderSize > 0.f && - llmax(llmax(group->mBounds[1].mV[0], group->mBounds[1].mV[1]), group->mBounds[1].mV[2]) < sMinRenderSize) + llmax(llmax(group->mBounds[1][0], group->mBounds[1][1]), group->mBounds[1][2]) < sMinRenderSize) { return; } @@ -1736,33 +2139,34 @@ void LLPipeline::markOccluder(LLSpatialGroup* group) void LLPipeline::doOcclusion(LLCamera& camera) { - LLVertexBuffer::unbind(); - - if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) + if (LLPipeline::sUseOcclusion > 1 && sCull->hasOcclusionGroups()) { - gGL.setColorMask(true, false, false, false); - } - else - { - gGL.setColorMask(false, false); - } - LLGLDisable blend(GL_BLEND); - LLGLDisable test(GL_ALPHA_TEST); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLGLDepthTest depth(GL_TRUE, GL_FALSE); + LLVertexBuffer::unbind(); - LLGLDisable cull(GL_CULL_FACE); - if (LLPipeline::sUseOcclusion > 1) - { + if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) + { + gGL.setColorMask(true, false, false, false); + } + else + { + gGL.setColorMask(false, false); + } + LLGLDisable blend(GL_BLEND); + LLGLDisable test(GL_ALPHA_TEST); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + + LLGLDisable cull(GL_CULL_FACE); + for (LLCullResult::sg_list_t::iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter) { LLSpatialGroup* group = *iter; group->doOcclusion(&camera); group->clearOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION); } + + gGL.setColorMask(true, false); } - - gGL.setColorMask(true, false); } BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) @@ -1789,17 +2193,14 @@ void LLPipeline::updateGL() void LLPipeline::rebuildPriorityGroups() { - if(!sAllowRebuildPriorityGroup) - { - return ; - } - sAllowRebuildPriorityGroup = FALSE ; - LLTimer update_timer; LLMemType mt(LLMemType::MTYPE_PIPELINE); assertInitialized(); + 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) @@ -1810,10 +2211,18 @@ void LLPipeline::rebuildPriorityGroups() } mGroupQ1.clear(); + mGroupQ1Locked = false; + } void LLPipeline::rebuildGroups() { + if (mGroupQ2.empty()) + { + return; + } + + mGroupQ2Locked = true; // Iterate through some drawables on the non-priority build queue S32 size = (S32) mGroupQ2.size(); S32 min_count = llclamp((S32) ((F32) (size * size)/4096*0.25f), 1, size); @@ -1823,33 +2232,30 @@ void LLPipeline::rebuildGroups() std::sort(mGroupQ2.begin(), mGroupQ2.end(), LLSpatialGroup::CompareUpdateUrgency()); LLSpatialGroup::sg_vector_t::iterator iter; + LLSpatialGroup::sg_vector_t::iterator last_iter = mGroupQ2.begin(); + for (iter = mGroupQ2.begin(); - iter != mGroupQ2.end(); ++iter) + iter != mGroupQ2.end() && count <= min_count; ++iter) { LLSpatialGroup* group = *iter; + last_iter = iter; - if (group->isDead()) + if (!group->isDead()) { - continue; + group->rebuildGeom(); + + if (group->mSpatialPartition->mRenderByGroup) + { + count++; + } } - group->rebuildGeom(); - - if (group->mSpatialPartition->mRenderByGroup) - { - count++; - } - group->clearState(LLSpatialGroup::IN_BUILD_Q2); - - if (count > min_count) - { - ++iter; - break; - } } - mGroupQ2.erase(mGroupQ2.begin(), iter); + mGroupQ2.erase(mGroupQ2.begin(), ++last_iter); + + mGroupQ2Locked = false; updateMovedList(mMovedBridge); } @@ -2075,6 +2481,9 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) 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++) { @@ -2083,7 +2492,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) { continue; } - drawablep->shiftPos(offset); + drawablep->shiftPos(offseta); drawablep->clearState(LLDrawable::ON_SHIFT_LIST); } mShiftList.resize(0); @@ -2097,7 +2506,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) LLSpatialPartition* part = region->getSpatialPartition(i); if (part) { - part->shift(offset); + part->shift(offseta); } } } @@ -2129,8 +2538,7 @@ void LLPipeline::markGLRebuild(LLGLUpdate* glu) void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) { LLMemType mt(LLMemType::MTYPE_PIPELINE); - //assert_main_thread(); - + if (group && !group->isDead() && group->mSpatialPartition) { if (group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD) @@ -2142,6 +2550,8 @@ void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) { if (!group->isState(LLSpatialGroup::IN_BUILD_Q1)) { + llassert_always(!mGroupQ1Locked); + mGroupQ1.push_back(group); group->setState(LLSpatialGroup::IN_BUILD_Q1); @@ -2158,11 +2568,7 @@ void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) } else if (!group->isState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1)) { - //llerrs << "Non-priority updates not yet supported!" << llendl; - if (std::find(mGroupQ2.begin(), mGroupQ2.end(), group) != mGroupQ2.end()) - { - llerrs << "WTF?" << llendl; - } + llassert_always(!mGroupQ2Locked); mGroupQ2.push_back(group); group->setState(LLSpatialGroup::IN_BUILD_Q2); @@ -2242,6 +2648,42 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } } } + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) + { + LLSpatialGroup* last_group = NULL; + for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) + { + LLCullResult::bridge_list_t::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); + } + + 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_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) { LLSpatialGroup* group = *iter; @@ -2257,19 +2699,6 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } } - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) - { - for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) - { - LLCullResult::bridge_list_t::iterator cur_iter = i; - LLSpatialBridge* bridge = *cur_iter; - LLSpatialGroup* group = bridge->getSpatialGroup(); - if (!bridge->isDead() && group && !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) - { - stateSort(bridge, camera); - } - } - } { LLFastTimer ftm(FTM_STATESORT_DRAWABLE); for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); @@ -2300,6 +2729,11 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) LLDrawable* drawablep = *i; stateSort(drawablep, camera); } + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) + { //avoid redundant stateSort calls + group->mLastUpdateDistance = group->mDistance; + } } } @@ -2307,7 +2741,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) { LLMemType mt(LLMemType::MTYPE_PIPELINE_STATE_SORT); - if (!sShadowRender && bridge->getSpatialGroup()->changeLOD()) + if (bridge->getSpatialGroup()->changeLOD()) { bool force_update = false; bridge->updateDistance(camera, force_update); @@ -2366,21 +2800,17 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) { - LLSpatialGroup* group = drawablep->getSpatialGroup(); - if (!group || group->changeLOD()) + //if (drawablep->isVisible()) isVisible() check here is redundant, if it wasn't visible, it wouldn't be here { - if (drawablep->isVisible()) + if (!drawablep->isActive()) { - 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() - } + 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() } } } @@ -2608,21 +3038,6 @@ void LLPipeline::postSort(LLCamera& camera) //rebuild groups sCull->assertDrawMapsEmpty(); - /*LLSpatialGroup::sNoDelete = FALSE; - for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) - { - LLSpatialGroup* group = *i; - if (sUseOcclusion && - group->isState(LLSpatialGroup::OCCLUDED)) - { - continue; - } - - group->rebuildGeom(); - } - LLSpatialGroup::sNoDelete = TRUE;*/ - - rebuildPriorityGroups(); llpushcallstacks ; @@ -2668,8 +3083,10 @@ void LLPipeline::postSort(LLCamera& camera) { if (sMinRenderSize > 0.f) { - LLVector3 bounds = (*k)->mExtents[1]-(*k)->mExtents[0]; - if (llmax(llmax(bounds.mV[0], bounds.mV[1]), bounds.mV[2]) > sMinRenderSize) + LLVector4a bounds; + bounds.setSub((*k)->mExtents[1],(*k)->mExtents[0]); + + if (llmax(llmax(bounds[0], bounds[1]), bounds[2]) > sMinRenderSize) { sCull->pushDrawInfo(j->first, *k); } @@ -2830,7 +3247,7 @@ void render_hud_elements() gGL.color4f(1,1,1,1); if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + LLGLEnable multisample(gSavedSettings.getU32("RenderFSAASamples") > 0 ? GL_MULTISAMPLE_ARB : 0); gViewerWindow->renderSelections(FALSE, FALSE, FALSE); // For HUD version in render_ui_3d() // Draw the tracking overlays @@ -3044,6 +3461,13 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) } } + S32 stack_depth = 0; + + if (gDebugGL) + { + glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &stack_depth); + } + /////////////////////////////////////////// // // Sync and verify GL state @@ -3074,7 +3498,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) glMatrixMode(GL_MODELVIEW); LLGLSPipeline gls_pipeline; - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + LLGLEnable multisample(gSavedSettings.getU32("RenderFSAASamples") > 0 ? GL_MULTISAMPLE_ARB : 0); LLGLState gls_color_material(GL_COLOR_MATERIAL, mLightingDetail < 2); @@ -3168,18 +3592,9 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) } poolp->endRenderPass(i); LLVertexBuffer::unbind(); - if (gDebugGL || gDebugPipeline) + if (gDebugGL) { - GLint depth; - glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); - if (depth > 3) - { - if (gDebugSession) - { - ll_fail("GL matrix stack corrupted."); - } - llerrs << "GL matrix stack corrupted!" << llendl; - } + check_stack_depth(stack_depth); std::string msg = llformat("%s pass %d", gPoolNames[cur_type].c_str(), i); LLGLState::checkStates(msg); LLGLState::checkTextureChannels(msg); @@ -3202,11 +3617,11 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) iter1 = iter2; stop_glerror(); } - - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPoolsEnd"); - - LLVertexBuffer::unbind(); + LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPoolsEnd"); + + LLVertexBuffer::unbind(); + gGLLastMatrix = NULL; glLoadMatrixd(gGLModelView); @@ -3253,9 +3668,9 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) { if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { - // Render debugging beacons. - gObjectList.renderObjectBeacons(); - gObjectList.resetObjectBeacons(); + // Render debugging beacons. + gObjectList.renderObjectBeacons(); + gObjectList.resetObjectBeacons(); } else { @@ -3314,7 +3729,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) } } - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + LLGLEnable multisample(gSavedSettings.getU32("RenderFSAASamples") > 0 ? GL_MULTISAMPLE_ARB : 0); LLVertexBuffer::unbind(); @@ -3403,7 +3818,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) LLGLEnable cull(GL_CULL_FACE); - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + LLGLEnable multisample(gSavedSettings.getU32("RenderFSAASamples") > 0 ? GL_MULTISAMPLE_ARB : 0); calcNearbyLights(camera); setupHWLights(NULL); @@ -3588,6 +4003,59 @@ void LLPipeline::addTrianglesDrawn(S32 index_count, U32 render_type) } } +void LLPipeline::renderPhysicsDisplay() +{ + if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) + { + return; + } + + allocatePhysicsBuffer(); + + gGL.flush(); + mPhysicsDisplay.bindTarget(); + glClearColor(0,0,0,1); + gGL.setColorMask(true, true); + mPhysicsDisplay.clear(); + glClearColor(0,0,0,0); + + gGL.setColorMask(true, 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)) + { + part->renderPhysicsShapes(); + } + } + } + } + + for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) + { + LLSpatialBridge* bridge = *i; + if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) + { + glPushMatrix(); + glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); + bridge->renderPhysicsShapes(); + glPopMatrix(); + } + } + + + gGL.flush(); + mPhysicsDisplay.flush(); +} + + void LLPipeline::renderDebug() { LLMemType mt(LLMemType::MTYPE_PIPELINE); @@ -3600,6 +4068,8 @@ void LLPipeline::renderDebug() glLoadMatrixd(gGLModelView); gGL.setColorMask(true, false); + bool hud_only = hasRenderType(LLPipeline::RENDER_TYPE_HUD); + // Debug stuff. for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -3610,7 +4080,8 @@ void LLPipeline::renderDebug() LLSpatialPartition* part = region->getSpatialPartition(i); if (part) { - if (hasRenderType(part->mDrawableType)) + if ( hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES) || + !hud_only && hasRenderType(part->mDrawableType) ) { part->renderDebug(); } @@ -3630,8 +4101,67 @@ void LLPipeline::renderDebug() } } + if (gSavedSettings.getBOOL("DebugShowUploadCost")) + { + std::set<LLUUID> textures; + std::set<LLUUID> sculpts; + std::set<LLUUID> meshes; + + BOOL selected = TRUE; + if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) + { + selected = FALSE; + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + LLSpatialGroup::OctreeNode* node = group->mOctreeNode; + for (LLSpatialGroup::OctreeNode::element_iter elem = node->getData().begin(); elem != node->getData().end(); ++elem) + { + LLDrawable* drawable = *elem; + LLVOVolume* volume = drawable->getVOVolume(); + if (volume && volume->isSelected() == selected) + { + for (U32 i = 0; i < volume->getNumTEs(); ++i) + { + LLTextureEntry* te = volume->getTE(i); + textures.insert(te->getID()); + } + + if (volume->isSculpted()) + { + LLUUID sculpt_id = volume->getVolume()->getParams().getSculptID(); + if (volume->isMesh()) + { + meshes.insert(sculpt_id); + } + else + { + sculpts.insert(sculpt_id); + } + } + } + } + } + + gPipeline.mDebugTextureUploadCost = textures.size() * 10; + gPipeline.mDebugSculptUploadCost = sculpts.size()*10; + + U32 mesh_cost = 0; + + for (std::set<LLUUID>::iterator iter = meshes.begin(); iter != meshes.end(); ++iter) + { + mesh_cost += gMeshRepo.getResourceCost(*iter)*10; + } + + gPipeline.mDebugMeshUploadCost = mesh_cost; + } + if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) { + LLVertexBuffer::unbind(); + LLGLEnable blend(GL_BLEND); LLGLDepthTest depth(TRUE, FALSE); LLGLDisable cull(GL_CULL_FACE); @@ -3695,7 +4225,7 @@ void LLPipeline::renderDebug() if (i < 4) { - if (i == 0 || !mShadowFrustPoints[i].empty()) + //if (i == 0 || !mShadowFrustPoints[i].empty()) { //render visible point cloud gGL.flush(); @@ -3735,11 +4265,12 @@ void LLPipeline::renderDebug() gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV); gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV); gGL.end(); - } - + } } - /*for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + /*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; @@ -3754,7 +4285,9 @@ void LLPipeline::renderDebug() } } } - }*/ + } + gGL.flush(); + glLineWidth(1.f);*/ } } @@ -3794,13 +4327,19 @@ void LLPipeline::renderDebug() if (mRenderDebugMask & LLPipeline::RENDER_DEBUG_BUILD_QUEUE) { U32 count = 0; - U32 size = mBuildQ2.size(); + U32 size = mGroupQ2.size(); LLColor4 col; + LLVertexBuffer::unbind(); LLGLEnable blend(GL_BLEND); + gGL.setSceneBlendType(LLRender::BT_ALPHA); LLGLDepthTest depth(GL_TRUE, GL_FALSE); gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); + gGL.pushMatrix(); + glLoadMatrixd(gGLModelView); + gGLLastMatrix = NULL; + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); iter != mGroupQ2.end(); ++iter) { LLSpatialGroup* group = *iter; @@ -3822,7 +4361,7 @@ void LLPipeline::renderDebug() glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); } - F32 alpha = (F32) (size-count)/size; + F32 alpha = llclamp((F32) (size-count)/size, 0.f, 1.f); LLVector2 c(1.f-alpha, alpha); @@ -3830,7 +4369,7 @@ void LLPipeline::renderDebug() ++count; - col.set(c.mV[0], c.mV[1], 0, alpha*0.5f+0.1f); + col.set(c.mV[0], c.mV[1], 0, alpha*0.5f+0.5f); group->drawObjectBox(col); if (bridge) @@ -3838,9 +4377,13 @@ void LLPipeline::renderDebug() gGL.popMatrix(); } } + + gGL.popMatrix(); } gGL.flush(); + + gPipeline.renderPhysicsDisplay(); } void LLPipeline::rebuildPools() @@ -4172,16 +4715,19 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) light_pos.normalize(); + LLLightState* light = gGL.getLight(1); + mHWLightColors[1] = diffuse; - glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse.mV); - glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV); - glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV); - glLightfv(GL_LIGHT1, GL_POSITION, light_pos.mV); - glLightf (GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0f); - glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f); - glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f); - glLightf (GL_LIGHT1, GL_SPOT_EXPONENT, 0.0f); - glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 180.0f); + + 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) { @@ -4212,22 +4758,28 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) backlight_diffuse *= backlight_mag / max_component; mHWLightColors[1] = backlight_diffuse; - glLightfv(GL_LIGHT1, GL_POSITION, backlight_pos.mV); // this is just sun/moon direction - glLightfv(GL_LIGHT1, GL_DIFFUSE, backlight_diffuse.mV); - glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV); - glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV); - glLightf (GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0f); - glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f); - glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f); - glLightf (GL_LIGHT1, GL_SPOT_EXPONENT, 0.0f); - glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 180.0f); + + 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; - glLightfv(GL_LIGHT1, GL_DIFFUSE, LLColor4::black.mV); - glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV); - glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV); + + light->setDiffuse(LLColor4::black); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); } } @@ -4246,7 +4798,7 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_ { return max_dist; } - F32 dist = fsqrtf(dist2); + F32 dist = (F32) sqrt(dist2); dist *= 1.f / inten; dist -= radius; if (selected) @@ -4275,7 +4827,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) // 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 = gAgentCamera.getCameraPositionAgent(); +// LLVector3 cam_pos = gAgent.getCameraPositionAgent(); LLVector3 cam_pos = LLViewerJoystick::getInstance()->getOverrideCamera() ? camera.getOrigin() : gAgent.getPositionAgent(); @@ -4408,15 +4960,17 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) LLVector4 light_pos(mSunDir, 0.0f); LLColor4 light_diffuse = mSunDiffuse; mHWLightColors[0] = light_diffuse; - glLightfv(GL_LIGHT0, GL_POSITION, light_pos.mV); // this is just sun/moon direction - glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse.mV); - glLightfv(GL_LIGHT0, GL_AMBIENT, LLColor4::black.mV); - glLightfv(GL_LIGHT0, GL_SPECULAR, LLColor4::black.mV); - glLightf (GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0f); - glLightf (GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.0f); - glLightf (GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.0f); - glLightf (GL_LIGHT0, GL_SPOT_EXPONENT, 0.0f); - glLightf (GL_LIGHT0, GL_SPOT_CUTOFF, 180.0f); + + LLLightState* light = gGL.getLight(0); + light->setPosition(light_pos); + light->setDiffuse(light_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); } // Light 1 = Backlight (for avatars) @@ -4474,13 +5028,23 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) float linatten = x / (light_radius); // % of brightness at radius mHWLightColors[cur_light] = light_color; - S32 gllight = GL_LIGHT0+cur_light; - glLightfv(gllight, GL_POSITION, light_pos_gl.mV); - glLightfv(gllight, GL_DIFFUSE, light_color.mV); - glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); - glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f); - glLightf (gllight, GL_LINEAR_ATTENUATION, linatten); - glLightf (gllight, GL_QUADRATIC_ATTENUATION, 0.0f); + 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); + if (sRenderDeferred) + { + light_state->setLinearAttenuation(light_radius*1.5f); + light_state->setQuadraticAttenuation(light->getLightFalloff()*0.5f+1.f); + } + else + { + light_state->setLinearAttenuation(linatten); + light_state->setQuadraticAttenuation(0.f); + } + if (light->isLightSpotlight() // directional (spot-)light && (LLPipeline::sRenderDeferred || gSavedSettings.getBOOL("RenderSpotLightsInNondeferred"))) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on { @@ -4488,22 +5052,21 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) LLQuaternion quat = light->getRenderRotation(); LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction at_axis *= quat; - //llinfos << "SPOT!!!!!!! fov: " << spotparams.mV[0] << " focus: " << spotparams.mV[1] << " dir: " << at_axis << llendl; - glLightfv(gllight, GL_SPOT_DIRECTION, at_axis.mV); - glLightf (gllight, GL_SPOT_EXPONENT, 2.0f); // 2.0 = good old dot product ^ 2 - glLightf (gllight, GL_SPOT_CUTOFF, 90.0f); // hemisphere - const float specular[] = {0.f, 0.f, 0.f, 0.f}; - glLightfv(gllight, GL_SPECULAR, specular); + + light_state->setSpotDirection(at_axis); + light_state->setSpotCutoff(90.f); + light_state->setSpotExponent(2.f); + + light_state->setSpecular(LLColor4::black); } else // omnidirectional (point) light { - glLightf (gllight, GL_SPOT_EXPONENT, 0.0f); - glLightf (gllight, GL_SPOT_CUTOFF, 180.0f); - + light_state->setSpotExponent(0.f); + light_state->setSpotCutoff(180.f); + // we use specular.w = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight - const float specular[] = {0.f, 0.f, 0.f, 1.f}; - glLightfv(gllight, GL_SPECULAR, specular); - //llinfos << "boring light" << llendl; + const LLColor4 specular(0.f, 0.f, 0.f, 1.f); + light_state->setSpecular(specular); } cur_light++; if (cur_light >= 8) @@ -4515,13 +5078,13 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) for ( ; cur_light < 8 ; cur_light++) { mHWLightColors[cur_light] = LLColor4::black; - S32 gllight = GL_LIGHT0+cur_light; - glLightfv(gllight, GL_DIFFUSE, LLColor4::black.mV); - glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); - glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV); - } + LLLightState* light = gGL.getLight(cur_light); - if (isAgentAvatarValid() && + light->setDiffuse(LLColor4::black); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); + } + if (gAgentAvatarp && gAgentAvatarp->mSpecialRenderMode == 3) { LLColor4 light_color = LLColor4::white; @@ -4536,23 +5099,24 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) float linatten = x / (light_radius); // % of brightness at radius mHWLightColors[2] = light_color; - S32 gllight = GL_LIGHT2; - glLightfv(gllight, GL_POSITION, light_pos_gl.mV); - glLightfv(gllight, GL_DIFFUSE, light_color.mV); - glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); - glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV); - glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f); - glLightf (gllight, GL_LINEAR_ATTENUATION, linatten); - glLightf (gllight, GL_QUADRATIC_ATTENUATION, 0.0f); - glLightf (gllight, GL_SPOT_EXPONENT, 0.0f); - glLightf (gllight, GL_SPOT_CUTOFF, 180.0f); + LLLightState* light = gGL.getLight(2); + + light->setPosition(light_pos_gl); + light->setDiffuse(light_color); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); + light->setQuadraticAttenuation(0.f); + light->setConstantAttenuation(0.f); + light->setLinearAttenuation(linatten); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); } // Init GL state glDisable(GL_LIGHTING); - for (S32 gllight=GL_LIGHT0; gllight<=GL_LIGHT7; gllight++) + for (S32 i = 0; i < 8; ++i) { - glDisable(gllight); + gGL.getLight(i)->disable(); } mLightMask = 0; } @@ -4577,15 +5141,16 @@ void LLPipeline::enableLights(U32 mask) stop_glerror(); for (S32 i=0; i<8; i++) { + LLLightState* light = gGL.getLight(i); if (mask & (1<<i)) { - glEnable(GL_LIGHT0 + i); - glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, mHWLightColors[i].mV); + light->enable(); + light->setDiffuse(mHWLightColors[i]); } else { - glDisable(GL_LIGHT0 + i); - glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, LLColor4::black.mV); + light->disable(); + light->setDiffuse(LLColor4::black); } } stop_glerror(); @@ -4609,7 +5174,6 @@ void LLPipeline::enableLightsStatic() if (mLightingDetail >= 2) { mask |= mLightMovingMask; // Hardware moving lights - glColor4f(0.f, 0.f, 0.f, 1.0f); // no local lighting by default } else { @@ -4623,11 +5187,7 @@ void LLPipeline::enableLightsDynamic() assertInitialized(); U32 mask = 0xff & (~2); // Local lights enableLights(mask); - if (mLightingDetail >= 2) - { - glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default - } - + if (isAgentAvatarValid() && getLightingDetail() <= 0) { if (gAgentAvatarp->mSpecialRenderMode == 0) // normal @@ -4648,6 +5208,65 @@ void LLPipeline::enableLightsAvatar() enableLights(mask); } +void LLPipeline::enableLightsPreview() +{ + disableLights(); + + glEnable(GL_LIGHTING); + LLColor4 ambient = gSavedSettings.getColor4("PreviewAmbientColor"); + glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambient.mV); + + + LLColor4 diffuse0 = gSavedSettings.getColor4("PreviewDiffuse0"); + LLColor4 specular0 = gSavedSettings.getColor4("PreviewSpecular0"); + LLColor4 diffuse1 = gSavedSettings.getColor4("PreviewDiffuse1"); + LLColor4 specular1 = gSavedSettings.getColor4("PreviewSpecular1"); + LLColor4 diffuse2 = gSavedSettings.getColor4("PreviewDiffuse2"); + LLColor4 specular2 = gSavedSettings.getColor4("PreviewSpecular2"); + + LLVector3 dir0 = gSavedSettings.getVector3("PreviewDirection0"); + LLVector3 dir1 = gSavedSettings.getVector3("PreviewDirection1"); + LLVector3 dir2 = gSavedSettings.getVector3("PreviewDirection2"); + + dir0.normVec(); + dir1.normVec(); + dir2.normVec(); + + LLVector4 light_pos(dir0, 0.0f); + + LLLightState* light = gGL.getLight(0); + + light->enable(); + light->setPosition(light_pos); + light->setDiffuse(diffuse0); + light->setAmbient(LLColor4::black); + light->setSpecular(specular0); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); + + light_pos = LLVector4(dir1, 0.f); + + light = gGL.getLight(1); + light->enable(); + light->setPosition(light_pos); + light->setDiffuse(diffuse1); + light->setAmbient(LLColor4::black); + light->setSpecular(specular1); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); + + light_pos = LLVector4(dir2, 0.f); + light = gGL.getLight(2); + light->enable(); + light->setPosition(light_pos); + light->setDiffuse(diffuse2); + light->setAmbient(LLColor4::black); + 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 @@ -4664,16 +5283,11 @@ void LLPipeline::enableLightsFullbright(const LLColor4& color) enableLights(mask); glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV); - /*if (mLightingDetail >= 2) - { - glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default - }*/ } void LLPipeline::disableLights() { enableLights(0); // no lighting (full bright) - glColor4f(1.f, 1.f, 1.f, 1.f); // lighting color = white by default } //============================================================================ @@ -4939,6 +5553,18 @@ BOOL LLPipeline::toggleRenderDebugFeatureControl(void* data) return gPipeline.hasRenderDebugFeatureMask(bit); } +void LLPipeline::setRenderDebugFeatureControl(U32 bit, bool value) +{ + if (value) + { + gPipeline.mRenderDebugFeatureMask |= bit; + } + else + { + gPipeline.mRenderDebugFeatureMask &= !bit; + } +} + // static void LLPipeline::setRenderScriptedBeacons(BOOL val) { @@ -5289,17 +5915,12 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable) for (S32 i = 0; i < drawable->getNumFaces(); i++) { LLFace* facep = drawable->getFace(i); - facep->mVertexBuffer = NULL; - facep->mLastVertexBuffer = NULL; + facep->clearVertexBuffer(); } } void LLPipeline::resetVertexBuffers() -{ - sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); - sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); - LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO"); - +{ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { @@ -5339,8 +5960,16 @@ void LLPipeline::resetVertexBuffers() llwarns << "VBO name pool cleanup failed." << llendl; } - LLVertexBuffer::unbind(); - + LLVertexBuffer::unbind(); + + sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); + sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); + LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO"); + LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw"); + LLVertexBuffer::sEnableVBOs = gSavedSettings.getBOOL("RenderVBOEnable"); + LLVertexBuffer::sDisableVBOMapping = LLVertexBuffer::sEnableVBOs && gSavedSettings.getBOOL("RenderVBOMappingDisable") ; + sBakeSunlight = gSavedSettings.getBOOL("RenderBakeSunlight"); + sNoAlpha = gSavedSettings.getBOOL("RenderNoAlpha"); LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind"); } @@ -5355,42 +5984,6 @@ void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture) gGLLastMatrix = NULL; } -void LLPipeline::setUseVBO(BOOL use_vbo) -{ - if (use_vbo != LLVertexBuffer::sEnableVBOs) - { - if (use_vbo) - { - llinfos << "Enabling VBO." << llendl; - } - else - { - llinfos << "Disabling VBO." << llendl; - } - - resetVertexBuffers(); - LLVertexBuffer::initClass(use_vbo, gSavedSettings.getBOOL("RenderVBOMappingDisable")); - } -} - -void LLPipeline::setDisableVBOMapping(BOOL no_vbo_mapping) -{ - if (LLVertexBuffer::sEnableVBOs && no_vbo_mapping != LLVertexBuffer::sDisableVBOMapping) - { - if (no_vbo_mapping) - { - llinfos << "Disabling VBO glMapBufferARB." << llendl; - } - else - { - llinfos << "Enabling VBO glMapBufferARB." << llendl; - } - - resetVertexBuffers(); - LLVertexBuffer::initClass(true, no_vbo_mapping); - } -} - void apply_cube_face_rotation(U32 face) { switch (face) @@ -5422,21 +6015,21 @@ void apply_cube_face_rotation(U32 face) void validate_framebuffer_object() { GLenum status; - status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT); switch(status) { - case GL_FRAMEBUFFER_COMPLETE_EXT: + case GL_FRAMEBUFFER_COMPLETE: //framebuffer OK, no error. break; - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: // frame buffer not OK: probably means unsupported depth buffer format - llerrs << "Framebuffer Incomplete Dimensions." << llendl; + llerrs << "Framebuffer Incomplete Missing Attachment." << llendl; break; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: // frame buffer not OK: probably means unsupported depth buffer format llerrs << "Framebuffer Incomplete Attachment." << llendl; break; - case GL_FRAMEBUFFER_UNSUPPORTED_EXT: + case GL_FRAMEBUFFER_UNSUPPORTED: /* choose different formats */ llerrs << "Framebuffer unsupported." << llendl; break; @@ -5484,8 +6077,6 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) tc2 /= (F32) res_mod; } - gGL.setColorMask(true, true); - LLFastTimer ftm(FTM_RENDER_BLOOM); gGL.color4f(1,1,1,1); LLGLDepthTest depth(GL_FALSE); @@ -5681,7 +6272,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) if (LLRenderTarget::sUseFBO) { LLFastTimer ftm(FTM_RENDER_BLOOM_FBO); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); } gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; @@ -5697,16 +6288,149 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) LLVertexBuffer::unbind(); - if (LLPipeline::sRenderDeferred && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) + if (LLPipeline::sRenderDeferred && !LLViewerCamera::getInstance()->cameraUnderWater()) { + bool dof_enabled = true; + + LLGLSLShader* shader = &gDeferredPostProgram; + if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) + { + shader = &gDeferredGIFinalProgram; + dof_enabled = false; + } + else if (LLToolMgr::getInstance()->inBuildMode() || !gSavedSettings.getBOOL("RenderDepthOfField")) + { //squish focal length when in build mode (or if DoF is disabled) so DoF doesn't make editing objects difficult + shader = &gDeferredPostNoDoFProgram; + dof_enabled = false; + } + + LLGLDisable blend(GL_BLEND); - bindDeferredShader(gDeferredGIFinalProgram); + bindDeferredShader(*shader); + + if (dof_enabled) + { + //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 = gDebugRaycastIntersection; + } + else if (gAgentCamera.cameraMouselook()) + { //focus on point under mouselook crosshairs + gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, + NULL, + &focus_point); + } + else + { + LLViewerObject* obj = gAgentCamera.getFocusObject(); + if (obj) + { //focus on alt-zoom target + focus_point = LLVector3(gAgentCamera.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal()); + } + else + { //focus on your avatar + focus_point = gAgent.getPositionAgent(); + } + } + } - S32 channel = gDeferredGIFinalProgram.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); + 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/gSavedSettings.getF32("CameraFocusTransitionTime")*gFrameIntervalSeconds; + 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 = gSavedSettings.getF32("CameraFNumber"); + F32 default_focal_length = gSavedSettings.getF32("CameraFocalLength"); + + F32 fov = LLViewerCamera::getInstance()->getView(); + + const F32 default_fov = gSavedSettings.getF32("CameraFieldOfView") * F_PI/180.f; + //const F32 default_aspect_ratio = gSavedSettings.getF32("CameraAspectRatio"); + + //F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight(); + + F32 dv = 2.f*default_focal_length * tanf(default_fov/2.f); + //F32 dh = 2.f*default_focal_length * tanf(default_fov*default_aspect_ratio/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); + + shader->uniform1f("focal_distance", -subject_distance/1000.f); + shader->uniform1f("blur_constant", blur_constant); + shader->uniform1f("tan_pixel_angle", tanf(1.f/LLDrawable::sCurPixelAngle)); + shader->uniform1f("magnification", magnification); + } + + S32 channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); if (channel > -1) { mScreen.bindTexture(0, channel); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); } + //channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); + //if (channel > -1) + //{ + //gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + //} gGL.begin(LLRender::TRIANGLE_STRIP); gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); @@ -5720,11 +6444,10 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) gGL.end(); - unbindDeferredShader(gDeferredGIFinalProgram); + unbindDeferredShader(*shader); } else { - if (res_mod > 1) { tc2 /= (F32) res_mod; @@ -5772,7 +6495,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) gGL.getTexUnit(1)->bind(&mScreen); gGL.getTexUnit(1)->activate(); - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + LLGLEnable multisample(gSavedSettings.getU32("RenderFSAASamples") > 0 ? GL_MULTISAMPLE_ARB : 0); buff->setBuffer(mask); buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3); @@ -5782,16 +6505,41 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + } - if (LLRenderTarget::sUseFBO) - { //copy depth buffer from mScreen to framebuffer - LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), - 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); - } + if (LLRenderTarget::sUseFBO) + { //copy depth buffer from mScreen to framebuffer + LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), + 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); } - gGL.setSceneBlendType(LLRender::BT_ALPHA); + + if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) + { + LLVector2 tc1(0,0); + LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw()*2, + (F32) gViewerWindow->getWorldViewHeightRaw()*2); + + LLGLEnable blend(GL_BLEND); + gGL.color4f(1,1,1,0.75f); + + gGL.getTexUnit(0)->bind(&mPhysicsDisplay); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1,-1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1,3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3,-1); + + gGL.end(); + gGL.flush(); + } + glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); @@ -6174,6 +6922,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen shader.uniform2f("proj_shadow_res", mShadow[4].getWidth(), mShadow[4].getHeight()); shader.uniform1f("depth_cutoff", gSavedSettings.getF32("RenderEdgeDepthCutoff")); shader.uniform1f("norm_cutoff", gSavedSettings.getF32("RenderEdgeNormCutoff")); + if (shader.getUniformLocation("norm_mat") >= 0) { @@ -6211,7 +6960,7 @@ void LLPipeline::renderDeferredLighting() 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); } - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + LLGLEnable multisample(gSavedSettings.getU32("RenderFSAASamples") > 0 ? GL_MULTISAMPLE_ARB : 0); if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) { @@ -6250,16 +6999,15 @@ void LLPipeline::renderDeferredLighting() glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0); } - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - - mDeferredLight[0].bindTarget(); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); if (gSavedSettings.getBOOL("RenderDeferredSSAO") || gSavedSettings.getS32("RenderShadowDetail") > 0) { + mDeferredLight[0].bindTarget(); { //paint shadow/SSAO light map (direct lighting lightmap) LLFastTimer ftm(FTM_SUN_SHADOW); bindDeferredShader(gDeferredSunProgram, 0); @@ -6300,16 +7048,9 @@ void LLPipeline::renderDeferredLighting() unbindDeferredShader(gDeferredSunProgram); } - } - else - { - glClearColor(1,1,1,1); - mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT); - glClearColor(0,0,0,0); - } - mDeferredLight[0].flush(); - + } + { //global illumination specific block (still experimental) if (gSavedSettings.getBOOL("RenderDeferredBlurLight") && gSavedSettings.getBOOL("RenderDeferredGI")) @@ -6352,7 +7093,7 @@ void LLPipeline::renderDeferredLighting() mLuminanceMap.flush(); gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLuminanceMap.getTexture(), true); gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); - glGenerateMipmapEXT(GL_TEXTURE_2D); + glGenerateMipmap(GL_TEXTURE_2D); } } @@ -6415,75 +7156,74 @@ void LLPipeline::renderDeferredLighting() } if (gSavedSettings.getBOOL("RenderDeferredSSAO")) - { //soften direct lighting lightmap - LLFastTimer ftm(FTM_SOFTEN_SHADOW); - //blur lightmap - mDeferredLight[1].bindTarget(); + { //soften direct lighting lightmap + LLFastTimer ftm(FTM_SOFTEN_SHADOW); + //blur lightmap + mDeferredLight[1].bindTarget(); - glClearColor(1,1,1,1); - mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); - glClearColor(0,0,0,0); - - bindDeferredShader(gDeferredBlurLightProgram); + glClearColor(1,1,1,1); + mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); + glClearColor(0,0,0,0); + + bindDeferredShader(gDeferredBlurLightProgram); - LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); - const U32 kern_length = 4; - F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); - F32 dist_factor = gSavedSettings.getF32("RenderShadowBlurDistFactor"); + LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); + const U32 kern_length = 4; + F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); + F32 dist_factor = gSavedSettings.getF32("RenderShadowBlurDistFactor"); - // sample symmetrically with the middle sample falling exactly on 0.0 - F32 x = 0.f; + // sample symmetrically with the middle sample falling exactly on 0.0 + F32 x = 0.f; - LLVector3 gauss[32]; // xweight, yweight, offset + LLVector3 gauss[32]; // xweight, yweight, offset - for (U32 i = 0; i < kern_length; i++) - { - gauss[i].mV[0] = llgaussian(x, go.mV[0]); - gauss[i].mV[1] = llgaussian(x, go.mV[1]); - gauss[i].mV[2] = x; - x += 1.f; - } + for (U32 i = 0; i < kern_length; i++) + { + gauss[i].mV[0] = llgaussian(x, go.mV[0]); + gauss[i].mV[1] = llgaussian(x, go.mV[1]); + gauss[i].mV[2] = x; + x += 1.f; + } - gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); - gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor); - gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); + gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); + gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor); + gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); + gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + stop_glerror(); + } - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - stop_glerror(); - } - - mDeferredLight[1].flush(); - unbindDeferredShader(gDeferredBlurLightProgram); + mDeferredLight[1].flush(); + unbindDeferredShader(gDeferredBlurLightProgram); - bindDeferredShader(gDeferredBlurLightProgram, 1); - mDeferredLight[0].bindTarget(); + bindDeferredShader(gDeferredBlurLightProgram, 1); + mDeferredLight[0].bindTarget(); - gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); + gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - stop_glerror(); - } - mDeferredLight[0].flush(); - unbindDeferredShader(gDeferredBlurLightProgram); + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + stop_glerror(); } + mDeferredLight[0].flush(); + unbindDeferredShader(gDeferredBlurLightProgram); + } - stop_glerror(); - glPopMatrix(); - stop_glerror(); - glMatrixMode(GL_MODELVIEW); - stop_glerror(); - glPopMatrix(); - stop_glerror(); + stop_glerror(); + glPopMatrix(); + stop_glerror(); + glMatrixMode(GL_MODELVIEW); + stop_glerror(); + glPopMatrix(); + stop_glerror(); //copy depth and stencil from deferred screen //mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), @@ -6549,10 +7289,8 @@ void LLPipeline::renderDeferredLighting() gPipeline.popRenderTypeMask(); } - BOOL render_local = gSavedSettings.getBOOL("RenderDeferredLocalLights"); - BOOL render_fullscreen = gSavedSettings.getBOOL("RenderDeferredFullscreenLights"); - - + BOOL render_local = gSavedSettings.getBOOL("RenderLocalLights"); + if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) { mDeferredLight[1].flush(); @@ -6560,7 +7298,7 @@ void LLPipeline::renderDeferredLighting() mDeferredLight[2].clear(GL_COLOR_BUFFER_BIT); } - if (render_local || render_fullscreen) + if (render_local) { gGL.setSceneBlendType(LLRender::BT_ADD); std::list<LLVector4> fullscreen_lights; @@ -6574,10 +7312,11 @@ void LLPipeline::renderDeferredLighting() std::list<LLVector4> light_colors; + LLVertexBuffer::unbind(); + F32 v[24]; glVertexPointer(3, GL_FLOAT, 0, v); - BOOL render_local = gSavedSettings.getBOOL("RenderDeferredLocalLights"); - + { bindDeferredShader(gDeferredLightProgram); LLGLDepthTest depth(GL_TRUE, GL_FALSE); @@ -6600,8 +7339,9 @@ void LLPipeline::renderDeferredLighting() } - LLVector3 center = drawablep->getPositionAgent(); - F32* c = center.mV; + LLVector4a center; + center.load3(drawablep->getPositionAgent().mV); + const F32* c = center.getF32ptr(); F32 s = volume->getLightRadius()*1.5f; LLColor3 col = volume->getLightColor(); @@ -6617,7 +7357,9 @@ void LLPipeline::renderDeferredLighting() continue; } - if (camera->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0) + LLVector4a sa; + sa.splat(s); + if (camera->AABBInFrustumNoFarClip(center, sa) == 0) { continue; } @@ -6661,11 +7403,11 @@ void LLPipeline::renderDeferredLighting() glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center)); + GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, center)); stop_glerror(); } } - else if (render_fullscreen) + else { if (volume->isLightSpotlight()) { @@ -6695,8 +7437,9 @@ void LLPipeline::renderDeferredLighting() LLVOVolume* volume = drawablep->getVOVolume(); - LLVector3 center = drawablep->getPositionAgent(); - F32* c = center.mV; + LLVector4a center; + center.load3(drawablep->getPositionAgent().mV); + const F32* c = center.getF32ptr(); F32 s = volume->getLightRadius()*1.5f; sVisibleLightCount++; @@ -6726,7 +7469,7 @@ void LLPipeline::renderDeferredLighting() glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center)); + GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, center)); } gDeferredSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); unbindDeferredShader(gDeferredSpotLightProgram); @@ -6768,9 +7511,7 @@ void LLPipeline::renderDeferredLighting() if (count == max_count || fullscreen_lights.empty()) { gDeferredMultiLightProgram.uniform1i("light_count", count); - gDeferredMultiLightProgram.uniform4fv("light[0]", count, (GLfloat*) light); gDeferredMultiLightProgram.uniform4fv("light", count, (GLfloat*) light); - gDeferredMultiLightProgram.uniform4fv("light_col[0]", count, (GLfloat*) col); gDeferredMultiLightProgram.uniform4fv("light_col", count, (GLfloat*) col); gDeferredMultiLightProgram.uniform1f("far_z", far_z); far_z = 0.f; @@ -7138,11 +7879,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLCamera camera = camera_in; camera.setFar(camera.getFar()*0.87654321f); LLPipeline::sReflectionRender = TRUE; - S32 occlusion = LLPipeline::sUseOcclusion; - - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; - - LLPipeline::sUseOcclusion = llmin(occlusion, 1); gPipeline.pushRenderTypeMask(); @@ -7178,22 +7914,27 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) if (!LLViewerCamera::getInstance()->cameraUnderWater()) { //generate planar reflection map + + //disable occlusion culling for reflection map for now + S32 occlusion = LLPipeline::sUseOcclusion; + LLPipeline::sUseOcclusion = 0; gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); glClearColor(0,0,0,0); mWaterRef.bindTarget(); + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0; gGL.setColorMask(true, true); mWaterRef.clear(); gGL.setColorMask(true, false); mWaterRef.getViewport(gGLViewport); - + stop_glerror(); glPushMatrix(); mat.set_scale(glh::vec3f(1,1,-1)); mat.set_translate(glh::vec3f(0,0,height*2.f)); - + glh::matrix4f current = glh_get_current_modelview(); mat = current * mat; @@ -7213,47 +7954,46 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) glCullFace(GL_FRONT); static LLCullResult ref_result; - + if (LLDrawPoolWater::sNeedsDistortionUpdate) { //initial sky pass (no user clip plane) { //mask out everything but the sky gPipeline.pushRenderTypeMask(); gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, - LLPipeline::RENDER_TYPE_WL_SKY, - LLPipeline::END_RENDER_TYPES); + LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::RENDER_TYPE_CLOUDS, + LLPipeline::END_RENDER_TYPES); + static LLCullResult result; updateCull(camera, result); stateSort(camera, result); - andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, - LLPipeline::RENDER_TYPE_CLOUDS, - LLPipeline::RENDER_TYPE_WL_SKY, - LLPipeline::END_RENDER_TYPES); renderGeom(camera, TRUE); + gPipeline.popRenderTypeMask(); } gPipeline.pushRenderTypeMask(); clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER, - LLPipeline::RENDER_TYPE_VOIDWATER, - LLPipeline::RENDER_TYPE_GROUND, - LLPipeline::RENDER_TYPE_SKY, - LLPipeline::RENDER_TYPE_CLOUDS, - LLPipeline::END_RENDER_TYPES); + LLPipeline::RENDER_TYPE_VOIDWATER, + LLPipeline::RENDER_TYPE_GROUND, + LLPipeline::RENDER_TYPE_SKY, + LLPipeline::RENDER_TYPE_CLOUDS, + LLPipeline::END_RENDER_TYPES); - S32 detail = gSavedSettings.getS32("RenderReflectionDetail"); + S32 detail = gSavedSettings.getS32("RenderReflectionDetail"); if (detail > 0) { //mask out selected geometry based on reflection detail if (detail < 4) { clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES); - if (detail < 3) - { - clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); - if (detail < 2) + if (detail < 3) { + clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); + if (detail < 2) + { clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES); } } @@ -7261,19 +8001,19 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLGLUserClipPlane clip_plane(plane, mat, projection); LLGLDisable cull(GL_CULL_FACE); - updateCull(camera, ref_result, 1); + updateCull(camera, ref_result, -water_clip, &plane); stateSort(camera, ref_result); - } - - if (LLDrawPoolWater::sNeedsDistortionUpdate) - { - if (gSavedSettings.getS32("RenderReflectionDetail") > 0) + } + + if (LLDrawPoolWater::sNeedsDistortionUpdate) { - gPipeline.grabReferences(ref_result); - LLGLUserClipPlane clip_plane(plane, mat, projection); - renderGeom(camera); - } - } + if (gSavedSettings.getS32("RenderReflectionDetail") > 0) + { + gPipeline.grabReferences(ref_result); + LLGLUserClipPlane clip_plane(plane, mat, projection); + renderGeom(camera); + } + } gPipeline.popRenderTypeMask(); } @@ -7281,6 +8021,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) glPopMatrix(); mWaterRef.flush(); glh_set_current_modelview(current); + LLPipeline::sUseOcclusion = occlusion; } camera.setOrigin(camera_in.getOrigin()); @@ -7311,15 +8052,18 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLColor4& col = LLDrawPoolWater::sWaterFogColor; glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f); mWaterDis.bindTarget(); + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1; mWaterDis.getViewport(gGLViewport); if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate) { //clip out geometry on the same side of water as the camera mat = glh_get_current_modelview(); - LLGLUserClipPlane clip_plane(LLPlane(-pnorm, -(pd+pad)), mat, projection); + LLPlane plane(-pnorm, -(pd+pad)); + + LLGLUserClipPlane clip_plane(plane, mat, projection); static LLCullResult result; - updateCull(camera, result, water_clip); + updateCull(camera, result, water_clip, &plane); stateSort(camera, result); gGL.setColorMask(true, true); @@ -7347,8 +8091,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gPipeline.popRenderTypeMask(); LLDrawPoolWater::sNeedsReflectionUpdate = FALSE; LLDrawPoolWater::sNeedsDistortionUpdate = FALSE; - LLViewerCamera::getInstance()->setUserClipPlane(LLPlane(-pnorm, -pd)); - LLPipeline::sUseOcclusion = occlusion; + LLPlane npnorm(-pnorm, -pd); + LLViewerCamera::getInstance()->setUserClipPlane(npnorm); LLGLState::checkStates(); LLGLState::checkTextureChannels(); @@ -7358,6 +8102,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) { gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode()); } + + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; } } @@ -7460,14 +8206,14 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera glLoadMatrixf(proj.m); glMatrixMode(GL_MODELVIEW); glPushMatrix(); - glLoadMatrixf(view.m); + glLoadMatrixd(gGLModelView); stop_glerror(); gGLLastMatrix = NULL; { - LLGLDepthTest depth(GL_TRUE); - glClear(GL_DEPTH_BUFFER_BIT); + //LLGLDepthTest depth(GL_TRUE); + //glClear(GL_DEPTH_BUFFER_BIT); } gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -7480,6 +8226,8 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera //glCullFace(GL_FRONT); + LLVertexBuffer::unbind(); + { LLFastTimer ftm(FTM_SHADOW_SIMPLE); LLGLDisable test(GL_ALPHA_TEST); @@ -7547,14 +8295,13 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector } //get set of planes on bounding box - std::vector<LLPlane> bp; - - bp.push_back(LLPlane(min, LLVector3(-1,0,0))); - bp.push_back(LLPlane(min, LLVector3(0,-1,0))); - bp.push_back(LLPlane(min, LLVector3(0,0,-1))); - bp.push_back(LLPlane(max, LLVector3(1,0,0))); - bp.push_back(LLPlane(max, LLVector3(0,1,0))); - bp.push_back(LLPlane(max, LLVector3(0,0,1))); + 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<LLVector3> pp; @@ -7602,7 +8349,8 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector const LLPlane& cp = camera.getAgentPlane(j); const LLVector3& v1 = pp[bs[i*2+0]]; const LLVector3& v2 = pp[bs[i*2+1]]; - const LLVector3 n(cp.mV); + LLVector3 n; + cp.getVector3(n); LLVector3 line = v1-v2; @@ -7616,8 +8364,8 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector LLVector3 intersect = v2+line*t; pp.push_back(intersect); } - } } + } //camera frustum line segments const U32 fs[] = @@ -7625,7 +8373,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector 0,1, 1,2, 2,3, - 3,1, + 3,0, 4,5, 5,6, @@ -7648,7 +8396,8 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector const LLVector3& v1 = pp[fs[i*2+0]+8]; const LLVector3& v2 = pp[fs[i*2+1]+8]; const LLPlane& cp = bp[j]; - const LLVector3 n(cp.mV); + LLVector3 n; + cp.getVector3(n); LLVector3 line = v1-v2; @@ -7663,7 +8412,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector pp.push_back(intersect); } } - } + } LLVector3 ext[] = { min-LLVector3(0.05f,0.05f,0.05f), max+LLVector3(0.05f,0.05f,0.05f) }; @@ -8027,6 +8776,14 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLVector3 n = gSavedSettings.getVector3("RenderShadowNearDist"); //F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] }; + //put together a universal "near clip" plane for shadow frusta + LLPlane shadow_near_clip; + { + LLVector3 p = gAgent.getPositionAgent(); + p += mSunDir * gSavedSettings.getF32("RenderFarClip")*2.f; + shadow_near_clip.setVec(p, mSunDir); + } + LLVector3 lightDir = -mSunDir; lightDir.normVec(); @@ -8101,7 +8858,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) near_clip = -max.mV[2]; F32 far_clip = -min.mV[2]*2.f; - far_clip = llmin(far_clip, 128.f); + //far_clip = llmin(far_clip, 128.f); far_clip = llmin(far_clip, camera.getFar()); F32 range = far_clip-near_clip; @@ -8391,11 +9148,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera) fovx = acos(fovx); fovz = acos(fovz); - if (fovx > cutoff || llround(fovz, 0.01f) > cutoff) - { - // llerrs << "WTF?" << llendl; - } - mShadowFOV.mV[j] = cutoff; } @@ -8451,7 +9203,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) } } - shadow_cam.setFar(128.f); + //shadow_cam.setFar(128.f); shadow_cam.setOriginAndLookAt(eye, up, center); shadow_cam.setOrigin(0,0,0); @@ -8461,7 +9213,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); - shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR); + //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, @@ -8488,7 +9241,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mShadow[j].bindTarget(); mShadow[j].getViewport(gGLViewport); - + mShadow[j].clear(); + { static LLCullResult result[4]; @@ -8507,152 +9261,138 @@ void LLPipeline::generateSunShadow(LLCamera& camera) //hack to disable projector shadows - static bool clear = true; bool gen_shadow = gSavedSettings.getS32("RenderShadowDetail") > 1; if (gen_shadow) { - clear = true; - F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); + F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); - //update shadow targets - for (U32 i = 0; i < 2; i++) - { //for each current shadow - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i; - - if (mShadowSpotLight[i].notNull() && - (mShadowSpotLight[i] == mTargetShadowSpotLight[0] || - mShadowSpotLight[i] == mTargetShadowSpotLight[1])) - { //keep this spotlight - mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f); - } - else - { //fade out this light - mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f); - - if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) - { //faded out, grab one of the pending spots (whichever one isn't already taken) - if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2]) - { - mShadowSpotLight[i] = mTargetShadowSpotLight[0]; - } - else - { - mShadowSpotLight[i] = mTargetShadowSpotLight[1]; + //update shadow targets + for (U32 i = 0; i < 2; i++) + { //for each current shadow + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i; + + if (mShadowSpotLight[i].notNull() && + (mShadowSpotLight[i] == mTargetShadowSpotLight[0] || + mShadowSpotLight[i] == mTargetShadowSpotLight[1])) + { //keep this spotlight + mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f); + } + else + { //fade out this light + mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f); + + if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) + { //faded out, grab one of the pending spots (whichever one isn't already taken) + if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2]) + { + mShadowSpotLight[i] = mTargetShadowSpotLight[0]; + } + else + { + mShadowSpotLight[i] = mTargetShadowSpotLight[1]; + } } } } - } - - for (S32 i = 0; i < 2; i++) - { - glh_set_current_modelview(saved_view); - glh_set_current_projection(saved_proj); - if (mShadowSpotLight[i].isNull()) + for (S32 i = 0; i < 2; i++) { - continue; - } + glh_set_current_modelview(saved_view); + glh_set_current_projection(saved_proj); - LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); + if (mShadowSpotLight[i].isNull()) + { + continue; + } - if (!volume) - { - mShadowSpotLight[i] = NULL; - continue; - } + LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); - LLDrawable* drawable = mShadowSpotLight[i]; + if (!volume) + { + mShadowSpotLight[i] = NULL; + continue; + } - LLVector3 params = volume->getSpotLightParams(); - F32 fov = params.mV[0]; + LLDrawable* drawable = mShadowSpotLight[i]; - //get agent->light space matrix (modelview) - LLVector3 center = drawable->getPositionAgent(); - LLQuaternion quat = volume->getRenderRotation(); + LLVector3 params = volume->getSpotLightParams(); + F32 fov = params.mV[0]; - //get near clip plane - LLVector3 scale = volume->getScale(); - LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); - at_axis *= quat; + //get agent->light space matrix (modelview) + LLVector3 center = drawable->getPositionAgent(); + LLQuaternion quat = volume->getRenderRotation(); - LLVector3 np = center+at_axis; - at_axis.normVec(); + //get near clip plane + LLVector3 scale = volume->getScale(); + LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); + at_axis *= quat; - //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 np = center+at_axis; + at_axis.normVec(); - LLVector3 origin = np - at_axis*dist; + //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); - LLMatrix4 mat(quat, LLVector4(origin, 1.f)); + LLVector3 origin = np - at_axis*dist; - view[i+4] = glh::matrix4f((F32*) mat.mMatrix); + LLMatrix4 mat(quat, LLVector4(origin, 1.f)); - view[i+4] = view[i+4].inverse(); + view[i+4] = glh::matrix4f((F32*) mat.mMatrix); - //get perspective matrix - F32 near_clip = dist+0.01f; - F32 width = scale.mV[VX]; - F32 height = scale.mV[VY]; - F32 far_clip = dist+volume->getLightRadius()*1.5f; + view[i+4] = view[i+4].inverse(); - F32 fovy = fov * RAD_TO_DEG; - F32 aspect = width/height; - - proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip); + //get perspective matrix + F32 near_clip = dist+0.01f; + F32 width = scale.mV[VX]; + F32 height = scale.mV[VY]; + F32 far_clip = dist+volume->getLightRadius()*1.5f; - //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); + F32 fovy = fov * RAD_TO_DEG; + F32 aspect = width/height; + + proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip); - glh_set_current_modelview(view[i+4]); - glh_set_current_projection(proj[i+4]); + //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); - mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; - - for (U32 j = 0; j < 16; j++) - { - gGLLastModelView[j] = mShadowModelview[i+4].m[j]; - gGLLastProjection[j] = mShadowProjection[i+4].m[j]; - } + glh_set_current_modelview(view[i+4]); + glh_set_current_projection(proj[i+4]); - mShadowModelview[i+4] = view[i+4]; - mShadowProjection[i+4] = proj[i+4]; + mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; + + for (U32 j = 0; j < 16; j++) + { + gGLLastModelView[j] = mShadowModelview[i+4].m[j]; + gGLLastProjection[j] = mShadowProjection[i+4].m[j]; + } - LLCamera shadow_cam = camera; - shadow_cam.setFar(far_clip); - shadow_cam.setOrigin(origin); + mShadowModelview[i+4] = view[i+4]; + mShadowProjection[i+4] = proj[i+4]; - LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); + LLCamera shadow_cam = camera; + shadow_cam.setFar(far_clip); + shadow_cam.setOrigin(origin); - stop_glerror(); + LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); - mShadow[i+4].bindTarget(); - mShadow[i+4].getViewport(gGLViewport); + stop_glerror(); - static LLCullResult result[2]; + mShadow[i+4].bindTarget(); + mShadow[i+4].getViewport(gGLViewport); + mShadow[i+4].clear(); - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4; + static LLCullResult result[2]; - renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE); + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4; - mShadow[i+4].flush(); - } - } - else - { - if (clear) - { - clear = false; - for (U32 i = 4; i < 6; i++) - { - mShadow[i].bindTarget(); - mShadow[i].clear(); - mShadow[i].flush(); - } - } + renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE); + + mShadow[i+4].flush(); + } } if (!gSavedSettings.getBOOL("CameraOffset")) @@ -8772,7 +9512,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) stateSort(*LLViewerCamera::getInstance(), result); - const LLVector3* ext = avatar->mDrawable->getSpatialExtents(); + const LLVector4a* ext = avatar->mDrawable->getSpatialExtents(); LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset()); LLCamera camera = *viewer_camera; @@ -8781,25 +9521,30 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) LLVector2 tdim; - LLVector3 half_height = (ext[1]-ext[0])*0.5f; - LLVector3 left = camera.getLeftAxis(); - left *= left; - left.normalize(); + 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); + left.normalize3fast(); - LLVector3 up = camera.getUpAxis(); - up *= up; - up.normalize(); + LLVector4a up; + up.load3(camera.getUpAxis().mV); + up.mul(up); + up.normalize3fast(); - tdim.mV[0] = fabsf(half_height * left); - tdim.mV[1] = fabsf(half_height * up); + tdim.mV[0] = fabsf(half_height.dot3(left).getF32()); + tdim.mV[1] = fabsf(half_height.dot3(up).getF32()); glMatrixMode(GL_PROJECTION); glPushMatrix(); - //glh::matrix4f ortho = gl_ortho(-tdim.mV[0], tdim.mV[0], -tdim.mV[1], tdim.mV[1], 1.0, 256.0); + 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]; //128.f/256.f; + F32 aspect = tdim.mV[0]/tdim.mV[1]; glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f); glh_set_current_projection(persp); glLoadMatrixf(persp.m); @@ -8816,9 +9561,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) glClearColor(0.0f,0.0f,0.0f,0.0f); gGL.setColorMask(true, true); - glStencilMask(0xFFFFFFFF); - glClearStencil(0); - + // get the number of pixels per angle F32 pa = gViewerWindow->getWindowHeightRaw() / (RAD_TO_DEG * viewer_camera->getView()); @@ -8829,7 +9572,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) if (!avatar->mImpostor.isComplete() || resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight()) { - avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,TRUE); + avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE); if (LLPipeline::sRenderDeferred) { @@ -8841,43 +9584,30 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } - LLGLEnable stencil(GL_STENCIL_TEST); - glStencilMask(0xFFFFFFFF); - glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + avatar->mImpostor.bindTarget(); - { - LLGLEnable scissor(GL_SCISSOR_TEST); - glScissor(0, 0, resX, resY); - avatar->mImpostor.bindTarget(); - avatar->mImpostor.clear(); - } - if (LLPipeline::sRenderDeferred) { - stop_glerror(); + avatar->mImpostor.clear(); renderGeomDeferred(camera); renderGeomPostDeferred(camera); } else { + LLGLEnable scissor(GL_SCISSOR_TEST); + glScissor(0, 0, resX, resY); + avatar->mImpostor.clear(); renderGeom(camera); } - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - glStencilFunc(GL_EQUAL, 1, 0xFFFFFF); - - { //create alpha mask based on stencil buffer (grey out if muted) - LLVector3 left = camera.getLeftAxis()*tdim.mV[0]*2.f; - LLVector3 up = camera.getUpAxis()*tdim.mV[1]*2.f; - + { //create alpha mask based on depth buffer (grey out if muted) if (LLPipeline::sRenderDeferred) { - GLuint buff = GL_COLOR_ATTACHMENT0_EXT; + GLuint buff = GL_COLOR_ATTACHMENT0; glDrawBuffersARB(1, &buff); } - LLGLEnable blend(muted ? 0 : GL_BLEND); + LLGLDisable blend(GL_BLEND); if (muted) { @@ -8888,25 +9618,34 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) gGL.setColorMask(false, true); } - gGL.setSceneBlendType(LLRender::BT_ADD); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLGLDepthTest depth(GL_FALSE, GL_FALSE); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER); + + gGL.flush(); + + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + static const F32 clip_plane = 0.99999f; - gGL.color4f(1,1,1,1); gGL.color4ub(64,64,64,255); 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.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.setSceneBlendType(LLRender::BT_ALPHA); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); } - avatar->mImpostor.flush(); avatar->setImpostorDim(tdim); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 92ae40ebb0..e9a250cd6d 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -42,6 +42,10 @@ #include <stack> +#include <stack> + +#include <stack> + class LLViewerTexture; class LLEdge; class LLFace; @@ -54,6 +58,9 @@ class LLCubeMap; class LLCullResult; class LLVOAvatar; class LLGLSLShader; +class LLCurlRequest; + +class LLMeshResponder; typedef enum e_avatar_skinning_method { @@ -107,11 +114,11 @@ public: void resizeScreenTexture(); void releaseGLBuffers(); void createGLBuffers(); - void allocateScreenBuffer(U32 resX, U32 resY); + void allocateScreenBuffer(U32 resX, U32 resY); + void allocatePhysicsBuffer(); + void resetVertexBuffers(LLDrawable* drawable); - void setUseVBO(BOOL use_vbo); - void setDisableVBOMapping(BOOL no_vbo_mapping); void generateImpostor(LLVOAvatar* avatar); void bindScreenToTexture(); void renderBloom(BOOL for_snapshot, F32 zoom_factor = 1.f, int subfield = 0); @@ -201,7 +208,7 @@ public: BOOL visibleObjectsInFrustum(LLCamera& camera); BOOL getVisibleExtents(LLCamera& camera, LLVector3 &min, LLVector3& max); BOOL getVisiblePointCloud(LLCamera& camera, LLVector3 &min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir = LLVector3(0,0,0)); - void updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip = 0); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane + void updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip = 0, LLPlane* plane = NULL); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane void createObjects(F32 max_dtime); void createObject(LLViewerObject* vobj); void updateGeom(F32 max_dtime); @@ -211,6 +218,7 @@ public: //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); @@ -223,6 +231,14 @@ public: void renderGroups(LLRenderPass* pass, U32 type, U32 mask, 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 renderGeom(LLCamera& camera, BOOL forceVBOUpdate = FALSE); void renderGeomDeferred(LLCamera& camera); @@ -245,6 +261,7 @@ public: void generateGI(LLCamera& camera, LLVector3& lightDir, std::vector<LLVector3>& vpc); void renderHighlights(); void renderDebug(); + void renderPhysicsDisplay(); void rebuildPools(); // Rebuild pools @@ -260,6 +277,7 @@ public: void enableLightsStatic(); void enableLightsDynamic(); void enableLightsAvatar(); + void enableLightsPreview(); void enableLightsAvatarEdit(const LLColor4& color); void enableLightsFullbright(const LLColor4& color); void disableLights(); @@ -303,6 +321,7 @@ public: static BOOL toggleRenderTypeControlNegated(void* data); static BOOL toggleRenderDebugControl(void* data); static BOOL toggleRenderDebugFeatureControl(void* data); + static void setRenderDebugFeatureControl(U32 bit, bool value); static void setRenderParticleBeacons(BOOL val); static void toggleRenderParticleBeacons(void* data); @@ -337,6 +356,7 @@ public: static BOOL getRenderHighlights(void* data); static void updateRenderDeferred(); + static void refreshRenderDeferred(); private: void unloadShaders(); @@ -430,6 +450,9 @@ public: RENDER_DEBUG_BUILD_QUEUE = 0x0200000, RENDER_DEBUG_AGENT_TARGET = 0x0400000, RENDER_DEBUG_UPDATE_TYPE = 0x0800000, + RENDER_DEBUG_PHYSICS_SHAPES = 0x1000000, + RENDER_DEBUG_NORMALS = 0x2000000, + RENDER_DEBUG_LOD_INFO = 0x4000000, }; public: @@ -452,6 +475,10 @@ public: S32 mNumVisibleNodes; S32 mVerticesRelit; + S32 mDebugTextureUploadCost; + S32 mDebugSculptUploadCost; + S32 mDebugMeshUploadCost; + S32 mLightingChanges; S32 mGeometryChanges; @@ -467,6 +494,8 @@ public: static BOOL sAutoMaskAlphaNonDeferred; static BOOL sDisableShaders; // if TRUE, rendering will be done without shaders static BOOL sRenderBump; + static BOOL sBakeSunlight; + static BOOL sNoAlpha; static BOOL sUseTriStrips; static BOOL sUseFarClip; static BOOL sShadowRender; @@ -482,7 +511,6 @@ public: static BOOL sRenderAttachedLights; static BOOL sRenderAttachedParticles; static BOOL sRenderDeferred; - static BOOL sAllowRebuildPriorityGroup; static S32 sVisibleLightCount; static F32 sMinRenderSize; @@ -501,6 +529,7 @@ public: LLRenderTarget mGIMapPost[2]; LLRenderTarget mLuminanceMap; LLRenderTarget mHighlight; + LLRenderTarget mPhysicsDisplay; //sun shadow map LLRenderTarget mShadow[6]; @@ -608,6 +637,8 @@ protected: LLDrawable::drawable_list_t mBuildQ2; // non-priority LLSpatialGroup::sg_vector_t mGroupQ1; //priority LLSpatialGroup::sg_vector_t mGroupQ2; // non-priority + bool mGroupQ2Locked; + bool mGroupQ1Locked; LLViewerObject::vobj_list_t mCreateQ; diff --git a/indra/newview/res/resource.h b/indra/newview/res/resource.h index 28813be896..01d90da971 100644 --- a/indra/newview/res/resource.h +++ b/indra/newview/res/resource.h @@ -38,6 +38,7 @@ #define IDC_CURSOR5 154 #define IDI_LCD_LL_ICON 157 #define IDC_CURSOR6 158 +#define IDC_STATIC 1000 #define IDC_RADIO_56 1000 #define IDC_RADIO_128 1001 #define IDC_RADIO_256 1002 diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc index 5e8cee1f5f..38d04b4b5c 100644 --- a/indra/newview/res/viewerRes.rc +++ b/indra/newview/res/viewerRes.rc @@ -7,7 +7,7 @@ // // Generated from the TEXTINCLUDE 2 resource. // -#include "winres.h" +#include "windows.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS @@ -34,7 +34,7 @@ END 2 TEXTINCLUDE BEGIN - "#include ""winres.h""\r\n" + "#include ""windows.h""\r\n" "\0" END diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index a19eccf748..d02662681b 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -760,6 +760,14 @@ <color name="MenuBarProjectBgColor" reference="MdBlue" /> + + <color + name="MeshImportTableNormalColor" + value="1 1 1 1"/> + <color + name="MeshImportTableHighlightColor" + value="0.2 0.8 1 1"/> + <!-- Generic color names (legacy) --> <color diff --git a/indra/newview/skins/default/textures/icons/Edit_Wrench.png b/indra/newview/skins/default/textures/icons/Edit_Wrench.png Binary files differindex 250697b4b1..edb40b9c96 100644 --- a/indra/newview/skins/default/textures/icons/Edit_Wrench.png +++ b/indra/newview/skins/default/textures/icons/Edit_Wrench.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Mesh.png b/indra/newview/skins/default/textures/icons/Inv_Mesh.png Binary files differnew file mode 100644 index 0000000000..f1f21f7941 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Mesh.png diff --git a/indra/newview/skins/default/textures/icons/check_mark.png b/indra/newview/skins/default/textures/icons/check_mark.png Binary files differnew file mode 100644 index 0000000000..2c05297f4f --- /dev/null +++ b/indra/newview/skins/default/textures/icons/check_mark.png diff --git a/indra/newview/skins/default/textures/model_wizard/divider_line.png b/indra/newview/skins/default/textures/model_wizard/divider_line.png Binary files differnew file mode 100644 index 0000000000..76c9e68767 --- /dev/null +++ b/indra/newview/skins/default/textures/model_wizard/divider_line.png diff --git a/indra/newview/skins/default/textures/model_wizard/progress_bar_bg.png b/indra/newview/skins/default/textures/model_wizard/progress_bar_bg.png Binary files differnew file mode 100644 index 0000000000..d0b213cdc5 --- /dev/null +++ b/indra/newview/skins/default/textures/model_wizard/progress_bar_bg.png diff --git a/indra/newview/skins/default/textures/model_wizard/progress_light.png b/indra/newview/skins/default/textures/model_wizard/progress_light.png Binary files differnew file mode 100644 index 0000000000..019344f812 --- /dev/null +++ b/indra/newview/skins/default/textures/model_wizard/progress_light.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 1ca48b01a8..cc7cce99c9 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -73,7 +73,22 @@ with the same filename but different name <texture name="BackButton_Press" file_name="icons/back_arrow_press.png" preload="false" scale.left="22" scale.top="12" scale.right="25" scale.bottom="12" /> <texture name="Blank" file_name="Blank.png" preload="false" /> - + + <texture name="BreadCrumbBtn_Left_Disabled" file_name="widgets/BreadCrumbBtn_Left_Disabled.png" preload="false"/> + <texture name="BreadCrumbBtn_Left_Off" file_name="widgets/BreadCrumbBtn_Left_Off.png" preload="false"/> + <texture name="BreadCrumbBtn_Left_Over" file_name="widgets/BreadCrumbBtn_Left_Over.png" preload="false"/> + <texture name="BreadCrumbBtn_Left_Press" file_name="widgets/BreadCrumbBtn_Left_Press.png" preload="false"/> + + <texture name="BreadCrumbBtn_Middle_Disabled" file_name="widgets/BreadCrumbBtn_Middle_Disabled.png" preload="false"/> + <texture name="BreadCrumbBtn_Middle_Off" file_name="widgets/BreadCrumbBtn_Middle_Off.png" preload="false"/> + <texture name="BreadCrumbBtn_Middle_Over" file_name="widgets/BreadCrumbBtn_Middle_Over.png" preload="false"/> + <texture name="BreadCrumbBtn_Middle_Press" file_name="widgets/BreadCrumbBtn_Middle_Press.png" preload="false"/> + + <texture name="BreadCrumbBtn_Right_Disabled" file_name="widgets/BreadCrumbBtn_Right_Disabled.png" preload="false"/> + <texture name="BreadCrumbBtn_Right_Off" file_name="widgets/BreadCrumbBtn_Right_Off.png" preload="false"/> + <texture name="BreadCrumbBtn_Right_Over" file_name="widgets/BreadCrumbBtn_Right_Over.png" preload="false"/> + <texture name="BreadCrumbBtn_Right_Press" file_name="widgets/BreadCrumbBtn_Right_Press.png" preload="false"/> + <texture name="BuyArrow_Over" file_name="navbar/BuyArrow_Over.png" preload="true" scale.left="0" scale.top="1" scale.right="0" scale.bottom="0" /> <texture name="BuyArrow_Press" file_name="navbar/BuyArrow_Press.png" preload="true" scale.left="1" scale.top="1" scale.right="0" scale.bottom="0" /> @@ -102,6 +117,7 @@ with the same filename but different name <texture name="Checkbox_On" file_name="widgets/Checkbox_On.png" preload="true" /> <texture name="Checkbox_On_Press" file_name="widgets/Checkbox_On_Press.png" preload="true" /> <texture name="Checkbox_Press" file_name="widgets/Checkbox_Press.png" preload="true" /> + <texture name="Check_Mark" file_name="icons/check_mark" preload="true" /> <texture name="ComboButton_Disabled" file_name="widgets/ComboButton_Disabled.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" /> <texture name="ComboButton_Selected" file_name="widgets/ComboButton_Selected.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" /> @@ -211,6 +227,7 @@ with the same filename but different name <texture name="Inv_LostClosed" file_name="icons/Inv_LostClosed.png" preload="false" /> <texture name="Inv_LostOpen" file_name="icons/Inv_LostOpen.png" preload="false" /> <texture name="Inv_Landmark" file_name="icons/Inv_Landmark.png" preload="false" /> + <texture name="Inv_Mesh" file_name="icons/Inv_Mesh.png" preload="false" /> <texture name="Inv_Notecard" file_name="icons/Inv_Notecard.png" preload="false" /> <texture name="Inv_Object" file_name="icons/Inv_Object.png" preload="false" /> <texture name="Inv_Object_Multi" file_name="icons/Inv_Object_Multi.png" preload="false" /> @@ -258,6 +275,10 @@ with the same filename but different name <texture name="menu_separator" file_name="navbar/FileMenu_Divider.png" scale.left="4" scale.top="166" scale.right="0" scale.bottom="0" /> + <texture name="ModelImport_Status_Good" file_name="lag_status_good.tga" preload="false"/> + <texture name="ModelImport_Status_Warning" file_name="lag_status_warning.tga" preload="false"/> + <texture name="ModelImport_Status_Error" file_name="lag_status_critical.tga" preload="false"/> + <texture name="MouseLook_View_Off" file_name="bottomtray/MouseLook_view_off.png" preload="false" /> <texture name="MouseLook_View_On" file_name="bottomtray/MouseLook_view_on.png" preload="false" /> @@ -626,6 +647,8 @@ with the same filename but different name <texture name="icon_for_sale.tga" file_name="icons/Icon_For_Sale.png" /> <texture name="icon_top_pick.tga" /> + <texture name="inv_folder_mesh.tga"/> + <texture name="inv_item_mesh.tga"/> <texture name="lag_status_critical.tga" /> <texture name="lag_status_good.tga" /> <texture name="lag_status_warning.tga" /> diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Disabled.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Disabled.png Binary files differnew file mode 100644 index 0000000000..c7c0eaa96b --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Disabled.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Off.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Off.png Binary files differnew file mode 100644 index 0000000000..4a73c254fc --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Off.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Over.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Over.png Binary files differnew file mode 100644 index 0000000000..6fb5c432de --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Over.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Press.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Press.png Binary files differnew file mode 100644 index 0000000000..fa18517933 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Left_Press.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Disabled.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Disabled.png Binary files differnew file mode 100644 index 0000000000..bed1a701bd --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Disabled.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Off.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Off.png Binary files differnew file mode 100644 index 0000000000..57ce9af574 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Off.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Over.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Over.png Binary files differnew file mode 100644 index 0000000000..2c43022f0e --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Over.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Press.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Press.png Binary files differnew file mode 100644 index 0000000000..6b8c1baca4 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Middle_Press.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Disabled.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Disabled.png Binary files differnew file mode 100644 index 0000000000..51505e80c5 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Disabled.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Off.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Off.png Binary files differnew file mode 100644 index 0000000000..9f93efbd93 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Off.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Over.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Over.png Binary files differnew file mode 100644 index 0000000000..3a4ec1a315 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Over.png diff --git a/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Press.png b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Press.png Binary files differnew file mode 100644 index 0000000000..1f1b4c2ed5 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/BreadCrumbBtn_Right_Press.png diff --git a/indra/newview/skins/default/xui/da/panel_media_settings_security.xml b/indra/newview/skins/default/xui/da/panel_media_settings_security.xml index 278fe0eeea..1b64888271 100644 --- a/indra/newview/skins/default/xui/da/panel_media_settings_security.xml +++ b/indra/newview/skins/default/xui/da/panel_media_settings_security.xml @@ -2,7 +2,8 @@ <panel label="Sikkerhed" name="Media Settings Security"> <check_box initial_value="false" label="Tillad kun adgang til angivne URL mønstre" name="whitelist_enable"/> <text name="home_url_fails_some_items_in_whitelist"> - Angivelser som hjemmesiden fejler imod er markeret: + Angivelser som hjemmesiden fejler imod er +markeret: </text> <button label="Tilføj" name="whitelist_add"/> <button label="Slet" name="whitelist_del"/> diff --git a/indra/newview/skins/default/xui/de/floater_buy_land.xml b/indra/newview/skins/default/xui/de/floater_buy_land.xml index 5369155cf9..ca4ee8981b 100644 --- a/indra/newview/skins/default/xui/de/floater_buy_land.xml +++ b/indra/newview/skins/default/xui/de/floater_buy_land.xml @@ -127,41 +127,41 @@ unterstützt [AMOUNT2] Objekte <text name="region_name_label"> Region: </text> - <text left="680" left_delta="140" name="region_name_text"> + <text name="region_name_text"> (unbekannt) </text> <text name="region_type_label"> Typ: </text> - <text left="680" left_delta="140" name="region_type_text"> + <text name="region_type_text"> (unbekannt) </text> <text name="estate_name_label"> Grundbesitz: </text> - <text left="680" left_delta="140" name="estate_name_text"> + <text name="estate_name_text"> (unbekannt) </text> - <text name="estate_owner_label" right="600" width="200"> + <text name="estate_owner_label"> Grundbesitzer: </text> - <text left="680" left_delta="140" name="estate_owner_text"> + <text name="estate_owner_text"> (unbekannt) </text> - <text left="410" name="resellable_changeable_label"> + <text name="resellable_changeable_label"> Gekauftes Land in dieser Region: </text> - <text left="410" name="resellable_clause"> + <text name="resellable_clause"> Wiederverkauf möglich oder nicht möglich. </text> - <text left="410" name="changeable_clause"> + <text name="changeable_clause"> Darft oder darf nicht zusammengelegt/unterteilt werden. </text> - <text left="410" name="covenant_text"> + <text name="covenant_text"> Sie müssen dem Grundbesitzvertrag zustimmen: </text> - <text left="470" name="covenant_timestamp_text"/> - <text_editor left="470" name="covenant_editor"> + <text name="covenant_timestamp_text"/> + <text_editor name="covenant_editor"> Wird geladen... </text_editor> <check_box label="Ich stimme dem obigen Vertrag zu." name="agree_covenant"/> @@ -191,7 +191,7 @@ Objekte im Verkauf eingeschlossen <text name="error_message"> Irgendetwas stimmt nicht. </text> - <button label="Gehe zu Website" name="error_web" top_delta="136"/> + <button label="Gehe zu Website" name="error_web" /> <text name="account_action"> Macht Sie zum Premium-Mitglied. </text> @@ -203,9 +203,8 @@ Objekte im Verkauf eingeschlossen <combo_box.item label="7,50 US$/Monat, vierteljährliche Abrechnung" name="US$7.50/month,billedquarterly"/> <combo_box.item label="6,00 US$/Monat, jährliche Abrechnung" name="US$6.00/month,billedannually"/> </combo_box> - <text height="36" name="land_use_action" top="270"> - Erhöhen Sie Ihre monatlichen Landnutzungsgebühren -auf 40 US$/month. + <text name="land_use_action"> + Erhöhen Sie Ihre monatlichen Landnutzungsgebühren auf 40 US$/month. </text> <text name="land_use_reason"> Sie besitzen 1309 m² Land. diff --git a/indra/newview/skins/default/xui/de/floater_postcard.xml b/indra/newview/skins/default/xui/de/floater_postcard.xml index 91e0bb8133..49dcd4af51 100644 --- a/indra/newview/skins/default/xui/de/floater_postcard.xml +++ b/indra/newview/skins/default/xui/de/floater_postcard.xml @@ -1,42 +1,36 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Postcard" title="FOTO EMAILEN"> - <text name="to_label"> - E-Mail des Empfängers: - </text> - <line_editor left_delta="145" name="to_form" width="125"/> - <text name="from_label"> - Ihre E-Mail: - </text> - <line_editor left_delta="145" name="from_form" width="125"/> - <text name="name_label"> - Ihr Name: - </text> - <line_editor left_delta="145" name="name_form" width="125"/> - <text name="subject_label"> - Betreff: - </text> - <line_editor label="Betreff hier eingeben." left_delta="145" name="subject_form" width="125"/> - <text name="msg_label"> - Nachricht: - </text> - <text_editor name="msg_form"> - Nachricht hier eingeben. - </text_editor> - <check_box label="Im Web veröffentlichen" name="allow_publish_check" tool_tip="Veröffentlicht diese Postkarte im Web."/> - <check_box label="Ab-18-Inhalt" name="mature_check" tool_tip="Diese Postkarte enthält nicht jugendfreie Inhalte."/> - <button label="?" name="publish_help_btn"/> - <text name="fine_print" bottom_delta="21" height="140"> - Wenn sich der Empfänger bei SL anmeldet, erhalten Sie einen Empfehlungsbonus. - </text> - <button label="Abbrechen" name="cancel_btn"/> - <button label="Senden" name="send_btn"/> - <text name="default_subject"> - Postkarte aus [SECOND_LIFE]. - </text> - <text name="default_message"> - Sehen Sie hier! - </text> - <string name="upload_message"> - Wird gesendet... - </string> -</floater> +<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Postcard" title="FOTO EMAILEN">
+ <text name="to_label">
+ E-Mail des Empfängers:
+ </text>
+ <text name="from_label">
+ Ihre E-Mail:
+ </text>
+ <text name="name_label">
+ Ihr Name:
+ </text>
+ <text name="subject_label">
+ Betreff:
+ </text>
+ <line_editor label="Betreff hier eingeben." name="subject_form"/>
+ <text name="msg_label">
+ Nachricht:
+ </text>
+ <text_editor name="msg_form">
+ Nachricht hier eingeben.
+ </text_editor>
+ <text name="fine_print">
+ Wenn sich der Empfänger bei SL anmeldet, erhalten Sie einen Empfehlungsbonus.
+ </text>
+ <button label="Abbrechen" name="cancel_btn"/>
+ <button label="Senden" name="send_btn"/>
+ <text name="default_subject">
+ Postkarte aus [SECOND_LIFE].
+ </text>
+ <text name="default_message">
+ Sehen Sie hier!
+ </text>
+ <string name="upload_message">
+ Wird gesendet...
+ </string>
+</floater>
diff --git a/indra/newview/skins/default/xui/de/floater_sell_land.xml b/indra/newview/skins/default/xui/de/floater_sell_land.xml index 8f67fae464..646138eaad 100644 --- a/indra/newview/skins/default/xui/de/floater_sell_land.xml +++ b/indra/newview/skins/default/xui/de/floater_sell_land.xml @@ -5,16 +5,16 @@ <text name="info_parcel_label"> Parzelle: </text> - <text bottom_delta="-5" height="16" name="info_parcel" left="70"> + <text name="info_parcel"> PARZELLENNAME </text> <text name="info_size_label"> Größe: </text> - <text bottom_delta="-21" height="32" name="info_size" left="70"> + <text name="info_size"> [AREA] m². </text> - <text bottom_delta="-57" height="28" name="info_action"> + <text name="info_action"> Zum Verkauf dieser Parzelle: </text> <text name="price_label"> @@ -32,13 +32,13 @@ <text name="price_per_m"> ([PER_METER] L$ pro m²) </text> - <text bottom_delta="38" left="72" name="sell_to_label" right="-20"> + <text name="sell_to_label"> 2. Land verkaufen an: </text> - <text bottom_delta="-16" height="16" left="72" name="sell_to_text" right="-10"> + <text name="sell_to_text"> Offener Verkauf oder Verkauf an bestimmte Person? </text> - <combo_box bottom_delta="-32" height="16" left="72" name="sell_to" width="140"> + <combo_box name="sell_to"> <combo_box.item label="-- Auswählen --" name="--selectone--"/> <combo_box.item label="An jeden" name="Anyone"/> <combo_box.item label="An bestimmte Person:" name="Specificuser:"/> @@ -50,15 +50,15 @@ <text name="sell_objects_text"> Die transferierbaren Landeigentümer-Objekte auf der Parzelle wechseln den Eigentümer. </text> - <radio_group bottom_delta="-58" name="sell_objects"> + <radio_group name="sell_objects"> <radio_item label="Nein, Objekte behalten" name="no"/> <radio_item label="Ja, Objekte mit Land verkaufen" name="yes"/> </radio_group> - <button label="Objekte anzeigen" name="show_objects" width="116"/> + <button label="Objekte anzeigen" name="show_objects"/> <text name="nag_message_label"> ACHTUNG: Verkäufe sind endgültig. </text> - <button label="Zum Verkauf freigeben" name="sell_btn" width="180"/> + <button label="Zum Verkauf freigeben" name="sell_btn"/> <button label="Abbrechen" name="cancel_btn"/> </panel> </scroll_container> diff --git a/indra/newview/skins/default/xui/de/floater_top_objects.xml b/indra/newview/skins/default/xui/de/floater_top_objects.xml index dad550227e..d2055a53db 100644 --- a/indra/newview/skins/default/xui/de/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/de/floater_top_objects.xml @@ -39,21 +39,18 @@ <text name="id_text"> Objekt-ID: </text> - <line_editor bg_readonly_color="clear" bottom_delta="3" enabled="false" follows="left|bottom|right" font="SansSerifSmall" height="20" left="80" name="id_editor" text_readonly_color="white" width="244"/> - <button bottom_delta="0" follows="bottom|right" height="20" label="Beacon anzeigen" name="show_beacon_btn" right="-10" width="110"/> + <button label="Beacon anzeigen" name="show_beacon_btn"/> <text name="obj_name_text"> Objektname: - </text> - <line_editor bg_readonly_color="clear" bottom_delta="3" enabled="false" follows="left|bottom|right" font="SansSerifSmall" height="20" left="80" name="object_name_editor" text_readonly_color="white" width="244"/> - <button bottom_delta="0" follows="bottom|right" height="20" label="Filter" name="filter_object_btn" right="-10" width="110"/> + </text> + <button label="Filter" name="filter_object_btn"/> <text name="owner_name_text"> Eigentümer: - </text> - <line_editor bg_readonly_color="clear" bottom_delta="3" enabled="true" follows="left|bottom|right" font="SansSerifSmall" height="20" left="106" name="owner_name_editor" text_readonly_color="white" width="218"/> - <button bottom_delta="0" follows="bottom|right" height="20" label="Filter" name="filter_owner_btn" right="-10" width="110"/> - <button bottom_delta="0" follows="bottom|right" height="20" label="Aktualisieren" name="refresh_btn" right="-10" width="110"/> - <button bottom="35" follows="bottom|left" height="20" label="Auswahl zurückgeben" left="10" name="return_selected_btn" width="134"/> - <button bottom="35" follows="bottom|left" height="20" label="Alle zurückgeben" left="150" name="return_all_btn" width="134"/> - <button bottom="10" follows="bottom|left" height="20" label="Auswahl deaktivieren" left="10" name="disable_selected_btn" width="134"/> - <button bottom="10" follows="bottom|left" height="20" label="Alle deaktivieren" left="150" name="disable_all_btn" width="134"/> + </text> + <button label="Filter" name="filter_owner_btn"/> + <button label="Aktualisieren" name="refresh_btn"/> + <button label="Auswahl zurückgeben" name="return_selected_btn" width="134"/> + <button label="Alle zurückgeben" left="150" name="return_all_btn" width="134"/> + <button label="Auswahl deaktivieren" name="disable_selected_btn" width="134"/> + <button label="Alle deaktivieren" left="150" name="disable_all_btn" width="134"/> </floater> diff --git a/indra/newview/skins/default/xui/de/floater_water.xml b/indra/newview/skins/default/xui/de/floater_water.xml index 097a60a444..bb0dd9c75d 100644 --- a/indra/newview/skins/default/xui/de/floater_water.xml +++ b/indra/newview/skins/default/xui/de/floater_water.xml @@ -3,9 +3,10 @@ <floater.string name="WLDefaultWaterNames"> Default:Glassy:Pond:Murky:Second Plague:SNAKE!!!:Valdez </floater.string> - <text name="KeyFramePresetsText" width="116"> + <text name="KeyFramePresetsText" width="110"> Voreinstellungen: </text> + <combo_box left_delta="110" name="WaterPresetsCombo"/> <button label="Neu" label_selected="Neu" name="WaterNewPreset"/> <button label="Speichern" label_selected="Speichern" name="WaterSavePreset"/> <button label="Löschen" label_selected="Löschen" name="WaterDeletePreset"/> diff --git a/indra/newview/skins/default/xui/de/panel_group_notices.xml b/indra/newview/skins/default/xui/de/panel_group_notices.xml index 8c1df04ed8..df423cc69a 100644 --- a/indra/newview/skins/default/xui/de/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/de/panel_group_notices.xml @@ -49,7 +49,7 @@ Maximal 200 pro Gruppe täglich Archivierte Mitteilung </text> <text name="lbl2"> - Um eine neue Mitteilung zu senden, klicken Sie die Schaltfläche + + Um eine neue Mitteilung zu senden, klicken Sie die + Neue Mitteilung </text> <text name="lbl3"> Betreff: diff --git a/indra/newview/skins/default/xui/de/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/de/panel_preferences_privacy.xml index b56f150394..e21bed6bb5 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_privacy.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_privacy.xml @@ -11,7 +11,7 @@ <check_box label="Nur Freunde und Gruppen wissen, dass ich online bin" name="online_visibility"/> <check_box label="Nur Freunde und Gruppen können mich anrufen oder mir eine IM schicken" name="voice_call_friends_only_check"/> <check_box label="Mikrofon ausschalten, wenn Anrufe beendet werden" name="auto_disengage_mic_check"/> - <check_box label="Meine Lieblingslandmarken bei Anmeldung anzeigen (im Dropdown-Menü „Hier anfangen“)" name="favorites_on_login_check"/> + <check_box label="Meine Lieblingslandmarken bei Anmeldung anzeigen (im Dropdown-Menü „Hier anfangen“)" name="favorites_on_login_check" top_pad="15"/> <text name="Logs:"> Chatprotokolle: </text> diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml index 6a1a600696..a8b3ce9c28 100644 --- a/indra/newview/skins/default/xui/en/floater_about.xml +++ b/indra/newview/skins/default/xui/en/floater_about.xml @@ -139,27 +139,32 @@ Thank you to the following Residents for helping to ensure that this is the best word_wrap="true"> 3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion APR Copyright (C) 2000-2004 The Apache Software Foundation +Collada DOM Copyright 2005 Sony Computer Entertainment Inc. cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se) DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc. expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org). GL Copyright (C) 1999-2004 Brian Paul. +GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia. google-perftools Copyright (c) 2005, Google Inc. Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) jpeglib Copyright (C) 1991-1998, Thomas G. Lane. ogg/vorbis Copyright (C) 2001, Xiphophorus OpenSSL Copyright (C) 1998-2002 The OpenSSL Project. +PCRE Copyright (c) 1997-2008 University of Cambridge SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) xmlrpc-epi Copyright (C) 2000 Epinions, Inc. zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler. google-perftools Copyright (c) 2005, Google Inc. +Second Life Viewer uses Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (and its Licensors). All Rights Reserved. See www.havok.com for details. + All rights reserved. See licenses.txt for details. Voice chat Audio coding: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C) - </text_editor> + </text_editor> </panel> </tab_container> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency.xml b/indra/newview/skins/default/xui/en/floater_buy_currency.xml index 49deb9b025..9f6eac198b 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_currency.xml @@ -299,7 +299,7 @@ Re-enter amount to see the latest exchange rate. type="string" font="SansSerifHuge" left="165" - width="170" + width="360" height="25" top="25" name="info_cannot_buy"> diff --git a/indra/newview/skins/default/xui/en/floater_buy_land.xml b/indra/newview/skins/default/xui/en/floater_buy_land.xml index d5d4565ca1..ab81a86720 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_land.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_land.xml @@ -204,7 +204,7 @@ supports [AMOUNT2] objects follows="left|top" height="14" layout="topleft" - left_delta="110" + left_delta="125" name="region_name_text" top_delta="0" use_ellipses="true" @@ -237,7 +237,7 @@ supports [AMOUNT2] objects follows="left|top" height="14" layout="topleft" - left_delta="110" + left_delta="125" name="region_type_text" top_delta="0" width="175"> @@ -262,7 +262,7 @@ supports [AMOUNT2] objects follows="left|top" height="14" layout="topleft" - left_delta="110" + left_delta="125" name="estate_name_text" top_delta="0" width="175"> @@ -276,8 +276,8 @@ supports [AMOUNT2] objects layout="topleft" left="440" name="estate_owner_label" - right="550" - width="100" + right="565" + width="120" word_wrap="true"> Estate Owner: </text> @@ -287,7 +287,7 @@ supports [AMOUNT2] objects follows="left|top" height="20" layout="topleft" - left_delta="110" + left_delta="125" name="estate_owner_text" top_delta="0" width="175"> diff --git a/indra/newview/skins/default/xui/en/floater_day_cycle_options.xml b/indra/newview/skins/default/xui/en/floater_day_cycle_options.xml index b54dc87d24..59cdb295ef 100644 --- a/indra/newview/skins/default/xui/en/floater_day_cycle_options.xml +++ b/indra/newview/skins/default/xui/en/floater_day_cycle_options.xml @@ -411,125 +411,6 @@ left="12" top="101" width="240" /> - <text - type="string" - length="1" - border_visible="true" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left_pad="15" - name="DayCycleText2" - top_delta="71" - width="120"> - Length of Cycle: - </text> - <spinner - control_name="WLLengthOfDayHour" - decimal_digits="0" - follows="left|top" - height="16" - increment="1" - initial_value="0" - label="Hour" - label_width="33" - layout="topleft" - left_delta="-3" - max_val="100" - name="WLLengthOfDayHour" - top_pad="4" - width="74" /> - <spinner - control_name="WLLengthOfDayMin" - decimal_digits="0" - follows="left|top" - height="16" - increment="1" - initial_value="0" - label="Min" - label_width="25" - layout="topleft" - left_pad="2" - max_val="59" - name="WLLengthOfDayMin" - top_delta="0" - width="65" /> - <spinner - control_name="WLLengthOfDaySec" - decimal_digits="0" - follows="left|top" - height="16" - increment="1" - initial_value="24" - label="Sec" - label_width="25" - layout="topleft" - left_pad="2" - max_val="59" - name="WLLengthOfDaySec" - top_delta="0" - width="65"/> - <text - type="string" - halign="right" - length="1" - border_visible="true" - follows="left|top|right" - font="SansSerif" - height="16" - layout="topleft" - left_delta="-23" - name="DayCycleText3" - top="114" - width="85"> - Preview : - </text> - <button - height="20" - label="Play" - label_selected="Play" - layout="topleft" - left="480" - name="WLAnimSky" - top_pad="5" - width="83" /> - <button - height="20" - label="Stop!" - label_selected="Stop" - layout="topleft" - left_pad="4" - name="WLStopAnimSky" - top_delta="0" - width="83" /> - <button - height="20" - label="Use Estate Time" - label_selected="Go to Estate Time" - layout="topleft" - left="480" - name="WLUseLindenTime" - top_pad="9" - width="170" /> - <button - height="20" - label="Save Test Day" - label_selected="Save Test Day" - layout="topleft" - left_delta="0" - name="WLSaveDayCycle" - top_pad="9" - width="170" /> - <button - height="20" - label="Load Test Day" - label_selected="Load Test Day" - layout="topleft" - left_delta="0" - name="WLLoadDayCycle" - top_pad="3" - width="170" /> </panel> </tab_container> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_edit_sky_preset.xml b/indra/newview/skins/default/xui/en/floater_edit_sky_preset.xml index 924ffebedc..ae7e83ee56 100644 --- a/indra/newview/skins/default/xui/en/floater_edit_sky_preset.xml +++ b/indra/newview/skins/default/xui/en/floater_edit_sky_preset.xml @@ -993,16 +993,6 @@ name="WLCloudScrollY" top_pad="6" width="200" /> - <check_box - control_name="DrawClassicClouds" - follows="left|top" - height="16" - label="Draw Classic Clouds" - layout="topleft" - left_delta="-15" - name="DrawClassicClouds" - top_pad="20" - width="200" /> </panel> </tab_container> <!--======== End of Controls panel ========--> diff --git a/indra/newview/skins/default/xui/en/floater_import_collada.xml b/indra/newview/skins/default/xui/en/floater_import_collada.xml new file mode 100644 index 0000000000..441ab6a2de --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_import_collada.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater can_close="false" can_drag_on_left="false" can_minimize="false" + can_resize="false" height="160" min_height="160" width="300" min_width="300" + name="Import Collada" title="Import Scene"> + + <text bottom_delta="40" left="20" name="mesh count" height="15" follows="top|left"> + Meshes: [COUNT] + </text> + + <text bottom_delta="20" left="20" name="texture count" height="15" follows="top|left"> + Textures: [COUNT] + </text> + + <text bottom_delta="40" left="10" name="status" height="15" follows="top|left"> + Status: [STATUS] + </text> + + <button + bottom_delta="40" + name="cancel" + label="Cancel" + enabled="true" + height="20" + layout="topleft" + left="125" + width="75" /> + + <button + bottom_delta="0" + name="ok" + label="OK" + enabled="true" + height="20" + layout="topleft" + left="210" + width="75" /> + + <string name="status_idle">Idle</string> + <string name="status_uploading">Uploading [NAME]</string> + <string name="status_creating">Creating object [NAME]</string> + + </floater> diff --git a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml index 90fee857fb..c86ed595a7 100644 --- a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml +++ b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml @@ -95,6 +95,23 @@ width="126" /> <icon height="16" + image_name="Inv_Mesh" + layout="topleft" + left="8" + mouse_opaque="true" + name="icon_mesh" + top="142" + width="16" /> + <check_box + height="16" + label="Meshes" + layout="topleft" + left_pad="2" + name="check_mesh" + top_delta="0" + width="126" /> + <icon + height="16" image_name="Inv_Notecard" layout="topleft" left="8" @@ -117,7 +134,7 @@ left="8" mouse_opaque="true" name="icon_object" - top="142" + top="162" width="16" /> <check_box height="16" @@ -134,7 +151,7 @@ left="8" mouse_opaque="true" name="icon_script" - top="162" + top="182" width="16" /> <check_box height="16" @@ -151,7 +168,7 @@ left="8" mouse_opaque="true" name="icon_sound" - top="182" + top="202" width="16" /> <check_box height="16" @@ -168,7 +185,7 @@ left="8" mouse_opaque="true" name="icon_texture" - top="202" + top="222" width="16" /> <check_box height="16" @@ -185,7 +202,7 @@ left="8" mouse_opaque="true" name="icon_snapshot" - top="222" + top="242" width="16" /> <check_box height="16" @@ -203,7 +220,7 @@ layout="topleft" left="8" name="All" - top="242" + top="262" width="100" /> <button follows="left|top" diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml new file mode 100644 index 0000000000..d08c3e7078 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -0,0 +1,547 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater can_close="true" can_drag_on_left="false" can_minimize="false" + can_resize="true" height="550" min_height="550" min_width="620" + name="Model Preview" title="Upload Model" width="620"> + + <string name="status_idle">Idle</string> + <string name="status_reading_file">Loading...</string> + <string name="status_generating_meshes">Generating Meshes...</string> + <string name="status_vertex_number_overflow">Error: Vertex number is more than 65534, aborted!</string> + <string name="high">High</string> + <string name="medium">Medium</string> + <string name="low">Low</string> + <string name="lowest">Lowest</string> + <string name="mesh_status_good">Ship it!</string> + <string name="mesh_status_na">N/A</string> + <string name="mesh_status_none">None</string> + <string name="mesh_status_submesh_mismatch">Levels of detail have a different number of textureable faces.</string> + <string name="mesh_status_mesh_mismatch">Levels of detail have a different number of mesh instances.</string> + <string name="mesh_status_too_many_vertices">Level of detail has too many vertices.</string> + <string name="mesh_status_missing_lod">Missing required level of detail.</string> + <string name="layer_all">All</string> <!-- Text to display in physics layer combo box for "all layers" --> + <string name="decomposing">Analyzing...</string> + <string name="simplifying">Simplifying...</string> + + + <text left="15" bottom="25" follows="top|left" height="15" name="name_label"> + Name: + </text> + <line_editor bottom_delta="20" follows="top|left|right" height="19" + name="description_form" prevalidate_callback="ascii" width="290" /> + + <text bottom_delta="20" left="15" follows="left|top" height="15" name="lod_label"> + Preview: + </text> + <combo_box bottom_delta="20" follows="left|top" height="18" + name="preview_lod_combo" width="240" tool_tip="LOD to view in preview render"> + <combo_item name="high"> + Level of Detail: High + </combo_item> + <combo_item name="medium"> + Level of Detail: Medium + </combo_item> + <combo_item name="low"> + Level of Detail: Low + </combo_item> + <combo_item name="lowest"> + Level of Detail: Lowest + </combo_item> + </combo_box> + + <menu_button follows="top|left" + image_hover_unselected="Toolbar_Left_Over" + image_overlay="OptionsMenu_Off" + image_selected="Toolbar_Left_Selected" + image_unselected="Toolbar_Left_Off" + layout="topleft" + left_pad="5" + name="options_gear_btn" + width="31" + height="25"/> + <!-- Placeholder panel for 3D preview render --> + <panel + name="preview_panel" + left="15" + bevel_style="none" + border_style="line" + border="true" + width="290" + height="290" + follows="all"/> + + <text bottom_delta="25" left="25" width="100" follows="bottom|left">Upload Details</text> + <panel top_pad="5" border="true" left="15" width="290" height="70" follows="bottom|left" + bevel_style="none" bg_alpha_color="0 0 0 0" bg_opaque_color="0 0 0 0.3"> + <text left="25" follows="bottom|left" width="140" height="15" name="streaming cost"> + Resource Cost: [COST] + </text> + <text left="25" top_pad="5" width="140" follows="bottom|left" height="15" name="physics cost"> + Physics Cost: [COST] + </text> + <text left="25" top_pad="5" follows="bottom|left" height="15" name="upload fee"> + Upload Fee: N/A + </text> + </panel> + + <text left="10" bottom="540" width="290" height="15" follows="bottom|left|right" name="status">[STATUS]</text> + + + <button bottom="540" left="300" follows="bottom|right" height="20" label="Defaults" + width="80" name="reset_btn" tool_tip="Reset to defaults"/> + <button bottom="540" left="430" follows="bottom|right" height="20" label="Upload" + width="80" name="ok_btn" tool_tip="Upload to simulator"/> + <button left_pad="10" follows="right|bottom" height="20" width="80" label="Cancel" name="cancel_btn"/> + + <tab_container + follows="right|top|bottom" + top="15" + left="310" + height="470" + width="300" + name="import_tab" + border="true" + tab_position="top"> + + <!-- LOD PANEL --> + <panel + border="true" + label="Level of Detail" + name="lod_panel"> + + <text left="10" width="240" bottom="20" height="15" follows="left|top" name="lod_table_header"> + Select Level of Detail: + </text> + + <text valign="center" halign="center" bg_visible="true" bottom_delta="16" left="75" width="65" height="18" follows="left|top" value="Triangles"/> + <text valign="center" halign="center" bg_visible="true" left_pad="0" width="65" height="18" follows="left|top" value="Vertices"/> + <text valign="center" halign="center" left_pad="0" width="65" bg_visible="true" height="18" follows="left|top" value="Status"/> + + <text valign="center" halign="center" bg_visible="true" name="high_label" left="10" top_pad="0" width="65" height="18" follows="left|top" value="High"/> + <text valign="center" halign="center" bg_visible="true" name="high_triangles" left_pad="0" width="65" height="18" follows="left|top" value="0"/> + <text valign="center" halign="center" bg_visible="true" name="high_vertices" left_pad="0" width="65" height="18" follows="left|top" value="0"/> + <text valign="center" halign="center" bg_visible="true" name="high_status" left_pad="0" width="65" height="18" follows="left|top" value=""/> + <icon height="16" width="16" image_name="lag_status_critical.tga" mouse_opaque="true" name="status_icon_high" left_delta="20" top_delta="0" /> + + <text valign="center" halign="center" bg_visible="true" name="medium_label" left="10" top_pad="0" width="65" height="18" follows="left|top" value="Medium"/> + <text valign="center" halign="center" bg_visible="true" name="medium_triangles" left_pad="0" width="65" height="18" follows="left|top" value="0"/> + <text valign="center" halign="center" bg_visible="true" name="medium_vertices" left_pad="0" width="65" height="18" follows="left|top" value="0"/> + <text valign="center" halign="center" bg_visible="true" name="medium_status" left_pad="0" width="65" height="18" follows="left|top" value=""/> + <icon height="16" width="16" image_name="lag_status_critical.tga" mouse_opaque="true" name="status_icon_medium" left_delta="20" top_delta="0" /> + + <text valign="center" halign="center" bg_visible="true" name="low_label" left="10" top_pad="0" width="65" height="18" follows="left|top" value="Low"/> + <text valign="center" halign="center" bg_visible="true" name="low_triangles" left_pad="0" width="65" height="18" follows="left|top" value="0"/> + <text valign="center" halign="center" bg_visible="true" name="low_vertices" left_pad="0" width="65" height="18" follows="left|top" value="0"/> + <text valign="center" halign="center" bg_visible="true" name="low_status" left_pad="0" width="65" height="18" follows="left|top" value=""/> + <icon height="16" width="16" image_name="lag_status_critical.tga" mouse_opaque="true" name="status_icon_low" left_delta="20" top_delta="0" /> + + <text valign="center" halign="center" bg_visible="true" name="lowest_label" left="10" top_pad="0" width="65" height="18" follows="left|top" value="Lowest"/> + <text valign="center" halign="center" bg_visible="true" name="lowest_triangles" left_pad="0" width="65" height="18" follows="left|top" value="0"/> + <text valign="center" halign="center" bg_visible="true" name="lowest_vertices" left_pad="0" width="65" height="18" follows="left|top" value="0"/> + <text valign="center" halign="center" bg_visible="true" name="lowest_status" left_pad="0" width="65" height="18" follows="left|top" value=""/> + <icon height="16" width="16" image_name="lag_status_critical.tga" mouse_opaque="true" name="status_icon_lowest" left_delta="20" top_delta="0" /> + + <text left="10" width="240" height="15" top_pad="15" follows="left|top" name="lod_table_footer"> + Level of Detail: [DETAIL] + </text> + + <icon height="16" width="16" left="20" follows="left|top" name="lod_status_message_icon"/> + <text left_pad="5" width="200" height="28" follows="left|top" top_pad="-15" wrap="true" name="lod_status_message_text"/> + + <text top_pad="-3" left="10" height="15" follows="left|top"> + Mesh + </text> + + <radio_group follows="top|left" height="210" left="30" name="lod_file_or_limit" width="240" value="lod_from_file"> + <radio_item bottom="195" label="Load from file" name="lod_from_file"/> + <radio_item bottom="150" label="Auto generate" name="lod_auto_generate"/> + <radio_item bottom="0" label="None" name="lod_none"/> + </radio_group> + + <line_editor follows="left|top" bottom_delta="-170" width="140" left="45" value="" name="lod_file" height="20"/> + <button bottom_delta="3" name="lod_browse" label="Browse..." left_pad="5" follows="left|top" width="70" height="25"/> + + <combo_box follows="top|left" name="lod_mode" top_pad="22" width="100" left="45" height="20"> + <combo_item name="triangle_limit"> + Triangle Limit + </combo_item> + <combo_item name="error_threshold"> + Error Threshold + </combo_item> + </combo_box> + <spinner follows="top|left" name="lod_triangle_limit" increment="10" left_pad="5" height="20" width="100" decimal_digits="0" enabled="true"/> + <spinner left_delta="0" bottom_delta="0" increment="0.01" follows="top|left" name="lod_error_threshold" min_val="0" max_val="100" height="20" width="100" decimal_digits="3" visible="false" enabled="true"/> + + <text follows="top|left" name="build_operator_text" left="45" top_pad="10" width="100" height="15"> + Build Operator: + </text> + <text follows="top|left" name="queue_mode_text" left_pad="5" width="100" height="15"> + Queue Mode: + </text> + <combo_box follows="top|left" name="build_operator" top_pad="5" left="45" width="100" height="20"> + <combo_item name="edge_collapse"> + Edge Collapse + </combo_item> + <combo_item name="half_edge_collapse"> + Half Edge Collapse + </combo_item> + </combo_box> + + <combo_box follows="top|left" name="queue_mode" left_pad="5" width="100" height="20"> + <combo_item name="greedy"> + Greedy + </combo_item> + <combo_item name="lazy"> + Lazy + </combo_item> + <combo_item name="independent"> + Independent + </combo_item> + </combo_box> + + <text top_pad="10" name="border_mode_text" left="45" follows="left|top" width="100" height="15"> + Border Mode: + </text> + + <text left_pad="5" name="share_tolderance_text" follows="left|top" width="100" height="15"> + Share Tolerance: + </text> + + <combo_box follows="left|top" left="45" height="20" name="border_mode" width="100"> + <combo_item name="border_unlock"> + Unlock + </combo_item> + <combo_item name="border_lock"> + Lock + </combo_item> + </combo_box> + <spinner follows="left|top" name="share_tolerance" left_pad="5" width="100" decimal_digits="5" initial_value="0.00001" height="20"/> + + <text left="10" top_pad="35" follows="top|left" width="240" height="15"> + Generate Normals + </text> + <text left="35" top_pad="5" follows="top|left" width="100" height="15"> + Crease Angle: + </text> + <spinner follows="top|left" left_pad="5" min_val="0" max_val="180" value="75" width="60" height="20" name="crease_angle"/> + </panel> + + <!-- PANEL --> + <panel + border="true" + label="Physics" + name="physics_panel"> + + <!-- PHYSICS GEOMETRY--> + <panel + follows="top|left" + name="physics geometry" + left="0" + top="0" + width="300" + height="65" + visible="true" + border="true" + bevel_style="none" bg_alpha_color="0 0 0 0" bg_opaque_color="0 0 0 0.3"> + + <radio_group follows="top|left" top="10" width="240" height="40" name="physics_load_radio" value="physics_load_from_file"> + <radio_item bottom="0" name="physics_load_from_file" label="File:"/> + <radio_item bottom="23" name="physics_use_lod" label="Use Level of Detail:"/> + </radio_group> + + <combo_box left="180" top="10" follows="left|top" height="18" + name="physics_lod_combo" width="110" tool_tip="LOD to use for physics shape"> + <combo_item name="physics_lowest"> + Lowest + </combo_item> + <combo_item name="physics_low"> + Low + </combo_item> + <combo_item name="physics_medium"> + Medium + </combo_item> + <combo_item name="physics_high"> + High + </combo_item> + </combo_box> + + <line_editor follows="left|top" top_pad="5" width="140" left="60" value="" name="physics_file" height="20"/> + <button left_pad="10" name="physics_browse" label="Browse..." follows="left|top" width="70" height="20"/> + + <!-- + <check_box name="physics_optimize" follows="left|top" width="130" left="10" top_pad="5" height="20" label="Optimize"/> + <check_box name="physics_use_hull" follows="left|top" width="130" left_pad="5" height="20" label="Use Convex Hull"/> + --> + </panel> + + + <!-- PHYSICS ANALYSIS--> + <panel + follows="top|left" + name="physics analysis" + top_pad="0" + left="0" + width="300" + height="130" + visible="true" + border="true" + bevel_style="none" bg_alpha_color="0 0 0 0" bg_opaque_color="0 0 0 0.3"> + + <text follows="left|top" bottom="40" height="30" left="10" font="SansSerifBig"> + Step 1: Analysis + </text> + + <text top_pad="5" width="50" follows="top|left" height="15"> + Method: + </text> + <combo_box name="Method" follows="top|left" left_pad="5" bottom_delta="2" height="20" width="80"/> + <text left="160" bottom_delta="-2" width="50" follows="top|left" height="15"> + Quality: + </text> + <combo_box name="Decompose Quality" bottom_delta="2" follows="top|left" left_pad="5" height="20" width="80"/> + + <slider name="Smooth" left="10" width="280" follows="top|left" top_pad="10" height="20" label="Smooth:"/> + + <check_box name="Close Holes (Slow)" follows="top|left" top_pad="10" height="15" label="Close Holes (slow)"/> + + <button left="200" bottom_delta="0" width="90" follows="top|left" label="Analyze" name="Decompose" height="20"/> + <button left="200" bottom_delta="0" width="90" follows="top|left" label="Cancel" name="decompose_cancel" visble="false" height="20"/> + </panel> + + + <!-- PHYSICS SIMPLIFICATION --> + <panel + follows="top|left" + name="physics simplification" + left="0" + top_pad="0" + width="300" + height="150" + visible="true" + border="true" + bevel_style="none" bg_alpha_color="0 0 0 0" bg_opaque_color="0 0 0 0.3"> + + <text follows="left|top" bottom="40" height="30" left="10" font="SansSerifBig"> + Step 2: Simplification + </text> + + <text left="10" top_pad="5" height="15" width="140" follows="top|left"> + Method: + </text> + + <combo_box left_pad="5" height="20" width="120" follows="top|left" name="Simplify Method"/> + + <slider left="10" name="Combine Quality" label="Passes:" label_width="120" width="270" follows="top|left" top_pad="10" height="20"/> + <slider name="Detail Scale" label="Detail Scale:" label_width="120" width="270" follows="top|left" top_pad="10" height="20"/> + <slider name="Retain%" label="Retain:" label_width="120" width="270" follows="top|left" bottom_delta="0" left_delta="0" visible="false" height="20"/> + <button left="190" width="90" follows="top|left" label="Simplify" name="Simplify" height="20"/> + <button left="190" bottom_delta="0" width="90" follows="top|left" label="Cancel" name="simplify_cancel" height="20"/> + + </panel> + + <!-- INFO PANEL --> + <panel + left="0" + top_pad="0" + width="300" + height="100" + follows="left|top" + name="physics info" + visible="true" + border="true" + bevel_style="none" bg_alpha_color="0 0 0 0" bg_opaque_color="0 0 0 0.3"> + + <slider name="physics_explode" follows="top|left" top="10" left="10" label="Preview Spread:" min_val="0.0" max_val="3.0" height="20" width="280"/> + + <text follows="top|left" name="physics_triangles" top_pad="10" height="15" left="10"> + Triangles: [TRIANGLES] + </text> + <text follows="top|left" name="physics_points" top_pad="5" height="15"> + Vertices: [POINTS] + </text> + <text follows="top|left" name="physics_hulls" top_pad="5" height="15"> + Hulls: [HULLS] + </text> + + + </panel> + </panel> + + <!-- MODIFIERS PANEL --> + <panel + border="true" + label="Modifiers" + name="modifiers_panel"> + <text left="10" width="90" bottom="30" follows="top|left" height="15"> + Scale: + </text> + <text left_pad="5" width="140" follows="top|left" height="15"> + Dimensions: + </text> + + <spinner left="10" height="20" follows="top|left" width="80" top_pad="5" value="1.0" min_val="0.01" max_val="64.0" name="import_scale"/> + + <text left_pad="20" height="15" name="import_dimensions" follows="top|left"> + [X] x [Y] x [Z] m + </text> + + <text left="10" top_pad="20" follows="top|left" height="15"> + Include: + </text> + + <check_box top_pad="5" name="upload_textures" height="15" follows="top|left" label="Textures"/> + <check_box top_pad="5" name="upload_skin" height="15" follows="top|left" label="Skin weight"/> + <check_box top_pad="5" left="20" name="upload_joints" height="15" follows="top|left" label="Joint positions"/> + + <text left="10" top_pad="4" width="90" bottom="30" follows="top|left" height="15"> + Pelvis Z Offset: + </text> + + <spinner left="10" top_pad="4" height="20" follows="top|left" width="80" value="0.0" min_val="-3.00" max_val="3.0" name="pelvis_offset"/> + + </panel> + </tab_container> + + <!-- + <button bottom_delta="0" left="10" width="120" name="auto fill" label="Generate LOD" tool_tip="Automatically generate levels of detail"/> + <button bottom_delta="0" left="140" width="120" name="smooth normals" label="Generate Normals" tool_tip="Regenerate normals based on mesh shape"/> + <button bottom_delta="0" left="260" width="120" name="consolidate" label="Consolidate" tool_tip="Combine similar submeshes (reduces number of submeshes)"/> + <button bottom_delta="30" left="260" width="120" name="scrub materials" label="Scrub Materials" tool_tip="Remove all material information (clear textures, set all colors to white)."/> + + <spinner bottom_delta="0" left="140" width="120" height="16" initial_value="75" label_width="60" name="edge threshold" decimal_digits="0" min_val="0" max_val="180" increment="5" label="Hard Angle" tool_tip="Maximum angle that will be smoothed between triangles when using Generate Normals"/> + + <text bottom_delta="30" follows="top|left" height="15" left="10" name="high_lod_label"> + High LOD: + </text> + <combo_box bottom_delta="0" left="97" follows="left|top" height="18" + name="high detail combo" width="100" tool_tip="Specify mesh for this level of detail"> + <combo_item name="high none" value="none"> + None + </combo_item> + <combo_item name="high choose file" value="file"> + Choose File... + </combo_item> + <combo_item name="high triangle limit" value="limit"> + Triangle Limit + </combo_item> + </combo_box> + <spinner bottom_delta="-5" left="200" width="120" name="high limit" decimal_digits="0" increment="1" min_val="0" max_val="100" tool_tip="Triangle budget for this LOD"/> + <text bottom_delta="25" follows="top|left" height="15" left="10" name="high info" width="300"> + [TRIANGLES] Triangles, [VERTICES] Vertices, [SUBMESHES] Submeshes. + [MESSAGE] + </text> + + <text bottom_delta="35" follows="top|left" height="15" left="10" name="medium_lod_label"> + Medium LOD: + </text> + <combo_box bottom_delta="0" left="97" follows="left|top" height="18" + name="medium detail combo" width="100" tool_tip="Specify mesh for this level of detail"> + <combo_item name="medium none" value="none"> + None + </combo_item> + <combo_item name="medium choose file" value="file"> + Choose File... + </combo_item> + <combo_item name="medium triangle limit" value="limit"> + Triangle Limit + </combo_item> + </combo_box> + <spinner bottom_delta="-5" left="200" width="120" name="medium limit" decimal_digits="0" increment="1" min_val="0" max_val="100" tool_tip="Triangle budget for this LOD"/> + <text bottom_delta="25" follows="top|left" height="15" left="10" name="medium info" width="300"> + [TRIANGLES] Triangles, [VERTICES] Vertices, [SUBMESHES] Submeshes. + [MESSAGE] + </text> + + <text bottom_delta="35" follows="top|left" height="15" left="10" name="low_lod_label"> + Low LOD: + </text> + <combo_box bottom_delta="0" left="97" follows="left|top" height="18" + name="low detail combo" width="100" tool_tip="Specify mesh for this level of detail"> + <combo_item name="low none" value="none"> + None + </combo_item> + <combo_item name="low choose file" value="file"> + Choose File... + </combo_item> + <combo_item name="low triangle limit" value="limit"> + Triangle Limit + </combo_item> + </combo_box> + <spinner bottom_delta="-5" left="200" width="120" name="low limit" decimal_digits="0" increment="1" min_val="0" max_val="100" tool_tip="Triangle budget for this LOD"/> + <text bottom_delta="25" follows="top|left" height="15" left="10" name="low info" width="300"> + [TRIANGLES] Triangles, [VERTICES] Vertices, [SUBMESHES] Submeshes + [MESSAGE] + </text> + + <text bottom_delta="35" follows="top|left" height="15" left="10" name="lowest_lod_label"> + Lowest LOD: + </text> + <combo_box bottom_delta="0" left="97" follows="left|top" height="18" + name="lowest detail combo" width="100" tool_tip="Specify mesh for this level of detail"> + <combo_item name="lowest none" value="none"> + None + </combo_item> + <combo_item name="lowest choose file" value="file"> + Choose File... + </combo_item> + <combo_item name="lowest triangle limit" value="limit"> + Triangle Limit + </combo_item> + </combo_box> + <spinner bottom_delta="-5" left="200" width="120" name="lowest limit" decimal_digits="0" increment="1" min_val="0" max_val="100" tool_tip="Triangle budget for this LOD"/> + <text bottom_delta="25" follows="top|left" height="15" left="10" name="lowest info" width="300"> + [TRIANGLES] Triangles, [VERTICES] Vertices, [SUBMESHES] Submeshes + [MESSAGE] + </text> + + <text bottom_delta="35" follows="top|left" height="15" left="10" name="physics_lod_label"> + Physical Shape: + </text> + <combo_box bottom_delta="0" left="97" follows="left|top" height="18" + name="physics detail combo" width="100"> + <combo_item name="physics none" value="none"> + None + </combo_item> + <combo_item name="physics choose file" value="file"> + Choose File... + </combo_item> + <combo_item name="physics triangle limit" value="limit"> + Triangle Limit... + </combo_item> + </combo_box> + <spinner bottom_delta="-5" left="200" width="90" name="physics limit" decimal_digits="0" increment="1" min_val="0" max_val="100" tool_tip="Triangle budget for this LOD"/> + <button bottom_delta="0" left="290" width="30" follows="left|top" height="20" label=">>" + name="decompose_btn" tool_tip="Create convex decomposition."/> + <text bottom_delta="25" follows="top|left" height="15" left="10" name="physics info" width="300"> + [TRIANGLES] Triangles, [HULLS] Hulls, [POINTS] Points + </text> + + <text bottom_delta="25" follows="top|left" height="15" left="10" name="include label" width="300"> + Include: + </text> + + <check_box bottom_delta="20" follow="bottom|left" height="20" label="Textures" + left="15" width="125" name="upload_textures" tool_tip="Upload associated textures "/> + + <check_box bottom_delta="20" follow="bottom|left" height="20" label="Skin Weights" + left="15" width="125" name="upload_skin" tool_tip="Upload vertex skin weighting information."/> + + <check_box bottom_delta="20" follow="bottom|left" height="20" label="Joint Positions" + left="15" width="125" name="upload_joints" tool_tip="Upload joint position information (will override avatar joint positions when mesh is worn)."/> + + + <button bottom_delta="25" follows="bottom|left" height="20" label="Upload" + left="15" name="ok_btn" width="125" tool_tip="Upload to simulator"/> + + <text bottom_delta="20" left="15" width="280" follows="top|left" height="15" name="description_label" text_color="1 0.82 0.46 1"> + (No charge for upload during First Look) + </text> + <text bottom_delta="20" left="15" width="280" follows="top|left" height="15" name="upload_message"> + [MESSAGE] + </text> + + <spinner bottom_delta="20" label="Scale" left="15" width="120" name="debug scale" decimal_digits="3" increment="0.1" min_val="0" max_val="64" initial_value="1" tool_tip="Multiplier for incoming object scale. If incoming dimensions are very small or very large, modify this value to get dimensions into an acceptable range."/> + <text bottom_delta="30" left="15" width="280" follows="top|left" height="15" name="dimensions"> + Model Dimensions: [X]m x [Y]m x [Z]m + </text> + --> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_model_wizard.xml b/indra/newview/skins/default/xui/en/floater_model_wizard.xml new file mode 100644 index 0000000000..92d57b20be --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_model_wizard.xml @@ -0,0 +1,1039 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + legacy_header_height="18" + layout="topleft" + name="Model Wizard" + help_topic="model_wizard" + bg_opaque_image_overlay="0.5 0.5 0.5 1" + height="480" + save_rect="true" + title="UPLOAD MODEL WIZARD" + width="535"> + <button + top="32" + tab_stop="false" + left="410" + height="32" + name="upload_btn" + enabled="false" + label="5. Upload" + border="false" + image_unselected="BreadCrumbBtn_Right_Off" + image_selected="BreadCrumbBtn_Right_Press" + image_hover_unselected="BreadCrumbBtn_Right_Over" + image_disabled="BreadCrumbBtn_Right_Disabled" + image_disabled_selected="BreadCrumbBtn_Right_Disabled" + width="110"> + <button.commit_callback + function="Wizard.Upload"/> + </button> + <button + top="32" + left="310" + height="32" + tab_stop="false" + name="review_btn" + label="4. Review" + enabled="false" + border="false" + image_unselected="BreadCrumbBtn_Middle_Off" + image_selected="BreadCrumbBtn_Middle_Press" + image_hover_unselected="BreadCrumbBtn_Middle_Over" + image_disabled="BreadCrumbBtn_Middle_Disabled" + image_disabled_selected="BreadCrumbBtn_Middle_Disabled" + width="110"> + <button.commit_callback + function="Wizard.Review"/> + </button> + <button + top="32" + left="210" + height="32" + name="physics2_btn" + label="3. Physics" + tab_stop="false" + enabled="false" + border="false" + image_unselected="BreadCrumbBtn_Middle_Off" + image_selected="BreadCrumbBtn_Middle_Press" + image_hover_unselected="BreadCrumbBtn_Middle_Over" + image_disabled="BreadCrumbBtn_Middle_Disabled" + image_disabled_selected="BreadCrumbBtn_Middle_Disabled" + width="110"> + <button.commit_callback + function="Wizard.Physics2"/> + </button> + <button + top="32" + left="210" + height="32" + name="physics_btn" + label="3. Physics" + tab_stop="false" + enabled="false" + border="false" + image_unselected="BreadCrumbBtn_Middle_Off" + image_selected="BreadCrumbBtn_Middle_Press" + image_hover_unselected="BreadCrumbBtn_Middle_Over" + image_disabled="BreadCrumbBtn_Middle_Disabled" + image_disabled_selected="BreadCrumbBtn_Middle_Disabled" + width="110"> + <button.commit_callback + function="Wizard.Physics"/> + </button> + <button + top="32" + left="115" + name="optimize_btn" + label="2. Optimize" + tab_stop="false" + height="32" + border="false" + image_unselected="BreadCrumbBtn_Middle_Off" + image_selected="BreadCrumbBtn_Middle_Press" + image_hover_unselected="BreadCrumbBtn_Middle_Over" + image_disabled="BreadCrumbBtn_Middle_Disabled" + image_disabled_selected="BreadCrumbBtn_Middle_Disabled" + width="110"> + <button.commit_callback + function="Wizard.Optimize"/> + </button> + <button + top="32" + left="15" + name="choose_file_btn" + tab_stop="false" + enabled="false" + label="1. Choose File" + height="32" + image_unselected="BreadCrumbBtn_Left_Off" + image_selected="BreadCrumbBtn_Left_Press" + image_hover_unselected="BreadCrumbBtn_Left_Over" + image_disabled="BreadCrumbBtn_Left_Disabled" + image_disabled_selected="BreadCrumbBtn_Left_Disabled" + width="110"> + <button.commit_callback + function="Wizard.Choose"/> + </button> + <panel + height="388" + top_pad="0" + name="choose_file_panel" + visible="false" + width="535" + left="0"> + <panel + height="22" + top_pad="15" + width="505" + name="header_panel" + bg_opaque_color="DkGray2" + background_visible="true" + background_opaque="true" + left="15"> + <text + width="200" + left="10" + top="3" + name="header_text" + text_color="White" + height="10" + font="SansSerifBig" + layout="topleft"> + Upload Model + </text> + </panel> + <text + top_pad="14" + width="460" + height="20" + name="description" + font="SansSerifSmall" + layout="topleft" + word_wrap="true" + left_delta="5"> + This wizard will help you import mesh models to Second Life. First specify a file containing the model you wish to import. Second Life supports COLLADA (.dae) files. + </text> + <panel + top_delta="40" + left="15" + height="270" + width="505" + name="content" + bg_opaque_color="DkGray2" + background_visible="true" + background_opaque="true"> + <text + type="string" + length="1" + text_color="White" + follows="left|top" + top="10" + height="10" + layout="topleft" + left_delta="10" + name="Cache location" + width="300"> + Filename: + </text> + <line_editor + border_style="line" + border_thickness="1" + follows="left|top" + font="SansSerifSmall" + height="20" + layout="topleft" + left_delta="0" + max_length="4096" + name="lod_file" + top_pad="5" + width="220" /> + <button + follows="left|top" + height="23" + label="Browse..." + label_selected="Browse..." + layout="topleft" + left_pad="5" + name="browse" + top_delta="-1" + width="85"> + </button> + <text + top_delta="-15" + width="200" + height="15" + font="SansSerifSmall" + layout="topleft" + text_color="White" + left_pad="19"> + Model Preview: + </text> + <!-- Placeholder panel for 3D preview render --> + <panel + left_delta="0" + top_pad="0" + name="preview_panel" + bevel_style="none" + highlight_light_color="0.09 0.09 0.09 1" + border="true" + height="150" + follows="all" + width="150"> + </panel> + <text + top_pad="10" + width="130" + height="14" + left="340" + text_color="White" + word_wrap="true"> + Dimensions (meters): + </text> + <text + top_pad="0" + width="160" + height="15" + font="SansSerifSmallBold" + text_color="White" + name="dimensions" + left_delta="0"> + X: Y: Z: + </text> + <text + top_delta="0" + width="160" + height="15" + name="dimension_dividers" + left_delta="41"> + | | + </text> + <text + top_delta="0" + width="160" + height="15" + name="dimension_x" + left="356"/> + <text + top_delta="0" + width="160" + height="15" + name="dimension_y" + left="403"/> + <text + top_delta="0" + width="160" + height="15" + name="dimension_z" + left="450"/> + <text + top="100" + width="320" + height="15" + left="10" + text_color="White" + word_wrap="true"> + Note: + </text> + <text + top_pad="0" + width="320" + height="40" + left="10" + word_wrap="true"> +Advanced users familiar with 3d content creation tools may prefer to use the [secondlife:///app/floater/upload_model Advanced Mesh Import Window] . + </text> + </panel> + </panel> + + + <panel + height="388" + top_delta="0" + name="optimize_panel" + visible="false" + width="535" + left="0"> + <panel + height="22" + top_pad="15" + name="header_panel" + width="505" + bg_opaque_color="DkGray2" + background_visible="true" + background_opaque="true" + left="15"> + <text + width="200" + left="10" + name="header_text" + top="3" + text_color="White" + height="10" + font="SansSerifBig" + layout="topleft"> + Optimize + </text> + </panel> + <text + top_pad="14" + width="460" + height="20" + font="SansSerifSmall" + layout="topleft" + name="description" + word_wrap="true" + left_delta="5"> + This wizard has optimized your model to improve performance. You may adjust the results of the optimization process bellow or click Next to continue. + </text> + <panel + top_delta="40" + visible="false" + left="15" + height="270" + width="505" + name="content" + bg_opaque_color="DkGray2" + background_visible="true" + background_opaque="true"> + <text + top="20" + width="300" + height="12" + font="SansSerifBold" + left="112">Generating Level of Detail</text> + <progress_bar + name="optimize_progress_bar" + image_fill="model_wizard\progress_light.png" + color_bg="1 1 1 1" + color_bar="1 1 1 0.96" + follows="left|right|top" + width="260" + height="16" + image_bar="model_wizard\progress_bar_bg.png" + top_pad="14" + left="110"/> + <icon + top_pad="10" + left_delta="0" + width="13" + height="12" + image_name="model_wizard\check_mark.png"/> + <text + top_delta="0" + left_delta="18" + name="high_detail_text" + width="200" + height="14">Generate Level of Detail: High</text> + <icon + top_pad="10" + left_delta="-18" + width="13" + height="12" + image_name="model_wizard\check_mark.png"/> + <text + top_delta="0" + left_delta="18" + name="medium_detail_text" + width="200" + height="14">Generate Level of Detail: Medium</text> + <icon + top_pad="10" + left_delta="-18" + width="13" + height="12" + image_name="model_wizard\check_mark.png"/> + <text + top_delta="0" + left_delta="18" + name="low_detail_text" + width="200" + height="14">Generate Level of Detail: Low</text> + <icon + top_pad="10" + left_delta="-18" + width="13" + height="12" + image_name="model_wizard\check_mark.png"/> + <text + top_delta="0" + left_delta="18" + name="lowest_detail_text" + width="200" + height="14">Generate Level of Detail: Lowest</text> + </panel> + <panel + top_delta="0" + left_delta="0" + height="270" + width="505" + name="content2" + bg_opaque_color="DkGray2" + background_visible="true" + background_opaque="true"> + <text top="10" left="10" width="85" text_color="White" follows="left|top" height="15" name="lod_label"> + Model Preview: + </text> + <combo_box left_pad="5" top_delta="-5" follows="left|top" list_position="below" height="22" + name="preview_lod_combo2" width="90" tool_tip="LOD to view in preview render"> + <combo_item name="high"> + High + </combo_item> + <combo_item name="medium"> + Medium + </combo_item> + <combo_item name="low"> + Low + </combo_item> + <combo_item name="lowest"> + Lowest + </combo_item> + </combo_box> + <panel + left="10" + top_pad="5" + name="preview_panel" + bevel_style="none" + highlight_light_color="0.09 0.09 0.09 1" + border_style="line" + border="true" + height="185" + follows="all" + width="185"> + </panel> + <text top="45" left="214" text_color="White" font="SansSerifSmallBold" halign="center" width="110" height="30" wrap="true">Higher Performance</text> + <text top="75" left="204" halign="center" width="130" word_wrap="true" font="SansSerifSmall" height="80">Faster rendering but less detailed; lowers Resource (prim) cost.</text> + <text top="45" left="378" text_color="White" font="SansSerifSmallBold" halign="center" width="90" height="30" wrap="true">Higher Accuracy</text> + <text top="75" left="364" halign="center" width="130" word_wrap="true" font="SansSerifSmall" height="80">More detailed model but slower; increases Resource (prim) cost.</text> + + <slider + follows="left|top" + height="20" + increment="1" + layout="topleft" + left="204" + max_val="3" + initial_value="2" + min_val="0" + name="accuracy_slider" + show_text="false" + top="130" + width="290" /> + <text + font="SansSerifSmall" + top_pad="0" + width="300" + left_delta="6" + height="4">' + </text> + + + <icon + top_pad="14" + left_delta="0" + width="280" + height="2" + image_name="model_wizard\divider_line.png"/> + + <text top_delta="20" width="200" text_color="White" left_delta="50" name="streaming cost" height="20">Resource Cost: [COST]</text> + <text + top_pad="15" + width="130" + height="14" + left="10" + text_color="White" + word_wrap="true"> + Dimensions (meters): + </text> + <text + top_pad="0" + width="160" + height="15" + font="SansSerifSmallBold" + text_color="White" + name="dimensions" + left_delta="0"> + X: Y: Z: + </text> + <text + top_delta="0" + width="160" + height="15" + name="dimension_dividers" + left_delta="41"> + | | + </text> + <text + top_delta="0" + width="160" + height="15" + name="dimension_x" + left_delta="-25"/> + <text + top_delta="0" + width="160" + height="15" + name="dimension_y" + left_delta="46"/> + <text + top_delta="0" + width="160" + height="15" + name="dimension_z" + left_delta="46"/> + </panel> + </panel> + + <panel + height="388" + top_delta="0" + name="physics_panel" + visible="false" + width="535" + left="0"> + <panel + height="22" + top_pad="15" + name="header_panel" + width="505" + bg_opaque_color="DkGray2" + background_visible="true" + background_opaque="true" + left="15"> + <text + width="200" + left="10" + name="header_text" + top="3" + height="10" + font="SansSerifBig" + text_color="White" + layout="topleft"> + Physics + </text> + </panel> + <text + top_pad="10" + width="474" + height="50" + font="SansSerifSmall" + layout="topleft" + name="description" + word_wrap="true" + left_delta="5"> + The wizard will create a physical shape, which determines how the object interacts with other objects and avatars. Set the slider to the detail level most appropriate for how your object will be used: + </text> + <panel + top_delta="44" + left="15" + height="270" + width="505" + name="content" + bg_opaque_color="DkGray2" + background_visible="true" + background_opaque="true"> + <text top="25" left="30" text_color="White" font="SansSerifSmallBold" width="300" height="4">Performance</text> + <text top="45" left="10" halign="center" width="130" word_wrap="true" font="SansSerifSmall" height="80">Faster rendering but less detailed; lowers Resource (prim) cost.</text> + <text top="25" left="390" text_color="White" font="SansSerifSmallBold" width="300" height="4">Accuracy</text> + <text top="45" left="360" halign="center" width="130" word_wrap="true" font="SansSerifSmall" height="80">More detailed model but slower; increases Resource (prim) cost.</text> + + <slider + follows="left|top" + height="22" + increment=".1" + layout="topleft" + left="20" + max_val="1" + initial_value="0.5" + min_val="0" + name="physics_slider" + show_text="false" + top="90" + width="440" /> + <text + font="SansSerifSmall" + top_pad="0" + width="500" + left_delta="6" + height="4">' ' ' ' ' ' ' ' ' ' '</text> + <text top_pad="10" width="110" halign="center" word_wrap="true" left="25" height="40">Recommended for solid objects</text> + <text top_delta="0" width="110" halign="center" word_wrap="true" left="190" height="40">Recommended for buildings</text> + <text top_delta="0" width="110" halign="center" word_wrap="true" left="350" height="40">Recommended for vehicles</text> + + + <icon + top_pad="5" + left="15" + width="470" + height="2" + image_name="model_wizard\divider_line.png"/> + + <text top_delta="30" width="180" text_color="White" left="160" name="streaming cost" height="20">Resource Cost: [COST]</text> + + </panel> + </panel> + + <panel + height="388" + top_delta="0" + name="physics2_panel" + visible="true" + width="535" + left="0"> + <panel + height="22" + top_pad="15" + name="header_panel" + width="505" + bg_opaque_color="DkGray2" + background_visible="true" + background_opaque="true" + left="15"> + <text + width="200" + left="10" + name="header_text" + text_color="White" + top="3" + height="10" + font="SansSerifBig" + layout="topleft"> + Physics + </text> + </panel> + <text + top_pad="14" + width="475" + height="50" + font="SansSerifSmall" + layout="topleft" + name="description" + word_wrap="true" + left_delta="5"> + Preview the physics shape below then click Next to continue. To modify the physics shape, click the Back button. + </text> + <panel + top_delta="40" + left="15" + height="270" + width="505" + name="content" + bg_opaque_color="DkGray2" + background_visible="true" + background_opaque="true"> + <text top="10" left="10" width="85" text_color="White" follows="left|top" height="15" name="lod_label"> + Model Preview: + </text> + <combo_box left_pad="5" top_delta="-5" follows="left|top" list_position="below" height="22" + name="preview_lod_combo3" width="90" tool_tip="LOD to view in preview render"> + <combo_item name="high"> + High + </combo_item> + <combo_item name="medium"> + Medium + </combo_item> + <combo_item name="low"> + Low + </combo_item> + <combo_item name="lowest"> + Lowest + </combo_item> + </combo_box> + <panel + left="10" + top_pad="10" + name="preview_panel" + bevel_style="none" + highlight_light_color="0.09 0.09 0.09 1" + border_style="line" + border="true" + height="190" + follows="all" + width="190"> + </panel> + <text + top_pad="8" + width="130" + height="14" + left="10" + text_color="White" + word_wrap="true"> + Dimensions (meters): + </text> + <text + top_pad="0" + width="160" + height="15" + font="SansSerifSmallBold" + text_color="White" + name="dimensions" + left_delta="0"> + X: Y: Z: + </text> + <text + top_delta="0" + width="160" + height="15" + name="dimension_dividers" + left_delta="41"> + | | + </text> + <text + top_delta="0" + width="160" + height="15" + name="dimension_x" + left_delta="-25"/> + <text + top_delta="0" + width="160" + height="15" + name="dimension_y" + left_delta="46"/> + <text + top_delta="0" + width="160" + height="15" + name="dimension_z" + left_delta="46"/> + <text top="60" width="180" text_color="White" left="225" name="streaming cost" height="20">Resource Cost: [COST]</text> + </panel> + </panel> + + <panel + height="388" + top_delta="0" + name="review_panel" + visible="false" + width="535" + left="0"> + <panel + height="22" + top_pad="15" + name="header_panel" + width="505" + bg_opaque_color="DkGray2" + background_visible="true" + background_opaque="true" + left="15"> + <text + width="200" + left="10" + name="header_text" + text_color="White" + top="3" + height="10" + font="SansSerifBig" + layout="topleft"> + Review + </text> + </panel> + <text + top_pad="14" + width="470" + height="24" + font="SansSerifSmall" + layout="topleft" + name="description" + word_wrap="true" + left_delta="5"> + Review the details below then click. Upload to upload your model. Your L$ balance will be charged when you click Upload. + </text> + <icon + top_pad="10" + left="20" + width="495" + height="2" + image_name="model_wizard\divider_line.png"/> + <panel + top_pad="5" + left="15" + height="270" + width="505" + name="content"> + <text top="10" left="10" width="85" text_color="White" follows="left|top" height="15" name="lod_label"> + Model Preview: + </text> + <combo_box left_pad="5" top_delta="-5" follows="left|top" list_position="below" height="22" + name="preview_lod_combo" width="90" tool_tip="LOD to view in preview render"> + <combo_item name="high"> + High + </combo_item> + <combo_item name="medium"> + Medium + </combo_item> + <combo_item name="low"> + Low + </combo_item> + <combo_item name="lowest"> + Lowest + </combo_item> + </combo_box> + <panel + left="10" + top_pad="10" + name="preview_panel" + bevel_style="none" + highlight_light_color="0.09 0.09 0.09 1" + border_style="line" + border="true" + height="190" + follows="all" + width="190"> + </panel> + <text + top_pad="8" + width="130" + height="14" + left="10" + text_color="White" + word_wrap="true"> + Dimensions (meters): + </text> + <text + top_pad="0" + width="160" + height="15" + font="SansSerifSmallBold" + text_color="White" + name="dimensions" + left_delta="0"> + X: Y: Z: + </text> + <text + top_delta="0" + width="160" + height="15" + name="dimension_dividers" + left_delta="41"> + | | + </text> + <text + top_delta="0" + width="160" + height="15" + name="dimension_x" + left_delta="-25"/> + <text + top_delta="0" + width="160" + height="15" + name="dimension_y" + left_delta="46"/> + <text + top_delta="0" + width="160" + height="15" + name="dimension_z" + left_delta="46"/> + </panel> + <text + width="300" + height="12" + top="125" + name="streaming cost" + left="230" + font="SansSerifSmallBold" + text_color="White">Resource Cost: [COST]</text> + <text + width="285" + height="30" + top_pad="0" + left_delta="0" + word_wrap="true" + font="SansSerifItalic">This is the cost to your Region's prim/object limit, at default scale</text> + <text + width="300" + height="12" + name="physics cost" + top_pad="10" + left_delta="0" + font="SansSerifSmallBold" + text_color="White">Physics Cost: [COST]</text> + <text + width="285" + height="30" + top_pad="0" + left_delta="0" + word_wrap="true" + font="SansSerifItalic">This is the cost to your Region's prim/object limit, at default scale</text> + <text + width="200" + height="12" + top_pad="10" + left_delta="0" + font="SansSerifSmallBold" + text_color="White">Upload Fee:</text> + <text + width="285" + height="26" + top_pad="0" + left_delta="0" + word_wrap="true" + font="SansSerifItalic">This is the amount the upload will cost.</text> + <check_box + height="16" + layout="topleft" + left_delta="0" + name="confirm_checkbox" + top_pad="15" + width="16" /> + <text + height="100" + width="240" + word_wrap="true" + left_delta="25" + top_delta="0">I confirm that I have the appropriate rights to the material contained in this model. [secondlife:///app/floater/learn_more Learn more]</text> + </panel> + + + + + <panel + height="388" + top_delta="0" + name="upload_panel" + visible="false" + width="535" + left="0"> + <panel + height="22" + top_pad="15" + name="header_panel" + width="505" + bg_opaque_color="DkGray2" + background_visible="true" + background_opaque="true" + left="15"> + <text + width="200" + left="10" + name="header_text" + top="3" + text_color="White" + height="10" + font="SansSerifBig" + layout="topleft"> + Upload Complete! + </text> + </panel> + <text + top_pad="14" + width="474" + height="20" + font="SansSerifSmall" + layout="topleft" + name="description" + word_wrap="true" + left_delta="5"> + Congratulations! Your model has been sucessfully uploaded. You will find the model in the Objects folder in your inventory. + </text> + <icon + top_pad="15" + left_delta="0" + width="495" + height="2" + image_name="model_wizard\divider_line.png"/> + </panel> + + + + <button + top="440" + right="-245" + width="90" + height="22" + name="back" + label="<< Back" /> + <button + top_delta="0" + right="-150" + width="90" + height="22" + name="next" + label="Next >> " /> + <button + top_delta="0" + right="-150" + width="90" + height="22" + visible="false" + name="upload" + tool_tip="Upload to simulator" + label="Upload" /> + <button + top_delta="0" + right="-15" + width="90" + height="22" + name="cancel" + label="Cancel" /> + <button + top_delta="0" + right="-15" + width="90" + height="22" + name="close" + visible="false" + label="Close" /> + <spinner visible="false" left="10" height="20" follows="top|left" width="80" top_pad="-50" value="1.0" min_val="0.01" max_val="64.0" name="import_scale"/> + + <string name="status_idle">Idle</string> + <string name="status_reading_file">Loading...</string> + <string name="status_generating_meshes">Generating Meshes...</string> + <string name="status_vertex_number_overflow">Error: Vertex number is more than 65534, aborted!</string> + <string name="high">High</string> + <string name="medium">Medium</string> + <string name="low">Low</string> + <string name="lowest">Lowest</string> + <string name="mesh_status_good">Ship it!</string> + <string name="mesh_status_na">N/A</string> + <string name="mesh_status_none">None</string> + <string name="mesh_status_submesh_mismatch">Levels of detail have a different number of textureable faces.</string> + <string name="mesh_status_mesh_mismatch">Levels of detail have a different number of mesh instances.</string> + <string name="mesh_status_too_many_vertices">Level of detail has too many vertices.</string> + <string name="mesh_status_missing_lod">Missing required level of detail.</string> + <string name="layer_all">All</string> + <!-- Text to display in physics layer combo box for "all layers" --> + +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_price_for_listing.xml b/indra/newview/skins/default/xui/en/floater_price_for_listing.xml new file mode 100644 index 0000000000..6312366b86 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_price_for_listing.xml @@ -0,0 +1,81 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + legacy_header_height="18" + can_minimize="false" + height="240" + layout="topleft" + name="price_for_listing" + help_topic="price_for_listing" + title="PUBLISH CLASSIFIED AD" + width="320"> + <text + type="string" + length="1" + bottom="200" + follows="top|left" + font="SansSerif" + height="165" + layout="topleft" + left="15" + word_wrap="true" + name="explanation_text"> + Your classified ad will run for one week from the day it is published. + +Your ad's position in the classified listings is determined by how much you choose to pay. + +The highest paid ads go to the top of the list, and appear higher in searches. + </text> + <text + type="string" + length="1" + follows="top|right" + font="SansSerif" + height="20" + layout="topleft" + left="140" + name="price_text" + top_delta="135" + width="85"> + Price for Ad: + </text> + <text + type="string" + length="1" + follows="top|right" + font="SansSerif" + height="20" + layout="topleft" + left_pad="4" + name="price_symbol" + top_delta="0" + width="20"> + L$ + </text> + <line_editor + follows="top|left" + height="20" + layout="topleft" + left_pad="0" + max_length="6" + top_delta="-4" + name="price_edit" + width="60" /> + <button + follows="top|left" + height="22" + label="OK" + layout="topleft" + left="105" + name="set_price_btn" + top_pad="22" + width="100" /> + <button + follows="top|left" + height="22" + label="Cancel" + layout="topleft" + left_pad="5" + name="cancel_btn" + width="100" /> + +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_sell_land.xml b/indra/newview/skins/default/xui/en/floater_sell_land.xml index 619669d28a..38b305db7e 100644 --- a/indra/newview/skins/default/xui/en/floater_sell_land.xml +++ b/indra/newview/skins/default/xui/en/floater_sell_land.xml @@ -41,14 +41,14 @@ follows="top|left" left="16" name="info_parcel_label" - width="48"> + width="70"> Parcel: </text> <text top_delta="0" follows="top|left" height="16" - left="56" + left="78" name="info_parcel" right="-20"> PARCEL NAME @@ -57,14 +57,14 @@ follows="top|left" left="16" name="info_size_label" - width="48"> + width="70"> Size: </text> <text follows="top|left" top_delta="0" height="32" - left="56" + left="78" name="info_size" right="-20"> [AREA] m² @@ -164,14 +164,14 @@ left_delta="0" name="sell_to_agent" top_pad="4" - width="170" /> + width="150" /> <button height="20" label="Select" left_pad="5" name="sell_to_select_agent" top_delta="0" - width="60" /> + width="90" /> <text follows="top|left" font="SansSerif" @@ -199,20 +199,20 @@ <radio_item bottom="40" height="0" - left="10" + left="2" name="none" visible="false" /> <radio_item top_pad="10" - height="16" + height="18" label="No, keep ownership of objects" - left="10" + left="2" name="no" /> <radio_item top_pad="10" height="16" label="Yes, sell objects with land" - left="10" + left="2" name="yes" /> </radio_group> <button @@ -221,7 +221,7 @@ name="show_objects" left="70" top_pad="10" - width="110" /> + width="140" /> <text bottom_delta="30" follows="top|left" @@ -229,7 +229,7 @@ height="16" left="16" name="nag_message_label" - right="-20"> + right="-5"> REMEMBER: All sales are final. </text> <button @@ -239,15 +239,15 @@ left_delta="0" name="sell_btn" top_pad="10" - width="130" /> + width="185" /> <button follows="bottom|left" height="20" label="Cancel" - left_pad="30" + left_pad="5" name="cancel_btn" top_delta="0" - width="90" /> + width="85" /> </panel> </scroll_container> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml index e413228ddc..ec190ab656 100644 --- a/indra/newview/skins/default/xui/en/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml @@ -100,7 +100,7 @@ right="-5" name="upload_btn" top_delta="0" - width="100" /> + width="110" /> <flyout_button follows="left|top" height="23" @@ -147,7 +147,7 @@ right="-5" left_pad="5" name="discard_btn" - width="100" /> + width="110" /> <text type="string" length="1" diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index d0603cb30e..05d47506db 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -295,22 +295,24 @@ width="100"> þ: [COUNT] </text> - <check_box + <check_box control_name="ScaleUniform" height="19" label="" layout="topleft" left="143" name="checkbox uniform" - top="50" + top="50" width="20" /> <text height="19" label="Stretch Both Sides" - left="163" + left_delta="20" name="checkbox uniform label" - top="55" + top_delta="2" width="120" + layout="topleft" + follows="top|left" wrap="true"> Stretch Both Sides </text> @@ -323,6 +325,7 @@ left="143" name="checkbox stretch textures" top_pad="-6" + follows="left|top" width="134" /> <check_box control_name="SnapEnabled" @@ -361,9 +364,10 @@ image_selected="ForwardArrow_Press" image_unselected="ForwardArrow_Off" layout="topleft" + follows="top|left" name="Options..." tool_tip="See more grid options" - top_delta="0" + top_pad="-22" right="-10" width="18" height="23" > @@ -745,18 +749,73 @@ <button.commit_callback function="BuildTool.applyToSelection"/> </button> - <text + <text + text_color="LtGray_50" + type="string" + length="1" + height="10" + follows="left|top" + halign="right" + layout="topleft" + right="-10" + name="obj_count" + top_pad="5" + width="143"> + Objects: [COUNT] + </text> + <text text_color="LtGray_50" type="string" length="1" - height="10" + height="10" follows="left|top" halign="right" layout="topleft" right="-10" - name="obj_count" - top_pad="7" + name="prim_count" width="143"> + Prims: [COUNT] + </text> + <text + text_color="LtGray_50" + type="string" + length="1" + height="10" + follows="left|top" + halign="right" + layout="topleft" + right="-120" + name="linked_set_count" + top="144" + width="80"> + Linked Sets: [COUNT] + </text> + <text + text_color="LtGray_50" + type="string" + length="1" + height="10" + follows="left|top" + halign="right" + layout="topleft" + top_delta="0" + right="-8" + name="linked_set_cost" + tool_tip="Cost of currently selected linked sets as [prims],[physics complexity]" + width="80"> + Cost: [COST] / [PHYSICS] + </text> + <text + text_color="LtGray_50" + type="string" + length="1" + follows="left|top" + halign="right" + layout="topleft" + top_pad="5" + right="-120" + name="object_count" + width="80"> Objects: [COUNT] </text> <text @@ -766,11 +825,39 @@ follows="left|top" halign="right" layout="topleft" - right="-10" - name="prim_count" - width="143"> - Prims: [COUNT] + top_delta="0" + right="-8" + name="object_cost" + tool_tip="Cost of currently selected objects as [prims] / [physics complexity]" + width="80"> + Cost: [COST] / [PHYSICS] </text> + <!-- <text --> + <!-- text_color="LtGray_50" --> + <!-- type="string" --> + <!-- length="1" --> + <!-- height="10" --> + <!-- follows="left|top" --> + <!-- halign="right" --> + <!-- layout="topleft" --> + <!-- right="-10" --> + <!-- name="obj_count" --> + <!-- top_pad="5" --> + <!-- width="143"> --> + <!-- Objects: [COUNT] --> + <!-- </text> --> + <!-- <text --> + <!-- text_color="LtGray_50" --> + <!-- type="string" --> + <!-- length="1" --> + <!-- follows="left|top" --> + <!-- halign="right" --> + <!-- layout="topleft" --> + <!-- right="-10" --> + <!-- name="prim_count" --> + <!-- width="143"> --> + <!-- Prims: [COUNT] --> + <!-- </text> --> <tab_container follows="left|top" height="410" @@ -783,7 +870,8 @@ tab_height="25" top="173" width="295"> - <panel + +<panel border="false" follows="all" label="General" @@ -1253,7 +1341,7 @@ even though the user gets a free copy. <panel border="false" follows="all" - height="367" + height="567" label="Object" layout="topleft" left_delta="0" @@ -1372,7 +1460,7 @@ even though the user gets a free copy. label_width="10" layout="topleft" left_delta="0" - max_val="10" + max_val="64" min_val="0.01" name="Scale X" text_enabled_color="1 1 1 1" @@ -1387,7 +1475,7 @@ even though the user gets a free copy. label_width="10" layout="topleft" left_delta="0" - max_val="10" + max_val="64" min_val="0.01" name="Scale Y" text_enabled_color="1 1 1 1" @@ -1402,7 +1490,7 @@ even though the user gets a free copy. label_width="10" layout="topleft" left_delta="0" - max_val="10" + max_val="64" min_val="0.01" name="Scale Z" text_enabled_color="1 1 1 1" @@ -1468,7 +1556,6 @@ even though the user gets a free copy. text_enabled_color="1 1 1 1" top_pad="3" width="87" /> - <!-- <text type="string" length="1" @@ -2046,6 +2133,10 @@ even though the user gets a free copy. label="Cylinder" name="Cylinder" value="Cylinder" /> + <combo_box.item + label="Mesh" + name="Mesh" + value="Mesh" /> </combo_box> </panel> <panel @@ -2060,6 +2151,9 @@ even though the user gets a free copy. name="Features" top_delta="0" width="295"> + <panel.string name="None">None</panel.string> + <panel.string name="Prim">Prim</panel.string> + <panel.string name="Convex Hull">Convex Hull</panel.string> <text type="string" length="1" @@ -2202,6 +2296,7 @@ even though the user gets a free copy. name="FlexForceZ" top_pad="4" width="128" /> + <check_box height="16" label="Light" @@ -2312,6 +2407,94 @@ even though the user gets a free copy. mouse_opaque="true" name="Light Ambiance" width="120" /> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + name="label physicsshapetype" + top="38" + width="121"> + Physics Shape Type: + </text> + <combo_box + height="19" + top_delta="15" + layout="topleft" + follows="left|top" + name="Physics Shape Type Combo Ctrl" + tool_tip="Choose the physics shape type" + width="108"/> + + <spinner + follows="left|top" + height="19" + increment="1" + initial_value="1" + label="Gravity" + label_width="70" + layout="topleft" + min_val="-1" + max_val="28" + name="Physics Gravity" + top_pad="10" + width="132" /> + + <check_box + height="19" + label="Override material" + layout="topleft" + left_delta="0" + name="Physics Material Override" + tool_tip="Override Material" + top_pad="10" + width="132" /> + + <spinner + follows="left|top" + height="19" + increment="0.1" + initial_value="0" + label="Friction" + label_width="70" + layout="topleft" + left_delta="0" + max_val="255" + min_val="0" + name="Physics Friction" + top_pad="4" + width="132" /> + + <spinner + follows="left|top" + height="19" + increment="0.1" + initial_value="0" + label="Density" + label_width="70" + layout="topleft" + left_delta="0" + max_val="22587" + min_val="1" + name="Physics Density" + top_pad="4" + width="132" /> + + <spinner + follows="left|top" + height="19" + increment="0.01" + initial_value="0" + label="Restitution" + label_width="70" + layout="topleft" + left_delta="0" + max_val="1" + min_val="0" + name="Physics Restitution" + top_pad="4" + width="132" /> </panel> <panel border="false" @@ -2378,7 +2561,7 @@ even though the user gets a free copy. initial_value="0" layout="topleft" left_delta="0" - max_val="90" + max_val="100" name="ColorTrans" top_pad="4" width="80" /> diff --git a/indra/newview/skins/default/xui/en/floater_top_objects.xml b/indra/newview/skins/default/xui/en/floater_top_objects.xml index b06c6dc215..4dfdcd15c7 100644 --- a/indra/newview/skins/default/xui/en/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/en/floater_top_objects.xml @@ -105,7 +105,7 @@ left_delta="0" name="id_text" top_pad="10" - width="100"> + width="107"> Object ID: </text> <line_editor @@ -116,7 +116,7 @@ left_pad="3" name="id_editor" top_delta="-3" - width="575" /> + width="568" /> <button follows="bottom|right" height="23" @@ -138,7 +138,7 @@ left="10" top_pad="5" name="obj_name_text" - width="100"> + width="107"> Object name: </text> <line_editor @@ -148,7 +148,7 @@ left_pad="3" name="object_name_editor" top_delta="-3" - width="575" /> + width="568" /> <button follows="bottom|right" height="23" @@ -170,7 +170,7 @@ left="10" top_pad="5" name="owner_name_text" - width="100"> + width="107"> Owner: </text> <line_editor @@ -180,7 +180,7 @@ left_pad="3" name="owner_name_editor" top_delta="-3" - width="575" /> + width="568" /> <button follows="bottom|right" height="23" diff --git a/indra/newview/skins/default/xui/en/floater_windlight_options.xml b/indra/newview/skins/default/xui/en/floater_windlight_options.xml index 249ad95c41..b121f3daa5 100644 --- a/indra/newview/skins/default/xui/en/floater_windlight_options.xml +++ b/indra/newview/skins/default/xui/en/floater_windlight_options.xml @@ -1273,16 +1273,6 @@ name="WLCloudScrollY" top="85" width="200" /> - <check_box - control_name="DrawClassicClouds" - follows="left" - height="16" - label="Draw Classic Clouds" - layout="topleft" - left="480" - name="DrawClassicClouds" - top="104" - width="200" /> </panel> </tab_container> </floater> diff --git a/indra/newview/skins/default/xui/en/menu_inventory_add.xml b/indra/newview/skins/default/xui/en/menu_inventory_add.xml index 90e8db3709..484af63097 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml @@ -42,6 +42,18 @@ <menu_item_call.on_enable function="File.EnableUpload" /> </menu_item_call> + <menu_item_call + label="Model..." + layout="topleft" + name="Upload Model"> + <menu_item_call.on_click + function="File.UploadModel" + parameter="" /> + <menu_item_call.on_enable + function="File.EnableUploadModel" /> + <menu_item_call.on_visible + function="File.VisibleUploadModel"/> + </menu_item_call> <menu_item_call label="Bulk (L$[COST] per file)..." layout="topleft" @@ -239,4 +251,4 @@ parameter="eyes" /> </menu_item_call> </menu> -</menu>
\ No newline at end of file +</menu> diff --git a/indra/newview/skins/default/xui/en/menu_model_import_gear_default.xml b/indra/newview/skins/default/xui/en/menu_model_import_gear_default.xml new file mode 100644 index 0000000000..2650903f88 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_model_import_gear_default.xml @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + bottom="806" + layout="topleft" + left="0" + mouse_opaque="false" + name="model_menu_gear_default" + visible="false"> + <menu_item_check + label="Show edges" + layout="topleft" + name="show_edges"> + <on_click + function="ModelImport.ViewOption.Action" + parameter="show_edges" /> + <on_check + function="ModelImport.ViewOption.Check" + parameter="show_edges" /> + <on_enable + function="ModelImport.ViewOption.Enabled" + parameter="show_edges" /> + </menu_item_check> + <menu_item_check + label="Show physics" + layout="topleft" + name="show_physics"> + <on_click + function="ModelImport.ViewOption.Action" + parameter="show_physics" /> + <on_check + function="ModelImport.ViewOption.Check" + parameter="show_physics" /> + <on_enable + function="ModelImport.ViewOption.Enabled" + parameter="show_physics" /> + </menu_item_check> + <menu_item_check + label="Show textures" + layout="topleft" + name="show_textures"> + <on_click + function="ModelImport.ViewOption.Action" + parameter="show_textures" /> + <on_check + function="ModelImport.ViewOption.Check" + parameter="show_textures" /> + <on_enable + function="ModelImport.ViewOption.Enabled" + parameter="show_textures" /> + </menu_item_check> + <menu_item_check + label="Show skin weight" + layout="topleft" + name="show_skin_weight"> + <on_click + function="ModelImport.ViewOption.Action" + parameter="show_skin_weight" /> + <on_check + function="ModelImport.ViewOption.Check" + parameter="show_skin_weight" /> + <on_enable + function="ModelImport.ViewOption.Enabled" + parameter="show_skin_weight" /> + </menu_item_check> + <menu_item_check + label="Show joint positions" + layout="topleft" + name="show_joint_positions"> + <on_click + function="ModelImport.ViewOption.Action" + parameter="show_joint_positions" /> + <on_check + function="ModelImport.ViewOption.Check" + parameter="show_joint_positions" /> + <on_enable + function="ModelImport.ViewOption.Enabled" + parameter="show_joint_positions" /> + </menu_item_check> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index d5d41b981f..d8aec81eba 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -89,7 +89,7 @@ visibility_control="VoiceMorphingEnabled"> <menu_item_check.on_check function="Floater.Visible" - parameter="voice_effect" /> + Parameter="voice_effect" /> <menu_item_check.on_click function="Floater.Toggle" parameter="voice_effect" /> @@ -1061,6 +1061,30 @@ parameter="Upload Animation" /> </menu_item_call> <menu_item_call + label="Model..." + layout="topleft" + name="Upload Model"> + <menu_item_call.on_click + function="File.UploadModel" + parameter="" /> + <menu_item_call.on_enable + function="File.EnableUploadModel" /> + <menu_item_call.on_visible + function="File.VisibleUploadModel"/> + </menu_item_call> + <menu_item_call + label="Model Wizard..." + layout="topleft" + name="Upload Model Wizard"> + <menu_item_call.on_click + function="Floater.Show" + parameter="upload_model_wizard" /> + <menu_item_call.on_enable + function="File.EnableUploadModel" /> + <menu_item_call.on_visible + function="File.VisibleUploadModel"/> + </menu_item_call> + <menu_item_call label="Bulk (L$[COST] per file)..." layout="topleft" name="Bulk Upload"> @@ -1431,15 +1455,15 @@ parameter="character" /> </menu_item_check> <menu_item_check - label="SurfacePath" - name="SurfacePath" + label="Surface Patch" + name="Surface Patch" shortcut="control|alt|shift|5"> <menu_item_check.on_check function="Advanced.CheckRenderType" - parameter="surfacePath" /> + parameter="surfacePatch" /> <menu_item_check.on_click function="Advanced.ToggleRenderType" - parameter="surfacePath" /> + parameter="surfacePatch" /> </menu_item_check> <menu_item_check label="Sky" @@ -1966,6 +1990,16 @@ function="Advanced.ToggleConsole" parameter="memory view" /> </menu_item_check> + <menu_item_check + label="Scene Statistics" + name="Scene Statistics"> + <menu_item_check.on_check + function="Advanced.CheckConsole" + parameter="scene view" /> + <menu_item_check.on_click + function="Advanced.ToggleConsole" + parameter="scene view" /> + </menu_item_check> <menu_item_separator/> @@ -2050,6 +2084,17 @@ function="ToggleControl" parameter="DebugShowTime" /> </menu_item_check> + <menu_item_check + label="Show Upload Cost" + layout="topleft" + name="Show Upload Cost"> + <menu_item_check.on_check + function="CheckControl" + parameter="DebugShowUploadCost" /> + <menu_item_check.on_click + function="ToggleControl" + parameter="DebugShowUploadCost" /> + </menu_item_check> <menu_item_check label="Show Render Info" name="Show Render Info"> @@ -2233,6 +2278,16 @@ parameter="bboxes" /> </menu_item_check> <menu_item_check + label="Normals" + name="Normals"> + <menu_item_check.on_check + function="Advanced.CheckInfoDisplay" + parameter="normals" /> + <menu_item_check.on_click + function="Advanced.ToggleInfoDisplay" + parameter="normals" /> + </menu_item_check> + <menu_item_check label="Octree" name="Octree"> <menu_item_check.on_check @@ -2253,6 +2308,16 @@ parameter="shadow frusta" /> </menu_item_check> <menu_item_check + label="Physics Shapes" + name="Physics Shapes"> + <menu_item_check.on_check + function="Advanced.CheckInfoDisplay" + parameter="physics shapes" /> + <menu_item_check.on_click + function="Advanced.ToggleInfoDisplay" + parameter="physics shapes" /> + </menu_item_check> + <menu_item_check label="Occlusion" name="Occlusion"> <menu_item_check.on_check @@ -2323,6 +2388,26 @@ parameter="face area" /> </menu_item_check> <menu_item_check + label="LOD Info" + name="LOD Info"> + <menu_item_check.on_check + function="Advanced.CheckInfoDisplay" + parameter="lod info" /> + <menu_item_check.on_click + function="Advanced.ToggleInfoDisplay" + parameter="lod info" /> + </menu_item_check> + <menu_item_check + label="Build Queue" + name="Build Queue"> + <menu_item_check.on_check + function="Advanced.CheckInfoDisplay" + parameter="build queue" /> + <menu_item_check.on_click + function="Advanced.ToggleInfoDisplay" + parameter="build queue" /> + </menu_item_check> + <menu_item_check label="Lights" name="Lights"> <menu_item_check.on_check @@ -2352,6 +2437,16 @@ function="Advanced.ToggleInfoDisplay" parameter="raycast" /> </menu_item_check> + <menu_item_check + label="Sculpt" + name="Sculpt"> + <menu_item_check.on_check + function="Advanced.CheckInfoDisplay" + parameter="sculpt" /> + <menu_item_check.on_click + function="Advanced.ToggleInfoDisplay" + parameter="sculpt" /> + </menu_item_check> </menu> <menu create_jump_keys="true" @@ -2408,19 +2503,6 @@ <menu_item_check.on_enable function="Advanced.EnableObjectObjectOcclusion" /> </menu_item_check> - <menu_item_check - label="Framebuffer Objects" - name="Framebuffer Objects"> - <menu_item_check.on_check - function="CheckControl" - parameter="RenderUseFBO" /> - <menu_item_check.on_click - function="ToggleControl" - parameter="RenderUseFBO" /> - <menu_item_check.on_enable - function="Advanced.EnableRenderFBO" /> - </menu_item_check> - <menu_item_separator /> <menu_item_check @@ -2847,7 +2929,6 @@ function="Floater.Toggle" parameter="region_debug_console" /> </menu_item_check> - <menu_item_separator /> <menu_item_check @@ -3255,7 +3336,7 @@ <menu_item_call.on_click function="Advanced.LeaveAdminStatus" /> </menu_item_call> - <menu_item_check + <menu_item_check label="Show Admin Menu" name="View Admin Options"> <menu_item_check.on_enable diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 3c8daec68a..b07459908d 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6795,7 +6795,7 @@ Unable to find the help topic for this element. <tag>fail</tag> </notification> - <notification + <notification icon="alertmodal.tga" name="ObjectMediaFailure" type="alertmodal"> @@ -6827,6 +6827,17 @@ Your voice has been muted by moderator. name="okbutton" yestext="OK"/> </notification> + + <notification + icon="alertmodal.tga" + name="UploadCostConfirmation" + type="alertmodal"> +This upload will cost L$[PRICE], do you wish to continue with the upload? + <usetemplate + name="okcancelbuttons" + notext="Cancel" + yestext="Upload"/> + </notification> <notification icon="alertmodal.tga" @@ -6855,6 +6866,14 @@ The button will be shown when there is enough space for it. type="notifytip"> Select residents to share with. </notification> + + <notification + name="MeshUploadError" + icon="alert.tga" + type="alert"> + [LABEL] failed to upload: [MESSAGE] [IDENTIFIER] [INVALIDITY_IDENTIFIER] + </notification> + <notification icon="notifytip.tga" name="ShareItemsConfirmation" @@ -7069,7 +7088,6 @@ Mute everyone? notext="Cancel" unique="true"/> </notification> - <notification name="HintChat" label="Chat" @@ -7373,10 +7391,6 @@ The site at '<nolink>[HOST_NAME]</nolink>' in realm ' notext="Don't Quit"/> </notification> - <global name="UnsupportedCPU"> -- Your CPU speed does not meet the minimum requirements. - </global> - <global name="UnsupportedGLRequirements"> You do not appear to have the proper hardware requirements for [APP_NAME]. [APP_NAME] requires an OpenGL graphics card that has multitexture support. If this is the case, you may want to make sure that you have the latest drivers for your graphics card, and service packs and patches for your operating system. diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml index 600b0e3b71..607e1bb213 100644 --- a/indra/newview/skins/default/xui/en/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml @@ -84,7 +84,7 @@ Maximum 200 per group daily name="create_new_notice" tool_tip="Create a new notice" top_delta="0" - width="93" /> + width="127" /> <button follows="top|left" height="23" @@ -128,7 +128,7 @@ Maximum 200 per group daily layout="topleft" name="lbl3" top_pad="10" - width="60"> + width="62"> Subject: </text> <line_editor @@ -141,7 +141,7 @@ Maximum 200 per group daily max_length_bytes="63" name="create_subject" prevalidate_callback="ascii" - width="220" /> + width="218" /> <text follows="left|top" type="string" @@ -151,7 +151,7 @@ Maximum 200 per group daily left="10" name="lbl4" top_pad="5" - width="60"> + width="62"> Message: </text> <text_editor @@ -162,7 +162,7 @@ Maximum 200 per group daily max_length="511" name="create_message" top_delta="0" - width="220" + width="218" word_wrap="true" /> <text follows="left|top" diff --git a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml index 38e8b9844f..cdf14572fe 100644 --- a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml +++ b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml @@ -196,7 +196,7 @@ initial_val="256" label="" label_width="0" - left_delta="40" + left_delta="68" max_val="2048" min_val="0" mouse_opaque="true" diff --git a/indra/newview/skins/default/xui/en/panel_place_profile.xml b/indra/newview/skins/default/xui/en/panel_place_profile.xml index 7e89860c60..774a9e8bbf 100644 --- a/indra/newview/skins/default/xui/en/panel_place_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_place_profile.xml @@ -191,7 +191,7 @@ width="310"> <panel bg_alpha_color="DkGray2" - follows="left|top|right" + follows="left|top|right|bottom" height="580" layout="topleft" left="0" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml index cdc462109c..ea09286592 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml @@ -180,14 +180,14 @@ increment="1" initial_value="23" label="Nearby chat toasts life time:" - label_width="190" + label_width="285" layout="topleft" left="45" max_val="60" min_val="1" name="nearby_toasts_lifetime" top_pad="10" - width="230" /> + width="325" /> <spinner control_name="NearbyToastFadingTime" decimal_digits="0" @@ -196,14 +196,14 @@ increment="1" initial_value="3" label="Nearby chat toasts fading time:" - label_width="190" + label_width="285" layout="topleft" left_delta="0" max_val="60" min_val="0" name="nearby_toasts_fadingtime" top_pad="3" - width="230" /> + width="325" /> <check_box control_name="TranslateChat" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_colors.xml b/indra/newview/skins/default/xui/en/panel_preferences_colors.xml index 8a37822413..7717872a6a 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_colors.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_colors.xml @@ -47,7 +47,7 @@ height="12" name="font_colors" top_pad="20" - width="120" + width="170" > Chat font colors: </text> @@ -275,7 +275,7 @@ height="12" name="bubble_chat" top_pad="20" - width="450" + width="495" > Name tag background color (also affects Bubble Chat): </text> @@ -320,7 +320,7 @@ height="12" name="floater_opacity" top_pad="15" - width="120" + width="200" > Floater Opacity: </text> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index d74197d965..f7666bdc4c 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -193,8 +193,18 @@ left_delta="0" name="BumpShiny" top_pad="1" + width="256" /> + <check_box + control_name="RenderLocalLights" + height="16" + initial_value="true" + label="Local Lights" + layout="topleft" + left_delta="0" + name="LocalLights" + top_pad="1" width="256" /> - <check_box + <check_box control_name="VertexShaderEnable" height="16" initial_value="true" @@ -221,7 +231,6 @@ <check_box.commit_callback function="Pref.VertexShaderEnable" /> </check_box> -<!-- DISABLED UNTIL WE REALLY WANT TO SUPPORT THIS <check_box control_name="RenderDeferred" height="16" @@ -248,6 +257,19 @@ <check_box.commit_callback function="Pref.VertexShaderEnable" /> </check_box> + <check_box + control_name="RenderDepthOfField" + height="16" + initial_value="true" + label="Depth of Field" + layout="topleft" + left_delta="0" + name="UseDoF" + top_pad="1" + width="256"> + <check_box.commit_callback + function="Pref.VertexShaderEnable" /> + </check_box> <text type="string" @@ -283,7 +305,7 @@ name="2" value="2"/> </combo_box> ---> + <text type="string" length="1" @@ -701,7 +723,7 @@ follows="left|top" height="12" layout="topleft" - left="358" + left="407" left_pad="-30" name="TerrainDetailText" top="250" @@ -713,7 +735,7 @@ draw_border="false" height="38" layout="topleft" - left_delta="0" + left_delta="5" name="TerrainDetailRadio" top_pad="5" width="70"> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_move.xml b/indra/newview/skins/default/xui/en/panel_preferences_move.xml index 04412bdb9c..1a8aae7f91 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_move.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_move.xml @@ -195,7 +195,7 @@ left="0" name="radio_teleport" top_delta="20" - width="100" /> + width="110" /> <radio_item height="16" label="Auto-pilot" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml index e374c89f21..91fe6f544c 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml @@ -341,7 +341,7 @@ layout="topleft" left="25" name="voice_chat_settings" - width="180" + width="200" top_pad="7"> Voice Chat Settings </text> diff --git a/indra/newview/skins/default/xui/en/panel_region_general.xml b/indra/newview/skins/default/xui/en/panel_region_general.xml index ca9579284b..e0d9f3f714 100644 --- a/indra/newview/skins/default/xui/en/panel_region_general.xml +++ b/indra/newview/skins/default/xui/en/panel_region_general.xml @@ -114,7 +114,7 @@ layout="topleft" left="10" name="allow_land_resell_check" - top="160" + top="150" width="80" /> <check_box height="20" @@ -122,7 +122,7 @@ layout="topleft" left="10" name="allow_parcel_changes_check" - top="180" + top="170" width="80" /> <check_box height="20" @@ -131,7 +131,16 @@ left="10" name="block_parcel_search_check" tool_tip="Let people see this region and its parcels in search results" - top="200" + top="190" + width="80" /> + <check_box + height="20" + label="Allow Mesh Objects" + layout="topleft" + left="10" + name="mesh_rez_enabled_check" + tool_tip="Let people rez mesh objects on this region" + top="210" width="80" /> <spinner decimal_digits="0" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 740d3c4892..5a2e90d6f7 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -58,6 +58,83 @@ <string name="Quit">Quit</string> <string name="create_account_url">http://join.secondlife.com/</string> + <string name="LoginFailedViewerNotPermitted"> +The viewer you are using can no longer access Second Life. Please visit the following page to download a new viewer: +http://secondlife.com/download + +For more information, see our FAQ below: +http://secondlife.com/viewer-access-faq</string> + <string name="LoginIntermediateOptionalUpdateAvailable">Optional viewer update available: [VERSION]</string> + <string name="LoginFailedRequiredUpdate">Required viewer update: [VERSION]</string> + <string name="LoginFailedAlreadyLoggedIn">This agent is already logged in. +</string> + <string name="LoginFailedAuthenticationFailed">Sorry! We couldn't log you in. +Please check to make sure you entered the right + * Username (like bobsmith12 or steller.sunshine) + * Password +Also, please make sure your Caps Lock key is off.</string> + <string name="LoginFailedPasswordChanged">As a security precaution your password has been changed. +Please go to your account page at http://secondlife.com/password +and answer the security question to reset your password. +We are very sorry for the inconvenience.</string> + <string name="LoginFailedPasswordReset">We made some changes to our system and you will need to reset your password. +Please go to your account page at http://secondlife.com/password +and answer the security question to reset your password. +We are very sorry for the inconvenience.</string> + <string name="LoginFailedEmployeesOnly">Second Life is temporarily closed for maintenance. +Logins are currently restricted to employees only. +Check www.secondlife.com/status for updates.</string> + <string name="LoginFailedPremiumOnly">Second Life logins are temporarily restricted in order to make sure that those in-world have the best possible experience. + +People with free accounts will not be able to access Second Life during this time, to make room for those who have paid for Second Life.</string> + <string name="LoginFailedComputerProhibited">Second Life cannot be accessed from this computer. +If you feel this is an error, please contact +support@secondlife.com.</string> + <string name="LoginFailedAcountSuspended">Your account is not accessible until +[TIME] Pacific Time.</string> + <string name="LoginFailedAccountDisabled">We are unable to complete your request at this time. +Please contact Second Life support for assistance at http://secondlife.com/support. +If you are unable to change your password, please call (866) 476-9763.</string> + <string name="LoginFailedTransformError">Data inconsistency found during login. +Please contact support@secondlife.com.</string> + <string name="LoginFailedAccountMaintenance">Your account is undergoing minor maintenance. +Your account is not accessible until +[TIME] Pacific Time. +If you feel this is an error, please contact support@secondlife.com.</string> + <string name="LoginFailedPendingLogoutFault">Request for logout responded with a fault from simulator.</string> + <string name="LoginFailedPendingLogout">The system is logging you out right now. +Your Account will not be available until +[TIME] Pacific Time.</string> + <string name="LoginFailedUnableToCreateSession">Unable to create valid session.</string> + <string name="LoginFailedUnableToConnectToSimulator">Unable to connect to a simulator.</string> + <string name="LoginFailedRestrictedHours">Your account can only access Second Life +between [START] and [END] Pacific Time. +Please come back during those hours. +If you feel this is an error, please contact support@secondlife.com.</string> + <string name="LoginFailedIncorrectParameters">Incorrect parameters. +If you feel this is an error, please contact support@secondlife.com.</string> + <string name="LoginFailedFirstNameNotAlphanumeric">First name parameter must be alphanumeric. +If you feel this is an error, please contact support@secondlife.com.</string> + <string name="LoginFailedLastNameNotAlphanumeric">Last name parameter must be alphanumeric. +If you feel this is an error, please contact support@secondlife.com.</string> + <string name="LogoutFailedRegionGoingOffline">Region is going offline. +Please try logging in again in a minute.</string> + <string name="LogoutFailedAgentNotInRegion">Agent not in region. +Please try logging in again in a minute.</string> + <string name="LogoutFailedPendingLogin">The region was logging in another session. +Please try logging in again in a minute.</string> + <string name="LogoutFailedLoggingOut">The region was logging out the previous session. +Please try logging in again in a minute.</string> + <string name="LogoutFailedStillLoggingOut">The region is still logging out the previous session. +Please try logging in again in a minute.</string> + <string name="LogoutSucceeded">Region has logged out last session. +Please try logging in again in a minute.</string> + <string name="LogoutFailedLogoutBegun">Region has begun the logout process. +Please try logging in again in a minute.</string> + <string name="LoginFailedLoggingOutSession">The system has begun logging out your last session. +Please try logging in again in a minute.</string> + + <!-- Disconnection --> <string name="AgentLostConnection">This region may be experiencing trouble. Please check your connection to the Internet.</string> <string name="SavingSettings">Saving your settings...</string> @@ -198,6 +275,7 @@ <string name="favorite">favorite</string> <string name="symbolic link">link</string> <string name="symbolic folder link">folder link</string> + <string name="mesh">mesh</string> <!-- llvoavatar. Displayed in the avatar chat bubble --> <string name="AvatarEditingAppearance">(Editing Appearance)</string> @@ -2008,6 +2086,7 @@ Requests name of an avatar. When data is available the dataserver event will be <string name="InvFolder Initial Outfits">Initial Outfits</string> <string name="InvFolder My Outfits">My Outfits</string> <string name="InvFolder Accessories">Accessories</string> + <string name="InvFolder Meshes">Meshes</string> <!-- are used for Friends and Friends/All folders in Inventory "Calling cards" folder. See EXT-694--> <string name="InvFolder Friends">Friends</string> diff --git a/indra/newview/skins/default/xui/es/floater_about_land.xml b/indra/newview/skins/default/xui/es/floater_about_land.xml index 3df0f92842..c3f4310103 100644 --- a/indra/newview/skins/default/xui/es/floater_about_land.xml +++ b/indra/newview/skins/default/xui/es/floater_about_land.xml @@ -82,7 +82,7 @@ Vaya al menú Mundo > Acerca del terreno o seleccione otra parcela para ver s Calificación: </text> <text name="ContentRatingText"> - 'Adult' + Adulto </text> <text name="Owner:"> Propietario: @@ -187,7 +187,7 @@ Vaya al menú Mundo > Acerca del terreno o seleccione otra parcela para ver s Calificación: </text> <text name="region_maturity_text"> - 'Adult' + Adulto </text> <text name="resellable_lbl"> Revender: @@ -288,16 +288,16 @@ Sólo las parcelas más grandes pueden listarse en la búsqueda. Esta opción no esta activada porque usted no puede modificar las opciones de la parcela. </panel.string> <panel.string name="mature_check_mature"> - Contenido 'Mature' + Contenido Moderado </panel.string> <panel.string name="mature_check_adult"> - Contenido 'Adult' + Contenido Adulto </panel.string> <panel.string name="mature_check_mature_tooltip"> - La información o el contenido de su parcela se considera 'Mature'. + La información o el contenido de su parcela se considera Moderado. </panel.string> <panel.string name="mature_check_adult_tooltip"> - La información o el contenido de su parcela se considera 'Adult'. + La información o el contenido de su parcela se considera Adulto. </panel.string> <panel.string name="landing_point_none"> (ninguno) @@ -337,7 +337,7 @@ Sólo las parcelas más grandes pueden listarse en la búsqueda. <combo_box name="land category with adult"> <combo_box.item label="Cualquier categorÃa" name="item0"/> <combo_box.item label="Localización Linden" name="item1"/> - <combo_box.item label="'Adult'" name="item2"/> + <combo_box.item label="Adulto" name="item2"/> <combo_box.item label="Arte y Cultura" name="item3"/> <combo_box.item label="Negocios" name="item4"/> <combo_box.item label="Educativo" name="item5"/> @@ -365,7 +365,7 @@ Sólo las parcelas más grandes pueden listarse en la búsqueda. <combo_box.item label="Terreno en alquiler" name="item13"/> <combo_box.item label="Otra" name="item12"/> </combo_box> - <check_box label="Contenido 'Mature'" name="MatureCheck" tool_tip=""/> + <check_box label="Contenido Moderado" name="MatureCheck" tool_tip=""/> <text name="Snapshot:"> Foto: </text> diff --git a/indra/newview/skins/default/xui/es/floater_buy_land.xml b/indra/newview/skins/default/xui/es/floater_buy_land.xml index 74243a4d06..9d33b69de9 100644 --- a/indra/newview/skins/default/xui/es/floater_buy_land.xml +++ b/indra/newview/skins/default/xui/es/floater_buy_land.xml @@ -129,25 +129,25 @@ para cubrir esta parcela. <text name="region_name_label"> Región: </text> - <text left="565" name="region_name_text"> + <text name="region_name_text"> (desconocida) </text> <text name="region_type_label"> Tipo: </text> - <text left="565" name="region_type_text"> + <text name="region_type_text"> (desconocido) </text> <text name="estate_name_label"> Estado: </text> - <text left="565" name="estate_name_text"> + <text name="estate_name_text"> (desconocido) </text> - <text name="estate_owner_label" right="565" width="115"> + <text name="estate_owner_label"> Propietario del estado: </text> - <text left="565" name="estate_owner_text"> + <text name="estate_owner_text"> (desconocido) </text> <text name="resellable_changeable_label"> diff --git a/indra/newview/skins/default/xui/es/floater_postcard.xml b/indra/newview/skins/default/xui/es/floater_postcard.xml index df94486c0e..b5b9805fe2 100644 --- a/indra/newview/skins/default/xui/es/floater_postcard.xml +++ b/indra/newview/skins/default/xui/es/floater_postcard.xml @@ -1,29 +1,25 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Postcard" title="FOTO POR CORREO"> <text name="to_label"> - Correo electrónico - del destinatario: - </text> - <line_editor bottom_delta="-20" name="to_form"/> - <text bottom_delta="-12" name="from_label"> - Su correo - electrónico: - </text> - <line_editor bottom_delta="-20" name="from_form"/> + Correo del destinatario: + </text> + <text name="from_label"> + Su correo: + </text> <text name="name_label"> Su nombre: - </text> + </text> <text name="subject_label"> Asunto: </text> <line_editor label="Escriba aquà el asunto." name="subject_form"/> - <text bottom_delta="-18" name="msg_label"> + <text name="msg_label"> Mensaje: </text> <text_editor name="msg_form"> Escriba aquà el mensaje. </text_editor> - <text bottom_delta="-21" name="fine_print"> + <text name="fine_print"> Si su destinatario se registra en [SECOND_LIFE], usted conseguirá un bono de referido. </text> diff --git a/indra/newview/skins/default/xui/es/floater_preview_animation.xml b/indra/newview/skins/default/xui/es/floater_preview_animation.xml index 6b8c8b6ff5..c3f377a71a 100644 --- a/indra/newview/skins/default/xui/es/floater_preview_animation.xml +++ b/indra/newview/skins/default/xui/es/floater_preview_animation.xml @@ -6,6 +6,6 @@ <text name="desc txt"> Descripción: </text> - <button label="Ver en el mundo" label_selected="Parar" left="12" name="Anim play btn" tool_tip="Ejecutar esta animación de modo que puedan verla los demás" width="142"/> - <button label="Ejecutarla para usted" label_selected="Parar" left="156" name="Anim audition btn" tool_tip="Ejecutar esta animación de modo que sólo la vea yo" width="136"/> + <button label="Ver en el mundo" label_selected="Parar" name="Anim play btn" tool_tip="Ejecutar esta animación de modo que puedan verla los demás" width="130"/> + <button label="Ejecutarla para usted" label_selected="Parar" left="135" name="Anim audition btn" tool_tip="Ejecutar esta animación de modo que sólo la vea yo" width="130"/> </floater> diff --git a/indra/newview/skins/default/xui/es/floater_report_abuse.xml b/indra/newview/skins/default/xui/es/floater_report_abuse.xml index 760429e73d..dc5d430375 100644 --- a/indra/newview/skins/default/xui/es/floater_report_abuse.xml +++ b/indra/newview/skins/default/xui/es/floater_report_abuse.xml @@ -67,8 +67,8 @@ <combo_box.item label="Acoso > Abuso verbal" name="Harassment__Verbal_abuse"/> <combo_box.item label="Indecencia > En general, contenido o conducta ofensivos" name="Indecency__Broadly_offensive_content_or_conduct"/> <combo_box.item label="Indecencia > Nombre inapropiado del avatar" name="Indecency__Inappropriate_avatar_name"/> - <combo_box.item label="Indecencia > Contenido o conducta inapropiada en una región 'PG'" name="Indecency__Mature_content_in_PG_region"/> - <combo_box.item label="Indecencia > Contenido o conducta inapropiada en una región 'Mature'" name="Indecency__Inappropriate_content_in_Mature_region"/> + <combo_box.item label="Indecencia > Contenido o conducta inapropiada en una región General" name="Indecency__Mature_content_in_PG_region"/> + <combo_box.item label="Indecencia > Contenido o conducta inapropiada en una región Moderado" name="Indecency__Inappropriate_content_in_Mature_region"/> <combo_box.item label="Infracción de la propiedad intelectual > Eliminación de contenidos" name="Intellectual_property_infringement_Content_Removal"/> <combo_box.item label="Infracción de la propiedad intelectual > CopyBot o Exploit (programa malicioso) de permisos" name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit"/> <combo_box.item label="Intolerancia" name="Intolerance"/> diff --git a/indra/newview/skins/default/xui/es/floater_sell_land.xml b/indra/newview/skins/default/xui/es/floater_sell_land.xml index efedb5d689..d883683945 100644 --- a/indra/newview/skins/default/xui/es/floater_sell_land.xml +++ b/indra/newview/skins/default/xui/es/floater_sell_land.xml @@ -54,8 +54,8 @@ <radio_item label="No, mantener la propiedad de los objetos" name="no"/> <radio_item label="SÃ, vender los objetos con el terreno" name="yes"/> </radio_group> - <button label="Mostrar los objetos" name="show_objects" width="120"/> - <text name="nag_message_label"> + <button label="Mostrar los objetos" name="show_objects"/> + <text name="nag_message_label" font="SansSerifSmallBold" left="10"> RECUERDA: todas las ventas son definitivas. </text> <button label="Poner en venta el terreno" name="sell_btn"/> diff --git a/indra/newview/skins/default/xui/es/floater_top_objects.xml b/indra/newview/skins/default/xui/es/floater_top_objects.xml index 7c2522e8a9..033633bd22 100644 --- a/indra/newview/skins/default/xui/es/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/es/floater_top_objects.xml @@ -39,19 +39,16 @@ <text name="id_text"> ID del objeto: </text> - <line_editor font="SansSerifSmall" left="140" name="id_editor" width="280"/> - <button label="Mostrar la baliza" name="show_beacon_btn" width="115"/> + <button label="Mostrar la baliza" name="show_beacon_btn"/> <text name="obj_name_text"> Nombre del objeto: </text> - <line_editor font="SansSerifSmall" left="140" name="object_name_editor" width="280"/> - <button label="Filtro" name="filter_object_btn" width="115"/> - <text name="owner_name_text" width="130"> + <button label="Filtro" name="filter_object_btn"/> + <text name="owner_name_text"> Propietario: </text> - <line_editor font="SansSerifSmall" left="140" name="owner_name_editor" width="280"/> - <button label="Filtro" name="filter_owner_btn" width="115"/> - <button label="Actualizar" name="refresh_btn" width="115"/> + <button label="Filtro" name="filter_owner_btn"/> + <button label="Actualizar" name="refresh_btn"/> <button label="Devolver lo seleccionado" name="return_selected_btn" width="170"/> <button label="Devolver todo" left="190" name="return_all_btn"/> <button label="Desactivar lo seleccionado" name="disable_selected_btn" width="170"/> diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml index 91a03023a1..ce9273ab50 100644 --- a/indra/newview/skins/default/xui/es/notifications.xml +++ b/indra/newview/skins/default/xui/es/notifications.xml @@ -1761,11 +1761,11 @@ Puedes pulsar 'Cambiar las Preferencias' para incrementar las preferen <usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> </notification> <notification name="SetClassifiedMature"> - ¿Este anuncio tiene contenido 'Moderado'? + ¿Este anuncio tiene contenido moderado? <usetemplate canceltext="Cancelar" name="yesnocancelbuttons" notext="No" yestext="SÃ"/> </notification> <notification name="SetGroupMature"> - ¿Este grupo tiene contenido 'Moderado'? + ¿Este grupo tiene contenido moderado? <usetemplate canceltext="Cancelar" name="yesnocancelbuttons" notext="No" yestext="SÃ"/> </notification> <notification label="Confirmar el reinicio" name="ConfirmRestart"> @@ -2244,7 +2244,7 @@ Inténtalo seleccionando un trozo más pequeño de terreno. Se han excluido algunos términos de tu búsqueda debido a restricciones en el contenido, según se especifica en las Normas de la Comunidad. </notification> <notification name="NoContentToSearch"> - Por favor, elige al menos un tipo de contenido a buscar ('PG', 'Mature', o 'Adult'). + Por favor, elige al menos un tipo de contenido a buscar (General, Moderado o Adulto;). </notification> <notification name="SystemMessage"> [MESSAGE] diff --git a/indra/newview/skins/default/xui/es/panel_group_general.xml b/indra/newview/skins/default/xui/es/panel_group_general.xml index a0f7433d7d..b00c300c85 100644 --- a/indra/newview/skins/default/xui/es/panel_group_general.xml +++ b/indra/newview/skins/default/xui/es/panel_group_general.xml @@ -46,12 +46,12 @@ Deja el cursor sobre las opciones para ver más ayuda. <check_box label="Cualquiera puede entrar" name="open_enrollement" tool_tip="Configura si se permite la entrada de nuevos miembros sin ser invitados."/> <check_box label="Cuota de entrada" name="check_enrollment_fee" tool_tip="Configura si hay que pagar una cuota para entrar al grupo"/> <spinner label="L$" left_delta="130" name="spin_enrollment_fee" tool_tip="Si la opción Cuota de entrada está marcada, los nuevos miembros han de pagar esta cuota para entrar al grupo." width="60"/> - <combo_box bottom_delta="-38" name="group_mature_check" tool_tip="Establece si la información de su grupo es 'mature'." width="150"> + <combo_box bottom_delta="-38" name="group_mature_check" tool_tip="Establece si la información de su grupo es moderado." width="150"> <combo_item name="select_mature"> - Selecciona el nivel de calificación - </combo_item> - <combo_box.item label="Contenido 'Mature'" name="mature"/> - <combo_box.item label="Contenido 'PG'" name="pg"/> + <combo_box.item label="Contenido moderado" name="mature"/> + <combo_box.item label="Contenido general" name="pg"/> </combo_box> <check_box initial_value="true" label="Mostrar en la búsqueda" name="show_in_group_list" tool_tip="Permite que la gente vea este grupo en los resultados de la búsqueda"/> </panel> diff --git a/indra/newview/skins/default/xui/es/panel_media_settings_security.xml b/indra/newview/skins/default/xui/es/panel_media_settings_security.xml index c72f562a68..a1a3ec86cf 100644 --- a/indra/newview/skins/default/xui/es/panel_media_settings_security.xml +++ b/indra/newview/skins/default/xui/es/panel_media_settings_security.xml @@ -2,7 +2,8 @@ <panel label="Seguridad" name="Media Settings Security"> <check_box initial_value="false" label="Permitir el acceso sólo a los patrones de URL especificados" name="whitelist_enable"/> <text name="home_url_fails_some_items_in_whitelist"> - Están marcadas las entradas que la página web no admite: + Están marcadas las entradas que la página web no +admite: </text> <button label="Añadir" name="whitelist_add"/> <button label="Borrar" name="whitelist_del"/> diff --git a/indra/newview/skins/default/xui/es/panel_preferences_general.xml b/indra/newview/skins/default/xui/es/panel_preferences_general.xml index 790c7be581..e725e4a05a 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_general.xml @@ -24,9 +24,9 @@ </text> <text name="maturity_desired_textbox"/> <combo_box name="maturity_desired_combobox"> - <combo_box.item label="'PG', 'Mature' y 'Adult'" name="Desired_Adult"/> - <combo_box.item label="'PG' y 'Mature'" name="Desired_Mature"/> - <combo_box.item label="'PG'" name="Desired_PG"/> + <combo_box.item label="General, Moderado y Adulto" name="Desired_Adult"/> + <combo_box.item label="General y Moderado" name="Desired_Mature"/> + <combo_box.item label="General" name="Desired_PG"/> </combo_box> <text name="start_location_textbox"> Localización inicial: diff --git a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml index 1ae5d63ace..0ac3d11ab0 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml @@ -86,7 +86,7 @@ <check_box initial_value="true" label="Avatares simulados" name="AvatarImpostors"/> <check_box initial_value="true" label="Renderizado por hardware" name="AvatarVertexProgram"/> <check_box initial_value="true" label="Ropas del avatar" name="AvatarCloth"/> - <text name="TerrainDetailText"> + <text name="TerrainDetailText" left="402"> Detalle del terreno: </text> <radio_group name="TerrainDetailRadio"> diff --git a/indra/newview/skins/default/xui/es/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/es/panel_preferences_privacy.xml index adc0862cf1..c162130af6 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_privacy.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_privacy.xml @@ -11,7 +11,7 @@ <check_box label="Sólo saben si estoy conectado mis amigos y grupos" name="online_visibility"/> <check_box label="Sólo pueden llamarme o mandarme un MI mis amigos y grupos" name="voice_call_friends_only_check"/> <check_box label="Desconectar el micrófono cuando finalicen las llamadas" name="auto_disengage_mic_check"/> - <check_box label="Mostrar mis Hitos favoritos al Inicio de sesión (menú desplegable "Empezar en")" name="favorites_on_login_check"/> + <check_box label="Mostrar mis Hitos favoritos al Inicio de sesión (menú desplegable "Empezar en")" name="favorites_on_login_check" top_pad="15"/> <text name="Logs:"> Registros de chat: </text> diff --git a/indra/newview/skins/default/xui/es/panel_region_covenant.xml b/indra/newview/skins/default/xui/es/panel_region_covenant.xml index 06f4fffacf..2beacda235 100644 --- a/indra/newview/skins/default/xui/es/panel_region_covenant.xml +++ b/indra/newview/skins/default/xui/es/panel_region_covenant.xml @@ -52,7 +52,7 @@ del estado. Calificación: </text> <text name="region_maturity_text"> - 'Adult' + Adulto </text> <text name="resellable_lbl"> Revender: diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index 5a913c4c9d..27ca0e3bbb 100644 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -724,13 +724,13 @@ Controlar su cámara </string> <string name="SIM_ACCESS_PG"> - 'PG' + General </string> <string name="SIM_ACCESS_MATURE"> - 'Mature' + Moderado </string> <string name="SIM_ACCESS_ADULT"> - 'Adult' + Adulto </string> <string name="SIM_ACCESS_DOWN"> Desconectado @@ -1916,7 +1916,7 @@ Se esperaba .wav, .tga, .bmp, .jpg, .jpeg, o .bvh Localización Linden </string> <string name="Adult"> - 'Adult' + Adulto </string> <string name="Arts&Culture"> Arte y Cultura diff --git a/indra/newview/skins/default/xui/fr/floater_about_land.xml b/indra/newview/skins/default/xui/fr/floater_about_land.xml index a33c0344f7..bef41bb1ba 100644 --- a/indra/newview/skins/default/xui/fr/floater_about_land.xml +++ b/indra/newview/skins/default/xui/fr/floater_about_land.xml @@ -411,11 +411,11 @@ texture : <text name="replace_texture_help"> Les objets avec cette texture affichent le film ou la page web quand vous cliquez sur la flèche Jouer. Sélectionnez l'image miniature pour choisir une texture différente. </text> - <check_box label="Échelle automatique" left="97" name="media_auto_scale" tool_tip="Si vous sélectionnez cette option, le contenu de cette parcelle sera automatiquement mis à l'échelle. La qualité visuelle sera peut-être amoindrie mais vous n'aurez à faire aucune autre mise à l'échelle ou alignement."/> - <text left="102" name="media_size" tool_tip="Taille du média Web, laisser 0 pour la valeur par défaut." width="105"> + <check_box label="Échelle automatique" name="media_auto_scale" tool_tip="Si vous sélectionnez cette option, le contenu de cette parcelle sera automatiquement mis à l'échelle. La qualité visuelle sera peut-être amoindrie mais vous n'aurez à faire aucune autre mise à l'échelle ou alignement."/> + <text name="media_size" tool_tip="Taille du média Web, laisser 0 pour la valeur par défaut."> Taille : </text> - <spinner left_delta="89" name="media_size_width" tool_tip="Taille du média Web, laisser 0 pour la valeur par défaut."/> + <spinner name="media_size_width" tool_tip="Taille du média Web, laisser 0 pour la valeur par défaut."/> <spinner name="media_size_height" tool_tip="Taille du média Web, laisser 0 pour la valeur par défaut."/> <text name="pixels"> pixels diff --git a/indra/newview/skins/default/xui/fr/floater_postcard.xml b/indra/newview/skins/default/xui/fr/floater_postcard.xml index a4b0675fe4..948a3b973d 100644 --- a/indra/newview/skins/default/xui/fr/floater_postcard.xml +++ b/indra/newview/skins/default/xui/fr/floater_postcard.xml @@ -1,43 +1,36 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Postcard" title="ENVOYER LA PHOTO PAR E-MAIL"> - <text name="to_label" width="135"> - E-mail du destinataire : - </text> - <line_editor left="143" name="to_form" width="130" left_delta="146"/> - <text name="from_label"> - Votre e-mail : - </text> - <line_editor left="143" name="from_form" width="130" left_delta="146"/> - <text name="name_label"> - Votre nom : - </text> - <line_editor left="143" name="name_form" width="130" left_delta="146"/> - <text name="subject_label"> - Objet : - </text> - <line_editor left="143" name="subject_form" width="130" left_delta="146"/> - <line_editor label="Saisir ici votre objet" name="subject_form"/> - <text name="msg_label"> - Message : - </text> - <check_box label="Publier sur le web" name="allow_publish_check" tool_tip="Publiez cette carte postale sur le web."/> - <check_box label="Contenu adulte" name="mature_check" tool_tip="Cette carte postale est à caractère adulte."/> - <button label="?" name="publish_help_btn"/> - <text_editor name="msg_form"> - Saisir ici votre message - </text_editor> - <text name="fine_print"> - Si le destinataire s'inscrit sur [SECOND_LIFE], vous recevrez un bonus. - </text> - <button label="Annuler" name="cancel_btn"/> - <button label="Envoyer" name="send_btn"/> - <string name="default_subject"> - Carte postale de [SECOND_LIFE]. - </string> - <string name="default_message"> - Ouvrez-moi ! - </string> - <string name="upload_message"> - Envoi en cours... - </string> -</floater> +<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Postcard" title="ENVOYER LA PHOTO PAR E-MAIL">
+ <text name="to_label">
+ E-mail du destinataire :
+ </text>
+ <text name="from_label">
+ Votre e-mail :
+ </text>
+ <text name="name_label">
+ Votre nom :
+ </text>
+ <text name="subject_label">
+ Objet :
+ </text>
+ <line_editor label="Saisir ici votre objet" name="subject_form"/>
+ <text name="msg_label">
+ Message :
+ </text>
+ <text_editor name="msg_form">
+ Saisir ici votre message
+ </text_editor>
+ <text name="fine_print">
+ Si le destinataire s'inscrit sur [SECOND_LIFE], vous recevrez un bonus.
+ </text>
+ <button label="Annuler" name="cancel_btn"/>
+ <button label="Envoyer" name="send_btn"/>
+ <string name="default_subject">
+ Carte postale de [SECOND_LIFE].
+ </string>
+ <string name="default_message">
+ Ouvrez-moi !
+ </string>
+ <string name="upload_message">
+ Envoi en cours...
+ </string>
+</floater>
diff --git a/indra/newview/skins/default/xui/fr/floater_preview_animation.xml b/indra/newview/skins/default/xui/fr/floater_preview_animation.xml index b14aecafbb..a9407abfde 100644 --- a/indra/newview/skins/default/xui/fr/floater_preview_animation.xml +++ b/indra/newview/skins/default/xui/fr/floater_preview_animation.xml @@ -6,6 +6,6 @@ <text name="desc txt"> Description : </text> - <button label="Jouer dans Second Life" label_selected="Stop" left="20" name="Anim play btn" tool_tip="Lire cette animation de façon à ce que les autres puissent la voir" width="131"/> - <button label="Jouer localement" label_selected="Stop" left="162" name="Anim audition btn" tool_tip="Lire cette animation de façon à ce que vous soyez la seule personne à pouvoir la voir" width="125"/> + <button label="Jouer dans Second Life" label_selected="Stop" name="Anim play btn" tool_tip="Lire cette animation de façon à ce que les autres puissent la voir" width="131"/> + <button label="Jouer localement" label_selected="Stop" left="160" name="Anim audition btn" tool_tip="Lire cette animation de façon à ce que vous soyez la seule personne à pouvoir la voir" width="120"/> </floater> diff --git a/indra/newview/skins/default/xui/fr/floater_sell_land.xml b/indra/newview/skins/default/xui/fr/floater_sell_land.xml index b5ffc8f9c7..b835cc6d87 100644 --- a/indra/newview/skins/default/xui/fr/floater_sell_land.xml +++ b/indra/newview/skins/default/xui/fr/floater_sell_land.xml @@ -5,13 +5,13 @@ <text name="info_parcel_label"> Parcelle : </text> - <text name="info_parcel" left="70"> + <text name="info_parcel"> NOM DE LA PARCELLE </text> <text name="info_size_label"> Taille : </text> - <text name="info_size" left="70"> + <text name="info_size"> [AREA] m² </text> <text bottom_delta="-60" name="info_action"> @@ -38,27 +38,27 @@ <text name="sell_to_text"> Vendez votre terrain à n'importe qui ou uniquement à un acheteur spécifique. </text> - <combo_box bottom_delta="-32" name="sell_to"> + <combo_box name="sell_to"> <combo_box.item label="- Sélectionnez -" name="--selectone--"/> <combo_box.item label="Tout le monde" name="Anyone"/> <combo_box.item label="Personne spécifique :" name="Specificuser:"/> </combo_box> - <button label="Sélectionner" name="sell_to_select_agent" width="100"/> + <button label="Sélectionner" name="sell_to_select_agent"/> <text name="sell_objects_label"> 3. Vendre les objets avec ce terrain ? </text> <text name="sell_objects_text"> Les objets transférables se trouvant sur la parcelle changeront de propriétaire. </text> - <radio_group bottom_delta="-54" name="sell_objects" right="430"> + <radio_group name="sell_objects"> <radio_item label="Non, rester le propriétaire des objets" name="no"/> <radio_item label="Oui, vendre les objets avec le terrain" name="yes"/> </radio_group> - <button label="Afficher les objets" name="show_objects" right="420" width="120"/> - <text bottom_delta="-30" name="nag_message_label"> + <button label="Afficher les objets" name="show_objects"/> + <text name="nag_message_label" font="SansSerif"> Rappel : Toutes les ventes sont définitives. </text> - <button label="Indiquer le terrain à vendre" name="sell_btn" width="165"/> + <button label="Indiquer le terrain à vendre" name="sell_btn"/> <button label="Annuler" name="cancel_btn"/> </panel> </scroll_container> diff --git a/indra/newview/skins/default/xui/it/floater_buy_land.xml b/indra/newview/skins/default/xui/it/floater_buy_land.xml index f3b30f7048..3940c43a3d 100644 --- a/indra/newview/skins/default/xui/it/floater_buy_land.xml +++ b/indra/newview/skins/default/xui/it/floater_buy_land.xml @@ -142,10 +142,10 @@ consente [AMOUNT2] oggetti <text name="estate_name_text"> (sconosciuto) </text> - <text name="estate_owner_label" right="575" width="120"> + <text name="estate_owner_label"> Proprietario della regione: </text> - <text left="580" name="estate_owner_text" width="155"> + <text name="estate_owner_text"> (sconosciuto) </text> <text name="resellable_changeable_label"> diff --git a/indra/newview/skins/default/xui/it/floater_sell_land.xml b/indra/newview/skins/default/xui/it/floater_sell_land.xml index 0f8d24ebbd..106ae0373c 100644 --- a/indra/newview/skins/default/xui/it/floater_sell_land.xml +++ b/indra/newview/skins/default/xui/it/floater_sell_land.xml @@ -55,7 +55,7 @@ <radio_item label="Si, vendi gli oggetti con la terra" name="yes"/> </radio_group> <button label="Mostra oggetti" name="show_objects"/> - <text name="nag_message_label"> + <text name="nag_message_label" font="SansSerifSmallBold" left="9"> RICORDA: Tutte le vendite sono definitive. </text> <button label="Imposta terreno come in vendita" name="sell_btn"/> diff --git a/indra/newview/skins/default/xui/it/floater_top_objects.xml b/indra/newview/skins/default/xui/it/floater_top_objects.xml index 939c5e83a0..7d062db23b 100644 --- a/indra/newview/skins/default/xui/it/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/it/floater_top_objects.xml @@ -39,13 +39,13 @@ <text name="id_text"> ID oggetto: </text> - <line_editor font="SansSerifSmall" left="90" name="id_editor" width="280"/> - <button label="Mostra segnali luminosi" name="show_beacon_btn" width="150"/> + <line_editor font="SansSerifSmall" name="id_editor"/> + <button label="Mostra segnali luminosi" name="show_beacon_btn"/> <text name="obj_name_text"> Nome dell'oggetto: </text> - <line_editor font="SansSerifSmall" left="90" name="object_name_editor" width="280"/> - <button label="Filtro" name="filter_object_btn" width="150"/> + <line_editor font="SansSerifSmall" name="object_name_editor"/> + <button label="Filtro" name="filter_object_btn"/> <text name="owner_name_text"> Proprietario: </text> diff --git a/indra/newview/skins/default/xui/it/floater_water.xml b/indra/newview/skins/default/xui/it/floater_water.xml index c6ab646fbf..b25f0a6266 100644 --- a/indra/newview/skins/default/xui/it/floater_water.xml +++ b/indra/newview/skins/default/xui/it/floater_water.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Water Floater" title="EDITOR AVANZATO DELL'ACQUA"> - <text name="KeyFramePresetsText" width="224"> + <text name="KeyFramePresetsText" width="245"> Impostazioni predeterminate dell'acqua: </text> - <combo_box left_delta="230" name="WaterPresetsCombo" width="150"/> + <combo_box left_delta="245" name="WaterPresetsCombo" width="150"/> <button label="Nuovo" label_selected="Nuovo" name="WaterNewPreset"/> <button label="Salva" label_selected="Salva" name="WaterSavePreset"/> <button label="Cancella" label_selected="Cancella" name="WaterDeletePreset"/> diff --git a/indra/newview/skins/default/xui/it/floater_windlight_options.xml b/indra/newview/skins/default/xui/it/floater_windlight_options.xml index 1f6f0fab58..6828d05be0 100644 --- a/indra/newview/skins/default/xui/it/floater_windlight_options.xml +++ b/indra/newview/skins/default/xui/it/floater_windlight_options.xml @@ -1,8 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="WindLight floater" title="EDITOR AVANZATO DEL CIELO"> - <text name="KeyFramePresetsText"> + <text name="KeyFramePresetsText" width="105"> Cieli predefiniti: </text> + <combo_box left_delta="105" name="WLPresetsCombo"/> <button label="Nuovo" label_selected="Nuovo" name="WLNewPreset"/> <button label="Salva" label_selected="Salva" left_delta="72" name="WLSavePreset"/> <button label="Elimina" label_selected="Elimina" left_delta="72" name="WLDeletePreset"/> diff --git a/indra/newview/skins/default/xui/it/panel_group_notices.xml b/indra/newview/skins/default/xui/it/panel_group_notices.xml index 2e2f0dc7b0..524f7d2822 100644 --- a/indra/newview/skins/default/xui/it/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/it/panel_group_notices.xml @@ -25,18 +25,15 @@ Massimo 200 per gruppo al giorno <text name="lbl"> Crea una notice </text> - <text left="20" name="lbl3"> + <text name="lbl3"> Oggetto: </text> - <line_editor left_delta="61" name="create_subject" width="251"/> - <text left="15" name="lbl4" width="60"> + <text name="lbl4"> Messaggio: </text> - <text_editor left_delta="66" name="create_message" width="330"/> - <text name="lbl5" width="68"> + <text name="lbl5"> Allega: </text> - <line_editor left_delta="74" name="create_inventory_name" width="190"/> <text name="string"> Trascina e rilascia qui l'oggetto da allegare: </text> diff --git a/indra/newview/skins/default/xui/it/panel_media_settings_general.xml b/indra/newview/skins/default/xui/it/panel_media_settings_general.xml index 5ed7b23679..f11b2415ee 100644 --- a/indra/newview/skins/default/xui/it/panel_media_settings_general.xml +++ b/indra/newview/skins/default/xui/it/panel_media_settings_general.xml @@ -22,7 +22,7 @@ <text name="media_setting_note"> Nota: I residenti possono annullare questa impostazione </text> - <check_box initial_value="false" label="Messa in scala automatica dell'elemento multimediale sulla faccia dell'oggetto" name="auto_scale"/> + <check_box initial_value="false" label="Messa in scala automatica dell'elemento multimediale sulla faccia dell'oggetto" name="auto_scale"/> <text name="size_label"> Dimensioni: </text> diff --git a/indra/newview/skins/default/xui/nl/floater_about.xml b/indra/newview/skins/default/xui/nl/floater_about.xml index f543ebbbe3..4e22d865fe 100644 --- a/indra/newview/skins/default/xui/nl/floater_about.xml +++ b/indra/newview/skins/default/xui/nl/floater_about.xml @@ -8,7 +8,7 @@ Gemaakt met [COMPILER] versie [COMPILER_VERSION] </floater.string> <floater.string name="AboutPosition"> - U bent op [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] gelegen op [HOSTNAME] ([HOSTIP]) + U bent op [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] gelegen op <nolink>[HOSTNAME]</nolink> ([HOSTIP]) [SERVER_VERSION] [[SERVER_RELEASE_NOTES_URL] [ReleaseNotes]] </floater.string> diff --git a/indra/newview/skins/default/xui/nl/panel_group_notices.xml b/indra/newview/skins/default/xui/nl/panel_group_notices.xml index 134261197a..a1929bb5e1 100644 --- a/indra/newview/skins/default/xui/nl/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/nl/panel_group_notices.xml @@ -30,16 +30,13 @@ <text name="lbl2"> U kunt een enkel item aan een bericht toevoegen door het van uw inventaris naar dit paneel te slepen. Bevestigde items moeten kopieerbaar en overdraagbaar zijn en u kunt geen mappen versturen. </text> - <text bottom_delta="-79" halign="right" left="10" name="lbl3" width="60"> + <text name="lbl3"> Onderwerp: </text> - <line_editor name="create_subject" width="331" left_delta="71"/> - <text bottom_delta="-18" halign="right" left="10" name="lbl4" width="60"> + <text name="lbl4"> Bericht: </text> - <text_editor name="create_message" bottom_delta="-90" height="104" left_delta="71" width="330"/> - <line_editor name="create_inventory_name" width="190" left_delta="71"/> - <text name="lbl5" left="10"> + <text name="lbl5"> Bevestig: </text> <button label="Verwijder bevestiging" label_selected="Verwijder bevestiging" name="remove_attachment"/> diff --git a/indra/newview/skins/default/xui/pl/floater_preview_animation.xml b/indra/newview/skins/default/xui/pl/floater_preview_animation.xml index 6ce6914771..d276b1f63a 100644 --- a/indra/newview/skins/default/xui/pl/floater_preview_animation.xml +++ b/indra/newview/skins/default/xui/pl/floater_preview_animation.xml @@ -6,6 +6,6 @@ <text name="desc txt"> Opis: </text> - <button label="Uruchom in-world" label_selected="Stop" left="20" name="Anim play btn" tool_tip="Uruchom animacjÄ™ by widzieli jÄ… pozostali Rezydenci" width="131"/> - <button label="Używaj lokalnie" label_selected="Stop" left="162" name="Anim audition btn" tool_tip="Uruchom animacjÄ™ widocznÄ… tylko przez Ciebie" width="125"/> + <button label="Uruchom in-world" label_selected="Stop" name="Anim play btn" tool_tip="Uruchom animacjÄ™ by widzieli jÄ… pozostali Rezydenci" width="131"/> + <button label="Używaj lokalnie" label_selected="Stop" left="162" name="Anim audition btn" tool_tip="Uruchom animacjÄ™ widocznÄ… tylko przez Ciebie" width="120"/> </floater> diff --git a/indra/newview/skins/default/xui/pl/panel_group_notices.xml b/indra/newview/skins/default/xui/pl/panel_group_notices.xml index 5b62d13880..a3b0998de3 100644 --- a/indra/newview/skins/default/xui/pl/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/pl/panel_group_notices.xml @@ -47,7 +47,7 @@ Limit dzienny ogÅ‚oszeÅ„ dla grupy wynosi 200. OgÅ‚oszenia zachowane </text> <text name="lbl2"> - W celu wysÅ‚ania nowego ogÅ‚oszenia kliknij przycisk + + W celu wysÅ‚ania nowego ogÅ‚oszenia kliknij + Stwórz ogÅ‚oszenie </text> <text name="lbl3"> Temat: diff --git a/indra/newview/skins/default/xui/pl/panel_media_settings_security.xml b/indra/newview/skins/default/xui/pl/panel_media_settings_security.xml index da3142b54e..7e95c4942f 100644 --- a/indra/newview/skins/default/xui/pl/panel_media_settings_security.xml +++ b/indra/newview/skins/default/xui/pl/panel_media_settings_security.xml @@ -2,7 +2,8 @@ <panel label="Ochrona" name="Media Settings Security"> <check_box initial_value="false" label="DostÄ™p dozwolony tylko dla wybranych URL" name="whitelist_enable"/> <text name="home_url_fails_some_items_in_whitelist"> - WejÅ›cia na stronÄ™ WWW, które siÄ™ nie powiodÅ‚y sÄ… zaznaczone: + WejÅ›cia na stronÄ™ WWW, które siÄ™ nie powiodÅ‚y sÄ… +zaznaczone: </text> <button label="Dodaj" name="whitelist_add"/> <button label="UsuÅ„" name="whitelist_del"/> diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/pl/panel_preferences_privacy.xml index a2f9b4176e..5af2fed142 100644 --- a/indra/newview/skins/default/xui/pl/panel_preferences_privacy.xml +++ b/indra/newview/skins/default/xui/pl/panel_preferences_privacy.xml @@ -9,7 +9,7 @@ </text> <check_box label="Pokaż mój profil w wynikach wyszukiwarki" name="online_searchresults"/> <check_box label="Mój status online jest dostÄ™pny tylko dla znajomych i grup do których należę" name="online_visibility"/> - <check_box label="Możliwość wysyÅ‚ania wiadomoÅ›ci prywatnej (IM) oraz rozmowy gÅ‚osowej tylko dla znajomych i grup do których należę" name="voice_call_friends_only_check"/> + <check_box label="Możliwość wysyÅ‚ania wiadomoÅ›ci prywatnej (IM) oraz rozmowy gÅ‚osowej tylko dla znajomych i grup do których należę" name="voice_call_friends_only_check" top_pad="15"/> <check_box label="WyÅ‚Ä…cz mikrofon po zakoÅ„czeniu rozmowy gÅ‚osowej" name="auto_disengage_mic_check"/> <check_box label="Pokaż moje ulubione landmarki przy logowaniu (w rozwijanym menu 'Rozpocznij w')" name="favorites_on_login_check"/> <text name="Logs:"> diff --git a/indra/newview/skins/default/xui/pt/floater_about.xml b/indra/newview/skins/default/xui/pt/floater_about.xml index ac365f1702..a9da2a18af 100644 --- a/indra/newview/skins/default/xui/pt/floater_about.xml +++ b/indra/newview/skins/default/xui/pt/floater_about.xml @@ -7,7 +7,7 @@ ConstruÃdo com [COMPILER] versão [COMPILER_VERSION] </floater.string> <floater.string name="AboutPosition"> - Você está em [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] em [REGION] localizado em [HOSTNAME]</nolink>([HOSTIP]) + Você está em [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] em [REGION] localizado em <nolink>[HOSTNAME]</nolink>([HOSTIP]) [SERVER_VERSION] [[SERVER_RELEASE_NOTES_URL] [ReleaseNotes]] </floater.string> diff --git a/indra/newview/skins/default/xui/pt/floater_build_options.xml b/indra/newview/skins/default/xui/pt/floater_build_options.xml index 71a1483dde..666e185819 100644 --- a/indra/newview/skins/default/xui/pt/floater_build_options.xml +++ b/indra/newview/skins/default/xui/pt/floater_build_options.xml @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="build options floater" title="OPÇÕES DE GRADE"> - <spinner label="Unidade da grade (metros)" label_width="122" name="GridResolution" width="180"/> - <spinner label="Ext. da Grade (metros)" label_width="122" name="GridDrawSize" width="180"/> + <spinner label="Unidade da grade (metros)" name="GridResolution"/> + <spinner label="Ext. da Grade (metros)" name="GridDrawSize"/> <check_box label="Encaixar em sub-unidades" name="GridSubUnit"/> <check_box label="Ver corte transversal" name="GridCrossSection"/> <text name="grid_opacity_label" tool_tip="Opacidade da grade"> Opacidade: </text> - <slider label="Opacidade da grade" name="GridOpacity" width="220"/> + <slider label="Opacidade da grade" name="GridOpacity"/> </floater> diff --git a/indra/newview/skins/default/xui/pt/floater_buy_land.xml b/indra/newview/skins/default/xui/pt/floater_buy_land.xml index 5c5ee3b7a0..258c95cc7d 100644 --- a/indra/newview/skins/default/xui/pt/floater_buy_land.xml +++ b/indra/newview/skins/default/xui/pt/floater_buy_land.xml @@ -127,25 +127,25 @@ contribuÃdas para cobrir este lote antes da aquisição se completar. <text name="region_name_label"> Região: </text> - <text left="560" name="region_name_text"> + <text name="region_name_text"> (desconhecido) </text> <text name="region_type_label"> Tipo: </text> - <text left="560" name="region_type_text"> + <text name="region_type_text"> (desconhecido) </text> <text name="estate_name_label"> Propriedade: </text> - <text left="560" name="estate_name_text"> + <text name="estate_name_text"> (desconhecido) </text> - <text name="estate_owner_label" right="565" width="105"> + <text name="estate_owner_label"> Dono da propriedade: </text> - <text left="560" name="estate_owner_text"> + <text name="estate_owner_text"> (desconhecido) </text> <text name="resellable_changeable_label"> @@ -160,11 +160,11 @@ contribuÃdas para cobrir este lote antes da aquisição se completar. <text name="covenant_text"> Você deve concordar com o Corretor da Propriedade: </text> - <text left="470" name="covenant_timestamp_text"/> + <text name="covenant_timestamp_text"/> <text_editor name="covenant_editor"> Carregando... </text_editor> - <check_box label="Eu concordo com as definições do Corretor feitas acima." name="agree_covenant"/> + <check_box label="Eu concordo com as definições do Corretor feitas acima." name="agree_covenant" left="-330"/> <text name="info_parcel_label"> Lote: </text> diff --git a/indra/newview/skins/default/xui/pt/floater_image_preview.xml b/indra/newview/skins/default/xui/pt/floater_image_preview.xml index 3582923ed0..362a553d64 100644 --- a/indra/newview/skins/default/xui/pt/floater_image_preview.xml +++ b/indra/newview/skins/default/xui/pt/floater_image_preview.xml @@ -10,7 +10,7 @@ Prévia da imagem como: </text> - <combo_box label="Tipo de Roupas" left="100" name="clothing_type_combo" width="186"> + <combo_box label="Tipo de Roupas" name="clothing_type_combo"> <item label="Imagem" name="Image" value="Imagem"/> <item label="Cabelo" name="Hair" value="Cabelo"/> <item label="Cabeça de mulher" name="FemaleHead" value="Cabeça de mulher"/> diff --git a/indra/newview/skins/default/xui/pt/floater_preview_animation.xml b/indra/newview/skins/default/xui/pt/floater_preview_animation.xml index b66159354f..b650b7945c 100644 --- a/indra/newview/skins/default/xui/pt/floater_preview_animation.xml +++ b/indra/newview/skins/default/xui/pt/floater_preview_animation.xml @@ -6,6 +6,6 @@ <text name="desc txt"> Descrição: </text> - <button label="Tocar inworld" label_selected="Parar" left="20" name="Anim play btn" tool_tip="Tocar essa animação de forma que outros possam ver" width="131"/> - <button label="Executar localmente" label_selected="Parar" left="162" name="Anim audition btn" tool_tip="Tocar essa animação de forma que apenas você possa ver" width="125"/> + <button label="Tocar inworld" label_selected="Parar" name="Anim play btn" tool_tip="Tocar essa animação de forma que outros possam ver" width="131"/> + <button label="Executar localmente" label_selected="Parar" left="162" name="Anim audition btn" tool_tip="Tocar essa animação de forma que apenas você possa ver" width="120"/> </floater> diff --git a/indra/newview/skins/default/xui/pt/floater_preview_gesture.xml b/indra/newview/skins/default/xui/pt/floater_preview_gesture.xml index 80bdbb0fb4..b134dfeefa 100644 --- a/indra/newview/skins/default/xui/pt/floater_preview_gesture.xml +++ b/indra/newview/skins/default/xui/pt/floater_preview_gesture.xml @@ -1,75 +1,74 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="gesture_preview"> - <floater.string name="step_anim"> - Executar animação: - </floater.string> - <floater.string name="step_sound"> - Executar som: - </floater.string> - <floater.string name="step_chat"> - Executar bate-papo: - </floater.string> - <floater.string name="step_wait"> - Pausa - </floater.string> - <floater.string name="stop_txt"> - Parar - </floater.string> - <floater.string name="preview_txt"> - Prévia - </floater.string> - <floater.string name="none_text"> - -- Nenhum -- - </floater.string> - <floater.string name="Title"> - Gesto: [NAME] - </floater.string> - <text name="desc_label"> - Descrição: - </text> - <text name="trigger_label"> - Gatilho: - </text> - <text name="replace_text" tool_tip="Substituir a(s) palavra(s) de gatilho por estas palavras. Por exemplo, o gatilho 'oi' substituÃdo por 'olá', mudará a conversa de 'Eu digo oi' para 'Eu digo olá' e também executando o gesto!"> - Trocar por: - </text> - <line_editor name="replace_editor" tool_tip="Substituir a(s) palavra(s) gatilho por estas palavras. Por exemplo, o gatilho 'oi' substituÃdo por 'olá', mudará a conversa de 'Eu digo oi' para 'Eu digo olá' e também executando o gesto!"/> - <text name="key_label"> - Atalho: - </text> - <combo_box label="Nenhum" left="116" name="modifier_combo" width="76"/> - <combo_box label="Nenhum" left_delta="80" name="key_combo" width="76"/> - <text name="library_label"> - Biblioteca: - </text> - <scroll_list name="library_list" width="84"> - <scroll_list.rows name="action_animation" value="Animação"/> - <scroll_list.rows name="action_sound" value="Som"/> - <scroll_list.rows name="action_chat" value="Bate-papo"/> - <scroll_list.rows name="action_wait" value="Espere"/> - </scroll_list> - <button label="Incluir" left="118" name="add_btn" width="87"/> - <text name="steps_label"> - Passos: - </text> - <scroll_list left="226" name="step_list" width="205"/> - <button label="P/ cima" left_delta="-13" name="up_btn" width="114"/> - <button label="P/ baixo" name="down_btn" width="114"/> - <button label="Remover" left_delta="13" name="delete_btn" width="84"/> - <text name="options_text"> - (opções) - </text> - <radio_group name="animation_trigger_type"> - <radio_item label="Iniciar" name="start"/> - <radio_item label="Parar" name="stop"/> - </radio_group> - <check_box bottom_delta="34" label="até que as animações estejam concluÃdas" name="wait_anim_check"/> - <check_box bottom_delta="-30" label="segundos:" name="wait_time_check"/> - <line_editor left_delta="130" name="wait_time_editor"/> - <text name="help_label"> - Se não incluir uma pausa, todas as etapas ocorrem ao mesmo tempo. - </text> - <check_box label="Ativar" name="active_check" tool_tip="Gestos podem ser ativados escrevendo suas frases de gatilho no chat ou teclando o atalho. Gestos normalmente ficam inativos quando existe um conflito nas teclas de atalho."/> - <button label="Prévia" name="preview_btn"/> - <button label="Salvar" name="save_btn"/> -</floater> +<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="gesture_preview">
+ <floater.string name="step_anim">
+ Executar animação:
+ </floater.string>
+ <floater.string name="step_sound">
+ Executar som:
+ </floater.string>
+ <floater.string name="step_chat">
+ Executar bate-papo:
+ </floater.string>
+ <floater.string name="step_wait">
+ Pausa
+ </floater.string>
+ <floater.string name="stop_txt">
+ Parar
+ </floater.string>
+ <floater.string name="preview_txt">
+ Prévia
+ </floater.string>
+ <floater.string name="none_text">
+ -- Nenhum --
+ </floater.string>
+ <floater.string name="Title">
+ Gesto: [NAME]
+ </floater.string>
+ <text name="desc_label">
+ Descrição:
+ </text>
+ <text name="trigger_label">
+ Gatilho:
+ </text>
+ <text name="replace_text" tool_tip="Substituir a(s) palavra(s) de gatilho por estas palavras. Por exemplo, o gatilho 'oi' substituÃdo por 'olá', mudará a conversa de 'Eu digo oi' para 'Eu digo olá' e também executando o gesto!">
+ Trocar por:
+ </text>
+ <line_editor name="replace_editor" tool_tip="Substituir a(s) palavra(s) gatilho por estas palavras. Por exemplo, o gatilho 'oi' substituÃdo por 'olá', mudará a conversa de 'Eu digo oi' para 'Eu digo olá' e também executando o gesto!"/>
+ <text name="key_label">
+ Atalho:
+ </text>
+ <combo_box label="Nenhum" name="modifier_combo" width="68"/>
+ <combo_box label="Nenhum" name="key_combo" width="48"/>
+ <text name="library_label">
+ Biblioteca:
+ </text>
+ <scroll_list name="library_list">
+ <scroll_list.rows name="action_animation" value="Animação"/>
+ <scroll_list.rows name="action_sound" value="Som"/>
+ <scroll_list.rows name="action_chat" value="Bate-papo"/>
+ <scroll_list.rows name="action_wait" value="Espere"/>
+ </scroll_list>
+ <button label="Incluir" name="add_btn"/>
+ <text name="steps_label">
+ Passos:
+ </text>
+ <button label="P/ cima" name="up_btn" />
+ <button label="P/ baixo" name="down_btn"/>
+ <button label="Remover" name="delete_btn"/>
+ <text name="options_text">
+ (opções)
+ </text>
+ <radio_group name="animation_trigger_type">
+ <radio_item label="Iniciar" name="start"/>
+ <radio_item label="Parar" name="stop"/>
+ </radio_group>
+ <check_box label="até que as animações estejam concluÃdas" name="wait_anim_check"/>
+ <check_box label="segundos:" name="wait_time_check"/>
+ <line_editor name="wait_time_editor"/>
+ <text name="help_label">
+ Se não incluir uma pausa, todas as etapas ocorrem ao mesmo tempo.
+ </text>
+ <check_box label="Ativar" name="active_check" tool_tip="Gestos podem ser ativados escrevendo suas frases de gatilho no chat ou teclando o atalho. Gestos normalmente ficam inativos quando existe um conflito nas teclas de atalho."/>
+ <button label="Prévia" name="preview_btn"/>
+ <button label="Salvar" name="save_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_sell_land.xml b/indra/newview/skins/default/xui/pt/floater_sell_land.xml index e6d4dc7ed6..014ae0845e 100644 --- a/indra/newview/skins/default/xui/pt/floater_sell_land.xml +++ b/indra/newview/skins/default/xui/pt/floater_sell_land.xml @@ -55,8 +55,9 @@ <radio_item label="Sim, vender o terreno com os objetos" name="yes"/> </radio_group> <button label="Mostrar objetos" name="show_objects"/> - <text name="nag_message_label"> - LEMBRE-SE: Qualquer transação de compra e venda é irreversÃvel. + <text name="nag_message_label" font="SansSerifSmallBold"> + LEMBRE-SE: Qualquer transação de compra +e venda é irreversÃvel. </text> <button label="Colocar terreno à venda" name="sell_btn"/> <button label="Cancelar" name="cancel_btn"/> diff --git a/indra/newview/skins/default/xui/pt/floater_top_objects.xml b/indra/newview/skins/default/xui/pt/floater_top_objects.xml index dc3bf73818..c3d5820616 100644 --- a/indra/newview/skins/default/xui/pt/floater_top_objects.xml +++ b/indra/newview/skins/default/xui/pt/floater_top_objects.xml @@ -39,14 +39,14 @@ <text name="id_text"> ID do Objeto: </text> - <line_editor font="SansSerifSmall" left="140" name="id_editor" width="280"/> + <line_editor font="SansSerifSmall" name="id_editor"/> <button label="Mostrar Avisos" name="show_beacon_btn"/> <text name="obj_name_text"> Nome do objeto: </text> - <line_editor font="SansSerifSmall" left="140" name="object_name_editor" width="280"/> + <line_editor font="SansSerifSmall" name="object_name_editor"/> <button label="Filtro" name="filter_object_btn"/> - <text name="owner_name_text" width="130"> + <text name="owner_name_text"> Proprietário: </text> <line_editor font="SansSerifSmall" left="140" name="owner_name_editor" width="280"/> diff --git a/indra/newview/skins/default/xui/pt/floater_water.xml b/indra/newview/skins/default/xui/pt/floater_water.xml index b4613e0890..b2a06f4ff2 100644 --- a/indra/newview/skins/default/xui/pt/floater_water.xml +++ b/indra/newview/skins/default/xui/pt/floater_water.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Water Floater" title="EDITOR DE ÃGUA AVANÇADO"> - <text name="KeyFramePresetsText" width="154"> + <text name="KeyFramePresetsText" width="175"> Pré-configurações da Ãgua: </text> - <combo_box left_delta="160" name="WaterPresetsCombo" width="150"/> + <combo_box left_delta="175" name="WaterPresetsCombo" width="150"/> <button label="Novo" label_selected="Novo" name="WaterNewPreset"/> <button label="Salvar" label_selected="Salvar" name="WaterSavePreset"/> <button label="Deletar" label_selected="Deletar" name="WaterDeletePreset"/> diff --git a/indra/newview/skins/default/xui/pt/floater_windlight_options.xml b/indra/newview/skins/default/xui/pt/floater_windlight_options.xml index 22632a4ef8..ec459bbb26 100644 --- a/indra/newview/skins/default/xui/pt/floater_windlight_options.xml +++ b/indra/newview/skins/default/xui/pt/floater_windlight_options.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="WindLight floater" title="EDITOR DE CÉU AVANÇADO"> - <text name="KeyFramePresetsText" width="130"> + <text name="KeyFramePresetsText" width="140"> Pré-definições de Céu: </text> - <combo_box left_delta="130" name="WLPresetsCombo"/> + <combo_box left_delta="140" name="WLPresetsCombo"/> <button label="Novo" label_selected="Novo" name="WLNewPreset"/> <button label="Salvar" label_selected="Salvar" left_delta="72" name="WLSavePreset"/> <button label="Deletar" label_selected="Deletar" left_delta="72" name="WLDeletePreset"/> diff --git a/indra/newview/skins/default/xui/pt/panel_group_notices.xml b/indra/newview/skins/default/xui/pt/panel_group_notices.xml index 21136d06fb..3bff1f8fb3 100644 --- a/indra/newview/skins/default/xui/pt/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/pt/panel_group_notices.xml @@ -24,18 +24,15 @@ Cada grupo pode enviar no máximo 200 avisos/dia <text name="lbl"> Criar notÃcia </text> - <text left="20" name="lbl3"> + <text name="lbl3"> Assunto: </text> - <line_editor left_delta="61" name="create_subject" width="251"/> - <text left="15" name="lbl4" width="60"> + <text name="lbl4"> Mensagem: </text> - <text_editor left_delta="66" name="create_message" width="330"/> - <text name="lbl5" width="68"> + <text name="lbl5"> Anexo: </text> - <line_editor left_delta="74" name="create_inventory_name" width="190"/> <text name="string"> Arrastar e soltar o item aqui para anexá-lo: </text> diff --git a/indra/newview/skins/default/xui/pt/panel_media_settings_security.xml b/indra/newview/skins/default/xui/pt/panel_media_settings_security.xml index 646969946c..e38c44d8fe 100644 --- a/indra/newview/skins/default/xui/pt/panel_media_settings_security.xml +++ b/indra/newview/skins/default/xui/pt/panel_media_settings_security.xml @@ -2,7 +2,8 @@ <panel label="Segurança" name="Media Settings Security"> <check_box initial_value="false" label="Acesso permitido a URLs com padrão especÃfico" name="whitelist_enable"/> <text name="home_url_fails_some_items_in_whitelist"> - URLs com falha de acesso na página inicial são indicados com um: + URLs com falha de acesso na página inicial são +indicados com um: </text> <button label="Adicionar" name="whitelist_add"/> <button label="Excluir" name="whitelist_del"/> diff --git a/indra/newview/skins/default/xui/zh/floater_aaa.xml b/indra/newview/skins/default/xui/zh/floater_aaa.xml new file mode 100644 index 0000000000..c62fc8b5d1 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_aaa.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Test Floater" title="TEST FLOATER"> + <string name="test_the_vlt"> + This string CHANGE2 is extracted. + </string> + <string name="testing_eli"> + Just a test. changes. + </string> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_about.xml b/indra/newview/skins/default/xui/zh/floater_about.xml new file mode 100644 index 0000000000..825fe13e92 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_about.xml @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_about" title="ABOUT [CAPITALIZED_APP_NAME]"> + <floater.string name="AboutHeader"> + [APP_NAME] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2] ([VIEWER_VERSION_3]) [BUILD_DATE] [BUILD_TIME] ([CHANNEL]) +[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] + </floater.string> + <floater.string name="AboutCompiler"> + Built with [COMPILER] version [COMPILER_VERSION] + </floater.string> + <floater.string name="AboutPosition"> + You are at [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] located at <nolink>[HOSTNAME]</nolink> ([HOSTIP]) +[SERVER_VERSION] +[[SERVER_RELEASE_NOTES_URL] [ReleaseNotes]] + </floater.string> + <floater.string name="AboutSystem"> + CPU: [CPU] +Memory: [MEMORY_MB] MB +OS Version: [OS_VERSION] +Graphics Card Vendor: [GRAPHICS_CARD_VENDOR] +Graphics Card: [GRAPHICS_CARD] + </floater.string> + <floater.string name="AboutDriver"> + Windows Graphics Driver Version: [GRAPHICS_DRIVER_VERSION] + </floater.string> + <floater.string name="AboutLibs"> + OpenGL Version: [OPENGL_VERSION] + +libcurl Version: [LIBCURL_VERSION] +J2C Decoder Version: [J2C_VERSION] +Audio Driver Version: [AUDIO_DRIVER_VERSION] +Qt Webkit Version: [QT_WEBKIT_VERSION] +Voice Server Version: [VOICE_VERSION] + </floater.string> + <floater.string name="none"> + (無) + </floater.string> + <floater.string name="AboutTraffic"> + Packets Lost: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) + </floater.string> + <tab_container name="about_tab"> + <panel label="資訊" name="support_panel"> + <button label="覆製到剪貼簿" name="copy_btn"/> + </panel> + <panel label="Credits" name="credits_panel"> + <text_editor name="credits_editor"> + Second Life is brought to you by ..., and many others. + +Thank you to the following Residents for helping to ensure that this is the best version yet: ..., and many others. + + + + +"The work goes on, the cause endures, the hope still lives, and the dreams shall never die" - Edward Kennedy + </text_editor> + </panel> + <panel label="Licenses" name="licenses_panel"> + <text_editor name="credits_editor"> + 3Dconnexion SDK Copyright (C) 1992-2007 3Dconnexion +APR Copyright (C) 2000-2004 The Apache Software Foundation +cURL Copyright (C) 1996-2002, Daniel Stenberg, (daniel@haxx.se) +DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc. +expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. +FreeType Copyright (C) 1996-2002, The FreeType Project (www.freetype.org). +GL Copyright (C) 1999-2004 Brian Paul. +google-perftools Copyright (c) 2005, Google Inc. +Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. +jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) +jpeglib Copyright (C) 1991-1998, Thomas G. Lane. +ogg/vorbis Copyright (C) 2001, Xiphophorus +OpenSSL Copyright (C) 1998-2002 The OpenSSL Project. +Pth Copyright (C) 1999-2006 Ralf S. Engelschall <rse@gnu.org> +SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga +SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) +xmlrpc-epi Copyright (C) 2000 Epinions, Inc. +zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler. +google-perftools Copyright (c) 2005, Google Inc. + +All rights reserved. See licenses.txt for details. + +Voice chat Audio coding: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C) + </text_editor> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_about_land.xml b/indra/newview/skins/default/xui/zh/floater_about_land.xml new file mode 100644 index 0000000000..4e5c4f96f0 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_about_land.xml @@ -0,0 +1,478 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floaterland" title="關於土地"> + <floater.string name="maturity_icon_general"> + "Parcel_PG_Dark" + </floater.string> + <floater.string name="maturity_icon_moderate"> + "Parcel_M_Dark" + </floater.string> + <floater.string name="maturity_icon_adult"> + "Parcel_R_Dark" + </floater.string> + <floater.string name="Minutes"> + [MINUTES] minutes + </floater.string> + <floater.string name="Minute"> + minute + </floater.string> + <floater.string name="Seconds"> + [SECONDS] seconds + </floater.string> + <floater.string name="Remaining"> + remaining + </floater.string> + <tab_container name="landtab"> + <panel label="一般" name="land_general_panel"> + <panel.string name="new users only"> + New Residents only + </panel.string> + <panel.string name="anyone"> + Anyone + </panel.string> + <panel.string name="area_text"> + Area + </panel.string> + <panel.string name="area_size_text"> + [AREA] m² + </panel.string> + <panel.string name="auction_id_text"> + Auction ID: [ID] + </panel.string> + <panel.string name="need_tier_to_modify"> + You must approve your purchase to modify this land. + </panel.string> + <panel.string name="group_owned_text"> + (Group Owned) + </panel.string> + <panel.string name="profile_text"> + Profile + </panel.string> + <panel.string name="info_text"> + 資訊 + </panel.string> + <panel.string name="public_text"> + (公開) + </panel.string> + <panel.string name="none_text"> + (無) + </panel.string> + <panel.string name="sale_pending_text"> + (Sale Pending) + </panel.string> + <panel.string name="no_selection_text"> + No parcel selected. + </panel.string> + <panel.string name="time_stamp_template"> + [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] + </panel.string> + <text name="Name:"> + å稱: + </text> + <text name="Description:"> + æ述: + </text> + <text name="LandType"> + 類型: + </text> + <text name="LandTypeText"> + Mainland / Homestead + </text> + <text name="ContentRating"> + 分級: + </text> + <text name="ContentRatingText"> + Adult + </text> + <text name="Owner:"> + æ“有者: + </text> + <text name="Group:"> + Group: + </text> + <button label="è¨å®š" name="Set..."/> + <check_box label="Allow Deed to Group" name="check deed" tool_tip="A group officer can deed this land to the group, so it will be supported by the group's land allocation."/> + <button label="Deed" name="Deed..." tool_tip="You may only deed land if you are an officer in the selected group."/> + <check_box label="Owner Makes Contribution With Deed" name="check contrib" tool_tip="When the land is deeded to the group, the former owner contributes enough land allocation to support it."/> + <text name="For Sale:"> + 出售: + </text> + <text name="Not for sale."> + Not for sale + </text> + <text name="For Sale: Price L$[PRICE]."> + Price: L$[PRICE] (L$[PRICE_PER_SQM]/m²) + </text> + <button label="Sell Land" name="Sell Land..."/> + <text name="For sale to"> + 出售給:[BUYER] + </text> + <text name="Sell with landowners objects in parcel."> + Objects included in sale + </text> + <text name="Selling with no objects in parcel."> + Objects not included in sale + </text> + <button label="Cancel Land Sale" label_selected="Cancel Land Sale" name="Cancel Land Sale"/> + <text name="Claimed:"> + Claimed: + </text> + <text name="DateClaimText"> + Tue Aug 15 13:47:25 2006 + </text> + <text name="PriceLabel"> + é¢ç©ï¼š + </text> + <text name="PriceText"> + 4048 m² + </text> + <text name="Traffic:"> + æµé‡ï¼š + </text> + <text name="DwellText"> + 0 + </text> + <button label="購買土地" name="Buy Land..."/> + <button label="Script Info" name="Scripts..."/> + <button label="Buy For Group" name="Buy For Group..."/> + <button label="Buy Pass" name="Buy Pass..." tool_tip="A pass gives you temporary access to this land."/> + <button label="Abandon Land" name="Abandon Land..."/> + <button label="Reclaim Land" name="Reclaim Land..."/> + <button label="Linden Sale" name="Linden Sale..." tool_tip="Land must be owned, set content, and not already for auction."/> + </panel> + <panel label="契約" name="land_covenant_panel"> + <panel.string name="can_resell"> + Purchased land in this region may be resold. + </panel.string> + <panel.string name="can_not_resell"> + Purchased land in this region may not be resold. + </panel.string> + <panel.string name="can_change"> + Purchased land in this region may be joined or subdivided. + </panel.string> + <panel.string name="can_not_change"> + Purchased land in this region may not be joined or subdivided. + </panel.string> + <text name="estate_section_lbl"> + é ˜åœ°ï¼š + </text> + <text name="estate_name_text"> + mainland + </text> + <text name="estate_owner_lbl"> + æ“有者: + </text> + <text name="estate_owner_text"> + (無) + </text> + <text_editor name="covenant_editor"> + There is no Covenant provided for this Estate. + </text_editor> + <text name="covenant_timestamp_text"> + Last Modified Wed Dec 31 16:00:00 1969 + </text> + <text name="region_section_lbl"> + 地å€ï¼š + </text> + <text name="region_name_text"> + EricaVille + </text> + <text name="region_landtype_lbl"> + 類型: + </text> + <text name="region_landtype_text"> + Mainland / Homestead + </text> + <text name="region_maturity_lbl"> + 分級: + </text> + <text name="region_maturity_text"> + Adult + </text> + <text name="resellable_lbl"> + Resale: + </text> + <text name="resellable_clause"> + Land in this region may not be resold. + </text> + <text name="changeable_lbl"> + Subdivide: + </text> + <text name="changeable_clause"> + Land in this region may not be joined/subdivided. + </text> + </panel> + <panel label="OBJECTS" name="land_objects_panel"> + <panel.string name="objects_available_text"> + [COUNT] out of [MAX] ([AVAILABLE] available) + </panel.string> + <panel.string name="objects_deleted_text"> + [COUNT] out of [MAX] ([DELETED] will be deleted) + </panel.string> + <text name="parcel_object_bonus"> + Region Object Bonus Factor: [BONUS] + </text> + <text name="Simulator primitive usage:"> + Primitive usage: + </text> + <text name="objects_available"> + [COUNT] out of [MAX] ([AVAILABLE] available) + </text> + <text name="Primitives parcel supports:"> + Prims parcel supports: + </text> + <text name="object_contrib_text"> + [COUNT] + </text> + <text name="Primitives on parcel:"> + Prims on parcel: + </text> + <text name="total_objects_text"> + [COUNT] + </text> + <text name="Owned by parcel owner:"> + Owned by parcel owner: + </text> + <text name="owner_objects_text"> + [COUNT] + </text> + <button label="Show" label_selected="Show" name="ShowOwner"/> + <button label="Return" name="ReturnOwner..." tool_tip="Return objects to their owners."/> + <text name="Set to group:"> + Set to group: + </text> + <text name="group_objects_text"> + [COUNT] + </text> + <button label="Show" label_selected="Show" name="ShowGroup"/> + <button label="Return" name="ReturnGroup..." tool_tip="Return objects to their owners."/> + <text name="Owned by others:"> + Owned by others: + </text> + <text name="other_objects_text"> + [COUNT] + </text> + <button label="Show" label_selected="Show" name="ShowOther"/> + <button label="Return" name="ReturnOther..." tool_tip="Return objects to their owners."/> + <text name="Selected / sat upon:"> + Selected / sat upon: + </text> + <text name="selected_objects_text"> + [COUNT] + </text> + <text name="Autoreturn"> + Auto return other Residents' objects (minutes, 0 for off): + </text> + <text name="Object Owners:"> + Object Owners: + </text> + <button name="Refresh List" tool_tip="Refresh Object List"/> + <button label="退回物件" name="Return objects..."/> + <name_list name="owner list"> + <name_list.columns label="Type" name="type"/> + <name_list.columns label="å稱" name="name"/> + <name_list.columns label="Count" name="count"/> + <name_list.columns label="Most Recent" name="mostrecent"/> + </name_list> + </panel> + <panel label="OPTIONS" name="land_options_panel"> + <panel.string name="search_enabled_tooltip"> + Let people see this parcel in search results + </panel.string> + <panel.string name="search_disabled_small_tooltip"> + This option is disabled because this parcel's area is 128 m² or smaller. +Only large parcels can be listed in search. + </panel.string> + <panel.string name="search_disabled_permissions_tooltip"> + This option is disabled because you cannot modify this parcel's options. + </panel.string> + <panel.string name="mature_check_mature"> + Moderate Content + </panel.string> + <panel.string name="mature_check_adult"> + Adult Content + </panel.string> + <panel.string name="mature_check_mature_tooltip"> + Your parcel information or content is considered moderate. + </panel.string> + <panel.string name="mature_check_adult_tooltip"> + Your parcel information or content is considered adult. + </panel.string> + <panel.string name="landing_point_none"> + (無) + </panel.string> + <panel.string name="push_restrict_text"> + No Pushing + </panel.string> + <panel.string name="push_restrict_region_text"> + No Pushing (Region Override) + </panel.string> + <text name="allow_label"> + Allow other Residents to: + </text> + <check_box label="Edit Terrain" name="edit land check" tool_tip="If checked, anyone can terraform your land. It is best to leave this unchecked, as you can always edit your own land."/> + <check_box label="Fly" name="check fly" tool_tip="If checked, Residents can fly on your land. If unchecked, they can only fly into and over your land."/> + <text name="allow_label2"> + Build: + </text> + <check_box label="Everyone" name="edit objects check"/> + <check_box label="Group" name="edit group objects check"/> + <text name="allow_label3"> + Object Entry: + </text> + <check_box label="Everyone" name="all object entry check"/> + <check_box label="Group" name="group object entry check"/> + <text name="allow_label4"> + Run Scripts: + </text> + <check_box label="Everyone" name="check other scripts"/> + <check_box label="Group" name="check group scripts"/> + <text name="land_options_label"> + Land Options: + </text> + <check_box label="Safe (no damage)" name="check safe" tool_tip="If checked, sets the land to Safe, disabling damage combat. If cleared, damage combat is enabled."/> + <check_box label="No Pushing" name="PushRestrictCheck" tool_tip="Prevents scripts from pushing. Checking this option may be useful for preventing disruptive behavior on your land."/> + <check_box label="Show Place in Search (L$30/week)" name="ShowDirectoryCheck" tool_tip="Let people see this parcel in search results"/> + <combo_box name="land category with adult"> + <combo_box.item label="Any Category" name="item0"/> + <combo_box.item label="Linden Location" name="item1"/> + <combo_box.item label="Adult" name="item2"/> + <combo_box.item label="Arts & Culture" name="item3"/> + <combo_box.item label="Business" name="item4"/> + <combo_box.item label="Educational" name="item5"/> + <combo_box.item label="Gaming" name="item6"/> + <combo_box.item label="èšæœƒæ‰€" name="item7"/> + <combo_box.item label="Newcomer Friendly" name="item8"/> + <combo_box.item label="Parks & Nature" name="item9"/> + <combo_box.item label="Residential" name="item10"/> + <combo_box.item label="Shopping" name="item11"/> + <combo_box.item label="Rental" name="item13"/> + <combo_box.item label="Other" name="item12"/> + </combo_box> + <combo_box name="land category"> + <combo_box.item label="Any Category" name="item0"/> + <combo_box.item label="Linden Location" name="item1"/> + <combo_box.item label="Arts & Culture" name="item3"/> + <combo_box.item label="Business" name="item4"/> + <combo_box.item label="Educational" name="item5"/> + <combo_box.item label="Gaming" name="item6"/> + <combo_box.item label="èšæœƒæ‰€" name="item7"/> + <combo_box.item label="Newcomer Friendly" name="item8"/> + <combo_box.item label="Parks & Nature" name="item9"/> + <combo_box.item label="Residential" name="item10"/> + <combo_box.item label="Shopping" name="item11"/> + <combo_box.item label="Rental" name="item13"/> + <combo_box.item label="Other" name="item12"/> + </combo_box> + <check_box label="Moderate Content" name="MatureCheck" tool_tip=" "/> + <text name="Snapshot:"> + Snapshot: + </text> + <texture_picker name="snapshot_ctrl" tool_tip="點擊以挑é¸åœ–片"/> + <text name="landing_point"> + Landing Point: [LANDING] + </text> + <button label="è¨å®š" label_selected="è¨å®š" name="Set" tool_tip="Sets the landing point where visitors arrive. Sets to your avatar's location inside this parcel."/> + <button label="清除" label_selected="清除" name="Clear" tool_tip="清除登陸點"/> + <text name="Teleport Routing: "> + Teleport Routing: + </text> + <combo_box name="landing type" tool_tip="Teleport Routing -- select how to handle teleports onto your land"> + <combo_box.item label="Blocked" name="Blocked"/> + <combo_box.item label="Landing Point" name="LandingPoint"/> + <combo_box.item label="Anywhere" name="Anywhere"/> + </combo_box> + </panel> + <panel label="MEDIA" name="land_media_panel"> + <text name="with media:"> + 類型: + </text> + <combo_box name="media type" tool_tip="Specify if the URL is a movie, web page, or other media"/> + <text name="at URL:"> + Home Page: + </text> + <button label="è¨å®š" name="set_media_url"/> + <text name="Description:"> + æ述: + </text> + <line_editor name="url_description" tool_tip="Text displayed next to play/load button"/> + <text name="Media texture:"> + Replace Texture: + </text> + <texture_picker name="media texture" tool_tip="點擊以挑é¸åœ–片"/> + <text name="replace_texture_help"> + Objects using this texture will show the movie or web page after you click the play arrow. Select the thumbnail to choose a different texture. + </text> + <check_box label="Auto scale" name="media_auto_scale" tool_tip="Checking this option will scale the content for this parcel automatically. It may be slightly slower and lower quality visually but no other texture scaling or alignment will be required."/> + <text name="media_size" tool_tip="Size to render Web media, leave 0 for default."> + Size: + </text> + <spinner name="media_size_width" tool_tip="Size to render Web media, leave 0 for default."/> + <spinner name="media_size_height" tool_tip="Size to render Web media, leave 0 for default."/> + <text name="pixels"> + pixels + </text> + <text name="Options:"> + Options: + </text> + <check_box label="Loop" name="media_loop" tool_tip="Play media in a loop. When the media has finished playing, it will restart from the beginning."/> + </panel> + <panel label="SOUND" name="land_audio_panel"> + <text name="MusicURL:"> + Music URL: + </text> + <text name="Sound:"> + Sound: + </text> + <check_box label="Restrict gesture and object sounds to this parcel" name="check sound local"/> + <text name="Voice settings:"> + Voice: + </text> + <check_box label="Enable Voice" name="parcel_enable_voice_channel"/> + <check_box label="Enable Voice (established by the Estate)" name="parcel_enable_voice_channel_is_estate_disabled"/> + <check_box label="Restrict Voice to this parcel" name="parcel_enable_voice_channel_local"/> + </panel> + <panel label="ACCESS" name="land_access_panel"> + <panel.string name="access_estate_defined"> + (Defined by the Estate) + </panel.string> + <panel.string name="allow_public_access"> + Allow Public Access ([MATURITY]) (Note: Unchecking this will create ban lines) + </panel.string> + <panel.string name="estate_override"> + One or more of these options is set at the estate level + </panel.string> + <text name="Limit access to this parcel to:"> + Access To This Parcel + </text> + <text name="Only Allow"> + Restrict Access to Residents verified by: + </text> + <check_box label="Payment Information on File [ESTATE_PAYMENT_LIMIT]" name="limit_payment" tool_tip="Ban unidentified Residents."/> + <check_box label="å¹´é½¡é©—è‰ [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Ban Residents who have not verified their age. See the [SUPPORT_SITE] for more information."/> + <check_box label="Allow Group Access: [GROUP]" name="GroupCheck" tool_tip="Set group in the General tab."/> + <check_box label="Sell passes to:" name="PassCheck" tool_tip="Allows temporary access to this parcel"/> + <combo_box name="pass_combo"> + <combo_box.item label="Anyone" name="Anyone"/> + <combo_box.item label="Group" name="Group"/> + </combo_box> + <spinner label="Price in L$:" name="PriceSpin"/> + <spinner label="Hours of access:" name="HoursSpin"/> + <panel name="Allowed_layout_panel"> + <text label="Always Allow" name="AllowedText"> + Allowed Residents + </text> + <name_list name="AccessList" tool_tip="([LISTED] listed, [MAX] max)"/> + <button label="Add" name="add_allowed"/> + <button label="Remove" label_selected="Remove" name="remove_allowed"/> + </panel> + <panel name="Banned_layout_panel"> + <text label="Ban" name="BanCheck"> + Banned Residents + </text> + <name_list name="BannedList" tool_tip="([LISTED] listed, [MAX] max)"/> + <button label="Add" name="add_banned"/> + <button label="Remove" label_selected="Remove" name="remove_banned"/> + </panel> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_activeim.xml b/indra/newview/skins/default/xui/zh/floater_activeim.xml new file mode 100644 index 0000000000..93017bf5b2 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_activeim.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_activeim" title="ACTIVE IM"/> diff --git a/indra/newview/skins/default/xui/zh/floater_animation_preview.xml b/indra/newview/skins/default/xui/zh/floater_animation_preview.xml new file mode 100644 index 0000000000..0f1feaa843 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_animation_preview.xml @@ -0,0 +1,186 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Animation Preview"> + <floater.string name="failed_to_initialize"> + Failed to initialize motion + </floater.string> + <floater.string name="anim_too_long"> + Animation file is [LENGTH] seconds in length. + +Maximum animation length is [MAX_LENGTH] seconds. + </floater.string> + <floater.string name="failed_file_read"> + Unable to read animation file. + +[STATUS] + </floater.string> + <floater.string name="E_ST_OK"> + 確定 + </floater.string> + <floater.string name="E_ST_EOF"> + Premature end of file. + </floater.string> + <floater.string name="E_ST_NO_CONSTRAINT"> + Cannot read constraint definition. + </floater.string> + <floater.string name="E_ST_NO_FILE"> + Cannot open BVH file. + </floater.string> + <floater.string name="E_ST_NO_HIER"> + Invalid HIERARCHY header. + </floater.string> + <floater.string name="E_ST_NO_JOINT"> + Cannot find ROOT or JOINT. + </floater.string> + <floater.string name="E_ST_NO_NAME"> + Cannot get JOINT name. + </floater.string> + <floater.string name="E_ST_NO_OFFSET"> + Cannot find OFFSET. + </floater.string> + <floater.string name="E_ST_NO_CHANNELS"> + Cannot find CHANNELS. + </floater.string> + <floater.string name="E_ST_NO_ROTATION"> + Cannot get rotation order. + </floater.string> + <floater.string name="E_ST_NO_AXIS"> + Cannot get rotation axis. + </floater.string> + <floater.string name="E_ST_NO_MOTION"> + Cannot find MOTION. + </floater.string> + <floater.string name="E_ST_NO_FRAMES"> + Cannot get number of frames. + </floater.string> + <floater.string name="E_ST_NO_FRAME_TIME"> + Cannot get frame time. + </floater.string> + <floater.string name="E_ST_NO_POS"> + Cannot get position values. + </floater.string> + <floater.string name="E_ST_NO_ROT"> + Cannot get rotation values. + </floater.string> + <floater.string name="E_ST_NO_XLT_FILE"> + Cannot open translation file. + </floater.string> + <floater.string name="E_ST_NO_XLT_HEADER"> + Cannot read translation header. + </floater.string> + <floater.string name="E_ST_NO_XLT_NAME"> + Cannot read translation names. + </floater.string> + <floater.string name="E_ST_NO_XLT_IGNORE"> + Cannot read translation ignore value. + </floater.string> + <floater.string name="E_ST_NO_XLT_RELATIVE"> + Cannot read translation relative value. + </floater.string> + <floater.string name="E_ST_NO_XLT_OUTNAME"> + Cannot read translation outname value. + </floater.string> + <floater.string name="E_ST_NO_XLT_MATRIX"> + Cannot read translation matrix. + </floater.string> + <floater.string name="E_ST_NO_XLT_MERGECHILD"> + Cannot get mergechild name. + </floater.string> + <floater.string name="E_ST_NO_XLT_MERGEPARENT"> + Cannot get mergeparent name. + </floater.string> + <floater.string name="E_ST_NO_XLT_PRIORITY"> + Cannot get priority value. + </floater.string> + <floater.string name="E_ST_NO_XLT_LOOP"> + Cannot get loop value. + </floater.string> + <floater.string name="E_ST_NO_XLT_EASEIN"> + Cannot get easeIn values. + </floater.string> + <floater.string name="E_ST_NO_XLT_EASEOUT"> + Cannot get easeOut values. + </floater.string> + <floater.string name="E_ST_NO_XLT_HAND"> + Cannot get hand morph value. + </floater.string> + <floater.string name="E_ST_NO_XLT_EMOTE"> + Cannot read emote name. + </floater.string> + <floater.string name="E_ST_BAD_ROOT"> + Incorrect root joint name, use "hip". + </floater.string> + <text name="name_label"> + å稱: + </text> + <text name="description_label"> + æ述: + </text> + <spinner label="Priority" name="priority" tool_tip="Controls which other animations can be overridden by this animation"/> + <check_box label="Loop" name="loop_check" tool_tip="Makes this animation loop"/> + <spinner label="In(%)" name="loop_in_point" tool_tip="Sets point in animation that looping returns to"/> + <spinner label="Out(%)" name="loop_out_point" tool_tip="Sets point in animation that ends a loop"/> + <text name="hand_label"> + Hand Pose + </text> + <combo_box name="hand_pose_combo" tool_tip="Controls what hands do during animation"> + <combo_box.item label="Spread" name="Spread"/> + <combo_box.item label="Relaxed" name="Relaxed"/> + <combo_box.item label="Point Both" name="PointBoth"/> + <combo_box.item label="Fist" name="Fist"/> + <combo_box.item label="Relaxed Left" name="RelaxedLeft"/> + <combo_box.item label="Point Left" name="PointLeft"/> + <combo_box.item label="Fist Left" name="FistLeft"/> + <combo_box.item label="Relaxed Right" name="RelaxedRight"/> + <combo_box.item label="Point Right" name="PointRight"/> + <combo_box.item label="Fist Right" name="FistRight"/> + <combo_box.item label="Salute Right" name="SaluteRight"/> + <combo_box.item label="Typing" name="Typing"/> + <combo_box.item label="Peace Right" name="PeaceRight"/> + </combo_box> + <text name="emote_label"> + Expression + </text> + <combo_box name="emote_combo" tool_tip="Controls what face does during animation"> + <item label="(無)" name="[None]" value=""/> + <item label="Aaaaah" name="Aaaaah" value="Aaaaah"/> + <item label="Afraid" name="Afraid" value="Afraid"/> + <item label="Angry" name="Angry" value="Angry"/> + <item label="Big Smile" name="BigSmile" value="Big Smile"/> + <item label="Bored" name="Bored" value="Bored"/> + <item label="Cry" name="Cry" value="Cry"/> + <item label="Disdain" name="Disdain" value="Disdain"/> + <item label="Embarrassed" name="Embarrassed" value="Embarrassed"/> + <item label="Frown" name="Frown" value="Frown"/> + <item label="Kiss" name="Kiss" value="Kiss"/> + <item label="Laugh" name="Laugh" value="Laugh"/> + <item label="Plllppt" name="Plllppt" value="Plllppt"/> + <item label="Repulsed" name="Repulsed" value="Repulsed"/> + <item label="Sad" name="Sad" value="Sad"/> + <item label="Shrug" name="Shrug" value="Shrug"/> + <item label="Smile" name="Smile" value="Smile"/> + <item label="Surprise" name="Surprise" value="Surprise"/> + <item label="Wink" name="Wink" value="Wink"/> + <item label="Worry" name="Worry" value="Worry"/> + </combo_box> + <text name="preview_label"> + Preview while + </text> + <combo_box name="preview_base_anim" tool_tip="Use this to test your animation behavior while your avatar performs common actions."> + <item label="Standing" name="Standing" value="Standing"/> + <item label="Walking" name="Walking" value="Walking"/> + <item label="Sitting" name="Sitting" value="Sitting"/> + <item label="Flying" name="Flying" value="Flying"/> + </combo_box> + <spinner label="淡入(秒)" name="ease_in_time" tool_tip="Amount of time (in seconds) over which animations blends in"/> + <spinner label="淡出(秒)" name="ease_out_time" tool_tip="Amount of time (in seconds) over which animations blends out"/> + <button name="play_btn" tool_tip="Play your animation"/> + <button name="pause_btn" tool_tip="Pause your animation"/> + <button name="stop_btn" tool_tip="Stop animation playback"/> + <text name="bad_animation_text"> + Unable to read animation file. + +We recommend BVH files exported from Poser 4. + </text> + <button label="上傳(L$[AMOUNT])" name="ok_btn"/> + <button label="å–銷" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_auction.xml b/indra/newview/skins/default/xui/zh/floater_auction.xml new file mode 100644 index 0000000000..eb1c9e55dc --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_auction.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_auction" title="START LINDEN LAND SALE"> + <floater.string name="already for sale"> + You cannot auction parcels which are already for sale. + </floater.string> + <check_box initial_value="true" label="Include yellow selection fence" name="fence_check"/> + <button label="Snapshot" label_selected="Snapshot" name="snapshot_btn"/> + <button label="Sell to Anyone" label_selected="Sell to Anyone" name="sell_to_anyone_btn"/> + <button label="Clear Settings" label_selected="Clear Settings" name="reset_parcel_btn"/> + <button label="Start Auction" label_selected="Start Auction" name="start_auction_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_avatar_picker.xml b/indra/newview/skins/default/xui/zh/floater_avatar_picker.xml new file mode 100644 index 0000000000..2ffcaf5b55 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_avatar_picker.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="avatarpicker" title="挑é¸å±…æ°‘"> + <floater.string name="not_found"> + '[TEXT]' not found + </floater.string> + <floater.string name="no_one_near"> + No one near + </floater.string> + <floater.string name="no_results"> + No results + </floater.string> + <floater.string name="searching"> + Searching... + </floater.string> + <string name="Select"> + Select + </string> + <string name="Close"> + 關閉 + </string> + <tab_container name="ResidentChooserTabs"> + <panel label="Search" name="SearchPanel"> + <text name="InstructSearchResidentName"> + Type part of a person's name: + </text> + <button label="Go" label_selected="Go" name="Find"/> + <scroll_list name="SearchResults"> + <columns label="å稱" name="name"/> + <columns label="Username" name="username"/> + </scroll_list> + </panel> + <panel label="Friends" name="FriendsPanel"> + <text name="InstructSelectFriend"> + é¸æ“‡ä¸€å€‹äººï¼š + </text> + </panel> + <panel label="接近我" name="NearMePanel"> + <text name="InstructSelectResident"> + Select a person nearby: + </text> + <slider label="Range" name="near_me_range"/> + <text name="meters"> + Meters + </text> + <scroll_list name="NearMe"> + <columns label="å稱" name="name"/> + <columns label="Username" name="username"/> + </scroll_list> + </panel> + </tab_container> + <button label="確定" label_selected="確定" name="ok_btn"/> + <button label="å–銷" label_selected="å–銷" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_avatar_textures.xml b/indra/newview/skins/default/xui/zh/floater_avatar_textures.xml new file mode 100644 index 0000000000..f895fa2e9d --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_avatar_textures.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="avatar_texture_debug" title="AVATAR TEXTURES"> + <floater.string name="InvalidAvatar"> + INVALID AVATAR + </floater.string> + <scroll_container name="profile_scroll"> + <panel name="scroll_content_panel"> + <text name="label"> + Baked +Textures + </text> + <text name="composite_label"> + Composite +Textures + </text> + <button label="Dump IDs to Console" label_selected="Dump" name="Dump"/> + <panel name="scroll_content_panel"> + <texture_picker label="Hair" name="hair-baked"/> + <texture_picker label="Hair" name="hair_grain"/> + <texture_picker label="Hair Alpha" name="hair_alpha"/> + <texture_picker label="Head" name="head-baked"/> + <texture_picker label="Makeup" name="head_bodypaint"/> + <texture_picker label="Head Alpha" name="head_alpha"/> + <texture_picker label="Head Tattoo" name="head_tattoo"/> + <texture_picker label="眼ç›" name="eyes-baked"/> + <texture_picker label="Eye" name="eyes_iris"/> + <texture_picker label="Eyes Alpha" name="eyes_alpha"/> + <texture_picker label="Upper Body" name="upper-baked"/> + <texture_picker label="Upper BodyPaint" name="upper_bodypaint"/> + <texture_picker label="內衣" name="upper_undershirt"/> + <texture_picker label="手套" name="upper_gloves"/> + <texture_picker label="襯衫" name="upper_shirt"/> + <texture_picker label="Upper Jacket" name="upper_jacket"/> + <texture_picker label="Upper Alpha" name="upper_alpha"/> + <texture_picker label="Upper Tattoo" name="upper_tattoo"/> + <texture_picker label="Lower Body" name="lower-baked"/> + <texture_picker label="Lower BodyPaint" name="lower_bodypaint"/> + <texture_picker label="內褲" name="lower_underpants"/> + <texture_picker label="襪å" name="lower_socks"/> + <texture_picker label="éž‹å" name="lower_shoes"/> + <texture_picker label="褲å" name="lower_pants"/> + <texture_picker label="夾克" name="lower_jacket"/> + <texture_picker label="Lower Alpha" name="lower_alpha"/> + <texture_picker label="Lower Tattoo" name="lower_tattoo"/> + <texture_picker label="裙å" name="skirt-baked"/> + <texture_picker label="裙å" name="skirt"/> + </panel> + </panel> + </scroll_container> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_beacons.xml b/indra/newview/skins/default/xui/zh/floater_beacons.xml new file mode 100644 index 0000000000..1613b23e75 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_beacons.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="beacons" title="BEACONS"> + <panel name="beacons_panel"> + <text name="label_show"> + Show : + </text> + <check_box label="Beacons" name="beacons"/> + <check_box label="Highlights" name="highlights"/> + <text name="beacon_width_label" tool_tip="Beacon width"> + Width: + </text> + <text name="label_objects"> + For these objects: + </text> + <check_box label="Physical" name="physical"/> + <check_box label="Scripted" name="scripted"/> + <check_box label="Touch only" name="touch_only"/> + <check_box label="Sound sources" name="sounds"/> + <check_box label="Particle sources" name="particles"/> + <check_box label="Media sources" name="moapbeacon"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_build_options.xml b/indra/newview/skins/default/xui/zh/floater_build_options.xml new file mode 100644 index 0000000000..95211b746c --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_build_options.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="build options floater" title="æ ¼ç·šé¸é …"> + <spinner label="æ ¼ç·šå–®ä½ï¼ˆå…¬å°ºï¼‰" name="GridResolution"/> + <spinner label="Grid Extents (meters)" name="GridDrawSize"/> + <check_box label="貼齊至åå–®ä½" name="GridSubUnit"/> + <check_box label="View cross-sections" name="GridCrossSection"/> + <text name="grid_opacity_label" tool_tip="Grid opacity"> + Opacity: + </text> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_bulk_perms.xml b/indra/newview/skins/default/xui/zh/floater_bulk_perms.xml new file mode 100644 index 0000000000..98fa6804ba --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_bulk_perms.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floaterbulkperms" title="EDIT CONTENT PERMISSIONS"> + <floater.string name="nothing_to_modify_text"> + Selection contains no editable contents. + </floater.string> + <floater.string name="status_text"> + Setting permissions on [NAME] + </floater.string> + <floater.string name="start_text"> + Starting permission change requests... + </floater.string> + <floater.string name="done_text"> + Finished permission change requests. + </floater.string> + <icon name="icon_animation" tool_tip="Animation"/> + <icon name="icon_bodypart" tool_tip="Body Parts"/> + <icon name="icon_clothing" tool_tip="Clothing"/> + <icon name="icon_gesture" tool_tip="Gestures"/> + <icon name="icon_notecard" tool_tip="Notecards"/> + <icon name="icon_object" tool_tip="Objects"/> + <icon name="icon_script" tool_tip="Scripts"/> + <icon name="icon_sound" tool_tip="Sounds"/> + <icon name="icon_texture" tool_tip="Textures"/> + <button label="√ All" name="check_all"/> + <button label="清除" label_selected="ç„¡" name="check_none"/> + <text name="newperms"> + New Content Permissions + </text> + <text name="GroupLabel"> + Group: + </text> + <check_box label="分享" name="share_with_group"/> + <text name="AnyoneLabel"> + 任何人: + </text> + <check_box label="覆製" name="everyone_copy"/> + <text name="NextOwnerLabel"> + 下一個æ“有者: + </text> + <check_box label="修改" name="next_owner_modify"/> + <check_box label="覆製" name="next_owner_copy"/> + <check_box initial_value="true" label="轉移" name="next_owner_transfer" tool_tip="Next owner can give away or resell this object"/> + <button label="確定" name="apply"/> + <button label="å–銷" name="close"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_bumps.xml b/indra/newview/skins/default/xui/zh/floater_bumps.xml new file mode 100644 index 0000000000..d2b7494b08 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_bumps.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_bumps" title="BUMPS, PUSHES & HITS"> + <floater.string name="none_detected"> + None detected + </floater.string> + <floater.string name="bump"> + [TIME] [NAME] bumped you + </floater.string> + <floater.string name="llpushobject"> + [TIME] [NAME] pushed you with a script + </floater.string> + <floater.string name="selected_object_collide"> + [TIME] [NAME] hit you with an object + </floater.string> + <floater.string name="scripted_object_collide"> + [TIME] [NAME] hit you with a scripted object + </floater.string> + <floater.string name="physical_object_collide"> + [TIME] [NAME] hit you with a physical object + </floater.string> + <floater.string name="timeStr"> + [[hour,datetime,slt]:[min,datetime,slt]] + </floater.string> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_buy_contents.xml b/indra/newview/skins/default/xui/zh/floater_buy_contents.xml new file mode 100644 index 0000000000..de3c0aa075 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_buy_contents.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_buy_contents" title="BUY CONTENTS"> + <floater.string name="no_copy_text"> + (no copy) + </floater.string> + <floater.string name="no_modify_text"> + (no modify) + </floater.string> + <floater.string name="no_transfer_text"> + (no transfer) + </floater.string> + <text name="contains_text"> + [NAME] contains: + </text> + <text name="buy_text"> + Buy for L$[AMOUNT] from [NAME]? + </text> + <check_box label="Wear clothing now" name="wear_check"/> + <button label="購買" label_selected="購買" name="buy_btn"/> + <button label="å–銷" label_selected="å–銷" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_buy_currency.xml b/indra/newview/skins/default/xui/zh/floater_buy_currency.xml new file mode 100644 index 0000000000..bebc17a5cc --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_buy_currency.xml @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="buy currency" title="購買 L$"> + <floater.string name="buy_currency"> + Buy L$ [LINDENS] for approx. [LOCALAMOUNT] + </floater.string> + <text name="info_need_more"> + ä½ éœ€è¦æ›´å¤š L$ + </text> + <text name="contacting"> + Contacting LindeX... + </text> + <text name="info_buying"> + 購買 L$ + </text> + <text name="balance_label"> + 我有 + </text> + <text name="balance_amount"> + L$ [AMT] + </text> + <text name="currency_action"> + 我想購買 + </text> + <text name="currency_label"> + L$ + </text> + <line_editor label="L$" name="currency_amt"> + 1234 + </line_editor> + <text name="buying_label"> + For the price + </text> + <text name="currency_est"> + approx. [LOCALAMOUNT] + </text> + <text name="getting_data"> + Estimating... + </text> + <text name="buy_action"> + [ACTION] + </text> + <text name="total_label"> + My new balance will be + </text> + <text name="total_amount"> + L$ [AMT] + </text> + <text name="currency_links"> + [http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency] | [http://www.secondlife.com/my/account/exchange_rates.php exchange rate] + </text> + <text name="exchange_rate_note"> + Re-enter amount to see the latest exchange rate. + </text> + <text name="purchase_warning_repurchase"> + Confirming this purchase only buys L$, not the object. + </text> + <text name="purchase_warning_notenough"> + You aren't buying enough L$. Please increase the amount. + </text> + <button label="ç«‹å³è³¼è²·" name="buy_btn"/> + <button label="å–銷" name="cancel_btn"/> + <text name="info_cannot_buy"> + Unable to Buy + </text> + <button label="Continue to the Web" name="error_web"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_buy_currency_html.xml b/indra/newview/skins/default/xui/zh/floater_buy_currency_html.xml new file mode 100644 index 0000000000..ec700ad7af --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_buy_currency_html.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_buy_currency_html" title="購買貨幣"/> diff --git a/indra/newview/skins/default/xui/zh/floater_buy_land.xml b/indra/newview/skins/default/xui/zh/floater_buy_land.xml new file mode 100644 index 0000000000..d665a16639 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_buy_land.xml @@ -0,0 +1,233 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="buy land" title="購買土地"> + <floater.string name="can_resell"> + May be resold. + </floater.string> + <floater.string name="can_not_resell"> + May not be resold. + </floater.string> + <floater.string name="can_change"> + May be joined or subdivided. + </floater.string> + <floater.string name="can_not_change"> + May not be joined or subdivided. + </floater.string> + <floater.string name="cant_buy_for_group"> + You do not have permission to buy land for your active group. + </floater.string> + <floater.string name="no_land_selected"> + No land selected. + </floater.string> + <floater.string name="multiple_parcels_selected"> + Multiple different parcels selected. +Try selecting a smaller area. + </floater.string> + <floater.string name="no_permission"> + You do not have permission to buy land for your active group. + </floater.string> + <floater.string name="parcel_not_for_sale"> + The selected parcel is not for sale. + </floater.string> + <floater.string name="group_already_owns"> + The group already owns the parcel. + </floater.string> + <floater.string name="you_already_own"> + You already own the parcel. + </floater.string> + <floater.string name="set_to_sell_to_other"> + The selected parcel is set to sell to another party. + </floater.string> + <floater.string name="no_public_land"> + The selected area has no public land. + </floater.string> + <floater.string name="not_owned_by_you"> + Land owned by another Resident is selected. +Try selecting a smaller area. + </floater.string> + <floater.string name="processing"> + Processing your purchase... + +(This may take a minute or two.) + </floater.string> + <floater.string name="fetching_error"> + There has been an error while fetching land buying information. + </floater.string> + <floater.string name="buying_will"> + Buying this land will: + </floater.string> + <floater.string name="buying_for_group"> + Buying land for group will: + </floater.string> + <floater.string name="cannot_buy_now"> + Cannot buy now: + </floater.string> + <floater.string name="not_for_sale"> + Not for sale: + </floater.string> + <floater.string name="none_needed"> + none needed + </floater.string> + <floater.string name="must_upgrade"> + Your account must be upgraded to own land. + </floater.string> + <floater.string name="cant_own_land"> + Your account can own land. + </floater.string> + <floater.string name="land_holdings"> + You hold [BUYER] m² of land. + </floater.string> + <floater.string name="pay_to_for_land"> + Pay L$ [AMOUNT] to [SELLER] for this land + </floater.string> + <floater.string name="buy_for_US"> + Buy L$ [AMOUNT] for approx. [LOCAL_AMOUNT], + </floater.string> + <floater.string name="parcel_meters"> + This parcel is [AMOUNT] m² + </floater.string> + <floater.string name="premium_land"> + This land is premium, and will charge as [AMOUNT] m². + </floater.string> + <floater.string name="discounted_land"> + This land is discounted, and will charge as [AMOUNT] m². + </floater.string> + <floater.string name="meters_supports_object"> + [AMOUNT] m² +supports [AMOUNT2] objects + </floater.string> + <floater.string name="sold_with_objects"> + sold with objects + </floater.string> + <floater.string name="sold_without_objects"> + objects not included + </floater.string> + <floater.string name="info_price_string"> + L$ [PRICE] +(L$ [PRICE_PER_SQM]/m²) +[SOLD_WITH_OBJECTS] + </floater.string> + <floater.string name="insufficient_land_credits"> + The group [GROUP] will need sufficient contributed land use credits to cover this parcel before the purchase will complete. + </floater.string> + <floater.string name="have_enough_lindens"> + You have L$ [AMOUNT], which is enough to buy this land. + </floater.string> + <floater.string name="not_enough_lindens"> + You have only L$ [AMOUNT], and need L$ [AMOUNT2] more. + </floater.string> + <floater.string name="balance_left"> + After the purchase, you will have L$ [AMOUNT] left. + </floater.string> + <floater.string name="balance_needed"> + You need to buy at least L$ [AMOUNT] to afford this land. + </floater.string> + <floater.string name="no_parcel_selected"> + (no parcel selected) + </floater.string> + <text name="region_name_label"> + 地å€ï¼š + </text> + <text name="region_name_text"> + (未知) + </text> + <text name="region_type_label"> + 類型: + </text> + <text name="region_type_text"> + (未知) + </text> + <text name="estate_name_label"> + é ˜åœ°ï¼š + </text> + <text name="estate_name_text"> + (未知) + </text> + <text name="estate_owner_label"> + é ˜åœ°æ“有者: + </text> + <text name="estate_owner_text"> + (未知) + </text> + <text name="resellable_changeable_label"> + Purchased land in this region: + </text> + <text name="resellable_clause"> + May or may not be resold. + </text> + <text name="changeable_clause"> + May or may not be joined or subdivided. + </text> + <text name="covenant_text"> + You must agree to the Estate Covenant: + </text> + <text_editor name="covenant_editor"> + 載入ä¸... + </text_editor> + <check_box label="I Agree to the Covenant Defined Above." name="agree_covenant"/> + <text name="info_parcel_label"> + 地段: + </text> + <text name="info_parcel"> + Scotopteryx 138,204 + </text> + <text name="info_size_label"> + Size: + </text> + <text name="info_size"> + 1024 m² + </text> + <text name="info_price_label"> + åƒ¹æ ¼ï¼š + </text> + <text name="info_price"> + L$ 1500 +(L$ 1.1/m²) +sold with objects + </text> + <text name="info_action"> + Buying this land will: + </text> + <text name="error_message"> + Something ain't right. + </text> + <button label="Go to website" name="error_web"/> + <text name="account_action"> + Upgrade you to premium membership. + </text> + <text name="account_reason"> + Only premimum members may own land. + </text> + <combo_box name="account_level"> + <combo_box.item label="US$9.95/month, billed monthly" name="US$9.95/month,billedmonthly"/> + <combo_box.item label="US$7.50/month, billed quarterly" name="US$7.50/month,billedquarterly"/> + <combo_box.item label="US$6.00/month, billed annually" name="US$6.00/month,billedannually"/> + </combo_box> + <text name="land_use_action"> + Increase your monthly land use fees to US$ 40/month. + </text> + <text name="land_use_reason"> + You hold 1309 m² of land. +This parcel is 512 m² of land. + </text> + <text name="purchase_action"> + Pay Joe Resident L$ 4000 for the land + </text> + <text name="currency_reason"> + You have L$ 2,100. + </text> + <text name="currency_action"> + Buy additional L$ + </text> + <line_editor name="currency_amt"> + 1000 + </line_editor> + <text name="currency_est"> + for approx. [LOCAL_AMOUNT] + </text> + <text name="currency_balance"> + You have L$ 2,100. + </text> + <check_box label="Remove [AMOUNT] m² of contribution from group." name="remove_contribution"/> + <button label="Purchase" name="buy_btn"/> + <button label="å–銷" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_buy_object.xml b/indra/newview/skins/default/xui/zh/floater_buy_object.xml new file mode 100644 index 0000000000..559982b6c9 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_buy_object.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="contents" title="BUY COPY OF OBJECT"> + <floater.string name="title_buy_text"> + 購買 + </floater.string> + <floater.string name="title_buy_copy_text"> + Buy a copy of + </floater.string> + <floater.string name="no_copy_text"> + (no copy) + </floater.string> + <floater.string name="no_modify_text"> + (no modify) + </floater.string> + <floater.string name="no_transfer_text"> + (no transfer) + </floater.string> + <text name="contents_text"> + Contains: + </text> + <text name="buy_text"> + Buy for L$[AMOUNT] from: + </text> + <text name="buy_name_text"> + [NAME]? + </text> + <button label="購買" label_selected="購買" name="buy_btn"/> + <button label="å–銷" label_selected="å–銷" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_camera.xml b/indra/newview/skins/default/xui/zh/floater_camera.xml new file mode 100644 index 0000000000..65d04583f5 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_camera.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="camera_floater"> + <floater.string name="rotate_tooltip"> + Rotate Camera Around Focus + </floater.string> + <floater.string name="zoom_tooltip"> + Zoom Camera Towards Focus + </floater.string> + <floater.string name="move_tooltip"> + Move Camera Up and Down, Left and Right + </floater.string> + <floater.string name="camera_modes_title"> + Camera modes + </floater.string> + <floater.string name="pan_mode_title"> + Orbit Zoom Pan + </floater.string> + <floater.string name="presets_mode_title"> + Preset Views + </floater.string> + <floater.string name="free_mode_title"> + View Object + </floater.string> + <panel name="controls"> + <panel name="preset_views_list"> + <panel_camera_item name="front_view"> + <panel_camera_item.text name="front_view_text"> + Front View + </panel_camera_item.text> + </panel_camera_item> + <panel_camera_item name="group_view"> + <panel_camera_item.text name="side_view_text"> + Side View + </panel_camera_item.text> + </panel_camera_item> + <panel_camera_item name="rear_view"> + <panel_camera_item.text name="rear_view_text"> + Rear View + </panel_camera_item.text> + </panel_camera_item> + </panel> + <panel name="camera_modes_list"> + <panel_camera_item name="object_view"> + <panel_camera_item.text name="object_view_text"> + Object View + </panel_camera_item.text> + </panel_camera_item> + <panel_camera_item name="mouselook_view"> + <panel_camera_item.text name="mouselook_view_text"> + Mouselook View + </panel_camera_item.text> + </panel_camera_item> + </panel> + <panel name="zoom"> + <joystick_rotate name="cam_rotate_stick" tool_tip="Orbit camera around focus"/> + <slider_bar name="zoom_slider" tool_tip="Zoom camera toward focus"/> + <joystick_track name="cam_track_stick" tool_tip="Move camera up and down, left and right"/> + </panel> + </panel> + <panel name="buttons"> + <button label="" name="presets_btn" tool_tip="Preset Views"/> + <button label="" name="pan_btn" tool_tip="Orbit Zoom Pan"/> + <button label="" name="avatarview_btn" tool_tip="Camera modes"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_choose_group.xml b/indra/newview/skins/default/xui/zh/floater_choose_group.xml new file mode 100644 index 0000000000..ec67f8d4fa --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_choose_group.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="groups" title="GROUPS"> + <text name="groupdesc"> + Choose a group: + </text> + <button label="確定" label_selected="確定" name="OK"/> + <button label="å–銷" label_selected="å–銷" name="Cancel"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_color_picker.xml b/indra/newview/skins/default/xui/zh/floater_color_picker.xml new file mode 100644 index 0000000000..df9c780cbf --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_color_picker.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="ColorPicker" title="COLOR PICKER"> + <text name="r_val_text"> + Red: + </text> + <text name="g_val_text"> + Green: + </text> + <text name="b_val_text"> + Blue: + </text> + <text name="h_val_text"> + Hue: + </text> + <text name="s_val_text"> + Sat: + </text> + <text name="l_val_text"> + Lum: + </text> + <check_box label="ç«‹å³å¥—用" name="apply_immediate"/> + <button label="確定" label_selected="確定" name="select_btn"/> + <button label="å–銷" label_selected="å–銷" name="cancel_btn"/> + <text name="Current color:"> + Current color: + </text> + <text name="(Drag below to save.)"> + (Drag below to save) + </text> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_critical.xml b/indra/newview/skins/default/xui/zh/floater_critical.xml new file mode 100644 index 0000000000..da357bde56 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_critical.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="modal container"> + <button label="繼續" label_selected="繼續" name="Continue"/> + <text name="tos_heading"> + Please read the following message carefully. + </text> + <text_editor name="tos_text"> + TOS_TEXT + </text_editor> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_day_cycle_options.xml b/indra/newview/skins/default/xui/zh/floater_day_cycle_options.xml new file mode 100644 index 0000000000..c6ab787625 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_day_cycle_options.xml @@ -0,0 +1,95 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Day Cycle Floater" title="DAY CYCLE EDITOR"> + <tab_container name="Day Cycle Tabs"> + <panel label="Day Cycle" name="Day Cycle"> + <multi_slider initial_value="0" name="WLTimeSlider"/> + <multi_slider initial_value="0" name="WLDayCycleKeys"/> + <text name="WL12am"> + 12am + </text> + <text name="WL3am"> + 3am + </text> + <text name="WL6am"> + 6am + </text> + <text name="WL9amHash"> + 9am + </text> + <text name="WL12pmHash"> + 12pm + </text> + <text name="WL3pm"> + 3pm + </text> + <text name="WL6pm"> + 6pm + </text> + <text name="WL9pm"> + 9pm + </text> + <text name="WL12am2"> + 12am + </text> + <text name="WL12amHash"> + | + </text> + <text name="WL3amHash"> + I + </text> + <text name="WL6amHash"> + | + </text> + <text name="WL9amHash2"> + I + </text> + <text name="WL12pmHash2"> + | + </text> + <text name="WL3pmHash"> + I + </text> + <text name="WL6pmHash"> + | + </text> + <text name="WL9pmHash"> + I + </text> + <text name="WL12amHash2"> + | + </text> + <button label="Add Key" label_selected="Add Key" name="WLAddKey"/> + <button label="Delete Key" label_selected="Delete Key" name="WLDeleteKey"/> + <text name="WLCurKeyFrameText"> + Key Frame Settings: + </text> + <text name="WLCurKeyTimeText"> + Key Time: + </text> + <spinner label="Hour" name="WLCurKeyHour"/> + <spinner label="Min" name="WLCurKeyMin"/> + <text name="WLCurKeyTimeText2"> + Key Preset: + </text> + <combo_box label="Preset" name="WLKeyPresets"/> + <text name="DayCycleText"> + Snap: + </text> + <combo_box label="五分é˜" name="WLSnapOptions"/> + <text name="DayCycleText2"> + Length of Cycle: + </text> + <spinner label="å°æ™‚" name="WLLengthOfDayHour"/> + <spinner label="分" name="WLLengthOfDayMin"/> + <spinner label="秒" name="WLLengthOfDaySec"/> + <text name="DayCycleText3"> + é 覽: + </text> + <button label="Play" label_selected="Play" name="WLAnimSky"/> + <button label="Stop!" label_selected="Stop" name="WLStopAnimSky"/> + <button label="Use Estate Time" label_selected="Go to Estate Time" name="WLUseLindenTime"/> + <button label="Save Test Day" label_selected="Save Test Day" name="WLSaveDayCycle"/> + <button label="Load Test Day" label_selected="Load Test Day" name="WLLoadDayCycle"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_display_name.xml b/indra/newview/skins/default/xui/zh/floater_display_name.xml new file mode 100644 index 0000000000..5a89ecaa82 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_display_name.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Display Name" title="CHANGE DISPLAY NAME"> + <text name="info_text"> + The name you give your avatar is called your Display Name. You can change it once a week. + </text> + <text name="lockout_text"> + You cannot change your Display Name until: [TIME]. + </text> + <text name="set_name_label"> + New Display Name: + </text> + <text name="name_confirm_label"> + Type your new name again to confirm: + </text> + <button label="儲å˜" name="save_btn" tool_tip="Save your new Display Name"/> + <button label="Reset" name="reset_btn" tool_tip="Make Display Name the same as Username"/> + <button label="å–銷" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_env_settings.xml b/indra/newview/skins/default/xui/zh/floater_env_settings.xml new file mode 100644 index 0000000000..65a97f0cff --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_env_settings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Environment Editor Floater" title="ENVIRONMENT EDITOR"> + <floater.string name="timeStr"> + [hour12,datetime,utc]:[min,datetime,utc] [ampm,datetime,utc] + </floater.string> + <text name="EnvTimeText"> + Time of Day + </text> + <text name="EnvTimeText2"> + 12:00 PM + </text> + <text name="EnvCloudText"> + Cloud Cover + </text> + <text name="EnvWaterColorText"> + Water Color + </text> + <color_swatch name="EnvWaterColor" tool_tip="Click to open color picker"/> + <text name="EnvWaterFogText"> + Water Fog + </text> + <button label="Use Estate Time" name="EnvUseEstateTimeButton"/> + <button label="Advanced Sky" name="EnvAdvancedSkyButton"/> + <button label="Advanced Water" name="EnvAdvancedWaterButton"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_event.xml b/indra/newview/skins/default/xui/zh/floater_event.xml new file mode 100644 index 0000000000..349b5717f2 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_event.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater label="Event" name="Event" title="EVENT DETAILS"> + <floater.string name="loading_text"> + 載入ä¸... + </floater.string> + <floater.string name="done_text"> + Done + </floater.string> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_font_test.xml b/indra/newview/skins/default/xui/zh/floater_font_test.xml new file mode 100644 index 0000000000..ec83c51eb3 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_font_test.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="contents" title="å—型測試"/> diff --git a/indra/newview/skins/default/xui/zh/floater_gesture.xml b/indra/newview/skins/default/xui/zh/floater_gesture.xml new file mode 100644 index 0000000000..22e7451d13 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_gesture.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater label="Places" name="gestures" title="GESTURES"> + <floater.string name="loading"> + 載入ä¸... + </floater.string> + <floater.string name="playing"> + (Playing) + </floater.string> + <floater.string name="copy_name"> + Copy of [COPY_NAME] + </floater.string> + <scroll_list name="gesture_list"> + <scroll_list.columns label="å稱" name="name"/> + <scroll_list.columns label="èŠå¤©" name="trigger"/> + <scroll_list.columns label="Key" name="shortcut"/> + </scroll_list> + <panel label="bottom_panel" name="bottom_panel"> + <menu_button name="gear_btn" tool_tip="More options"/> + <button name="new_gesture_btn" tool_tip="Make new gesture"/> + <button name="activate_btn" tool_tip="Activate/Deactivate selected gesture"/> + <button name="del_btn" tool_tip="Delete this gesture"/> + </panel> + <button label="編輯" name="edit_btn"/> + <button label="Play" name="play_btn"/> + <button label="Stop" name="stop_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_god_tools.xml b/indra/newview/skins/default/xui/zh/floater_god_tools.xml new file mode 100644 index 0000000000..b01d346a64 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_god_tools.xml @@ -0,0 +1,96 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="godtools floater" title="GOD TOOLS"> + <tab_container name="GodTools Tabs"> + <panel label="Grid" name="grid"> + <button label="Flush This Region's Map Visibility Caches" label_selected="Flush This Region's Map Visibility Caches" name="Flush This Region's Map Visibility Caches"/> + </panel> + <panel label="地å€" name="region"> + <text name="Region Name:"> + 地å€å稱: + </text> + <check_box label="Prelude" name="check prelude" tool_tip="Set this to make the region a prelude"/> + <check_box label="Fixed Sun" name="check fixed sun" tool_tip="Fix the sun position (like in Region/Estate > Terrain"/> + <check_box label="Reset Home On Teleport" name="check reset home" tool_tip="When Resident teleports out, reset their home to the destination position."/> + <check_box label="Visible" name="check visible" tool_tip="Set this to make the region visible to non-gods"/> + <check_box label="Damage" name="check damage" tool_tip="Set this to enable damage in this region"/> + <check_box label="Block Traffic Tracking" name="block dwell" tool_tip="Set this to make the region not compute traffic"/> + <check_box label="Block Terraform" name="block terraform" tool_tip="Set this to disallow people terraforming their land"/> + <check_box label="Sandbox" name="is sandbox" tool_tip="Toggle whether this is a sandbox region"/> + <button label="Bake Terrain" label_selected="Bake Terrain" name="Bake Terrain" tool_tip="Save the current terrain as default"/> + <button label="Revert Terrain" label_selected="Revert Terrain" name="Revert Terrain" tool_tip="Replace the current terrain with default"/> + <button label="Swap Terrain" label_selected="Swap Terrain" name="Swap Terrain" tool_tip="Swap current terrain with default"/> + <text name="estate id"> + Estate ID: + </text> + <text name="parent id"> + Parent ID: + </text> + <line_editor name="parentestate" tool_tip="This is the parent estate for this region"/> + <text name="Grid Pos: "> + Grid Pos: + </text> + <line_editor name="gridposx" tool_tip="This is the grid x position for this region"/> + <line_editor name="gridposy" tool_tip="This is the grid y position for this region"/> + <text name="Redirect to Grid: "> + Redirect to Grid: + </text> + <text name="billable factor text"> + Billable Factor: + </text> + <text name="land cost text"> + L$ per m²: + </text> + <button label="Refresh" label_selected="Refresh" name="Refresh" tool_tip="Click here to refresh the above information"/> + <button label="套用" label_selected="套用" name="Apply" tool_tip="Click here to apply any changes from above"/> + <button label="é¸æ“‡åœ°å€" label_selected="é¸æ“‡åœ°å€" name="Select Region" tool_tip="Select the whole region with the land tool"/> + <button label="Autosave now" label_selected="Autosave now" name="Autosave now" tool_tip="Save gzipped state to autosave directory"/> + </panel> + <panel label="Objects" name="objects"> + <panel.string name="no_target"> + (no target) + </panel.string> + <text name="Region Name:"> + 地å€å稱: + </text> + <text name="region name"> + Welsh + </text> + <check_box label="Disable Scripts" name="disable scripts" tool_tip="Set this to disable all scripts in this region"/> + <check_box label="Disable Collisions" name="disable collisions" tool_tip="Set this to disable non-agent collisions in this region"/> + <check_box label="Disable Physics" name="disable physics" tool_tip="Set this to disable all physics in this region"/> + <button label="套用" label_selected="套用" name="Apply" tool_tip="Click here to apply any changes from above"/> + <button label="Set Target" label_selected="Set Target" name="Set Target" tool_tip="Set the target avatar for object deletion"/> + <text name="target_avatar_name"> + (no target) + </text> + <button label="Delete Target's Scripted Objects On Others Land" label_selected="Delete Target's Scripted Objects On Others Land" name="Delete Target's Scripted Objects On Others Land" tool_tip="Delete all scripted objects owned by the target on land not owned by the target. (no copy) objects will be returned."/> + <button label="Delete Target's Scripted Objects On *Any* Land" label_selected="Delete Target's Scripted Objects On *Any* Land" name="Delete Target's Scripted Objects On *Any* Land" tool_tip="Delete all scripted objects owned by the target in this region. (no copy) objects will be returned."/> + <button label="Delete *ALL* Of Target's Objects" label_selected="Delete *ALL* Of Target's Objects" name="Delete *ALL* Of Target's Objects" tool_tip="Delete all objects owned by the target in this region. (no copy) objects will be returned."/> + <button label="Get Top Colliders" label_selected="Get Top Colliders" name="Get Top Colliders" tool_tip="Gets list of objects experiencing the most narrowphase callbacks"/> + <button label="Get Top Scripts" label_selected="Get Top Scripts" name="Get Top Scripts" tool_tip="Gets list of objects spending the most time running scripts"/> + <button label="Scripts digest" label_selected="Scripts digest" name="Scripts digest" tool_tip="Gets a list of all scripts and number of occurences of each"/> + </panel> + <panel label="Request" name="request"> + <text name="Destination:"> + Destination: + </text> + <combo_box name="destination"> + <combo_box.item label="Selection" name="item1"/> + <combo_box.item label="Agent Region" name="item2"/> + </combo_box> + <text name="Request:"> + Request: + </text> + <combo_box name="request"> + <combo_box.item label="colliders <steps>" name="item1"/> + <combo_box.item label="scripts <count>,<optional pattern>" name="item2"/> + <combo_box.item label="objects <pattern>" name="item3"/> + <combo_box.item label="rez <asset_id>" name="item4"/> + </combo_box> + <text name="Parameter:"> + Parameter: + </text> + <button label="Make Request" label_selected="Make Request" name="Make Request"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_hardware_settings.xml b/indra/newview/skins/default/xui/zh/floater_hardware_settings.xml new file mode 100644 index 0000000000..75403a79dd --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_hardware_settings.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Hardware Settings Floater" title="硬體è¨å®š"> + <text name="Filtering:"> + Filtering: + </text> + <check_box label="Anisotropic Filtering (slower when enabled)" name="ani"/> + <text name="Antialiasing:"> + Antialiasing: + </text> + <combo_box label="Antialiasing" name="fsaa"> + <combo_box.item label="Disabled" name="FSAADisabled"/> + <combo_box.item label="2x" name="2x"/> + <combo_box.item label="4x" name="4x"/> + <combo_box.item label="8x" name="8x"/> + <combo_box.item label="16x" name="16x"/> + </combo_box> + <text name="antialiasing restart"> + ï¼ˆé ˆé‡æ–°å•Ÿå‹•ç€è¦½å™¨ï¼‰ + </text> + <spinner label="Gamma:" name="gamma"/> + <text name="(brightness, lower is brighter)"> + (0 = default brightness, lower = brighter) + </text> + <text name="Enable VBO:"> + Enable VBO: + </text> + <check_box initial_value="true" label="Enable OpenGL Vertex Buffer Objects" name="vbo" tool_tip="Enabling this on modern hardware gives a performance gain. However, older hardware often has poor implementations of VBOs and you may get crashes when this is enabled."/> + <slider label="Texture Memory (MB):" name="GraphicsCardTextureMemory" tool_tip="Amount of memory to allocate for textures. Defaults to video card memory. Reducing this may improve performance but may also make textures blurry."/> + <spinner label="Fog Distance Ratio:" name="fog"/> + <button label="確定" label_selected="確定" name="OK"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_help_browser.xml b/indra/newview/skins/default/xui/zh/floater_help_browser.xml new file mode 100644 index 0000000000..957c37bd63 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_help_browser.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_help_browser" title="HELP BROWSER"> + <floater.string name="loading_text"> + 載入ä¸... + </floater.string> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_hud.xml b/indra/newview/skins/default/xui/zh/floater_hud.xml new file mode 100644 index 0000000000..e458913452 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_hud.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_hud" title="TUTORIAL"/> diff --git a/indra/newview/skins/default/xui/zh/floater_im_container.xml b/indra/newview/skins/default/xui/zh/floater_im_container.xml new file mode 100644 index 0000000000..5ea073365e --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_im_container.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<multi_floater name="floater_im_box" title="CONVERSATIONS"/> diff --git a/indra/newview/skins/default/xui/zh/floater_im_session.xml b/indra/newview/skins/default/xui/zh/floater_im_session.xml new file mode 100644 index 0000000000..e8db97560e --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_im_session.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="panel_im"> + <layout_stack name="im_panels"> + <layout_panel> + <line_editor label="To" name="chat_editor"/> + </layout_panel> + </layout_stack> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_image_preview.xml b/indra/newview/skins/default/xui/zh/floater_image_preview.xml new file mode 100644 index 0000000000..92d5c3df73 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_image_preview.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Image Preview"> + <text name="name_label"> + å稱: + </text> + <text name="description_label"> + æ述: + </text> + <text name="preview_label"> + Preview image as: + </text> + <combo_box label="Clothing Type" name="clothing_type_combo"> + <item label="Image" name="Image" value="Image"/> + <item label="Hair" name="Hair" value="Hair"/> + <item label="Female Head" name="FemaleHead" value="Female Head"/> + <item label="Female Upper Body" name="FemaleUpperBody" value="Female Upper Body"/> + <item label="Female Lower Body" name="FemaleLowerBody" value="Female Lower Body"/> + <item label="Male Head" name="MaleHead" value="Male Head"/> + <item label="Male Upper Body" name="MaleUpperBody" value="Male Upper Body"/> + <item label="Male Lower Body" name="MaleLowerBody" value="Male Lower Body"/> + <item label="裙å" name="Skirt" value="裙å"/> + <item label="Sculpted Prim" name="SculptedPrim" value="Sculpted Prim"/> + </combo_box> + <text name="bad_image_text"> + Unable to read image. + +Try saving image as 24 bit Targa (.tga). + </text> + <check_box label="Use lossless compression" name="lossless_check"/> + <button label="å–銷" name="cancel_btn"/> + <button label="Upload (L$[AMOUNT])" name="ok_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_incoming_call.xml b/indra/newview/skins/default/xui/zh/floater_incoming_call.xml new file mode 100644 index 0000000000..9ca08c06b1 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_incoming_call.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="incoming call" title="Incoming call"> + <floater.string name="lifetime"> + 5 + </floater.string> + <floater.string name="localchat"> + Nearby Voice Chat + </floater.string> + <floater.string name="anonymous"> + anonymous + </floater.string> + <floater.string name="VoiceInviteP2P"> + is calling. + </floater.string> + <floater.string name="VoiceInviteAdHoc"> + has joined a Voice Chat call with a conference chat. + </floater.string> + <floater.string name="VoiceInviteGroup"> + just joined '[GROUP]' voice channel. + </floater.string> + <floater.string name="VoiceInviteQuestionGroup"> + Would you like to leave [CURRENT_CHAT] and join the call with '[GROUP]'? + </floater.string> + <floater.string name="VoiceInviteQuestionDefault"> + Do you want to leave [CURRENT_CHAT] and join this voice chat? + </floater.string> + <text name="question"> + Do you want to leave [CURRENT_CHAT] and join this voice chat? + </text> + <button label="接å—" label_selected="接å—" name="Accept"/> + <button label="Reject" label_selected="Reject" name="Reject"/> + <button label="Start IM" name="Start IM"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_inspect.xml b/indra/newview/skins/default/xui/zh/floater_inspect.xml new file mode 100644 index 0000000000..7f23bba37a --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_inspect.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="inspect" title="INSPECT OBJECTS"> + <floater.string name="timeStamp"> + [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] + </floater.string> + <scroll_list name="object_list" tool_tip="Select an object from this list to highlight it in-world"> + <scroll_list.columns label="物件å稱" name="object_name"/> + <scroll_list.columns label="Owner Name" name="owner_name"/> + <scroll_list.columns label="Creator Name" name="creator_name"/> + <scroll_list.columns label="Creation Date" name="creation_date"/> + </scroll_list> + <button label="See Owner Profile..." name="button owner" tool_tip="See profile of the highlighted object's owner"/> + <button label="See Creator Profile..." name="button creator" tool_tip="See profile of the highlighted object's original creator"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_inventory.xml b/indra/newview/skins/default/xui/zh/floater_inventory.xml new file mode 100644 index 0000000000..93cd681126 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_inventory.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Inventory" title="MY INVENTORY"> + <panel label="Inventory Panel" name="Inventory Panel"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/zh/floater_inventory_item_properties.xml new file mode 100644 index 0000000000..4fac10df81 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_inventory_item_properties.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="item properties" title="INVENTORY ITEM PROPERTIES"> + <floater.string name="unknown"> + (未知) + </floater.string> + <floater.string name="public"> + (公開) + </floater.string> + <floater.string name="you_can"> + ä½ å¯ä»¥ï¼š + </floater.string> + <floater.string name="owner_can"> + æ“有者å¯ä»¥ï¼š + </floater.string> + <floater.string name="acquiredDate"> + [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] + </floater.string> + <text name="LabelItemNameTitle"> + å稱: + </text> + <text name="LabelItemDescTitle"> + æ述: + </text> + <text name="LabelCreatorTitle"> + å‰µé€ è€…ï¼š + </text> + <button label="Profile..." name="BtnCreator"/> + <text name="LabelOwnerTitle"> + æ“有者: + </text> + <button label="Profile..." name="BtnOwner"/> + <text name="LabelAcquiredTitle"> + Acquired: + </text> + <text name="LabelAcquiredDate"> + Wed May 24 12:50:46 2006 + </text> + <text name="OwnerLabel"> + ä½ ï¼š + </text> + <check_box label="編輯" name="CheckOwnerModify"/> + <check_box label="覆製" name="CheckOwnerCopy"/> + <check_box label="轉售" name="CheckOwnerTransfer"/> + <text name="AnyoneLabel"> + 任何人: + </text> + <check_box label="覆製" name="CheckEveryoneCopy"/> + <text name="GroupLabel"> + Group: + </text> + <check_box label="分享" name="CheckShareWithGroup"/> + <text name="NextOwnerLabel"> + 下一個æ“有者: + </text> + <check_box label="編輯" name="CheckNextOwnerModify"/> + <check_box label="覆製" name="CheckNextOwnerCopy"/> + <check_box label="轉售" name="CheckNextOwnerTransfer"/> + <check_box label="出售" name="CheckPurchase"/> + <combo_box name="combobox sale copy"> + <combo_box.item label="副本" name="Copy"/> + <combo_box.item label="原件" name="Original"/> + </combo_box> + <spinner label="åƒ¹æ ¼ï¼š" name="Edit Cost"/> + <text name="CurrencySymbol"> + L$ + </text> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml new file mode 100644 index 0000000000..41ea8dc593 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Inventory Finder" title="INVENTORY_RECENT_ITEMS"> + <check_box label="Animation" name="check_animation"/> + <check_box label="Calling Cards" name="check_calling_card"/> + <check_box label="Clothing" name="check_clothing"/> + <check_box label="Gestures" name="check_gesture"/> + <check_box label="Landmarks" name="check_landmark"/> + <check_box label="Notecards" name="check_notecard"/> + <check_box label="Objects" name="check_object"/> + <check_box label="Scripts" name="check_script"/> + <check_box label="Sounds" name="check_sound"/> + <check_box label="Textures" name="check_texture"/> + <check_box label="Snapshots" name="check_snapshot"/> + <button label="全部" label_selected="全部" name="All"/> + <button label="ç„¡" label_selected="ç„¡" name="None"/> + <check_box label="Always show folders" name="check_show_empty"/> + <check_box label="Since Logoff" name="check_since_logoff"/> + <text name="- OR -"> + - 或 - + </text> + <spinner label="å°æ™‚å‰" name="spin_hours_ago"/> + <spinner label="天å‰" name="spin_days_ago"/> + <button label="關閉" label_selected="關閉" name="Close"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_joystick.xml b/indra/newview/skins/default/xui/zh/floater_joystick.xml new file mode 100644 index 0000000000..91f2bc6d81 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_joystick.xml @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Joystick" title="JOYSTICK CONFIGURATION"> + <floater.string name="NoDevice"> + 未åµæ¸¬åˆ°è¨å‚™ + </floater.string> + <check_box label="Enable Joystick:" name="enable_joystick"/> + <spinner label="X Axis Mapping" name="JoystickAxis1"/> + <spinner label="Y Axis Mapping" name="JoystickAxis2"/> + <spinner label="Z Axis Mapping" name="JoystickAxis0"/> + <spinner label="Pitch Mapping" name="JoystickAxis4"/> + <spinner label="Yaw Mapping" name="JoystickAxis5"/> + <spinner label="Roll Mapping" name="JoystickAxis3"/> + <spinner label="Zoom Mapping" name="JoystickAxis6"/> + <check_box label="Direct Zoom" name="ZoomDirect"/> + <check_box label="3D Cursor" name="Cursor3D"/> + <check_box label="Auto Level" name="AutoLeveling"/> + <text name="Control Modes:"> + Control Modes: + </text> + <check_box label="Avatar" name="JoystickAvatarEnabled"/> + <check_box label="Build" name="JoystickBuildEnabled"/> + <check_box label="Flycam" name="JoystickFlycamEnabled"/> + <stat_view label="Joystick Monitor" name="axis_view"> + <stat_bar label="Axis 0" name="axis0"/> + <stat_bar label="Axis 1" name="axis1"/> + <stat_bar label="Axis 2" name="axis2"/> + <stat_bar label="Axis 3" name="axis3"/> + <stat_bar label="Axis 4" name="axis4"/> + <stat_bar label="Axis 5" name="axis5"/> + </stat_view> + <text name="XScale"> + X Scale + </text> + <text name="YScale"> + Y Scale + </text> + <text name="ZScale"> + Z Scale + </text> + <text name="PitchScale"> + Pitch Scale + </text> + <text name="YawScale"> + Yaw Scale + </text> + <text name="RollScale"> + Roll Scale + </text> + <text name="XDeadZone"> + X Dead Zone + </text> + <text name="YDeadZone"> + Y Dead Zone + </text> + <text name="ZDeadZone"> + Z Dead Zone + </text> + <text name="PitchDeadZone"> + Pitch Dead Zone + </text> + <text name="YawDeadZone"> + Yaw Dead Zone + </text> + <text name="RollDeadZone"> + Roll Dead Zone + </text> + <text name="Feathering"> + Feathering + </text> + <text name="ZoomScale2"> + Zoom Scale + </text> + <text name="ZoomDeadZone"> + Zoom Dead Zone + </text> + <button label="SpaceNavigator Defaults" name="SpaceNavigatorDefaults"/> + <button label="確定" label_selected="確定" name="ok_btn"/> + <button label="å–銷" label_selected="å–銷" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_lagmeter.xml b/indra/newview/skins/default/xui/zh/floater_lagmeter.xml new file mode 100644 index 0000000000..4ff6c45b17 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_lagmeter.xml @@ -0,0 +1,151 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_lagmeter" title="LAG METER"> + <floater.string name="max_title_msg"> + Lag Meter + </floater.string> + <floater.string name="max_width_px"> + 360 + </floater.string> + <floater.string name="min_title_msg"> + Lag + </floater.string> + <floater.string name="min_width_px"> + 90 + </floater.string> + <floater.string name="client_text_msg"> + Client + </floater.string> + <floater.string name="client_frame_rate_critical_fps"> + 10 + </floater.string> + <floater.string name="client_frame_rate_warning_fps"> + 15 + </floater.string> + <floater.string name="client_frame_time_window_bg_msg"> + Normal, window in background + </floater.string> + <floater.string name="client_frame_time_critical_msg"> + Client frame rate below [CLIENT_FRAME_RATE_CRITICAL] + </floater.string> + <floater.string name="client_frame_time_warning_msg"> + Client frame rate between [CLIENT_FRAME_RATE_CRITICAL] and [CLIENT_FRAME_RATE_WARNING] + </floater.string> + <floater.string name="client_frame_time_normal_msg"> + Normal + </floater.string> + <floater.string name="client_draw_distance_cause_msg"> + Possible cause: Draw distance set too high + </floater.string> + <floater.string name="client_texture_loading_cause_msg"> + Possible cause: Images loading + </floater.string> + <floater.string name="client_texture_memory_cause_msg"> + Possible cause: Too many images in memory + </floater.string> + <floater.string name="client_complex_objects_cause_msg"> + Possible cause: Too many complex objects in scene + </floater.string> + <floater.string name="network_text_msg"> + Network + </floater.string> + <floater.string name="network_packet_loss_critical_pct"> + 10 + </floater.string> + <floater.string name="network_packet_loss_warning_pct"> + 5 + </floater.string> + <floater.string name="network_packet_loss_critical_msg"> + Connection is dropping over [NETWORK_PACKET_LOSS_CRITICAL]% of packets + </floater.string> + <floater.string name="network_packet_loss_warning_msg"> + Connection is dropping [NETWORK_PACKET_LOSS_WARNING]%-[NETWORK_PACKET_LOSS_CRITICAL]% of packets + </floater.string> + <floater.string name="network_performance_normal_msg"> + Normal + </floater.string> + <floater.string name="network_ping_critical_ms"> + 600 + </floater.string> + <floater.string name="network_ping_warning_ms"> + 300 + </floater.string> + <floater.string name="network_ping_critical_msg"> + Connection ping time is over [NETWORK_PING_CRITICAL] ms + </floater.string> + <floater.string name="network_ping_warning_msg"> + Connection ping time is [NETWORK_PING_WARNING]-[NETWORK_PING_CRITICAL] ms + </floater.string> + <floater.string name="network_packet_loss_cause_msg"> + Possible bad connection or 'Bandwidth' pref too high. + </floater.string> + <floater.string name="network_ping_cause_msg"> + Possible bad connection or file-sharing app. + </floater.string> + <floater.string name="server_text_msg"> + Server + </floater.string> + <floater.string name="server_frame_rate_critical_fps"> + 20 + </floater.string> + <floater.string name="server_frame_rate_warning_fps"> + 30 + </floater.string> + <floater.string name="server_single_process_max_time_ms"> + 20 + </floater.string> + <floater.string name="server_frame_time_critical_msg"> + Simulator framerate below [SERVER_FRAME_RATE_CRITICAL] + </floater.string> + <floater.string name="server_frame_time_warning_msg"> + Simulator framerate between [SERVER_FRAME_RATE_CRITICAL] and [SERVER_FRAME_RATE_WARNING] + </floater.string> + <floater.string name="server_frame_time_normal_msg"> + Normal + </floater.string> + <floater.string name="server_physics_cause_msg"> + Possible Cause: Too many physical objects + </floater.string> + <floater.string name="server_scripts_cause_msg"> + Possible Cause: Too many scripted objects + </floater.string> + <floater.string name="server_net_cause_msg"> + Possible Cause: Too much network traffic + </floater.string> + <floater.string name="server_agent_cause_msg"> + Possible Cause: Too many moving people in region + </floater.string> + <floater.string name="server_images_cause_msg"> + Possible Cause: Too many image calculations + </floater.string> + <floater.string name="server_generic_cause_msg"> + Possible Cause: Simulator load too heavy + </floater.string> + <floater.string name="smaller_label"> + >> + </floater.string> + <floater.string name="bigger_label"> + << + </floater.string> + <button name="client_lagmeter" tool_tip="Client lag status"/> + <text name="client"> + Client + </text> + <text name="client_text"> + Normal + </text> + <button name="network_lagmeter" tool_tip="Network lag status"/> + <text name="network"> + Network + </text> + <text name="network_text"> + Normal + </text> + <button name="server_lagmeter" tool_tip="Server lag status"/> + <text name="server"> + Server + </text> + <text name="server_text"> + Normal + </text> + <button label=">>" name="minimize" tool_tip="Toggle floater size"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_land_holdings.xml b/indra/newview/skins/default/xui/zh/floater_land_holdings.xml new file mode 100644 index 0000000000..de551f8c96 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_land_holdings.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="land holdings floater" title="MY LAND"> + <floater.string name="area_string"> + [AREA] m² + </floater.string> + <scroll_list name="parcel list"> + <scroll_list.columns label="地段" name="name"/> + <scroll_list.columns label="地å€" name="location"/> + <scroll_list.columns label="Type" name="type"/> + <scroll_list.columns label="Area" name="area"/> + </scroll_list> + <button label="Teleport" label_selected="Teleport" name="Teleport" tool_tip="Teleport to the center of this land."/> + <button label="地圖" label_selected="地圖" name="Show on Map" tool_tip="Show this land on the world map"/> + <text name="contrib_label"> + Contributions to your groups: + </text> + <scroll_list name="grant list"> + <scroll_list.columns label="Group" name="group"/> + <scroll_list.columns label="Area" name="area"/> + </scroll_list> + <text name="allowed_label"> + Allowed land holdings at current payment plan: + </text> + <text name="allowed_text"> + [AREA] m² + </text> + <text name="current_label"> + Current land holdings: + </text> + <text name="current_text"> + [AREA] m² + </text> + <text name="available_label"> + Available for land purchases: + </text> + <text name="available_text"> + [AREA] m² + </text> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_live_lsleditor.xml b/indra/newview/skins/default/xui/zh/floater_live_lsleditor.xml new file mode 100644 index 0000000000..6c8bd76a8a --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_live_lsleditor.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="script ed float" title="SCRIPT: NEW SCRIPT"> + <floater.string name="not_allowed"> + You can not view or edit this script, since it has been set as "no copy". You need full permissions to view or edit a script inside an object. + </floater.string> + <floater.string name="script_running"> + Running + </floater.string> + <floater.string name="Title"> + SCRIPT: [NAME] + </floater.string> + <button label="Reset" label_selected="Reset" name="Reset"/> + <check_box initial_value="true" label="Running" name="running"/> + <check_box initial_value="true" label="Mono" name="mono"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_lsl_guide.xml b/indra/newview/skins/default/xui/zh/floater_lsl_guide.xml new file mode 100644 index 0000000000..e5c3c47827 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_lsl_guide.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="script ed float" title="LSL REFERENCE"> + <check_box label="Follow cursor" name="lock_check"/> + <combo_box label="Lock" name="history_combo"/> + <button label="Back" name="back_btn"/> + <button label="Forward" name="fwd_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_map.xml b/indra/newview/skins/default/xui/zh/floater_map.xml new file mode 100644 index 0000000000..b535ef0074 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_map.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Map" title=""> + <floater.string name="ToolTipMsg"> + [REGION](Double-click to open Map, shift-drag to pan) + </floater.string> + <floater.string name="AltToolTipMsg"> + [REGION](Double-click to teleport, shift-drag to pan) + </floater.string> + <floater.string name="mini_map_caption"> + MINIMAP + </floater.string> + <text label="N" name="floater_map_north"> + N + </text> + <text label="E" name="floater_map_east"> + E + </text> + <text label="W" name="floater_map_west"> + W + </text> + <text label="S" name="floater_map_south"> + S + </text> + <text label="SE" name="floater_map_southeast"> + SE + </text> + <text label="NE" name="floater_map_northeast"> + NE + </text> + <text label="SW" name="floater_map_southwest"> + SW + </text> + <text label="NW" name="floater_map_northwest"> + NW + </text> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_media_browser.xml b/indra/newview/skins/default/xui/zh/floater_media_browser.xml new file mode 100644 index 0000000000..616c326d6b --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_media_browser.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_about" title="MEDIA BROWSER"> + <floater.string name="home_page_url"> + http://www.secondlife.com + </floater.string> + <floater.string name="support_page_url"> + http://support.secondlife.com + </floater.string> + <layout_stack name="stack1"> + <layout_panel name="nav_controls"> + <button label="Back" name="back"/> + <button label="Forward" name="forward"/> + <button label="Reload" name="reload"/> + <button label="Go" name="go"/> + </layout_panel> + <layout_panel name="time_controls"> + <button label="rewind" name="rewind"/> + <button label="stop" name="stop"/> + <button label="forward" name="seek"/> + </layout_panel> + <layout_panel name="parcel_owner_controls"> + <button label="Send Current Page to Parcel" name="assign"/> + </layout_panel> + <layout_panel name="external_controls"> + <button label="Open in My Web Browser" name="open_browser"/> + <check_box label="Always open in my web browser" name="open_always"/> + <button label="關閉" name="close"/> + </layout_panel> + </layout_stack> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_media_settings.xml b/indra/newview/skins/default/xui/zh/floater_media_settings.xml new file mode 100644 index 0000000000..821b93c06f --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_media_settings.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="media_settings" title="MEDIA SETTINGS"> + <button label="確定" label_selected="確定" name="OK"/> + <button label="å–銷" label_selected="å–銷" name="Cancel"/> + <button label="套用" label_selected="套用" name="Apply"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_mem_leaking.xml b/indra/newview/skins/default/xui/zh/floater_mem_leaking.xml new file mode 100644 index 0000000000..3fa62b1b60 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_mem_leaking.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="MemLeak" title="SIMULATE A MEMORY LEAK"> + <spinner label="Leaking Speed (bytes per frame):" name="leak_speed"/> + <spinner label="Max Leaked Memory (MB):" name="max_leak"/> + <text name="total_leaked_label"> + Current leaked memory: [SIZE] KB + </text> + <text name="note_label_1"> + [NOTE1] + </text> + <text name="note_label_2"> + [NOTE2] + </text> + <button label="Start" name="start_btn"/> + <button label="Stop" name="stop_btn"/> + <button label="Release" name="release_btn"/> + <button label="關閉" name="close_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_moveview.xml b/indra/newview/skins/default/xui/zh/floater_moveview.xml new file mode 100644 index 0000000000..1866592d84 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_moveview.xml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="move_floater"> + <string name="walk_forward_tooltip"> + Walk Forward (press Up Arrow or W) + </string> + <string name="walk_back_tooltip"> + Walk Backwards (press Down Arrow or S) + </string> + <string name="walk_left_tooltip"> + Walk left (press Shift + Left Arrow or A) + </string> + <string name="walk_right_tooltip"> + Walk right (press Shift + Right Arrow or D) + </string> + <string name="run_forward_tooltip"> + Run Forward (press Up Arrow or W) + </string> + <string name="run_back_tooltip"> + Run Backwards (press Down Arrow or S) + </string> + <string name="run_left_tooltip"> + Run left (press Shift + Left Arrow or A) + </string> + <string name="run_right_tooltip"> + Run right (press Shift + Right Arrow or D) + </string> + <string name="fly_forward_tooltip"> + Fly Forward (press Up Arrow or W) + </string> + <string name="fly_back_tooltip"> + Fly Backwards (press Down Arrow or S) + </string> + <string name="fly_left_tooltip"> + Fly left (press Shift + Left Arrow or A) + </string> + <string name="fly_right_tooltip"> + Fly right (press Shift + Right Arrow or D) + </string> + <string name="fly_up_tooltip"> + Fly up (press E) + </string> + <string name="fly_down_tooltip"> + Fly down (press C) + </string> + <string name="jump_tooltip"> + Jump (press E) + </string> + <string name="crouch_tooltip"> + Crouch (press C) + </string> + <string name="walk_title"> + Walk + </string> + <string name="run_title"> + Run + </string> + <string name="fly_title"> + Fly + </string> + <panel name="panel_actions"> + <button name="turn left btn" tool_tip="Turn left (press Left Arrow or A)"/> + <joystick_slide name="move left btn" tool_tip="Walk left (press Shift + Left Arrow or A)"/> + <button name="turn right btn" tool_tip="Turn right (press Right Arrow or D)"/> + <joystick_slide name="move right btn" tool_tip="Walk right (press Shift + Right Arrow or D)"/> + <joystick_turn name="forward btn" tool_tip="Walk forward (press up arrow or W)"/> + <joystick_turn name="backward btn" tool_tip="Walk backward (press down arrow or S)"/> + <button name="move up btn" tool_tip="Fly up (press E)"/> + <button name="move down btn" tool_tip="Fly down (press C)"/> + </panel> + <panel name="panel_modes"> + <button label="" name="mode_walk_btn" tool_tip="Walking mode"/> + <button label="" name="mode_run_btn" tool_tip="Running mode"/> + <button label="" name="mode_fly_btn" tool_tip="Flying mode"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_mute_object.xml b/indra/newview/skins/default/xui/zh/floater_mute_object.xml new file mode 100644 index 0000000000..a2a56f769e --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_mute_object.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="block by name" title="BLOCK OBJECT BY NAME"> + <text name="message"> + Block an object: + </text> + <line_editor name="object_name"> + Object name + </line_editor> + <text name="note"> + * Only blocks object text, not sounds + </text> + <button label="確定" name="OK"/> + <button label="å–銷" name="Cancel"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_nearby_chat.xml b/indra/newview/skins/default/xui/zh/floater_nearby_chat.xml new file mode 100644 index 0000000000..bed7c20ba5 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_nearby_chat.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="nearby_chat" title="NEARBY CHAT"> + <check_box label="Translate chat (powered by Google)" name="translate_chat_checkbox"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_notification.xml b/indra/newview/skins/default/xui/zh/floater_notification.xml new file mode 100644 index 0000000000..65102216d2 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_notification.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="notification" title="NOTIFICATIONS CONSOLE"> + <text_editor name="payload"> + 載入ä¸... + </text_editor> + <combo_box label="Response" name="response"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_notifications_console.xml b/indra/newview/skins/default/xui/zh/floater_notifications_console.xml new file mode 100644 index 0000000000..4e92aa69e0 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_notifications_console.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="notifications_console" title="NOTIFICATIONS CONSOLE"> + <combo_box label="Select notification type" name="notification_types"/> + <button label="Add" name="add_notification"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_openobject.xml b/indra/newview/skins/default/xui/zh/floater_openobject.xml new file mode 100644 index 0000000000..0739e01833 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_openobject.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="objectcontents" title="OBJECT CONTENTS"> + <text name="object_name"> + [DESC]: + </text> + <button label="Copy To Inventory" label_selected="Copy To Inventory" name="copy_to_inventory_button"/> + <button label="Copy And Wear" label_selected="Copy And Wear" name="copy_and_wear_button"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_outfit_save_as.xml b/indra/newview/skins/default/xui/zh/floater_outfit_save_as.xml new file mode 100644 index 0000000000..63c9d6c950 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_outfit_save_as.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="modal container" title="Save Outfit"> + <button label="儲å˜" label_selected="儲å˜" name="Save"/> + <button label="å–銷" label_selected="å–銷" name="Cancel"/> + <text name="Save item as:"> + Save what I'm wearing +as a new Outfit: + </text> + <line_editor name="name ed"> + [DESC] (new) + </line_editor> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_outgoing_call.xml b/indra/newview/skins/default/xui/zh/floater_outgoing_call.xml new file mode 100644 index 0000000000..a871f821e3 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_outgoing_call.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="outgoing call" title="CALLING"> + <floater.string name="lifetime"> + 5 + </floater.string> + <floater.string name="localchat"> + Nearby Voice Chat + </floater.string> + <floater.string name="anonymous"> + anonymous + </floater.string> + <floater.string name="VoiceInviteP2P"> + is calling. + </floater.string> + <floater.string name="VoiceInviteAdHoc"> + has joined a Voice Chat call with a conference chat. + </floater.string> + <text name="connecting"> + Connecting to [CALLEE_NAME] + </text> + <text name="calling"> + Calling [CALLEE_NAME] + </text> + <text name="noanswer"> + No Answer. Please try again later. + </text> + <text name="nearby"> + You have been disconnected from [VOICE_CHANNEL_NAME]. [RECONNECT_NEARBY] + </text> + <text name="nearby_P2P_by_other"> + Your call has ended. [RECONNECT_NEARBY] + </text> + <text name="nearby_P2P_by_agent"> + You have ended the call. [RECONNECT_NEARBY] + </text> + <text name="leaving"> + Leaving [CURRENT_CHAT]. + </text> + <button label="å–銷" label_selected="å–銷" name="Cancel"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_pay.xml b/indra/newview/skins/default/xui/zh/floater_pay.xml new file mode 100644 index 0000000000..9374ac3f3b --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_pay.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Give Money"> + <string name="payee_group"> + Pay Group + </string> + <string name="payee_resident"> + Pay Resident + </string> + <text name="payee_name"> + Test Name That Is Extremely Long To Check Clipping + </text> + <button label="L$1" label_selected="L$1" name="fastpay 1"/> + <button label="L$5" label_selected="L$5" name="fastpay 5"/> + <button label="L$10" label_selected="L$10" name="fastpay 10"/> + <button label="L$20" label_selected="L$20" name="fastpay 20"/> + <text name="amount text"> + Or, choose amount: + </text> + <button label="Pay" label_selected="Pay" name="pay btn"/> + <button label="å–銷" label_selected="å–銷" name="cancel btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_pay_object.xml b/indra/newview/skins/default/xui/zh/floater_pay_object.xml new file mode 100644 index 0000000000..fbb6a8ab36 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_pay_object.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Give Money"> + <string name="payee_group"> + Pay Group + </string> + <string name="payee_resident"> + Pay Resident + </string> + <text name="payee_name"> + Ericacita Moostopolison + </text> + <text name="object_name_label"> + Via object: + </text> + <icon name="icon_object" tool_tip="Objects"/> + <text name="object_name_text"> + My awesome object with a really damn long name + </text> + <button label="L$1" label_selected="L$1" name="fastpay 1"/> + <button label="L$5" label_selected="L$5" name="fastpay 5"/> + <button label="L$10" label_selected="L$10" name="fastpay 10"/> + <button label="L$20" label_selected="L$20" name="fastpay 20"/> + <text name="amount text"> + 或者,é¸æ“‡ä¸€å€‹é‡‘é¡ï¼š + </text> + <button label="Pay" label_selected="Pay" name="pay btn"/> + <button label="å–銷" label_selected="å–銷" name="cancel btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_perm_prefs.xml b/indra/newview/skins/default/xui/zh/floater_perm_prefs.xml new file mode 100644 index 0000000000..8d44d474c0 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_perm_prefs.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="perm prefs" title="é è¨ä¸Šå‚³æ¬Šé™"> + <panel label="權é™" name="permissions"> + <check_box label="與社團分享" name="share_with_group"/> + <check_box label="å…許任何人覆製" name="everyone_copy"/> + <text name="NextOwnerLabel"> + 下一個æ“有者å¯ä»¥ï¼š + </text> + <check_box label="修改" name="next_owner_modify"/> + <check_box label="覆製" name="next_owner_copy"/> + <check_box initial_value="true" label="轉售 / é€äºº" name="next_owner_transfer"/> + </panel> + <button label="確定" label_selected="確定" name="ok"/> + <button label="å–銷" label_selected="å–銷" name="cancel"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_post_process.xml b/indra/newview/skins/default/xui/zh/floater_post_process.xml new file mode 100644 index 0000000000..0972c6dfa6 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_post_process.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Post-Process Floater" title="POST-PROCESS SETTINGS"> + <tab_container name="Post-Process Tabs"> + <panel label="Color Filter" name="wmiColorFilterPanel"> + <check_box label="Enable" name="wmiColorFilterToggle"/> + <text name="wmiColorFilterBrightnessText"> + Brightness + </text> + <text name="wmiColorFilterSaturationText"> + Saturation + </text> + <text name="wmiColorFilterContrastText"> + Contrast + </text> + <text name="wmiColorFilterBaseText"> + Contrast Base Color + </text> + <slider label="R" name="wmiColorFilterBaseR"/> + <slider label="G" name="wmiColorFilterBaseG"/> + <slider label="B" name="wmiColorFilterBaseB"/> + <slider label="I" name="wmiColorFilterBaseI"/> + </panel> + <panel label="Night Vision" name="wmiNightVisionPanel"> + <check_box label="Enable" name="wmiNightVisionToggle"/> + <text name="wmiNightVisionBrightMultText"> + Light Amplification Multiple + </text> + <text name="wmiNightVisionNoiseSizeText"> + Noise Size + </text> + <text name="wmiNightVisionNoiseStrengthText"> + Noise Strength + </text> + </panel> + <panel label="Bloom" name="wmiBloomPanel"> + <check_box label="Enable" name="wmiBloomToggle"/> + <text name="wmiBloomExtractText"> + Luminosity Extraction + </text> + <text name="wmiBloomSizeText"> + Bloom Size + </text> + <text name="wmiBloomStrengthText"> + Bloom Strength + </text> + </panel> + <panel label="Extras" name="Extras"> + <button label="LoadEffect" label_selected="LoadEffect" name="PPLoadEffect"/> + <button label="SaveEffect" label_selected="SaveEffect" name="PPSaveEffect"/> + <line_editor label="效果å稱" name="PPEffectNameEditor"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_postcard.xml b/indra/newview/skins/default/xui/zh/floater_postcard.xml new file mode 100644 index 0000000000..c85ca93e85 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_postcard.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Postcard" title="EMAIL SNAPSHOT"> + <floater.string name="default_subject"> + Postcard from [SECOND_LIFE]. + </floater.string> + <floater.string name="default_message"> + Check this out! + </floater.string> + <floater.string name="upload_message"> + Sending... + </floater.string> + <text name="to_label"> + Recipient's Email: + </text> + <text name="from_label"> + Your Email: + </text> + <text name="name_label"> + Your Name: + </text> + <text name="subject_label"> + Subject: + </text> + <line_editor label="Type your subject here." name="subject_form"/> + <text name="msg_label"> + Message: + </text> + <text_editor name="msg_form"> + Type your message here. + </text_editor> + <button label="å–銷" name="cancel_btn"/> + <button label="Send" name="send_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_preferences.xml b/indra/newview/skins/default/xui/zh/floater_preferences.xml new file mode 100644 index 0000000000..777425ba30 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_preferences.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Preferences" title="PREFERENCES"> + <button label="確定" label_selected="確定" name="OK"/> + <button label="å–銷" label_selected="å–銷" name="Cancel"/> + <tab_container name="pref core"> + <panel label="一般" name="general"/> + <panel label="Graphics" name="display"/> + <panel label="Sound & Media" name="audio"/> + <panel label="èŠå¤©" name="chat"/> + <panel label="Move & View" name="move"/> + <panel label="Notifications" name="msgs"/> + <panel label="Colors" name="colors"/> + <panel label="Privacy" name="im"/> + <panel label="Setup" name="input"/> + <panel label="Advanced" name="advanced1"/> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_preview_animation.xml b/indra/newview/skins/default/xui/zh/floater_preview_animation.xml new file mode 100644 index 0000000000..5ac2de4dc5 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_preview_animation.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="preview_anim"> + <floater.string name="Title"> + Animation: [NAME] + </floater.string> + <text name="desc txt"> + æ述: + </text> + <button label="Play Inworld" label_selected="Stop" name="Anim play btn" tool_tip="Play this animation so that others can see it"/> + <button label="Play Locally" label_selected="Stop" name="Anim audition btn" tool_tip="Play this animation so that only you can see it"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_preview_gesture.xml b/indra/newview/skins/default/xui/zh/floater_preview_gesture.xml new file mode 100644 index 0000000000..fe64f75777 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_preview_gesture.xml @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="gesture_preview"> + <floater.string name="step_anim"> + Animation to play: + </floater.string> + <floater.string name="step_sound"> + Sound to play: + </floater.string> + <floater.string name="step_chat"> + Chat to say: + </floater.string> + <floater.string name="step_wait"> + Wait: + </floater.string> + <floater.string name="stop_txt"> + Stop + </floater.string> + <floater.string name="preview_txt"> + é 覽 + </floater.string> + <floater.string name="none_text"> + -- ç„¡ -- + </floater.string> + <floater.string name="Title"> + Gesture: [NAME] + </floater.string> + <text name="desc_label"> + æ述: + </text> + <text name="trigger_label"> + Trigger: + </text> + <text name="replace_text" tool_tip="Replace the trigger word(s) with these words. For example, trigger 'hello' replace with 'howdy' will turn the chat 'I wanted to say hello' into 'I wanted to say howdy' as well as playing the gesture!"> + Replace with: + </text> + <line_editor name="replace_editor" tool_tip="Replace the trigger word(s) with these words. For example, trigger 'hello' replace with 'howdy' will turn the chat 'I wanted to say hello' into 'I wanted to say howdy' as well as playing the gesture"/> + <text name="key_label"> + Shortcut Key: + </text> + <combo_box label="ç„¡" name="modifier_combo"/> + <combo_box label="ç„¡" name="key_combo"/> + <text name="library_label"> + Library: + </text> + <scroll_list name="library_list"> + <scroll_list.rows name="action_animation" value="Animation"/> + <scroll_list.rows name="action_sound" value="Sound"/> + <scroll_list.rows name="action_chat" value="èŠå¤©"/> + <scroll_list.rows name="action_wait" value="Wait"/> + </scroll_list> + <button label="Add >>" name="add_btn"/> + <text name="steps_label"> + Steps: + </text> + <button label="Up" name="up_btn"/> + <button label="Down" name="down_btn"/> + <button label="Remove" name="delete_btn"/> + <text name="options_text"> + (options) + </text> + <radio_group name="animation_trigger_type"> + <radio_item label="Start" name="start"/> + <radio_item label="Stop" name="stop"/> + </radio_group> + <check_box label="until animations are done" name="wait_anim_check"/> + <check_box label="time in seconds:" name="wait_time_check"/> + <text name="help_label"> + All steps happen simultaneously, unless you add wait steps. + </text> + <check_box label="Active" name="active_check" tool_tip="Active gestures can be triggered by chatting their trigger phrases or pressing their hot keys. Gestures usually become inactive when there is a key binding conflict."/> + <button label="é 覽" name="preview_btn"/> + <button label="儲å˜" name="save_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_preview_notecard.xml b/indra/newview/skins/default/xui/zh/floater_preview_notecard.xml new file mode 100644 index 0000000000..a3eaa559e0 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_preview_notecard.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="preview notecard" title="NOTECARD:"> + <floater.string name="no_object"> + Unable to find object containing this notecard. + </floater.string> + <floater.string name="not_allowed"> + You do not have permission to view this notecard. + </floater.string> + <floater.string name="Title"> + Notecard: [NAME] + </floater.string> + <text name="desc txt"> + æ述: + </text> + <text_editor name="Notecard Editor"> + 載入ä¸... + </text_editor> + <button label="儲å˜" label_selected="儲å˜" name="Save"/> + <button label="刪除" label_selected="刪除" name="Delete"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_preview_sound.xml b/indra/newview/skins/default/xui/zh/floater_preview_sound.xml new file mode 100644 index 0000000000..d9854a85b6 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_preview_sound.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="preview_sound"> + <floater.string name="Title"> + Sound: [NAME] + </floater.string> + <text name="desc txt"> + æ述: + </text> + <button label="Play Inworld" label_selected="Play Inworld" name="Sound play btn" tool_tip="Play this sound so that others can hear it"/> + <button label="Play Locally" label_selected="Play Locally" name="Sound audition btn" tool_tip="Play this sound so that only you can hear it"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_preview_texture.xml b/indra/newview/skins/default/xui/zh/floater_preview_texture.xml new file mode 100644 index 0000000000..53fb7ef2f1 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_preview_texture.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="preview_texture"> + <floater.string name="Title"> + Texture: [NAME] + </floater.string> + <floater.string name="Copy"> + Copy To Inventory + </floater.string> + <text name="desc txt"> + æ述: + </text> + <text name="dimensions"> + [WIDTH]px x [HEIGHT]px + </text> + <text name="aspect_ratio"> + Preview aspect ratio + </text> + <combo_box name="combo_aspect_ratio" tool_tip="Preview at a fixed aspect ratio"> + <combo_item name="Unconstrained"> + Unconstrained + </combo_item> + <combo_item name="1:1" tool_tip="Group insignia or Real World profile"> + 1:1 + </combo_item> + <combo_item name="4:3" tool_tip="[SECOND_LIFE] profile"> + 4:3 + </combo_item> + <combo_item name="10:7" tool_tip="Classifieds and search listings, landmarks"> + 10:7 + </combo_item> + <combo_item name="3:2" tool_tip="關於土地"> + 3:2 + </combo_item> + <combo_item name="16:10"> + 16:10 + </combo_item> + <combo_item name="16:9" tool_tip="Profile picks"> + 16:9 + </combo_item> + <combo_item name="2:1"> + 2:1 + </combo_item> + </combo_box> + <button label="確定" name="Keep"/> + <button label="Discard" name="Discard"/> + <button label="å¦å˜" name="save_tex_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_publish_classified.xml b/indra/newview/skins/default/xui/zh/floater_publish_classified.xml new file mode 100644 index 0000000000..45bbe7b979 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_publish_classified.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="publish_classified" title="Publishing Classified"> + <text name="explanation_text"> + Your classified ad will run for one week from the date it is published. + +Remember, Classified fees are non-refundable. + </text> + <spinner label="åƒ¹æ ¼ï¼š L$" name="price_for_listing" tool_tip="Price for listing." value="50"/> + <button label="Publish" name="publish_btn"/> + <button label="å–銷" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_region_debug_console.xml b/indra/newview/skins/default/xui/zh/floater_region_debug_console.xml new file mode 100644 index 0000000000..b16a3bd9cc --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_region_debug_console.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="region_debug_console" title="Region Debug"/> diff --git a/indra/newview/skins/default/xui/zh/floater_region_info.xml b/indra/newview/skins/default/xui/zh/floater_region_info.xml new file mode 100644 index 0000000000..0e4879f555 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_region_info.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="regioninfo" title="åœ°å€ / é ˜åœ°"/> diff --git a/indra/newview/skins/default/xui/zh/floater_report_abuse.xml b/indra/newview/skins/default/xui/zh/floater_report_abuse.xml new file mode 100644 index 0000000000..c745051c8b --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_report_abuse.xml @@ -0,0 +1,94 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_report_abuse" title="REPORT ABUSE"> + <floater.string name="Screenshot"> + Screenshot + </floater.string> + <check_box label="Use this screenshot" name="screen_check"/> + <text name="reporter_title"> + Reporter: + </text> + <text name="sim_title"> + 地å€ï¼š + </text> + <text name="sim_field"> + 地å€å稱 + </text> + <text name="pos_title"> + Position: + </text> + <text name="pos_field"> + {128.1, 128.1, 15.4} + </text> + <text name="select_object_label"> + Click the button, then the abusive object: + </text> + <button name="pick_btn" tool_tip="Object Picker - Identify an object as the subject of this report"/> + <text name="object_name_label"> + Object: + </text> + <text name="owner_name_label"> + æ“有者: + </text> + <combo_box name="category_combo" tool_tip="Category -- select the category that best describes this report"> + <combo_box.item label="Select category" name="Select_category"/> + <combo_box.item label="Age > Age play" name="Age__Age_play"/> + <combo_box.item label="Age > Adult Resident on Teen Second Life" name="Age__Adult_resident_on_Teen_Second_Life"/> + <combo_box.item label="Age > Underage Resident outside of Teen Second Life" name="Age__Underage_resident_outside_of_Teen_Second_Life"/> + <combo_box.item label="Assault > Combat sandbox / unsafe area" name="Assault__Combat_sandbox___unsafe_area"/> + <combo_box.item label="Assault > Safe area" name="Assault__Safe_area"/> + <combo_box.item label="Assault > Weapons testing sandbox" name="Assault__Weapons_testing_sandbox"/> + <combo_box.item label="Commerce > Failure to deliver product or service" name="Commerce__Failure_to_deliver_product_or_service"/> + <combo_box.item label="Disclosure > Real world information" name="Disclosure__Real_world_information"/> + <combo_box.item label="Disclosure > Remotely monitoring chat" name="Disclosure__Remotely_monitoring chat"/> + <combo_box.item label="Disclosure > Second Life information/chat/IMs" name="Disclosure__Second_Life_information_chat_IMs"/> + <combo_box.item label="Disturbing the peace > Unfair use of region resources" name="Disturbing_the_peace__Unfair_use_of_region_resources"/> + <combo_box.item label="Disturbing the peace > Excessive scripted objects" name="Disturbing_the_peace__Excessive_scripted_objects"/> + <combo_box.item label="Disturbing the peace > Object littering" name="Disturbing_the_peace__Object_littering"/> + <combo_box.item label="Disturbing the peace > Repetitive spam" name="Disturbing_the_peace__Repetitive_spam"/> + <combo_box.item label="Disturbing the peace > Unwanted advert spam" name="Disturbing_the_peace__Unwanted_advert_spam"/> + <combo_box.item label="Fraud > L$" name="Fraud__L$"/> + <combo_box.item label="Fraud > Land" name="Fraud__Land"/> + <combo_box.item label="Fraud > Pyramid scheme or chain letter" name="Fraud__Pyramid_scheme_or_chain_letter"/> + <combo_box.item label="Fraud > US$" name="Fraud__US$"/> + <combo_box.item label="Harassment > Advert farms / visual spam" name="Harassment__Advert_farms___visual_spam"/> + <combo_box.item label="Harassment > Defaming individuals or groups" name="Harassment__Defaming_individuals_or_groups"/> + <combo_box.item label="Harassment > Impeding movement" name="Harassment__Impeding_movement"/> + <combo_box.item label="Harassment > Sexual harassment" name="Harassment__Sexual_harassment"/> + <combo_box.item label="Harassment > Solicting/inciting others to violate ToS" name="Harassment__Solicting_inciting_others_to_violate_ToS"/> + <combo_box.item label="Harassment > Verbal abuse" name="Harassment__Verbal_abuse"/> + <combo_box.item label="Indecency > Broadly offensive content or conduct" name="Indecency__Broadly_offensive_content_or_conduct"/> + <combo_box.item label="Indecency > Inappropriate avatar name" name="Indecency__Inappropriate_avatar_name"/> + <combo_box.item label="Indecency > Inappropriate content or conduct in a PG region" name="Indecency__Mature_content_in_PG_region"/> + <combo_box.item label="Indecency > Inappropriate content or conduct in a Moderate region" name="Indecency__Inappropriate_content_in_Mature_region"/> + <combo_box.item label="Intellectual property infringement > Content Removal" name="Intellectual_property_infringement_Content_Removal"/> + <combo_box.item label="Intellectual property infringement > CopyBot or Permissions Exploit" name="Intellectual_property_infringement_CopyBot_or_Permissions_Exploit"/> + <combo_box.item label="Intolerance" name="Intolerance"/> + <combo_box.item label="Land > Abuse of sandbox resources" name="Land__Abuse_of_sandbox_resources"/> + <combo_box.item label="Land > Encroachment > Objects/textures" name="Land__Encroachment__Objects_textures"/> + <combo_box.item label="Land > Encroachment > Particles" name="Land__Encroachment__Particles"/> + <combo_box.item label="Land > Encroachment > Trees/plants" name="Land__Encroachment__Trees_plants"/> + <combo_box.item label="Wagering/gambling" name="Wagering_gambling"/> + <combo_box.item label="Other" name="Other"/> + </combo_box> + <text name="abuser_name_title"> + Abuser name: + </text> + <button label="Choose" name="select_abuser" tool_tip="Select the name of the abuser from a list"/> + <text name="abuser_name_title2"> + Location of Abuse: + </text> + <text name="sum_title"> + Summary: + </text> + <text name="dscr_title"> + Details: + </text> + <text name="bug_aviso"> + Please be as specific as possible + </text> + <text name="incomplete_title"> + * Incomplete reports won't be investigated + </text> + <button label="Report Abuse" label_selected="Report Abuse" name="send_btn"/> + <button label="å–銷" label_selected="å–銷" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_script_debug.xml b/indra/newview/skins/default/xui/zh/floater_script_debug.xml new file mode 100644 index 0000000000..12e646785d --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_script_debug.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<multi_floater name="script debug floater" title="Script Warning/Error"/> diff --git a/indra/newview/skins/default/xui/zh/floater_script_debug_panel.xml b/indra/newview/skins/default/xui/zh/floater_script_debug_panel.xml new file mode 100644 index 0000000000..e70a30fa24 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_script_debug_panel.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="script" short_title="[ALL SCRIPTS]" title="[ALL SCRIPTS]"/> diff --git a/indra/newview/skins/default/xui/zh/floater_script_limits.xml b/indra/newview/skins/default/xui/zh/floater_script_limits.xml new file mode 100644 index 0000000000..7cd2c8e6c6 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_script_limits.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="scriptlimits" title="腳本資訊"/> diff --git a/indra/newview/skins/default/xui/zh/floater_script_preview.xml b/indra/newview/skins/default/xui/zh/floater_script_preview.xml new file mode 100644 index 0000000000..75ef4ebe73 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_script_preview.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="preview lsl text" title="SCRIPT: ROTATION SCRIPT"> + <floater.string name="Title"> + SCRIPT: [NAME] + </floater.string> + <text name="desc txt"> + æ述: + </text> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_script_queue.xml b/indra/newview/skins/default/xui/zh/floater_script_queue.xml new file mode 100644 index 0000000000..4062db5014 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_script_queue.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="queue" title="RESET PROGRESS"> + <floater.string name="Starting"> + Starting [START] of [COUNT] items. + </floater.string> + <floater.string name="Done"> + Done. + </floater.string> + <floater.string name="Resetting"> + Resetting + </floater.string> + <floater.string name="Running"> + Running + </floater.string> + <floater.string name="NotRunning"> + Not running + </floater.string> + <button label="關閉" label_selected="關閉" name="close"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_script_search.xml b/indra/newview/skins/default/xui/zh/floater_script_search.xml new file mode 100644 index 0000000000..b6671df0e2 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_script_search.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="script search" title="SCRIPT SEARCH"> + <check_box label="Case Insensitive" name="case_text"/> + <button label="Search" label_selected="Search" name="search_btn"/> + <button label="å–代" label_selected="å–代" name="replace_btn"/> + <button label="全部å–代" label_selected="全部å–代" name="replace_all_btn"/> + <text name="txt"> + Search + </text> + <text name="txt2"> + å–代 + </text> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_search.xml b/indra/newview/skins/default/xui/zh/floater_search.xml new file mode 100644 index 0000000000..5b247350b8 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_search.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_search" title="FIND"> + <floater.string name="loading_text"> + 載入ä¸... + </floater.string> + <floater.string name="done_text"> + Done + </floater.string> + <layout_stack name="stack1"> + <layout_panel name="browser_layout"> + <text name="refresh_search"> + Redo search to reflect current God level + </text> + </layout_panel> + </layout_stack> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_select_key.xml b/indra/newview/skins/default/xui/zh/floater_select_key.xml new file mode 100644 index 0000000000..1452f744da --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_select_key.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="modal container"> + <text name="Save item as:"> + Press a key to set your Speak button trigger. + </text> + <button label="å–銷" label_selected="å–銷" name="Cancel"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_sell_land.xml b/indra/newview/skins/default/xui/zh/floater_sell_land.xml new file mode 100644 index 0000000000..12d4ed606d --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_sell_land.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="sell land" title="出售土地"> + <scroll_container name="profile_scroll"> + <panel name="scroll_content_panel"> + <text name="info_parcel_label"> + 地段: + </text> + <text name="info_parcel"> + 地段å稱 + </text> + <text name="info_size_label"> + Size: + </text> + <text name="info_size"> + [AREA] m² + </text> + <text name="info_action"> + To sell this parcel: + </text> + <text name="price_label"> + 1. Set a price: + </text> + <text name="price_text"> + Choose an appropriate price. + </text> + <text name="price_ld"> + L$ + </text> + <line_editor name="price"> + 0 + </line_editor> + <text name="price_per_m"> + (L$[PER_METER] per m²) + </text> + <text name="sell_to_label"> + 2. Sell the land to: + </text> + <text name="sell_to_text"> + Choose whether to sell to anyone or a particular buyer. + </text> + <combo_box name="sell_to"> + <combo_box.item label="- Select one -" name="--selectone--"/> + <combo_box.item label="任何人" name="Anyone"/> + <combo_box.item label="Specific person:" name="Specificuser:"/> + </combo_box> + <button label="Select" name="sell_to_select_agent"/> + <text name="sell_objects_label"> + 3. Sell the objects with the land? + </text> + <text name="sell_objects_text"> + Land owner's transferable objects on parcel will change ownership. + </text> + <radio_group name="sell_objects"> + <radio_item label="No, keep ownership of objects" name="no"/> + <radio_item label="Yes, sell objects with land" name="yes"/> + </radio_group> + <button label="Show Objects" name="show_objects"/> + <text name="nag_message_label"> + REMEMBER: All sales are final. + </text> + <button label="Set Land For Sale" name="sell_btn"/> + <button label="å–銷" name="cancel_btn"/> + </panel> + </scroll_container> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_settings_debug.xml b/indra/newview/skins/default/xui/zh/floater_settings_debug.xml new file mode 100644 index 0000000000..bba075cf08 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_settings_debug.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="settings_debug" title="除錯è¨å®š"> + <radio_group name="boolean_combo"> + <radio_item label="TRUE" name="TRUE" value="true"/> + <radio_item label="FALSE" name="FALSE" value=""/> + </radio_group> + <color_swatch label="Color" name="val_color_swatch"/> + <spinner label="x" name="val_spinner_1"/> + <spinner label="x" name="val_spinner_2"/> + <spinner label="x" name="val_spinner_3"/> + <spinner label="x" name="val_spinner_4"/> + <button label="Reset to default" name="default_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_snapshot.xml b/indra/newview/skins/default/xui/zh/floater_snapshot.xml new file mode 100644 index 0000000000..80b9d69a79 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_snapshot.xml @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Snapshot" title="SNAPSHOT PREVIEW"> + <floater.string name="unknown"> + 未知 + </floater.string> + <radio_group label="Snapshot type" name="snapshot_type_radio"> + <radio_item label="Email" name="postcard"/> + <radio_item label="My inventory (L$[AMOUNT])" name="texture"/> + <radio_item label="Save to my computer" name="local"/> + </radio_group> + <text name="file_size_label"> + [SIZE] KB + </text> + <button label="Send" name="send_btn"/> + <button label="Save (L$[AMOUNT])" name="upload_btn"/> + <flyout_button label="儲å˜" name="save_btn" tool_tip="Save image to a file"> + <flyout_button.item label="儲å˜" name="save_item"/> + <flyout_button.item label="å¦å˜..." name="saveas_item"/> + </flyout_button> + <button label="More" name="more_btn" tool_tip="Advanced options"/> + <button label="Less" name="less_btn" tool_tip="Advanced options"/> + <button label="å–銷" name="discard_btn"/> + <text name="type_label2"> + Size + </text> + <text name="format_label"> + Format + </text> + <combo_box label="Resolution" name="postcard_size_combo"> + <combo_box.item label="Current Window" name="CurrentWindow"/> + <combo_box.item label="640x480" name="640x480"/> + <combo_box.item label="800x600" name="800x600"/> + <combo_box.item label="1024x768" name="1024x768"/> + <combo_box.item label="Custom" name="Custom"/> + </combo_box> + <combo_box label="Resolution" name="texture_size_combo"> + <combo_box.item label="Current Window" name="CurrentWindow"/> + <combo_box.item label="Small (128x128)" name="Small(128x128)"/> + <combo_box.item label="Medium (256x256)" name="Medium(256x256)"/> + <combo_box.item label="Large (512x512)" name="Large(512x512)"/> + <combo_box.item label="Custom" name="Custom"/> + </combo_box> + <combo_box label="Resolution" name="local_size_combo"> + <combo_box.item label="Current Window" name="CurrentWindow"/> + <combo_box.item label="320x240" name="320x240"/> + <combo_box.item label="640x480" name="640x480"/> + <combo_box.item label="800x600" name="800x600"/> + <combo_box.item label="1024x768" name="1024x768"/> + <combo_box.item label="1280x1024" name="1280x1024"/> + <combo_box.item label="1600x1200" name="1600x1200"/> + <combo_box.item label="Custom" name="Custom"/> + </combo_box> + <combo_box label="Format" name="local_format_combo"> + <combo_box.item label="PNG" name="PNG"/> + <combo_box.item label="JPEG" name="JPEG"/> + <combo_box.item label="BMP" name="BMP"/> + </combo_box> + <spinner label="Width" name="snapshot_width"/> + <spinner label="Height" name="snapshot_height"/> + <check_box label="Constrain proportions" name="keep_aspect_check"/> + <slider label="Image quality" name="image_quality_slider"/> + <text name="layer_type_label"> + Capture: + </text> + <combo_box label="Image Layers" name="layer_types"> + <combo_box.item label="Colors" name="Colors"/> + <combo_box.item label="Depth" name="Depth"/> + </combo_box> + <check_box label="Interface" name="ui_check"/> + <check_box label="HUDs" name="hud_check"/> + <check_box label="Keep open after saving" name="keep_open_check"/> + <check_box label="Freeze frame (fullscreen)" name="freeze_frame_check"/> + <check_box label="Auto-refresh" name="auto_snapshot_check"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_sound_preview.xml b/indra/newview/skins/default/xui/zh/floater_sound_preview.xml new file mode 100644 index 0000000000..269cd5db08 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_sound_preview.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Sound Preview" title="SOUND.WAV"> + <text name="name_label"> + å稱: + </text> + <text name="description_label"> + æ述: + </text> + <button label="上傳(L$[AMOUNT])" name="ok_btn"/> + <button label="å–銷" label_selected="å–銷" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_stats.xml b/indra/newview/skins/default/xui/zh/floater_stats.xml new file mode 100644 index 0000000000..6b6276e88f --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_stats.xml @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Statistics" title="STATISTICS"> + <scroll_container name="statistics_scroll"> + <container_view name="statistics_view"> + <stat_view label="Basic" name="basic"> + <stat_bar label="FPS" name="fps"/> + <stat_bar label="Bandwidth" name="bandwidth"/> + <stat_bar label="å°åŒ…æ失" name="packet_loss"/> + <stat_bar label="Ping Sim" name="ping"/> + </stat_view> + <stat_view label="Advanced" name="advanced"> + <stat_view label="Render" name="render"> + <stat_bar label="KTris Drawn" name="ktrisframe"/> + <stat_bar label="KTris Drawn" name="ktrissec"/> + <stat_bar label="Total Objects" name="objs"/> + <stat_bar label="New Objects" name="newobjs"/> + </stat_view> + <stat_view label="Texture" name="texture"> + <stat_bar label="Count" name="numimagesstat"/> + <stat_bar label="Raw Count" name="numrawimagesstat"/> + <stat_bar label="GL Mem" name="gltexmemstat"/> + <stat_bar label="Formatted Mem" name="formattedmemstat"/> + <stat_bar label="Raw Mem" name="rawmemstat"/> + <stat_bar label="Bound Mem" name="glboundmemstat"/> + </stat_view> + <stat_view label="Network" name="network"> + <stat_bar label="Packets In" name="packetsinstat"/> + <stat_bar label="Packets Out" name="packetsoutstat"/> + <stat_bar label="Objects" name="objectkbitstat"/> + <stat_bar label="Texture" name="texturekbitstat"/> + <stat_bar label="Asset" name="assetkbitstat"/> + <stat_bar label="Layers" name="layerskbitstat"/> + <stat_bar label="Actual In" name="actualinkbitstat"/> + <stat_bar label="Actual Out" name="actualoutkbitstat"/> + <stat_bar label="VFS Pending Ops" name="vfspendingoperations"/> + </stat_view> + </stat_view> + <stat_view label="Simulator" name="sim"> + <stat_bar label="Time Dilation" name="simtimedilation"/> + <stat_bar label="Sim FPS" name="simfps"/> + <stat_bar label="Physics FPS" name="simphysicsfps"/> + <stat_view label="Physics Details" name="physicsdetail"> + <stat_bar label="Pinned Objects" name="physicspinnedtasks"/> + <stat_bar label="Low LOD Objects" name="physicslodtasks"/> + <stat_bar label="Memory Allocated" name="physicsmemoryallocated"/> + </stat_view> + <stat_bar label="Agent Updates/Sec" name="simagentups"/> + <stat_bar label="Main Agents" name="simmainagents"/> + <stat_bar label="Child Agents" name="simchildagents"/> + <stat_bar label="Objects" name="simobjects"/> + <stat_bar label="Active Objects" name="simactiveobjects"/> + <stat_bar label="Active Scripts" name="simactivescripts"/> + <stat_bar label="Script Events" name="simscripteps"/> + <stat_bar label="Packets In" name="siminpps"/> + <stat_bar label="Packets Out" name="simoutpps"/> + <stat_bar label="擱置下載" name="simpendingdownloads"/> + <stat_bar label="擱置上傳" name="simpendinguploads"/> + <stat_bar label="Total Unacked Bytes" name="simtotalunackedbytes"/> + <stat_view label="Time (ms)" name="simperf"> + <stat_bar label="Total Frame Time" name="simframemsec"/> + <stat_bar label="Net Time" name="simnetmsec"/> + <stat_bar label="Physics Time" name="simsimphysicsmsec"/> + <stat_bar label="Simulation Time" name="simsimothermsec"/> + <stat_bar label="Agent Time" name="simagentmsec"/> + <stat_bar label="Images Time" name="simimagesmsec"/> + <stat_bar label="Script Time" name="simscriptmsec"/> + </stat_view> + </stat_view> + </container_view> + </scroll_container> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_sys_well.xml b/indra/newview/skins/default/xui/zh/floater_sys_well.xml new file mode 100644 index 0000000000..dbdd32974c --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_sys_well.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="sys_well_window" title="NOTIFICATIONS"> + <string name="title_im_well_window"> + CONVERSATIONS + </string> + <string name="title_notification_well_window"> + NOTIFICATIONS + </string> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_telehub.xml b/indra/newview/skins/default/xui/zh/floater_telehub.xml new file mode 100644 index 0000000000..b4c9f3ab29 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_telehub.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<!-- Explicit left edge to avoid overlapping build tools --> +<floater name="telehub" title="TELEHUB"> + <text name="status_text_connected"> + Telehub connected to object [OBJECT] + </text> + <text name="status_text_not_connected"> + No telehub connected. + </text> + <text name="help_text_connected"> + To remove, click Disconnect. + </text> + <text name="help_text_not_connected"> + Select object and click Connect Telehub. + </text> + <button label="Connect Telehub" name="connect_btn"/> + <button label="Disconnect" name="disconnect_btn"/> + <text name="spawn_points_text"> + Spawn Points (positions, not objects): + </text> + <button label="Add Spawn" name="add_spawn_point_btn"/> + <button label="Remove Spawn" name="remove_spawn_point_btn"/> + <text name="spawn_point_help"> + Select object and click "Add Spawn" to specify position. +You can then move or delete the object. +Positions are relative to the telehub center. +Select an item in list to highlight it inworld. + </text> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml new file mode 100644 index 0000000000..4c6dffea76 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="texture picker" title="PICK: TEXTURE"> + <floater.string name="choose_picture"> + 點擊以挑é¸åœ–片 + </floater.string> + <floater.string name="pick title"> + Pick: + </floater.string> + <text name="Multiple"> + Multiple textures + </text> + <text name="unknown"> + Size: [DIMENSIONS] + </text> + <button label="é è¨" label_selected="é è¨" name="Default"/> + <button label="ç„¡" label_selected="ç„¡" name="None"/> + <button label="Blank" label_selected="Blank" name="Blank"/> + <check_box initial_value="true" label="ç«‹å³å¥—用" name="apply_immediate_check"/> + <filter_editor label="Filter Textures" name="inventory search editor"/> + <check_box initial_value="false" label="顯示資料夾" name="show_folders_check"/> + <button label="確定" label_selected="確定" name="Select"/> + <button label="å–銷" label_selected="å–銷" name="Cancel"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_tools.xml b/indra/newview/skins/default/xui/zh/floater_tools.xml new file mode 100644 index 0000000000..b0d3d69230 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_tools.xml @@ -0,0 +1,499 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="toolbox floater" short_title="BUILD TOOLS"> + <floater.string name="status_rotate"> + Drag colored bands to rotate object + </floater.string> + <floater.string name="status_scale"> + Click and drag to stretch selected side + </floater.string> + <floater.string name="status_move"> + Drag to move, shift-drag to copy + </floater.string> + <floater.string name="status_modifyland"> + Click and hold to modify land + </floater.string> + <floater.string name="status_camera"> + Click and drag to move camera + </floater.string> + <floater.string name="status_grab"> + Drag to move, Ctrl to lift, Ctrl+Shift to rotate + </floater.string> + <floater.string name="status_place"> + Click inworld to build + </floater.string> + <floater.string name="status_selectland"> + Click and drag to select land + </floater.string> + <floater.string name="grid_screen_text"> + Screen + </floater.string> + <floater.string name="grid_local_text"> + Local + </floater.string> + <floater.string name="grid_world_text"> + World + </floater.string> + <floater.string name="grid_reference_text"> + Reference + </floater.string> + <floater.string name="grid_attachment_text"> + Attachment + </floater.string> + <button name="button focus" tool_tip="Focus"/> + <button name="button move" tool_tip="移動"/> + <button name="button edit" tool_tip="編輯"/> + <button name="button create" tool_tip="Create"/> + <button name="button land" tool_tip="Land"/> + <text name="text status"> + Drag to move, shift-drag to copy + </text> + <radio_group name="focus_radio_group"> + <radio_item label="Zoom" name="radio zoom"/> + <radio_item label="Orbit (Ctrl)" name="radio orbit"/> + <radio_item label="Pan (Ctrl+Shift)" name="radio pan"/> + </radio_group> + <slider_bar initial_value="0.125" name="slider zoom"/> + <radio_group name="move_radio_group"> + <radio_item label="移動" name="radio move"/> + <radio_item label="Lift (Ctrl)" name="radio lift"/> + <radio_item label="Spin (Ctrl+Shift)" name="radio spin"/> + </radio_group> + <radio_group name="edit_radio_group"> + <radio_item label="移動" name="radio position"/> + <radio_item label="Rotate (Ctrl)" name="radio rotate"/> + <radio_item label="Stretch (Ctrl+Shift)" name="radio stretch"/> + <radio_item label="Select Face" name="radio select face"/> + </radio_group> + <check_box label="Edit linked" name="checkbox edit linked parts"/> + <button label="Link" name="link_btn"/> + <button label="Unlink" name="unlink_btn"/> + <text name="RenderingCost" tool_tip="Shows the rendering cost calculated for this object"> + þ: [COUNT] + </text> + <text label="Stretch Both Sides" name="checkbox uniform label"> + Stretch Both Sides + </text> + <check_box initial_value="true" label="Stretch Textures" name="checkbox stretch textures"/> + <check_box initial_value="true" label="è²¼é½Šæ ¼ç·š" name="checkbox snap to grid"/> + <combo_box name="combobox grid mode" tool_tip="Choose the type of grid ruler for positioning the object"> + <combo_box.item label="World grid" name="World"/> + <combo_box.item label="Local grid" name="Local"/> + <combo_box.item label="Reference grid" name="Reference"/> + </combo_box> + <button name="Options..." tool_tip="See more grid options"/> + <button name="ToolCube" tool_tip="Cube"/> + <button name="ToolPrism" tool_tip="Prism"/> + <button name="ToolPyramid" tool_tip="Pyramid"/> + <button name="ToolTetrahedron" tool_tip="Tetrahedron"/> + <button name="ToolCylinder" tool_tip="Cylinder"/> + <button name="ToolHemiCylinder" tool_tip="Hemicylinder"/> + <button name="ToolCone" tool_tip="Cone"/> + <button name="ToolHemiCone" tool_tip="Hemicone"/> + <button name="ToolSphere" tool_tip="Sphere"/> + <button name="ToolHemiSphere" tool_tip="Hemisphere"/> + <button name="ToolTorus" tool_tip="Torus"/> + <button name="ToolTube" tool_tip="Tube"/> + <button name="ToolRing" tool_tip="Ring"/> + <button name="ToolTree" tool_tip="Tree"/> + <button name="ToolGrass" tool_tip="Grass"/> + <check_box label="Keep Tool selected" name="checkbox sticky"/> + <check_box label="Copy selection" name="checkbox copy selection"/> + <check_box initial_value="true" label="Center Copy" name="checkbox copy centers"/> + <check_box label="Rotate Copy" name="checkbox copy rotates"/> + <radio_group name="land_radio_group"> + <radio_item label="Select Land" name="radio select land"/> + <radio_item label="Flatten" name="radio flatten"/> + <radio_item label="Raise" name="radio raise"/> + <radio_item label="Lower" name="radio lower"/> + <radio_item label="Smooth" name="radio smooth"/> + <radio_item label="Roughen" name="radio noise"/> + <radio_item label="Revert" name="radio revert"/> + </radio_group> + <text name="Bulldozer:"> + Bulldozer: + </text> + <text name="Dozer Size:"> + Size + </text> + <slider_bar initial_value="2.0" name="slider brush size"/> + <text name="Strength:"> + Strength + </text> + <slider_bar initial_value="0.00" name="slider force"/> + <button label="套用" label_selected="套用" name="button apply to selection" tool_tip="Modify selected land"/> + <text name="obj_count"> + Objects: [COUNT] + </text> + <text name="prim_count"> + Prims: [COUNT] + </text> + <tab_container name="Object Info Tabs"> + <panel label="一般" name="General"> + <panel.string name="text deed continued"> + Deed + </panel.string> + <panel.string name="text deed"> + Deed + </panel.string> + <panel.string name="text modify info 1"> + You can modify this object + </panel.string> + <panel.string name="text modify info 2"> + You can modify these objects + </panel.string> + <panel.string name="text modify info 3"> + You can't modify this object + </panel.string> + <panel.string name="text modify info 4"> + You can't modify these objects + </panel.string> + <panel.string name="text modify warning"> + You must select entire object to set permissions + </panel.string> + <panel.string name="Cost Default"> + åƒ¹æ ¼ï¼š L$ + </panel.string> + <panel.string name="Cost Total"> + 總價: L$ + </panel.string> + <panel.string name="Cost Per Unit"> + Price Per: L$ + </panel.string> + <panel.string name="Cost Mixed"> + Mixed Price + </panel.string> + <panel.string name="Sale Mixed"> + Mixed Sale + </panel.string> + <text name="Name:"> + å稱: + </text> + <text name="Description:"> + æ述: + </text> + <text name="Creator:"> + å‰µé€ è€…ï¼š + </text> + <text name="Owner:"> + æ“有者: + </text> + <text name="Group:"> + Group: + </text> + <name_box initial_value="載入ä¸..." name="Group Name Proxy"/> + <button name="button set group" tool_tip="Choose a group to share this object's permissions"/> + <check_box label="分享" name="checkbox share with group" tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions."/> + <button label="Deed" label_selected="Deed" name="button deed" tool_tip="Deeding gives this item away with next owner permissions. Group shared objects can be deeded by a group officer."/> + <text name="label click action"> + Click to: + </text> + <combo_box name="clickaction"> + <combo_box.item label="Touch (default)" name="Touch/grab(default)"/> + <combo_box.item label="Sit on object" name="Sitonobject"/> + <combo_box.item label="Buy object" name="Buyobject"/> + <combo_box.item label="Pay object" name="Payobject"/> + <combo_box.item label="Open" name="Open"/> + <combo_box.item label="Zoom" name="Zoom"/> + </combo_box> + <check_box label="出售:" name="checkbox for sale"/> + <combo_box name="sale type"> + <combo_box.item label="副本" name="Copy"/> + <combo_box.item label="內容" name="Contents"/> + <combo_box.item label="原件" name="Original"/> + </combo_box> + <spinner label="åƒ¹æ ¼ï¼š L$" name="Edit Cost"/> + <check_box label="Show in search" name="search_check" tool_tip="Let people see this object in search results"/> + <panel name="perms_build"> + <text name="perm_modify"> + You can modify this object + </text> + <text name="Anyone can:"> + 任何人: + </text> + <check_box label="移動" name="checkbox allow everyone move"/> + <check_box label="覆製" name="checkbox allow everyone copy"/> + <text name="Next owner can:"> + 下一個æ“有者: + </text> + <check_box label="修改" name="checkbox next owner can modify"/> + <check_box label="覆製" name="checkbox next owner can copy"/> + <check_box label="轉移" name="checkbox next owner can transfer" tool_tip="下一個æ“有者å¯ä»¥é€äººæˆ–轉售這個物件"/> + <text name="B:"> + B: + </text> + <text name="O:"> + O: + </text> + <text name="G:"> + G: + </text> + <text name="E:"> + E: + </text> + <text name="N:"> + N: + </text> + <text name="F:"> + F: + </text> + </panel> + </panel> + <panel label="Object" name="Object"> + <check_box label="Locked" name="checkbox locked" tool_tip="Prevents object from being moved or deleted. Frequently useful during building to avoid unintended edits."/> + <check_box label="Physical" name="Physical Checkbox Ctrl" tool_tip="Allows object to be pushed and affected by gravity"/> + <check_box label="Temporary" name="Temporary Checkbox Ctrl" tool_tip="Causes object to be deleted 1 minute after creation"/> + <check_box label="Phantom" name="Phantom Checkbox Ctrl" tool_tip="Causes object to not collide with other objects or avatars"/> + <text name="label position"> + Position (meters) + </text> + <spinner label="X" name="Pos X"/> + <spinner label="Y" name="Pos Y"/> + <spinner label="Z" name="Pos Z"/> + <text name="label size"> + Size (meters) + </text> + <spinner label="X" name="Scale X"/> + <spinner label="Y" name="Scale Y"/> + <spinner label="Z" name="Scale Z"/> + <text name="label rotation"> + Rotation (degrees) + </text> + <spinner label="X" name="Rot X"/> + <spinner label="Y" name="Rot Y"/> + <spinner label="Z" name="Rot Z"/> + <combo_box name="comboBaseType"> + <combo_box.item label="Box" name="Box"/> + <combo_box.item label="Cylinder" name="Cylinder"/> + <combo_box.item label="Prism" name="Prism"/> + <combo_box.item label="Sphere" name="Sphere"/> + <combo_box.item label="Torus" name="Torus"/> + <combo_box.item label="Tube" name="Tube"/> + <combo_box.item label="Ring" name="Ring"/> + <combo_box.item label="Sculpted" name="Sculpted"/> + </combo_box> + <combo_box name="material"> + <combo_box.item label="Stone" name="Stone"/> + <combo_box.item label="Metal" name="Metal"/> + <combo_box.item label="Glass" name="Glass"/> + <combo_box.item label="Wood" name="Wood"/> + <combo_box.item label="Flesh" name="Flesh"/> + <combo_box.item label="Plastic" name="Plastic"/> + <combo_box.item label="Rubber" name="Rubber"/> + </combo_box> + <text name="text cut"> + Path Cut (begin/end) + </text> + <spinner label="B" name="cut begin"/> + <spinner label="E" name="cut end"/> + <text name="text hollow"> + Hollow + </text> + <text name="text skew"> + Skew + </text> + <text name="Hollow Shape"> + Hollow Shape + </text> + <combo_box name="hole"> + <combo_box.item label="é è¨" name="Default"/> + <combo_box.item label="Circle" name="Circle"/> + <combo_box.item label="Square" name="Square"/> + <combo_box.item label="Triangle" name="Triangle"/> + </combo_box> + <text name="text twist"> + Twist (begin/end) + </text> + <spinner label="B" name="Twist Begin"/> + <spinner label="E" name="Twist End"/> + <text name="scale_taper"> + Taper + </text> + <text name="scale_hole"> + Hole Size + </text> + <spinner label="X" name="Taper Scale X"/> + <spinner label="Y" name="Taper Scale Y"/> + <text name="text topshear"> + Top Shear + </text> + <spinner label="X" name="Shear X"/> + <spinner label="Y" name="Shear Y"/> + <text name="advanced_cut"> + Profile Cut (begin/end) + </text> + <text name="advanced_dimple"> + Dimple (begin/end) + </text> + <text name="advanced_slice"> + Slice (begin/end) + </text> + <spinner label="B" name="Path Limit Begin"/> + <spinner label="E" name="Path Limit End"/> + <text name="text taper2"> + Taper + </text> + <spinner label="X" name="Taper X"/> + <spinner label="Y" name="Taper Y"/> + <text name="text radius delta"> + Radius + </text> + <text name="text revolutions"> + Revolutions + </text> + <texture_picker label="Sculpt Texture" name="sculpt texture control" tool_tip="點擊以挑é¸åœ–片"/> + <check_box label="Mirror" name="sculpt mirror control" tool_tip="Flips sculpted prim along the X axis"/> + <check_box label="Inside-out" name="sculpt invert control" tool_tip="Inverts the sculpted prims normals, making it appear inside-out"/> + <text name="label sculpt type"> + Stitching type + </text> + <combo_box name="sculpt type control"> + <combo_box.item label="(無)" name="None"/> + <combo_box.item label="Sphere" name="Sphere"/> + <combo_box.item label="Torus" name="Torus"/> + <combo_box.item label="Plane" name="Plane"/> + <combo_box.item label="Cylinder" name="Cylinder"/> + </combo_box> + </panel> + <panel label="Features" name="Features"> + <text name="select_single"> + Select only one primitive to edit features. + </text> + <text name="edit_object"> + Edit object features: + </text> + <check_box label="Flexible Path" name="Flexible1D Checkbox Ctrl" tool_tip="Allows object to flex about the Z axis (Client-side only)"/> + <spinner label="Softness" name="FlexNumSections"/> + <spinner label="Gravity" name="FlexGravity"/> + <spinner label="Drag" name="FlexFriction"/> + <spinner label="Wind" name="FlexWind"/> + <spinner label="Tension" name="FlexTension"/> + <spinner label="Force X" name="FlexForceX"/> + <spinner label="Force Y" name="FlexForceY"/> + <spinner label="Force Z" name="FlexForceZ"/> + <check_box label="Light" name="Light Checkbox Ctrl" tool_tip="Causes object to emit light"/> + <color_swatch name="colorswatch" tool_tip="Click to open color picker"/> + <texture_picker label="" name="light texture control" tool_tip="Click to choose a projection image (only has effect with deferred rendering enabled)"/> + <spinner label="Intensity" name="Light Intensity"/> + <spinner label="FOV" name="Light FOV"/> + <spinner label="Radius" name="Light Radius"/> + <spinner label="Focus" name="Light Focus"/> + <spinner label="Falloff" name="Light Falloff"/> + <spinner label="Ambiance" name="Light Ambiance"/> + </panel> + <panel label="Texture" name="Texture"> + <panel.string name="string repeats per meter"> + Repeats Per Meter + </panel.string> + <panel.string name="string repeats per face"> + Repeats Per Face + </panel.string> + <texture_picker label="Texture" name="texture control" tool_tip="點擊以挑é¸åœ–片"/> + <color_swatch label="Color" name="colorswatch" tool_tip="Click to open color picker"/> + <text name="color trans"> + Transparency % + </text> + <text name="glow label"> + Glow + </text> + <check_box label="Full Bright" name="checkbox fullbright"/> + <text name="tex gen"> + Mapping + </text> + <combo_box name="combobox texgen"> + <combo_box.item label="é è¨" name="Default"/> + <combo_box.item label="Planar" name="Planar"/> + </combo_box> + <text name="label shininess"> + Shininess + </text> + <combo_box name="combobox shininess"> + <combo_box.item label="ç„¡" name="None"/> + <combo_box.item label="Low" name="Low"/> + <combo_box.item label="Medium" name="Medium"/> + <combo_box.item label="High" name="High"/> + </combo_box> + <text name="label bumpiness"> + Bumpiness + </text> + <combo_box name="combobox bumpiness"> + <combo_box.item label="ç„¡" name="None"/> + <combo_box.item label="Brightness" name="Brightness"/> + <combo_box.item label="Darkness" name="Darkness"/> + <combo_box.item label="woodgrain" name="woodgrain"/> + <combo_box.item label="bark" name="bark"/> + <combo_box.item label="bricks" name="bricks"/> + <combo_box.item label="checker" name="checker"/> + <combo_box.item label="concrete" name="concrete"/> + <combo_box.item label="crustytile" name="crustytile"/> + <combo_box.item label="cutstone" name="cutstone"/> + <combo_box.item label="discs" name="discs"/> + <combo_box.item label="gravel" name="gravel"/> + <combo_box.item label="petridish" name="petridish"/> + <combo_box.item label="siding" name="siding"/> + <combo_box.item label="stonetile" name="stonetile"/> + <combo_box.item label="stucco" name="stucco"/> + <combo_box.item label="suction" name="suction"/> + <combo_box.item label="weave" name="weave"/> + </combo_box> + <check_box initial_value="false" label="Align planar faces" name="checkbox planar align" tool_tip="Align textures on all selected faces with the last selected face. Requires Planar texture mapping."/> + <text name="rpt"> + Repeats / Face + </text> + <spinner label="Horizontal (U)" name="TexScaleU"/> + <check_box label="Flip" name="checkbox flip s"/> + <spinner label="Vertical (V)" name="TexScaleV"/> + <check_box label="Flip" name="checkbox flip t"/> + <spinner label="RotationËš" name="TexRot"/> + <spinner label="Repeats / Meter" name="rptctrl"/> + <button label="套用" label_selected="套用" name="button apply"/> + <text name="tex offset"> + Texture Offset + </text> + <spinner label="Horizontal (U)" name="TexOffsetU"/> + <spinner label="Vertical (V)" name="TexOffsetV"/> + <panel name="Add_Media"> + <text name="media_tex"> + Media + </text> + <button name="add_media" tool_tip="Add Media"/> + <button name="delete_media" tool_tip="Delete this media texture"/> + <button name="edit_media" tool_tip="Edit this Media"/> + <button label="Align" label_selected="Align Media" name="button align" tool_tip="Align media texture (must load first)"/> + </panel> + </panel> + <panel label="Content" name="Contents"> + <button label="New Script" label_selected="New Script" name="button new script"/> + <button label="Permissions" name="button permissions"/> + </panel> + </tab_container> + <panel name="land info panel"> + <text name="label_parcel_info"> + Parcel Information + </text> + <text name="label_area_price"> + Price: L$[PRICE] for [AREA] m² + </text> + <text name="label_area"> + é¢ç©ï¼š [AREA] m² + </text> + <button label="關於土地" label_selected="關於土地" name="button about land"/> + <check_box label="顯示æ“有主" name="checkbox show owners" tool_tip="Colorize the parcels according to the type of owner: + +Green = Your land +Aqua = Your group's land +Red = Owned by others +Yellow = For sale +Purple = For auction +Grey = Public"/> + <text name="label_parcel_modify"> + Modify Parcel + </text> + <button label="Subdivide" label_selected="Subdivide" name="button subdivide land"/> + <button label="Join" label_selected="Join" name="button join land"/> + <text name="label_parcel_trans"> + Land Transactions + </text> + <button label="購買土地" label_selected="購買土地" name="button buy land"/> + <button label="Abandon Land" label_selected="Abandon Land" name="button abandon land"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_top_objects.xml b/indra/newview/skins/default/xui/zh/floater_top_objects.xml new file mode 100644 index 0000000000..c1ad927bbb --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_top_objects.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="top_objects" title="Top Objects"> + <floater.string name="top_scripts_title"> + Top Scripts + </floater.string> + <floater.string name="top_scripts_text"> + [COUNT] scripts taking a total of [TIME] ms + </floater.string> + <floater.string name="scripts_score_label"> + Time + </floater.string> + <floater.string name="scripts_mono_time_label"> + Mono Time + </floater.string> + <floater.string name="top_colliders_title"> + Top Colliders + </floater.string> + <floater.string name="top_colliders_text"> + Top [COUNT] objects experiencing many potential collisions + </floater.string> + <floater.string name="colliders_score_label"> + Score + </floater.string> + <floater.string name="none_descriptor"> + None found. + </floater.string> + <text name="title_text"> + 載入ä¸... + </text> + <scroll_list name="objects_list"> + <scroll_list.columns label="Score" name="score"/> + <scroll_list.columns label="å稱" name="name"/> + <scroll_list.columns label="æ“有者" name="owner"/> + <scroll_list.columns label="ä½ç½®" name="location"/> + <scroll_list.columns label="Time" name="time"/> + <scroll_list.columns label="Mono Time" name="mono_time"/> + <scroll_list.columns label="URLs" name="URLs"/> + </scroll_list> + <text name="id_text"> + Object ID: + </text> + <button label="Show Beacon" name="show_beacon_btn"/> + <text name="obj_name_text"> + 物件å稱: + </text> + <button label="Filter" name="filter_object_btn"/> + <text name="owner_name_text"> + æ“有者: + </text> + <button label="Filter" name="filter_owner_btn"/> + <button label="Return Selected" name="return_selected_btn"/> + <button label="全部退回" name="return_all_btn"/> + <button label="Disable Selected" name="disable_selected_btn"/> + <button label="Disable All" name="disable_all_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_tos.xml b/indra/newview/skins/default/xui/zh/floater_tos.xml new file mode 100644 index 0000000000..acc61a7961 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_tos.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="modal container"> + <floater.string name="real_url"> + http://secondlife.com/app/tos/ + </floater.string> + <floater.string name="loading_url"> + data:text/html,%3Chtml%3E%3Chead%3E%3C/head%3E%3Cbody text=%22000000%22%3E%3Ch2%3E Loading %3Ca%20target%3D%22_external%22%20href%3D%22http%3A//secondlife.com/app/tos/%22%3ETerms%20of%20Service%3C/a%3E...%3C/h2%3E %3C/body%3E %3C/html%3E + </floater.string> + <button label="繼續" label_selected="繼續" name="Continue"/> + <button label="å–銷" label_selected="å–銷" name="Cancel"/> + <check_box label="我åŒæ„接å—æœå‹™æ¢æ¬¾åŠéš±ç§æ”¿ç–" name="agree_chk"/> + <text name="tos_heading"> + 請謹慎閱讀以下的æœå‹™æ¢æ¬¾åŠéš±ç§æ”¿ç–。è¦ç¹¼çºŒç™»å…¥åˆ° [SECOND_LIFE]ï¼Œä½ å¿…é ˆæŽ¥å—這些å”è°ã€‚ + </text> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_url_entry.xml b/indra/newview/skins/default/xui/zh/floater_url_entry.xml new file mode 100644 index 0000000000..2b4f5ea11d --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_url_entry.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="url_entry"> + <text name="media_label"> + Media URL: + </text> + <button label="" name="ok_btn"/> + <button label="å–銷" name="cancel_btn"/> + <button label="清除" name="clear_btn"/> + <text name="loading_label"> + 載入ä¸... + </text> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_voice_controls.xml b/indra/newview/skins/default/xui/zh/floater_voice_controls.xml new file mode 100644 index 0000000000..d4a76555cb --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_voice_controls.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_voice_controls" title="Voice Controls"> + <string name="title_nearby"> + NEARBY VOICE + </string> + <string name="title_group"> + Group Call with [GROUP] + </string> + <string name="title_adhoc"> + Conference Call + </string> + <string name="title_peer_2_peer"> + Call with [NAME] + </string> + <string name="no_one_near"> + No one near has voice enabled + </string> + <layout_stack name="my_call_stack"> + <layout_panel name="my_panel"> + <text name="user_text" value="My Avatar:"/> + </layout_panel> + <layout_panel name="leave_call_panel"> + <layout_stack name="voice_effect_and_leave_call_stack"> + <layout_panel name="leave_call_btn_panel"> + <button label="Leave Call" name="leave_call_btn"/> + </layout_panel> + </layout_stack> + </layout_panel> + </layout_stack> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_voice_effect.xml b/indra/newview/skins/default/xui/zh/floater_voice_effect.xml new file mode 100644 index 0000000000..b9021d25d9 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_voice_effect.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater label="Places" name="voice_effects" title="語音變è²"> + <string name="no_voice_effect"> + (No Voice Morph) + </string> + <string name="active_voice_effect"> + (Active) + </string> + <string name="unsubscribed_voice_effect"> + (Unsubscribed) + </string> + <string name="new_voice_effect"> + (New!) + </string> + <text name="preview_text"> + To Preview + </text> + <text name="status_text"> + Record a sample, then click on a voice to hear how it will sound. + </text> + <button label="Record" name="record_btn" tool_tip="Record a sample of your voice."/> + <button label="Stop" name="record_stop_btn"/> + <text name="voice_morphing_link"> + [[URL] Subscribe Now] + </text> + <scroll_list name="voice_effect_list" tool_tip="Record a sample of your voice, then click an effect to preview."> + <scroll_list.columns label="語音å稱" name="name"/> + <scroll_list.columns label="éŽæœŸ" name="expires"/> + </scroll_list> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_water.xml b/indra/newview/skins/default/xui/zh/floater_water.xml new file mode 100644 index 0000000000..2e0fcd13a8 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_water.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="Water Floater" title="ADVANCED WATER EDITOR"> + <floater.string name="WLDefaultWaterNames"> + Default:Glassy:Pond:Murky:Second Plague:SNAKE!!!:Valdez + </floater.string> + <text name="KeyFramePresetsText"> + Water Presets: + </text> + <button label="New" label_selected="New" name="WaterNewPreset"/> + <button label="儲å˜" label_selected="儲å˜" name="WaterSavePreset"/> + <button label="刪除" label_selected="刪除" name="WaterDeletePreset"/> + <tab_container name="Water Tabs"> + <panel label="è¨å®š" name="Settings"> + <text name="BHText"> + Water Fog Color + </text> + <color_swatch name="WaterFogColor" tool_tip="Click to open color picker"/> + <text name="WaterFogDensText"> + Fog Density Exponent + </text> + <text name="WaterUnderWaterFogModText"> + Underwater Fog Modifier + </text> + <text name="BDensText"> + Reflection Wavelet Scale + </text> + <slider label="1" name="WaterNormalScaleX"/> + <slider label="2" name="WaterNormalScaleY"/> + <slider label="3" name="WaterNormalScaleZ"/> + <text name="HDText"> + Fresnel Scale + </text> + <text name="FresnelOffsetText"> + Fresnel Offset + </text> + <text name="DensMultText"> + Refract Scale Above + </text> + <text name="WaterScaleBelowText"> + Refract Scale Below + </text> + <text name="MaxAltText"> + Blur Multiplier + </text> + </panel> + <panel label="IMAGE" name="Waves"> + <text name="BHText"> + Big Wave Direction + </text> + <text name="WaterWave1DirXText"> + X + </text> + <text name="WaterWave1DirYText"> + Y + </text> + <text name="BHText2"> + Little Wave Direction + </text> + <text name="WaterWave2DirXText"> + X + </text> + <text name="WaterWave2DirYText"> + Y + </text> + <text name="BHText3"> + Normal Map + </text> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_web_content.xml b/indra/newview/skins/default/xui/zh/floater_web_content.xml new file mode 100644 index 0000000000..2670e223d3 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_web_content.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_web_content" title=""> + <layout_stack name="stack1"> + <layout_panel name="nav_controls"> + <button name="back" tool_tip="Navigate back"/> + <button name="forward" tool_tip="Navigate forward"/> + <button name="stop" tool_tip="Stop navigation"/> + <button name="reload" tool_tip="é‡è¼‰é é¢"/> + <combo_box name="address" tool_tip="Enter URL here"/> + <icon name="media_secure_lock_flag" tool_tip="Secured Browsing"/> + <button name="popexternal" tool_tip="Open current URL in your desktop browser"/> + </layout_panel> + </layout_stack> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_whitelist_entry.xml b/indra/newview/skins/default/xui/zh/floater_whitelist_entry.xml new file mode 100644 index 0000000000..ea360be6c9 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_whitelist_entry.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="whitelist_entry" title="WHITELIST ENTRY"> + <text name="media_label"> + Enter a URL or URL pattern to add to the list of allowed domains + </text> + <line_editor name="whitelist_entry" tool_tip="Enter a URL or URL pattern to White List"/> + <button label="確定" name="ok_btn"/> + <button label="å–銷" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_windlight_options.xml b/indra/newview/skins/default/xui/zh/floater_windlight_options.xml new file mode 100644 index 0000000000..2b202a9e6c --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_windlight_options.xml @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="WindLight floater" title="ADVANCED SKY EDITOR"> + <floater.string name="WLDefaultSkyNames"> + A-12AM:A-12PM:A-3AM:A-3PM:A-4.30PM:A-6AM:A-6PM:A-9AM:A-9PM:Barcelona:Blizzard:Blue Midday:Coastal Afternoon:Coastal Sunset:Default:Desert Sunset:Fine Day:Fluffy Big Clouds:Foggy:Funky Funky:Funky Funky Funky:Gelatto:Ghost:Incongruent Truths:Midday 1:Midday 2:Midday 3:Midday 4:Night:Pirate:Purple:Sailor's Delight:Sheer Sensuality + </floater.string> + <text name="KeyFramePresetsText"> + Sky Presets: + </text> + <button label="New" label_selected="New" name="WLNewPreset"/> + <button label="儲å˜" label_selected="儲å˜" name="WLSavePreset"/> + <button label="刪除" label_selected="刪除" name="WLDeletePreset"/> + <button label="Day Cycle Editor" label_selected="Day Cycle Editor" name="WLDayCycleMenuButton"/> + <tab_container name="WindLight Tabs"> + <panel label="ATMOSPHERE" name="Atmosphere"> + <text name="BHText"> + Blue Horizon + </text> + <text name="BHText2"> + R + </text> + <text name="BHText3"> + G + </text> + <text name="BHText4"> + B + </text> + <text name="BHText5"> + I + </text> + <text name="BDensText"> + Haze Horizon + </text> + <text name="BDensText2"> + Blue Density + </text> + <text name="BHText6"> + R + </text> + <text name="BHText7"> + G + </text> + <text name="BHText8"> + B + </text> + <text name="BHText9"> + I + </text> + <text name="HDText"> + Haze Density + </text> + <text name="DensMultText"> + Density Multiplier + </text> + <text name="WLDistanceMultText"> + Distance Multiplier + </text> + <text name="MaxAltText"> + Max Altitude + </text> + </panel> + <panel label="LIGHTING" name="Lighting"> + <text name="SLCText"> + Sun/Moon Color + </text> + <text name="BHText"> + R + </text> + <text name="BHText2"> + G + </text> + <text name="BHText3"> + B + </text> + <text name="BHText4"> + I + </text> + <text name="TODText"> + Sun/Moon Position + </text> + <text name="WLAmbientText"> + Ambient + </text> + <text name="BHText5"> + R + </text> + <text name="BHText6"> + G + </text> + <text name="BHText7"> + B + </text> + <text name="BHText8"> + I + </text> + <text name="WLEastAngleText"> + East Angle + </text> + <text name="SunGlowText"> + Sun Glow + </text> + <slider label="Focus" name="WLGlowB"/> + <slider label="Size" name="WLGlowR"/> + <text name="SceneGammaText"> + Scene Gamma + </text> + <text name="WLStarText"> + Star Brightness + </text> + </panel> + <panel label="CLOUDS" name="Clouds"> + <text name="WLCloudColorText"> + Cloud Color + </text> + <text name="BHText"> + R + </text> + <text name="BHText2"> + G + </text> + <text name="BHText3"> + B + </text> + <text name="BHText4"> + I + </text> + <text name="WLCloudColorText2"> + Cloud XY/Density + </text> + <text name="BHText5"> + X + </text> + <text name="BHText6"> + Y + </text> + <text name="BHText7"> + D + </text> + <text name="WLCloudCoverageText"> + Cloud Coverage + </text> + <text name="WLCloudScaleText"> + Cloud Scale + </text> + <text name="WLCloudDetailText"> + Cloud Detail (XY/Density) + </text> + <text name="BHText8"> + X + </text> + <text name="BHText9"> + Y + </text> + <text name="BHText10"> + D + </text> + <text name="WLCloudScrollXText"> + Cloud Scroll X + </text> + <check_box label="Lock" name="WLCloudLockX"/> + <text name="WLCloudScrollYText"> + Cloud Scroll Y + </text> + <check_box label="Lock" name="WLCloudLockY"/> + <check_box label="Draw Classic Clouds" name="DrawClassicClouds"/> + </panel> + </tab_container> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_window_size.xml b/indra/newview/skins/default/xui/zh/floater_window_size.xml new file mode 100644 index 0000000000..34b969c2dc --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_window_size.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="window_size" title="WINDOW SIZE"> + <string name="resolution_format"> + [RES_X] x [RES_Y] + </string> + <text name="windowsize_text"> + Set window size: + </text> + <combo_box name="window_size_combo" tool_tip="width x height"> + <combo_box.item label="1000 x 700 (default)" name="item0"/> + <combo_box.item label="1024 x 768" name="item1"/> + <combo_box.item label="1280 x 720 (720p)" name="item2"/> + <combo_box.item label="1920 x 1080 (1080p)" name="item3"/> + </combo_box> + <button label="è¨å®š" name="set_btn"/> + <button label="å–銷" name="cancel_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/floater_world_map.xml b/indra/newview/skins/default/xui/zh/floater_world_map.xml new file mode 100644 index 0000000000..e149285ab2 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/floater_world_map.xml @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="worldmap" title="世界地圖"> + <panel name="layout_panel_1"> + <text name="events_label"> + Legend + </text> + </panel> + <panel name="layout_panel_2"> + <button name="Show My Location" tool_tip="Center map on my avatar's location"/> + <text name="me_label"> + Me + </text> + <text name="person_label"> + Person + </text> + <text name="infohub_label"> + Infohub + </text> + <text name="land_sale_label"> + Land Sale + </text> + <text name="auction_label"> + land auction + </text> + <text name="by_owner_label"> + by owner + </text> + <button name="Go Home" tool_tip="Teleport to my home location"/> + <text name="Home_label"> + Home + </text> + <text name="events_label"> + Events: + </text> + <text name="pg_label"> + 一般 + </text> + <check_box initial_value="true" name="events_mature_chk"/> + <text name="events_mature_label"> + Moderate + </text> + <text name="events_adult_label"> + Adult + </text> + </panel> + <panel name="layout_panel_3"> + <text name="find_on_map_label"> + Find on Map + </text> + </panel> + <panel name="layout_panel_4"> + <combo_box label="Online Friends" name="friend combo" tool_tip="Show friends on map"> + <combo_box.item label="My Friends Online" name="item1"/> + </combo_box> + <combo_box label="My Landmarks" name="landmark combo" tool_tip="Landmark to show on map"> + <combo_box.item label="My Landmarks" name="item1"/> + </combo_box> + <search_editor label="Regions by Name" name="location" tool_tip="Type the name of a region"/> + <button label="Find" name="DoSearch" tool_tip="Search for region"/> + <button name="Clear" tool_tip="Clear tracking lines and reset map"/> + <text name="events_label"> + ä½ç½®ï¼š + </text> + <button label="Teleport" name="Teleport" tool_tip="Teleport to selected location"/> + <button label="Copy SLurl" name="copy_slurl" tool_tip="Copies current location as SLurl to be used on the web."/> + <button label="Show Selection" name="Show Destination" tool_tip="Center map on selected location"/> + </panel> + <panel name="layout_panel_5"> + <text name="zoom_label"> + Zoom + </text> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/zh/inspect_avatar.xml b/indra/newview/skins/default/xui/zh/inspect_avatar.xml new file mode 100644 index 0000000000..df450937fd --- /dev/null +++ b/indra/newview/skins/default/xui/zh/inspect_avatar.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<!-- + Not can_close / no title to avoid window chrome + Single instance - only have one at a time, recycle it each spawn +--> +<floater name="inspect_avatar"> + <string name="Subtitle"> + [AGE] + </string> + <string name="Details"> + [SL_PROFILE] + </string> + <text name="user_subtitle" value="11 Months, 3 days old"/> + <text name="user_details"> + This is my second life description and I really think it is great. But for some reason my description is super extra long because I like to talk a whole lot + </text> + <slider name="volume_slider" tool_tip="Voice volume" value="0.5"/> + <button label="åŠ ç‚ºæœ‹å‹" name="add_friend_btn"/> + <button label="IM" name="im_btn"/> + <button label="Profile" name="view_profile_btn"/> + <panel name="moderator_panel"> + <button label="Disable Voice" name="disable_voice"/> + <button label="Enable Voice" name="enable_voice"/> + </panel> +</floater> diff --git a/indra/newview/skins/default/xui/zh/inspect_group.xml b/indra/newview/skins/default/xui/zh/inspect_group.xml new file mode 100644 index 0000000000..72e5eade9c --- /dev/null +++ b/indra/newview/skins/default/xui/zh/inspect_group.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<!-- + Not can_close / no title to avoid window chrome + Single instance - only have one at a time, recycle it each spawn +--> +<floater name="inspect_group"> + <string name="PrivateGroup"> + Private group + </string> + <string name="FreeToJoin"> + Free to join + </string> + <string name="CostToJoin"> + L$[AMOUNT] to join + </string> + <string name="YouAreMember"> + You are a member + </string> + <text name="group_subtitle"> + 123 members + </text> + <text name="group_details"> + A group of folks charged with creating a room with a moose. +Fear the moose! Fear it! And the mongoose too! + </text> + <text name="group_cost"> + L$123 to join + </text> + <button label="Join" name="join_btn"/> + <button label="Leave" name="leave_btn"/> + <button label="View Profile" name="view_profile_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/inspect_object.xml b/indra/newview/skins/default/xui/zh/inspect_object.xml new file mode 100644 index 0000000000..f1fe037087 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/inspect_object.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<!-- + Not can_close / no title to avoid window chrome + Single instance - only have one at a time, recycle it each spawn +--> +<floater name="inspect_object"> + <string name="Creator"> + By [CREATOR] + </string> + <string name="CreatorAndOwner"> + By [CREATOR] +Owner [OWNER] + </string> + <string name="Price"> + L$[AMOUNT] + </string> + <string name="PriceFree"> + Free! + </string> + <string name="Touch"> + Touch + </string> + <string name="Sit"> + Sit + </string> + <text name="object_creator"> + by secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about +owner secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about + </text> + <text name="price_text"> + L$30,000 + </text> + <icon name="secure_browsing" tool_tip="Secure Browsing"/> + <text name="object_media_url"> + http://www.superdupertest.com + </text> + <button label="購買" name="buy_btn"/> + <button label="Pay" name="pay_btn"/> + <button label="å–得副本" name="take_free_copy_btn"/> + <button label="Touch" name="touch_btn"/> + <button label="Sit" name="sit_btn"/> + <button label="Open" name="open_btn"/> + <button label="More" name="more_info_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/inspect_remote_object.xml b/indra/newview/skins/default/xui/zh/inspect_remote_object.xml new file mode 100644 index 0000000000..26f49ce69a --- /dev/null +++ b/indra/newview/skins/default/xui/zh/inspect_remote_object.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<!-- + Not can_close / no title to avoid window chrome + Single instance - only have one at a time, recycle it each spawn +--> +<floater name="inspect_remote_object"> + <text name="object_name"> + Test Object Name That Is Really Long OMG so long I can't believe how long the name of this object is, I mean really. + </text> + <text name="object_owner_label"> + æ“有者: + </text> + <text name="object_owner"> + Longavatarname Johnsonlongstonnammer + </text> + <text name="object_slurl"> + http://slurl.com/Ahern/50/50/50 + </text> + <button label="地圖" name="map_btn"/> + <button label="Block" name="block_btn"/> + <button label="關閉" name="close_btn"/> +</floater> diff --git a/indra/newview/skins/default/xui/zh/menu_add_wearable_gear.xml b/indra/newview/skins/default/xui/zh/menu_add_wearable_gear.xml new file mode 100644 index 0000000000..3c8c3e4a31 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_add_wearable_gear.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="Add Wearable Gear Menu"> + <menu_item_check label="ä¾æœ€è¿‘排åº" name="sort_by_most_recent"/> + <menu_item_check label="ä¾å稱排åº" name="sort_by_name"/> + <menu_item_check label="ä¾é¡žåž‹æŽ’åº" name="sort_by_type"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_attachment_other.xml b/indra/newview/skins/default/xui/zh/menu_attachment_other.xml new file mode 100644 index 0000000000..b674ed2763 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_attachment_other.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<!-- *NOTE: See also menu_avatar_other.xml --> +<context_menu name="Avatar Pie"> + <menu_item_call label="View Profile" name="Profile..."/> + <menu_item_call label="åŠ ç‚ºæœ‹å‹" name="Add Friend"/> + <menu_item_call label="IM" name="Send IM..."/> + <menu_item_call label="Call" name="Call"/> + <menu_item_call label="Invite to Group" name="Invite..."/> + <menu_item_call label="Block" name="Avatar Mute"/> + <menu_item_call label="Report" name="abuse"/> + <menu_item_call label="Freeze" name="Freeze..."/> + <menu_item_call label="Eject" name="Eject..."/> + <menu_item_call label="Debug Textures" name="Debug..."/> + <menu_item_call label="Zoom In" name="Zoom In"/> + <menu_item_call label="Pay" name="Pay..."/> + <menu_item_call label="Object Profile" name="Object Inspect"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_attachment_self.xml b/indra/newview/skins/default/xui/zh/menu_attachment_self.xml new file mode 100644 index 0000000000..2089f8d58a --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_attachment_self.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Attachment Pie"> + <menu_item_call label="Touch" name="Attachment Object Touch"/> + <menu_item_call label="編輯" name="Edit..."/> + <menu_item_call label="å¸ä¸‹" name="Detach"/> + <menu_item_call label="å下" name="Sit Down Here"/> + <menu_item_call label="èµ·ç«‹" name="Stand Up"/> + <menu_item_call label="My Appearance" name="Change Outfit"/> + <menu_item_call label="Edit My Outfit" name="Edit Outfit"/> + <menu_item_call label="Edit My Shape" name="Edit My Shape"/> + <menu_item_call label="My Friends" name="Friends..."/> + <menu_item_call label="My Groups" name="Groups..."/> + <menu_item_call label="My Profile" name="Profile..."/> + <menu_item_call label="Debug Textures" name="Debug..."/> + <menu_item_call label="Drop" name="Drop"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_avatar_icon.xml b/indra/newview/skins/default/xui/zh/menu_avatar_icon.xml new file mode 100644 index 0000000000..cce8fa3ca6 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_avatar_icon.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="Avatar Icon Menu"> + <menu_item_call label="View Profile" name="Show Profile"/> + <menu_item_call label="Send IM..." name="Send IM"/> + <menu_item_call label="åŠ ç‚ºæœ‹å‹..." name="Add Friend"/> + <menu_item_call label="Remove Friend..." name="Remove Friend"/> +</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_avatar_other.xml b/indra/newview/skins/default/xui/zh/menu_avatar_other.xml new file mode 100644 index 0000000000..db22646ced --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_avatar_other.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<!-- *NOTE: See also menu_attachment_other.xml --> +<context_menu name="Avatar Pie"> + <menu_item_call label="View Profile" name="Profile..."/> + <menu_item_call label="åŠ ç‚ºæœ‹å‹" name="Add Friend"/> + <menu_item_call label="IM" name="Send IM..."/> + <menu_item_call label="Call" name="Call"/> + <menu_item_call label="Invite to Group" name="Invite..."/> + <menu_item_call label="Block" name="Avatar Mute"/> + <menu_item_call label="Report" name="abuse"/> + <menu_item_call label="Freeze" name="Freeze..."/> + <menu_item_call label="Eject" name="Eject..."/> + <menu_item_call label="Debug Textures" name="Debug..."/> + <menu_item_call label="Zoom In" name="Zoom In"/> + <menu_item_call label="Pay" name="Pay..."/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_avatar_self.xml b/indra/newview/skins/default/xui/zh/menu_avatar_self.xml new file mode 100644 index 0000000000..bccae5b547 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_avatar_self.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Self Pie"> + <menu_item_call label="å下" name="Sit Down Here"/> + <menu_item_call label="èµ·ç«‹" name="Stand Up"/> + <context_menu label="脫下" name="Take Off >"> + <context_menu label="Clothes" name="Clothes >"> + <menu_item_call label="襯衫" name="Shirt"/> + <menu_item_call label="褲å" name="Pants"/> + <menu_item_call label="裙å" name="Skirt"/> + <menu_item_call label="éž‹å" name="Shoes"/> + <menu_item_call label="襪å" name="Socks"/> + <menu_item_call label="夾克" name="Jacket"/> + <menu_item_call label="手套" name="Gloves"/> + <menu_item_call label="內衣" name="Self Undershirt"/> + <menu_item_call label="內褲" name="Self Underpants"/> + <menu_item_call label="刺é’" name="Self Tattoo"/> + <menu_item_call label="Physics" name="Self Physics"/> + <menu_item_call label="Alpha" name="Self Alpha"/> + <menu_item_call label="All Clothes" name="All Clothes"/> + </context_menu> + <context_menu label="HUD" name="Object Detach HUD"/> + <context_menu label="å¸ä¸‹" name="Object Detach"/> + <menu_item_call label="全部å¸ä¸‹" name="Detach All"/> + </context_menu> + <menu_item_call label="My Appearance" name="Chenge Outfit"/> + <menu_item_call label="Edit My Outfit" name="Edit Outfit"/> + <menu_item_call label="Edit My Shape" name="Edit My Shape"/> + <menu_item_call label="My Friends" name="Friends..."/> + <menu_item_call label="My Groups" name="Groups..."/> + <menu_item_call label="My Profile" name="Profile..."/> + <menu_item_call label="Debug Textures" name="Debug..."/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_bottomtray.xml b/indra/newview/skins/default/xui/zh/menu_bottomtray.xml new file mode 100644 index 0000000000..d55b3afc95 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_bottomtray.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="hide_camera_move_controls_menu"> + <menu_item_check label="Speak Button" name="EnableVoiceChat"/> + <menu_item_check label="Gesture button" name="ShowGestureButton"/> + <menu_item_check label="Move button" name="ShowMoveButton"/> + <menu_item_check label="View button" name="ShowCameraButton"/> + <menu_item_check label="Snapshot button" name="ShowSnapshotButton"/> + <menu_item_check label="Build button" name="ShowBuildButton"/> + <menu_item_check label="Search button" name="ShowSearchButton"/> + <menu_item_check label="地圖按鈕" name="ShowWorldMapButton"/> + <menu_item_check label="è¿·ä½ åœ°åœ–æŒ‰éˆ•" name="ShowMiniMapButton"/> + <menu_item_call label="剪下" name="NearbyChatBar_Cut"/> + <menu_item_call label="覆製" name="NearbyChatBar_Copy"/> + <menu_item_call label="貼上" name="NearbyChatBar_Paste"/> + <menu_item_call label="刪除" name="NearbyChatBar_Delete"/> + <menu_item_call label="å…¨é¸" name="NearbyChatBar_Select_All"/> +</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_cof_attachment.xml b/indra/newview/skins/default/xui/zh/menu_cof_attachment.xml new file mode 100644 index 0000000000..876fef16df --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_cof_attachment.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="COF Attachment"> + <menu_item_call label="å¸ä¸‹" name="detach"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_cof_body_part.xml b/indra/newview/skins/default/xui/zh/menu_cof_body_part.xml new file mode 100644 index 0000000000..d06207b19d --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_cof_body_part.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="COF Body"> + <menu_item_call label="å–代" name="replace"/> + <menu_item_call label="編輯" name="edit"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_cof_clothing.xml b/indra/newview/skins/default/xui/zh/menu_cof_clothing.xml new file mode 100644 index 0000000000..300ff47b12 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_cof_clothing.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="COF Clothing"> + <menu_item_call label="脫下" name="take_off"/> + <menu_item_call label="編輯" name="edit"/> + <menu_item_call label="å–代" name="replace"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_cof_gear.xml b/indra/newview/skins/default/xui/zh/menu_cof_gear.xml new file mode 100644 index 0000000000..7314676c6c --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_cof_gear.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="Gear COF"> + <menu label="New Clothes" name="COF.Gear.New_Clothes"/> + <menu label="New Body Parts" name="COF.Geear.New_Body_Parts"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_edit.xml b/indra/newview/skins/default/xui/zh/menu_edit.xml new file mode 100644 index 0000000000..1e645acc7a --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_edit.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu label="編輯" name="Edit"> + <menu_item_call label="復原" name="Undo"/> + <menu_item_call label="Redo" name="Redo"/> + <menu_item_call label="剪下" name="Cut"/> + <menu_item_call label="覆製" name="Copy"/> + <menu_item_call label="貼上" name="Paste"/> + <menu_item_call label="刪除" name="Delete"/> + <menu_item_call label="覆製貼上" name="Duplicate"/> + <menu_item_call label="å…¨é¸" name="Select All"/> + <menu_item_call label="Deselect" name="Deselect"/> +</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_favorites.xml b/indra/newview/skins/default/xui/zh/menu_favorites.xml new file mode 100644 index 0000000000..042f5c3a93 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_favorites.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="Popup"> + <menu_item_call label="Teleport" name="Teleport To Landmark"/> + <menu_item_call label="View/Edit Landmark" name="Landmark Open"/> + <menu_item_call label="Copy SLurl" name="Copy slurl"/> + <menu_item_call label="顯示在地圖上" name="Show On Map"/> + <menu_item_call label="覆製" name="Landmark Copy"/> + <menu_item_call label="貼上" name="Landmark Paste"/> + <menu_item_call label="刪除" name="Delete"/> +</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_gesture_gear.xml b/indra/newview/skins/default/xui/zh/menu_gesture_gear.xml new file mode 100644 index 0000000000..488d80bfad --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_gesture_gear.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="menu_gesture_gear"> + <menu_item_call label="Add/Remove from Favorites" name="activate"/> + <menu_item_call label="覆製" name="copy_gesture"/> + <menu_item_call label="貼上" name="paste"/> + <menu_item_call label="Copy UUID" name="copy_uuid"/> + <menu_item_call label="Save to current outfit" name="save_to_outfit"/> + <menu_item_call label="編輯" name="edit_gesture"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_group_plus.xml b/indra/newview/skins/default/xui/zh/menu_group_plus.xml new file mode 100644 index 0000000000..77c2c92491 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_group_plus.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="menu_group_plus"> + <menu_item_call label="Join Group..." name="item_join"/> + <menu_item_call label="New Group..." name="item_new"/> +</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_hide_navbar.xml b/indra/newview/skins/default/xui/zh/menu_hide_navbar.xml new file mode 100644 index 0000000000..f03749533e --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_hide_navbar.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="hide_navbar_menu"> + <menu_item_check label="Show Navigation Bar" name="ShowNavbarNavigationPanel"/> + <menu_item_check label="Show Favorites Bar" name="ShowNavbarFavoritesPanel"/> + <menu_item_check label="Show Mini-Location Bar" name="ShowMiniLocationPanel"/> +</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_im_well_button.xml b/indra/newview/skins/default/xui/zh/menu_im_well_button.xml new file mode 100644 index 0000000000..4b9b4b2758 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_im_well_button.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="IM Well Button Context Menu"> + <menu_item_call label="全部關閉" name="Close All"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_imchiclet_adhoc.xml b/indra/newview/skins/default/xui/zh/menu_imchiclet_adhoc.xml new file mode 100644 index 0000000000..6cf86327be --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_imchiclet_adhoc.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="IMChiclet AdHoc Menu"> + <menu_item_call label="End Session" name="End Session"/> +</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_imchiclet_group.xml b/indra/newview/skins/default/xui/zh/menu_imchiclet_group.xml new file mode 100644 index 0000000000..7ca805278a --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_imchiclet_group.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="IMChiclet Group Menu"> + <menu_item_call label="Group Info" name="Show Profile"/> + <menu_item_call label="Show Session" name="Chat"/> + <menu_item_call label="End Session" name="End Session"/> +</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_imchiclet_p2p.xml b/indra/newview/skins/default/xui/zh/menu_imchiclet_p2p.xml new file mode 100644 index 0000000000..d9254f7aff --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_imchiclet_p2p.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="IMChiclet P2P Menu"> + <menu_item_call label="View Profile" name="Show Profile"/> + <menu_item_call label="åŠ ç‚ºæœ‹å‹" name="Add Friend"/> + <menu_item_call label="Show Session" name="Send IM"/> + <menu_item_call label="End Session" name="End Session"/> +</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/zh/menu_inspect_avatar_gear.xml new file mode 100644 index 0000000000..2ed6cfad89 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_inspect_avatar_gear.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<toggleable_menu name="Gear Menu"> + <menu_item_call label="View Profile" name="view_profile"/> + <menu_item_call label="åŠ ç‚ºæœ‹å‹" name="add_friend"/> + <menu_item_call label="IM" name="im"/> + <menu_item_call label="Call" name="call"/> + <menu_item_call label="Teleport" name="teleport"/> + <menu_item_call label="Invite to Group" name="invite_to_group"/> + <menu_item_call label="Block" name="block"/> + <menu_item_call label="Unblock" name="unblock"/> + <menu_item_call label="Report" name="report"/> + <menu_item_call label="Freeze" name="freeze"/> + <menu_item_call label="Eject" name="eject"/> + <menu_item_call label="Kick" name="kick"/> + <menu_item_call label="CSR" name="csr"/> + <menu_item_call label="Debug Textures" name="debug"/> + <menu_item_call label="Find On Map" name="find_on_map"/> + <menu_item_call label="Zoom In" name="zoom_in"/> + <menu_item_call label="Pay" name="pay"/> + <menu_item_call label="分享" name="share"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/zh/menu_inspect_object_gear.xml new file mode 100644 index 0000000000..41ea648803 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_inspect_object_gear.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<toggleable_menu name="Gear Menu"> + <menu_item_call label="Touch" name="touch"/> + <menu_item_call label="Sit" name="sit"/> + <menu_item_call label="Pay" name="pay"/> + <menu_item_call label="購買" name="buy"/> + <menu_item_call label="Take" name="take"/> + <menu_item_call label="å–得副本" name="take_copy"/> + <menu_item_call label="Open" name="open"/> + <menu_item_call label="編輯" name="edit"/> + <menu_item_call label="Wear" name="wear"/> + <menu_item_call label="Add" name="add"/> + <menu_item_call label="Report" name="report"/> + <menu_item_call label="Block" name="block"/> + <menu_item_call label="Zoom In" name="zoom_in"/> + <menu_item_call label="Remove" name="remove"/> + <menu_item_call label="更多資訊" name="more_info"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/zh/menu_inspect_self_gear.xml new file mode 100644 index 0000000000..c88826708e --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_inspect_self_gear.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="Self Pie"> + <menu_item_call label="å下" name="Sit Down Here"/> + <menu_item_call label="èµ·ç«‹" name="Stand Up"/> + <context_menu label="脫下" name="Take Off >"> + <context_menu label="Clothes" name="Clothes >"> + <menu_item_call label="襯衫" name="Shirt"/> + <menu_item_call label="褲å" name="Pants"/> + <menu_item_call label="裙å" name="Skirt"/> + <menu_item_call label="éž‹å" name="Shoes"/> + <menu_item_call label="襪å" name="Socks"/> + <menu_item_call label="夾克" name="Jacket"/> + <menu_item_call label="手套" name="Gloves"/> + <menu_item_call label="內衣" name="Self Undershirt"/> + <menu_item_call label="內褲" name="Self Underpants"/> + <menu_item_call label="刺é’" name="Self Tattoo"/> + <menu_item_call label="Alpha" name="Self Alpha"/> + <menu_item_call label="All Clothes" name="All Clothes"/> + </context_menu> + <context_menu label="HUD" name="Object Detach HUD"/> + <context_menu label="å¸ä¸‹" name="Object Detach"/> + <menu_item_call label="全部å¸ä¸‹" name="Detach All"/> + </context_menu> + <menu_item_call label="Change Outfit" name="Chenge Outfit"/> + <menu_item_call label="Edit My Outfit" name="Edit Outfit"/> + <menu_item_call label="Edit My Shape" name="Edit My Shape"/> + <menu_item_call label="My Friends" name="Friends..."/> + <menu_item_call label="My Groups" name="Groups..."/> + <menu_item_call label="My Profile" name="Profile..."/> + <menu_item_call label="Debug Textures" name="Debug..."/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_inv_offer_chiclet.xml b/indra/newview/skins/default/xui/zh/menu_inv_offer_chiclet.xml new file mode 100644 index 0000000000..577e5988f8 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_inv_offer_chiclet.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="InvOfferChiclet Menu"> + <menu_item_call label="關閉" name="Close"/> +</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_inventory.xml b/indra/newview/skins/default/xui/zh/menu_inventory.xml new file mode 100644 index 0000000000..086a89fc33 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_inventory.xml @@ -0,0 +1,87 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="Popup"> + <menu_item_call label="分享" name="Share"/> + <menu_item_call label="購買" name="Task Buy"/> + <menu_item_call label="Open" name="Task Open"/> + <menu_item_call label="Play" name="Task Play"/> + <menu_item_call label="Properties" name="Task Properties"/> + <menu_item_call label="æ›´å" name="Task Rename"/> + <menu_item_call label="刪除" name="Task Remove"/> + <menu_item_call label="清空垃圾ç’" name="Empty Trash"/> + <menu_item_call label="Empty Lost And Found" name="Empty Lost And Found"/> + <menu_item_call label="新資料夾" name="New Folder"/> + <menu_item_call label="New Script" name="New Script"/> + <menu_item_call label="New Notecard" name="New Note"/> + <menu_item_call label="New Gesture" name="New Gesture"/> + <menu label="New Clothes" name="New Clothes"> + <menu_item_call label="新襯衫" name="New Shirt"/> + <menu_item_call label="新褲å" name="New Pants"/> + <menu_item_call label="æ–°éž‹å" name="New Shoes"/> + <menu_item_call label="新襪å" name="New Socks"/> + <menu_item_call label="新夾克" name="New Jacket"/> + <menu_item_call label="新裙å" name="New Skirt"/> + <menu_item_call label="新手套" name="New Gloves"/> + <menu_item_call label="新內衣" name="New Undershirt"/> + <menu_item_call label="新內褲" name="New Underpants"/> + <menu_item_call label="New Alpha Mask" name="New Alpha Mask"/> + <menu_item_call label="New Tattoo" name="New Tattoo"/> + <menu_item_call label="New Physics" name="New Physics"/> + </menu> + <menu label="New Body Parts" name="New Body Parts"> + <menu_item_call label="New Shape" name="New Shape"/> + <menu_item_call label="New Skin" name="New Skin"/> + <menu_item_call label="New Hair" name="New Hair"/> + <menu_item_call label="New Eyes" name="New Eyes"/> + </menu> + <menu label="Change Type" name="Change Type"> + <menu_item_call label="é è¨" name="Default"/> + <menu_item_call label="手套" name="Gloves"/> + <menu_item_call label="夾克" name="Jacket"/> + <menu_item_call label="褲å" name="Pants"/> + <menu_item_call label="Shape" name="Shape"/> + <menu_item_call label="éž‹å" name="Shoes"/> + <menu_item_call label="襯衫" name="Shirt"/> + <menu_item_call label="裙å" name="Skirt"/> + <menu_item_call label="內褲" name="Underpants"/> + <menu_item_call label="內衣" name="Undershirt"/> + </menu> + <menu_item_call label="Teleport" name="Landmark Open"/> + <menu_item_call label="Open" name="Animation Open"/> + <menu_item_call label="Open" name="Sound Open"/> + <menu_item_call label="Replace Current Outfit" name="Replace Outfit"/> + <menu_item_call label="Add To Current Outfit" name="Add To Outfit"/> + <menu_item_call label="Remove From Current Outfit" name="Remove From Outfit"/> + <menu_item_call label="Find Original" name="Find Original"/> + <menu_item_call label="Purge Item" name="Purge Item"/> + <menu_item_call label="Restore Item" name="Restore Item"/> + <menu_item_call label="Open" name="Open"/> + <menu_item_call label="Open Original" name="Open Original"/> + <menu_item_call label="Properties" name="Properties"/> + <menu_item_call label="æ›´å" name="Rename"/> + <menu_item_call label="Copy Asset UUID" name="Copy Asset UUID"/> + <menu_item_call label="覆製" name="Copy"/> + <menu_item_call label="貼上" name="Paste"/> + <menu_item_call label="Paste As Link" name="Paste As Link"/> + <menu_item_call label="刪除" name="Remove Link"/> + <menu_item_call label="刪除" name="Delete"/> + <menu_item_call label="刪除系統資料夾" name="Delete System Folder"/> + <menu_item_call label="Start Conference Chat" name="Conference Chat Folder"/> + <menu_item_call label="Play" name="Sound Play"/> + <menu_item_call label="About Landmark" name="About Landmark"/> + <menu_item_call label="Play Inworld" name="Animation Play"/> + <menu_item_call label="Play Locally" name="Animation Audition"/> + <menu_item_call label="Send Instant Message" name="Send Instant Message"/> + <menu_item_call label="Offer Teleport..." name="Offer Teleport..."/> + <menu_item_call label="Start Conference Chat" name="Conference Chat"/> + <menu_item_call label="Activate" name="Activate"/> + <menu_item_call label="Deactivate" name="Deactivate"/> + <menu_item_call label="å¦å˜" name="Save As"/> + <menu_item_call label="Detach From Yourself" name="Detach From Yourself"/> + <menu_item_call label="Wear" name="Wearable And Object Wear"/> + <menu label="Attach To" name="Attach To"/> + <menu label="Attach To HUD" name="Attach To HUD"/> + <menu_item_call label="編輯" name="Wearable Edit"/> + <menu_item_call label="Add" name="Wearable Add"/> + <menu_item_call label="脫下" name="Take Off"/> + <menu_item_call label="--no options--" name="--no options--"/> +</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_inventory_add.xml b/indra/newview/skins/default/xui/zh/menu_inventory_add.xml new file mode 100644 index 0000000000..1cfba8e989 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_inventory_add.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="menu_inventory_add"> + <menu label="上傳" name="upload"> + <menu_item_call label="圖åƒï¼ˆL$[COST])..." name="Upload Image"/> + <menu_item_call label="è²éŸ³ï¼ˆL$[COST])..." name="Upload Sound"/> + <menu_item_call label="動作(L$[COST])..." name="Upload Animation"/> + <menu_item_call label="大批(L$[COST] æ¯æª”案)..." name="Bulk Upload"/> + <menu_item_call label="è¨å®šé è¨ä¸Šå‚³æ¬Šé™" name="perm prefs"/> + </menu> + <menu_item_call label="新資料夾" name="New Folder"/> + <menu_item_call label="新腳本" name="New Script"/> + <menu_item_call label="新記事å¡" name="New Note"/> + <menu_item_call label="新姿勢" name="New Gesture"/> + <menu label="æ–°è¡£æœ" name="New Clothes"> + <menu_item_call label="新襯衫" name="New Shirt"/> + <menu_item_call label="新褲å" name="New Pants"/> + <menu_item_call label="æ–°éž‹å" name="New Shoes"/> + <menu_item_call label="新襪å" name="New Socks"/> + <menu_item_call label="新夾克" name="New Jacket"/> + <menu_item_call label="新裙å" name="New Skirt"/> + <menu_item_call label="新手套" name="New Gloves"/> + <menu_item_call label="新內衣" name="New Undershirt"/> + <menu_item_call label="新內褲" name="New Underpants"/> + <menu_item_call label="New Alpha" name="New Alpha"/> + <menu_item_call label="新刺é’" name="New Tattoo"/> + <menu_item_call label="New Physics" name="New Physics"/> + </menu> + <menu label="New Body Parts" name="New Body Parts"> + <menu_item_call label="新體形" name="New Shape"/> + <menu_item_call label="新皮膚" name="New Skin"/> + <menu_item_call label="æ–°é é«®" name="New Hair"/> + <menu_item_call label="新眼ç›" name="New Eyes"/> + </menu> +</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/zh/menu_inventory_gear_default.xml new file mode 100644 index 0000000000..8b0fd8c014 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_inventory_gear_default.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="menu_gear_default"> + <menu_item_call label="New Inventory Window" name="new_window"/> + <menu_item_check label="ä¾å稱排åº" name="sort_by_name"/> + <menu_item_check label="ä¾æœ€è¿‘排åº" name="sort_by_recent"/> + <menu_item_check label="Sort Folders Always by Name" name="sort_folders_by_name"/> + <menu_item_check label="Sort System Folders to Top" name="sort_system_folders_to_top"/> + <menu_item_call label="Show Filters" name="show_filters"/> + <menu_item_call label="Reset Filters" name="reset_filters"/> + <menu_item_call label="關閉全部資料夾" name="close_folders"/> + <menu_item_call label="Empty Lost and Found" name="empty_lostnfound"/> + <menu_item_call label="Save Texture As" name="Save Texture As"/> + <menu_item_call label="分享" name="Share"/> + <menu_item_call label="Find Original" name="Find Original"/> + <menu_item_call label="Find All Links" name="Find All Links"/> + <menu_item_call label="清空垃圾ç’" name="empty_trash"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_land.xml b/indra/newview/skins/default/xui/zh/menu_land.xml new file mode 100644 index 0000000000..84941d138c --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_land.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Land Pie"> + <menu_item_call label="關於土地" name="Place Information..."/> + <menu_item_call label="å在æ¤è™•" name="Sit Here"/> + <menu_item_call label="購買這塊土地" name="Land Buy"/> + <menu_item_call label="購買通行權" name="Land Buy Pass"/> + <menu_item_call label="å»ºé€ " name="Create"/> + <menu_item_call label="編輯地形" name="Edit Terrain"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_landmark.xml b/indra/newview/skins/default/xui/zh/menu_landmark.xml new file mode 100644 index 0000000000..f91b479fb6 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_landmark.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="landmark_overflow_menu"> + <menu_item_call label="Copy SLurl" name="copy"/> + <menu_item_call label="刪除" name="delete"/> + <menu_item_call label="Create Pick" name="pick"/> + <menu_item_call label="Add to Favorites Bar" name="add_to_favbar"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_login.xml b/indra/newview/skins/default/xui/zh/menu_login.xml new file mode 100644 index 0000000000..056c11e69d --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_login.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu_bar name="Login Menu"> + <menu label="Me" name="File"> + <menu_item_call label="Preferences" name="Preferences..."/> + <menu_item_call label="Exit [APP_NAME]" name="Quit"/> + </menu> + <menu label="Help" name="Help"> + <menu_item_call label="[SECOND_LIFE] Help" name="Second Life Help"/> + <menu_item_call label="About [APP_NAME]" name="About Second Life"/> + </menu> + <menu_item_check label="Show Debug Menu" name="Show Debug Menu"/> + <menu label="除錯" name="Debug"> + <menu_item_call label="Show Debug Settings" name="Debug Settings"/> + <menu_item_call label="UI/Color Settings" name="UI/Color Settings"/> + <menu_item_call label="XUI Preview Tool" name="UI Preview Tool"/> + <menu label="UI Tests" name="UI Tests"/> + <menu_item_call label="Set Window Size..." name="Set Window Size..."/> + <menu_item_call label="Show TOS" name="TOS"/> + <menu_item_call label="Show Critical Message" name="Critical"/> + <menu_item_call label="Media Browser Test" name="Web Browser Test"/> + <menu_item_call label="Web Content Floater Test" name="Web Content Floater Test"/> + <menu_item_check label="Show Grid Picker" name="Show Grid Picker"/> + <menu_item_call label="Show Notifications Console" name="Show Notifications Console"/> + </menu> +</menu_bar> diff --git a/indra/newview/skins/default/xui/zh/menu_media_ctrl.xml b/indra/newview/skins/default/xui/zh/menu_media_ctrl.xml new file mode 100644 index 0000000000..2ec95aa4f9 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_media_ctrl.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="media ctrl context menu"> + <menu_item_call label="剪下" name="Cut"/> + <menu_item_call label="覆製" name="Copy"/> + <menu_item_call label="貼上" name="Paste"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_mini_map.xml b/indra/newview/skins/default/xui/zh/menu_mini_map.xml new file mode 100644 index 0000000000..24bc6355c7 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_mini_map.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="Popup"> + <menu_item_call label="Zoom Close" name="Zoom Close"/> + <menu_item_call label="Zoom Medium" name="Zoom Medium"/> + <menu_item_call label="Zoom Far" name="Zoom Far"/> + <menu_item_call label="Zoom Default" name="Zoom Default"/> + <menu_item_check label="旋轉地圖" name="Rotate Map"/> + <menu_item_check label="自動居ä¸" name="Auto Center"/> + <menu_item_call label="åœæ¢è¿½è¹¤" name="Stop Tracking"/> + <menu_item_call label="世界地圖" name="World Map"/> +</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_navbar.xml b/indra/newview/skins/default/xui/zh/menu_navbar.xml new file mode 100644 index 0000000000..66b5fbe58d --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_navbar.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="Navbar Menu"> + <menu_item_check label="顯示座標" name="Show Coordinates"/> + <menu_item_check label="顯示地段屬性" name="Show Parcel Properties"/> + <menu_item_call label="Landmark" name="Landmark"/> + <menu_item_call label="剪下" name="Cut"/> + <menu_item_call label="覆製" name="Copy"/> + <menu_item_call label="貼上" name="Paste"/> + <menu_item_call label="刪除" name="Delete"/> + <menu_item_call label="å…¨é¸" name="Select All"/> +</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_nearby_chat.xml b/indra/newview/skins/default/xui/zh/menu_nearby_chat.xml new file mode 100644 index 0000000000..6e525cccd5 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_nearby_chat.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="NearBy Chat Menu"> + <menu_item_call label="Show Nearby People..." name="nearby_people"/> + <menu_item_check label="Show Blocked Text" name="muted_text"/> + <menu_item_check label="Show Buddy Icons" name="show_buddy_icons"/> + <menu_item_check label="Show Names" name="show_names"/> + <menu_item_check label="Show Icons and Names" name="show_icons_and_names"/> + <menu_item_call label="Font Size" name="font_size"/> +</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml b/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml new file mode 100644 index 0000000000..b629f73584 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Notification Well Button Context Menu"> + <menu_item_call label="全部關閉" name="Close All"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_object.xml b/indra/newview/skins/default/xui/zh/menu_object.xml new file mode 100644 index 0000000000..6107318a0e --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_object.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Object Pie"> + <menu_item_call label="Touch" name="Object Touch"/> + <menu_item_call label="編輯" name="Edit..."/> + <menu_item_call label="Build" name="Build"/> + <menu_item_call label="Open" name="Open"/> + <menu_item_call label="Sit Here" name="Object Sit"/> + <menu_item_call label="èµ·ç«‹" name="Object Stand Up"/> + <menu_item_call label="Object Profile" name="Object Inspect"/> + <menu_item_call label="Zoom In" name="Zoom In"/> + <context_menu label="Put On" name="Put On"> + <menu_item_call label="Wear" name="Wear"/> + <menu_item_call label="Add" name="Add"/> + <context_menu label="Attach" name="Object Attach"/> + <context_menu label="Attach HUD" name="Object Attach HUD"/> + </context_menu> + <context_menu label="Manage" name="Remove"> + <menu_item_call label="Report Abuse" name="Report Abuse..."/> + <menu_item_call label="Block" name="Object Mute"/> + <menu_item_call label="Return" name="Return..."/> + </context_menu> + <menu_item_call label="Take" name="Pie Object Take"/> + <menu_item_call label="å–得副本" name="Take Copy"/> + <menu_item_call label="Pay" name="Pay..."/> + <menu_item_call label="購買" name="Buy..."/> + <menu_item_call label="刪除" name="Delete"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_object_icon.xml b/indra/newview/skins/default/xui/zh/menu_object_icon.xml new file mode 100644 index 0000000000..7cf6289bd1 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_object_icon.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="Object Icon Menu"> + <menu_item_call label="Object Profile..." name="Object Profile"/> + <menu_item_call label="Block..." name="Block"/> +</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml b/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml new file mode 100644 index 0000000000..6befd163b3 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_outfit_gear.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="Gear Outfit"> + <menu_item_call label="Wear - Replace Current Outfit" name="wear"/> + <menu_item_call label="Wear - Add to Current Outfit" name="wear_add"/> + <menu_item_call label="Take Off - Remove from Current Outfit" name="take_off"/> + <menu label="New Clothes" name="New Clothes"> + <menu_item_call label="新襯衫" name="New Shirt"/> + <menu_item_call label="新褲å" name="New Pants"/> + <menu_item_call label="æ–°éž‹å" name="New Shoes"/> + <menu_item_call label="新襪å" name="New Socks"/> + <menu_item_call label="新夾克" name="New Jacket"/> + <menu_item_call label="新裙å" name="New Skirt"/> + <menu_item_call label="新手套" name="New Gloves"/> + <menu_item_call label="新內衣" name="New Undershirt"/> + <menu_item_call label="新內褲" name="New Underpants"/> + <menu_item_call label="New Alpha" name="New Alpha"/> + <menu_item_call label="New Physics" name="New Physics"/> + <menu_item_call label="New Tattoo" name="New Tattoo"/> + </menu> + <menu label="New Body Parts" name="New Body Parts"> + <menu_item_call label="New Shape" name="New Shape"/> + <menu_item_call label="New Skin" name="New Skin"/> + <menu_item_call label="New Hair" name="New Hair"/> + <menu_item_call label="New Eyes" name="New Eyes"/> + </menu> + <menu_item_call label="Rename Outfit" name="rename"/> + <menu_item_call label="Delete Outfit" name="delete_outfit"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_outfit_tab.xml b/indra/newview/skins/default/xui/zh/menu_outfit_tab.xml new file mode 100644 index 0000000000..9254aadf56 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_outfit_tab.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Outfit"> + <menu_item_call label="Wear - Replace Current Outfit" name="wear_replace"/> + <menu_item_call label="Wear - Add to Current Outfit" name="wear_add"/> + <menu_item_call label="Take Off - Remove from Current Outfit" name="take_off"/> + <menu_item_call label="Edit Outfit" name="edit"/> + <menu_item_call label="Rename Outfit" name="rename"/> + <menu_item_call label="Delete Outfit" name="delete"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_participant_list.xml b/indra/newview/skins/default/xui/zh/menu_participant_list.xml new file mode 100644 index 0000000000..c487c35588 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_participant_list.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Participant List Context Menu"> + <menu_item_check label="ä¾å稱排åº" name="SortByName"/> + <menu_item_check label="Sort by Recent Speakers" name="SortByRecentSpeakers"/> + <menu_item_call label="View Profile" name="View Profile"/> + <menu_item_call label="åŠ ç‚ºæœ‹å‹" name="Add Friend"/> + <menu_item_call label="IM" name="IM"/> + <menu_item_call label="Call" name="Call"/> + <menu_item_call label="分享" name="Share"/> + <menu_item_call label="Pay" name="Pay"/> + <menu_item_check label="View People Icons" name="View Icons"/> + <menu_item_check label="Block Voice" name="Block/Unblock"/> + <menu_item_check label="Block Text" name="MuteText"/> + <context_menu label="Moderator Options" name="Moderator Options"> + <menu_item_check label="Allow text chat" name="AllowTextChat"/> + <menu_item_call label="Mute this participant" name="ModerateVoiceMuteSelected"/> + <menu_item_call label="Unmute this participant" name="ModerateVoiceUnMuteSelected"/> + <menu_item_call label="Mute everyone" name="ModerateVoiceMute"/> + <menu_item_call label="Unmute everyone" name="ModerateVoiceUnmute"/> + </context_menu> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/zh/menu_people_friends_view_sort.xml new file mode 100644 index 0000000000..2b0c461312 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_people_friends_view_sort.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="menu_group_plus"> + <menu_item_check label="ä¾å稱排åº" name="sort_name"/> + <menu_item_check label="ä¾ç‹€æ…‹æŽ’åº" name="sort_status"/> + <menu_item_check label="View People Icons" name="view_icons"/> + <menu_item_check label="View Permissions Granted" name="view_permissions"/> + <menu_item_call label="Show Blocked Residents & Objects" name="show_blocked_list"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_people_groups.xml b/indra/newview/skins/default/xui/zh/menu_people_groups.xml new file mode 100644 index 0000000000..c2d7182a6c --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_people_groups.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="menu_group_plus"> + <menu_item_call label="察看資訊" name="View Info"/> + <menu_item_call label="èŠå¤©" name="Chat"/> + <menu_item_call label="Call" name="Call"/> + <menu_item_call label="Activate" name="Activate"/> + <menu_item_call label="Leave" name="Leave"/> +</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_people_groups_view_sort.xml b/indra/newview/skins/default/xui/zh/menu_people_groups_view_sort.xml new file mode 100644 index 0000000000..2c84a858af --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_people_groups_view_sort.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="menu_group_plus"> + <menu_item_check label="Display Group Icons" name="Display Group Icons"/> + <menu_item_call label="Leave Selected Group" name="Leave Selected Group"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_people_nearby.xml b/indra/newview/skins/default/xui/zh/menu_people_nearby.xml new file mode 100644 index 0000000000..2ca0ad6a89 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_people_nearby.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Avatar Context Menu"> + <menu_item_call label="View Profile" name="View Profile"/> + <menu_item_call label="åŠ ç‚ºæœ‹å‹" name="Add Friend"/> + <menu_item_call label="Remove Friend" name="Remove Friend"/> + <menu_item_call label="IM" name="IM"/> + <menu_item_call label="Call" name="Call"/> + <menu_item_call label="地圖" name="Map"/> + <menu_item_call label="分享" name="Share"/> + <menu_item_call label="Pay" name="Pay"/> + <menu_item_check label="Block/Unblock" name="Block/Unblock"/> + <menu_item_call label="Offer Teleport" name="teleport"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_people_nearby_multiselect.xml b/indra/newview/skins/default/xui/zh/menu_people_nearby_multiselect.xml new file mode 100644 index 0000000000..a71609170b --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_people_nearby_multiselect.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Multi-Selected People Context Menu"> + <menu_item_call label="åŠ ç‚ºæœ‹å‹" name="Add Friends"/> + <menu_item_call label="移除朋å‹" name="Remove Friend"/> + <menu_item_call label="IM" name="IM"/> + <menu_item_call label="Call" name="Call"/> + <menu_item_call label="分享" name="Share"/> + <menu_item_call label="Pay" name="Pay"/> + <menu_item_call label="Offer Teleport" name="teleport"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/zh/menu_people_nearby_view_sort.xml new file mode 100644 index 0000000000..5cf54b117b --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_people_nearby_view_sort.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="menu_group_plus"> + <menu_item_check label="Sort by Recent Speakers" name="sort_by_recent_speakers"/> + <menu_item_check label="ä¾å稱排åº" name="sort_name"/> + <menu_item_check label="ä¾è·é›¢æŽ’åº" name="sort_distance"/> + <menu_item_check label="View People Icons" name="view_icons"/> + <menu_item_call label="Show Blocked Residents & Objects" name="show_blocked_list"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/zh/menu_people_recent_view_sort.xml new file mode 100644 index 0000000000..5a4729abde --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_people_recent_view_sort.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="menu_group_plus"> + <menu_item_check label="ä¾æœ€è¿‘排åº" name="sort_most"/> + <menu_item_check label="ä¾å稱排åº" name="sort_name"/> + <menu_item_check label="View People Icons" name="view_icons"/> + <menu_item_call label="Show Blocked Residents & Objects" name="show_blocked_list"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_picks.xml b/indra/newview/skins/default/xui/zh/menu_picks.xml new file mode 100644 index 0000000000..3c78e9f920 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_picks.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Picks"> + <menu_item_call label="資訊" name="pick_info"/> + <menu_item_call label="編輯" name="pick_edit"/> + <menu_item_call label="Teleport" name="pick_teleport"/> + <menu_item_call label="地圖" name="pick_map"/> + <menu_item_call label="刪除" name="pick_delete"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_picks_plus.xml b/indra/newview/skins/default/xui/zh/menu_picks_plus.xml new file mode 100644 index 0000000000..9e55c633f9 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_picks_plus.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="picks_plus_menu"> + <menu_item_call label="New Pick" name="create_pick"/> + <menu_item_call label="New Classified" name="create_classified"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_place.xml b/indra/newview/skins/default/xui/zh/menu_place.xml new file mode 100644 index 0000000000..63e44d808c --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_place.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="place_overflow_menu"> + <menu_item_call label="Make a Landmark" name="landmark"/> + <menu_item_call label="Create Pick" name="pick"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_place_add_button.xml b/indra/newview/skins/default/xui/zh/menu_place_add_button.xml new file mode 100644 index 0000000000..e86fe7367e --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_place_add_button.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="menu_folder_gear"> + <menu_item_call label="Add Folder" name="add_folder"/> + <menu_item_call label="Add Landmark" name="add_landmark"/> +</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/zh/menu_places_gear_folder.xml new file mode 100644 index 0000000000..e9658f72a2 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_places_gear_folder.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="menu_folder_gear"> + <menu_item_call label="Add Landmark" name="add_landmark"/> + <menu_item_call label="Add Folder" name="add_folder"/> + <menu_item_call label="Restore Item" name="restore_item"/> + <menu_item_call label="剪下" name="cut"/> + <menu_item_call label="覆製" name="copy_folder"/> + <menu_item_call label="貼上" name="paste"/> + <menu_item_call label="æ›´å" name="rename"/> + <menu_item_call label="刪除" name="delete"/> + <menu_item_call label="展開" name="expand"/> + <menu_item_call label="摺疊" name="collapse"/> + <menu_item_call label="展開全部資料夾" name="expand_all"/> + <menu_item_call label="摺疊全部資料夾" name="collapse_all"/> + <menu_item_check label="ä¾æ—¥æœŸæŽ’åº" name="sort_by_date"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/zh/menu_places_gear_landmark.xml new file mode 100644 index 0000000000..66247d3fe6 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_places_gear_landmark.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="menu_ladmark_gear"> + <menu_item_call label="Teleport" name="teleport"/> + <menu_item_call label="更多資訊" name="more_info"/> + <menu_item_call label="顯示在地圖上" name="show_on_map"/> + <menu_item_call label="Add Landmark" name="add_landmark"/> + <menu_item_call label="Add Folder" name="add_folder"/> + <menu_item_call label="Restore Item" name="restore_item"/> + <menu_item_call label="剪下" name="cut"/> + <menu_item_call label="Copy Landmark" name="copy_landmark"/> + <menu_item_call label="Copy SLurl" name="copy_slurl"/> + <menu_item_call label="貼上" name="paste"/> + <menu_item_call label="æ›´å" name="rename"/> + <menu_item_call label="刪除" name="delete"/> + <menu_item_call label="展開全部資料夾" name="expand_all"/> + <menu_item_call label="摺疊全部資料夾" name="collapse_all"/> + <menu_item_check label="ä¾æ—¥æœŸæŽ’åº" name="sort_by_date"/> + <menu_item_call label="Create Pick" name="create_pick"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_profile_overflow.xml b/indra/newview/skins/default/xui/zh/menu_profile_overflow.xml new file mode 100644 index 0000000000..9c52ddfd18 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_profile_overflow.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="profile_overflow_menu"> + <menu_item_call label="地圖" name="show_on_map"/> + <menu_item_call label="Pay" name="pay"/> + <menu_item_call label="分享" name="share"/> + <menu_item_call label="Block" name="block"/> + <menu_item_call label="Unblock" name="unblock"/> + <menu_item_call label="Kick" name="kick"/> + <menu_item_call label="Freeze" name="freeze"/> + <menu_item_call label="Unfreeze" name="unfreeze"/> + <menu_item_call label="CSR" name="csr"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_save_outfit.xml b/indra/newview/skins/default/xui/zh/menu_save_outfit.xml new file mode 100644 index 0000000000..7884df5b01 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_save_outfit.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="save_outfit_menu"> + <menu_item_call label="儲å˜" name="save_outfit"/> + <menu_item_call label="å¦å˜" name="save_as_new_outfit"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_script_chiclet.xml b/indra/newview/skins/default/xui/zh/menu_script_chiclet.xml new file mode 100644 index 0000000000..e9817dd2bc --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_script_chiclet.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="ScriptChiclet Menu"> + <menu_item_call label="關閉" name="Close"/> +</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_slurl.xml b/indra/newview/skins/default/xui/zh/menu_slurl.xml new file mode 100644 index 0000000000..7291239383 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_slurl.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="Popup"> + <menu_item_call label="About URL" name="about_url"/> + <menu_item_call label="Teleport to URL" name="teleport_to_url"/> + <menu_item_call label="地圖" name="show_on_map"/> +</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_teleport_history_gear.xml b/indra/newview/skins/default/xui/zh/menu_teleport_history_gear.xml new file mode 100644 index 0000000000..12989ea59c --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_teleport_history_gear.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="Teleport History Gear Context Menu"> + <menu_item_call label="展開全部資料夾" name="Expand all folders"/> + <menu_item_call label="摺疊全部資料夾" name="Collapse all folders"/> + <menu_item_call label="Clear Teleport History" name="Clear Teleport History"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/zh/menu_teleport_history_item.xml new file mode 100644 index 0000000000..4d1aa5f74a --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_teleport_history_item.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Teleport History Item Context Menu"> + <menu_item_call label="Teleport" name="Teleport"/> + <menu_item_call label="更多資訊" name="More Information"/> + <menu_item_call label="覆製到剪貼簿" name="CopyToClipboard"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_teleport_history_tab.xml b/indra/newview/skins/default/xui/zh/menu_teleport_history_tab.xml new file mode 100644 index 0000000000..423ba64aa7 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_teleport_history_tab.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Teleport History Item Context Menu"> + <menu_item_call label="Open" name="TabOpen"/> + <menu_item_call label="關閉" name="TabClose"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_text_editor.xml b/indra/newview/skins/default/xui/zh/menu_text_editor.xml new file mode 100644 index 0000000000..c25f5128c3 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_text_editor.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Text editor context menu"> + <menu_item_call label="剪下" name="Cut"/> + <menu_item_call label="覆製" name="Copy"/> + <menu_item_call label="貼上" name="Paste"/> + <menu_item_call label="刪除" name="Delete"/> + <menu_item_call label="å…¨é¸" name="Select All"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_topinfobar.xml b/indra/newview/skins/default/xui/zh/menu_topinfobar.xml new file mode 100644 index 0000000000..dc3981a4d8 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_topinfobar.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="menu_topinfobar"> + <menu_item_check label="顯示座標" name="Show Coordinates"/> + <menu_item_check label="顯示地段屬性" name="Show Parcel Properties"/> + <menu_item_call label="Landmark" name="Landmark"/> + <menu_item_call label="覆製" name="Copy"/> +</menu> diff --git a/indra/newview/skins/default/xui/zh/menu_url_agent.xml b/indra/newview/skins/default/xui/zh/menu_url_agent.xml new file mode 100644 index 0000000000..9f56edb959 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_url_agent.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Url Popup"> + <menu_item_call label="Show Resident Profile" name="show_agent"/> + <menu_item_call label="覆製å稱到剪貼簿" name="url_copy_label"/> + <menu_item_call label="Copy SLurl to clipboard" name="url_copy"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_url_group.xml b/indra/newview/skins/default/xui/zh/menu_url_group.xml new file mode 100644 index 0000000000..c574090a4a --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_url_group.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Url Popup"> + <menu_item_call label="Show Group Information" name="show_group"/> + <menu_item_call label="Copy Group to clipboard" name="url_copy_label"/> + <menu_item_call label="Copy SLurl to clipboard" name="url_copy"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_url_http.xml b/indra/newview/skins/default/xui/zh/menu_url_http.xml new file mode 100644 index 0000000000..cf953576f3 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_url_http.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Url Popup"> + <menu_item_call label="開啟網é " name="url_open"/> + <menu_item_call label="Open in Internal Browser" name="url_open_internal"/> + <menu_item_call label="Open in External Browser" name="url_open_external"/> + <menu_item_call label="Copy URL to clipboard" name="url_copy"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_url_inventory.xml b/indra/newview/skins/default/xui/zh/menu_url_inventory.xml new file mode 100644 index 0000000000..1e56aa1a47 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_url_inventory.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Url Popup"> + <menu_item_call label="Show Inventory Item" name="show_item"/> + <menu_item_call label="Copy Name to clipboard" name="url_copy_label"/> + <menu_item_call label="Copy SLurl to clipboard" name="url_copy"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_url_map.xml b/indra/newview/skins/default/xui/zh/menu_url_map.xml new file mode 100644 index 0000000000..fc8922318f --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_url_map.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Url Popup"> + <menu_item_call label="顯示在地圖上" name="show_on_map"/> + <menu_item_call label="Teleport to Location" name="teleport_to_location"/> + <menu_item_call label="Copy SLurl to clipboard" name="url_copy"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_url_objectim.xml b/indra/newview/skins/default/xui/zh/menu_url_objectim.xml new file mode 100644 index 0000000000..8ad8e4ba84 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_url_objectim.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Url Popup"> + <menu_item_call label="Show Object Information" name="show_object"/> + <menu_item_call label="顯示在地圖上" name="show_on_map"/> + <menu_item_call label="Teleport to Object Location" name="teleport_to_object"/> + <menu_item_call label="Copy Object Name to clipboard" name="url_copy_label"/> + <menu_item_call label="Copy SLurl to clipboard" name="url_copy"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_url_parcel.xml b/indra/newview/skins/default/xui/zh/menu_url_parcel.xml new file mode 100644 index 0000000000..d011ba8208 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_url_parcel.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Url Popup"> + <menu_item_call label="顯示地段資訊" name="show_parcel"/> + <menu_item_call label="顯示在地圖上" name="show_on_map"/> + <menu_item_call label="Copy SLurl to clipboard" name="url_copy"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_url_slapp.xml b/indra/newview/skins/default/xui/zh/menu_url_slapp.xml new file mode 100644 index 0000000000..10d7c9cba0 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_url_slapp.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Url Popup"> + <menu_item_call label="Run This Command" name="run_slapp"/> + <menu_item_call label="Copy SLurl to clipboard" name="url_copy"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_url_slurl.xml b/indra/newview/skins/default/xui/zh/menu_url_slurl.xml new file mode 100644 index 0000000000..cf4ff9f8ee --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_url_slurl.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Url Popup"> + <menu_item_call label="Show Place Information" name="show_place"/> + <menu_item_call label="顯示在地圖上" name="show_on_map"/> + <menu_item_call label="Teleport to Location" name="teleport_to_location"/> + <menu_item_call label="Copy SLurl to clipboard" name="url_copy"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_url_teleport.xml b/indra/newview/skins/default/xui/zh/menu_url_teleport.xml new file mode 100644 index 0000000000..c103582487 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_url_teleport.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Url Popup"> + <menu_item_call label="Teleport to this Location" name="teleport"/> + <menu_item_call label="顯示在地圖上" name="show_on_map"/> + <menu_item_call label="Copy SLurl to clipboard" name="url_copy"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_viewer.xml b/indra/newview/skins/default/xui/zh/menu_viewer.xml new file mode 100644 index 0000000000..3b1f7820af --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_viewer.xml @@ -0,0 +1,430 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu_bar name="Main Menu"> + <menu label="自己" name="Me"> + <menu_item_call label="å好è¨å®š" name="Preferences"/> + <menu_item_call label="我的塗鴉牆" name="Manage My Account"/> + <menu_item_call label="購買 L$" name="Buy and Sell L$"/> + <menu_item_call label="我的個人檔案" name="Profile"/> + <menu_item_call label="我的外觀" name="ChangeOutfit"/> + <menu_item_check label="我的庫å˜" name="Inventory"/> + <menu_item_check label="我的庫å˜" name="ShowSidetrayInventory"/> + <menu_item_check label="我的姿勢" name="Gestures"/> + <menu_item_check label="我的è²éŸ³" name="ShowVoice"/> + <menu label="移動" name="Movement"> + <menu_item_call label="å下" name="Sit Down Here"/> + <menu_item_check label="飛行" name="Fly"/> + <menu_item_check label="總是奔跑" name="Always Run"/> + <menu_item_call label="åœæ¢æˆ‘身上的動作" name="Stop Animating My Avatar"/> + </menu> + <menu label="我的狀態" name="Status"> + <menu_item_call label="離開" name="Set Away"/> + <menu_item_call label="忙碌" name="Set Busy"/> + </menu> + <menu_item_call label="Request Admin Status" name="Request Admin Options"/> + <menu_item_call label="Leave Admin Status" name="Leave Admin Options"/> + <menu_item_call label="çµæŸé›¢é–‹ [APP_NAME]" name="Quit"/> + </menu> + <menu label="æºé€š" name="Communicate"> + <menu_item_call label="我的朋å‹" name="My Friends"/> + <menu_item_call label="我的社團" name="My Groups"/> + <menu_item_check label="附近的èŠå¤©" name="Nearby Chat"/> + <menu_item_call label="附近的人群" name="Active Speakers"/> + </menu> + <menu label="世界" name="World"> + <menu_item_check label="è¿·ä½ åœ°åœ–" name="Mini-Map"/> + <menu_item_check label="世界地圖" name="World Map"/> + <menu_item_check label="æœå°‹" name="Search"/> + <menu_item_call label="æ‹æ”å¿«ç…§" name="Take Snapshot"/> + <menu_item_call label="Landmark This Place" name="Create Landmark Here"/> + <menu label="Place Profile" name="Land"> + <menu_item_call label="Place Profile" name="Place Profile"/> + <menu_item_call label="關於土地" name="About Land"/> + <menu_item_call label="åœ°å€ / é ˜åœ°" name="Region/Estate"/> + </menu> + <menu_item_call label="購買這塊土地" name="Buy Land"/> + <menu_item_call label="我的土地" name="My Land"/> + <menu label="顯示" name="LandShow"> + <menu_item_check label="移動控制" name="Movement Controls"/> + <menu_item_check label="視角控制" name="Camera Controls"/> + <menu_item_check label="ç¦è¶Šç·š" name="Ban Lines"/> + <menu_item_check label="指標" name="beacons"/> + <menu_item_check label="土地邊界" name="Property Lines"/> + <menu_item_check label="地主" name="Land Owners"/> + <menu_item_check label="座標" name="Coordinates"/> + <menu_item_check label="地段屬性" name="Parcel Properties"/> + <menu_item_check label="進階é¸å–®" name="Show Advanced Menu"/> + </menu> + <menu_item_call label="瞬間傳é€å›žå®¶" name="Teleport Home"/> + <menu_item_call label="è¨å®šå®¶åœ¨æ¤è™•" name="Set Home to Here"/> + <menu label="太陽" name="Environment Settings"> + <menu_item_call label="日出" name="Sunrise"/> + <menu_item_call label="ä¸åˆ" name="Noon"/> + <menu_item_call label="æ—¥è½" name="Sunset"/> + <menu_item_call label="åˆå¤œ" name="Midnight"/> + <menu_item_call label="é ˜åœ°æ™‚é–“" name="Revert to Region Default"/> + <menu_item_call label="環境編輯器" name="Environment Editor"/> + </menu> + </menu> + <menu label="å»ºé€ " name="BuildTools"> + <menu_item_check label="å»ºé€ " name="Show Build Tools"/> + <menu label="é¸æ“‡å»ºé€ 工具" name="Select Tool"> + <menu_item_call label="èšç„¦å·¥å…·" name="Focus"/> + <menu_item_call label="移動工具" name="Move"/> + <menu_item_call label="編輯工具" name="Edit"/> + <menu_item_call label="å‰µé€ å·¥å…·" name="Create"/> + <menu_item_call label="土地工具" name="Land"/> + </menu> + <menu_item_call label="è¯çµ" name="Link"/> + <menu_item_call label="å–銷è¯çµ" name="Unlink"/> + <menu_item_check label="編輯è¯çµéƒ¨ä½" name="Edit Linked Parts"/> + <menu label="é¸æ“‡è¯çµéƒ¨ä½" name="Select Linked Parts"> + <menu_item_call label="é¸æ“‡ä¸‹ä¸€éƒ¨ä½" name="Select Next Part"/> + <menu_item_call label="é¸æ“‡ä¸Šä¸€éƒ¨ä½" name="Select Previous Part"/> + <menu_item_call label="包括下一部ä½" name="Include Next Part"/> + <menu_item_call label="包括上一部ä½" name="Include Previous Part"/> + </menu> + <menu_item_call label="èšç„¦æ–¼æ‰€é¸éƒ¨ä½" name="Focus on Selection"/> + <menu_item_call label="Zoom to Selection" name="Zoom to Selection"/> + <menu label="Object" name="Object"> + <menu_item_call label="購買" name="Menu Object Buy"/> + <menu_item_call label="Take" name="Menu Object Take"/> + <menu_item_call label="å–得副本" name="Take Copy"/> + <menu_item_call label="Save Back to My Inventory" name="Save Object Back to My Inventory"/> + <menu_item_call label="Save Back to Object Contents" name="Save Object Back to Object Contents"/> + <menu_item_call label="退回物件" name="Return Object back to Owner"/> + </menu> + <menu label="Scripts" name="Scripts"> + <menu_item_call label="Recompile Scripts (Mono)" name="Mono"/> + <menu_item_call label="Recompile Scripts (LSL)" name="LSL"/> + <menu_item_call label="Reset Scripts" name="Reset Scripts"/> + <menu_item_call label="Set Scripts to Running" name="Set Scripts to Running"/> + <menu_item_call label="Set Scripts to Not Running" name="Set Scripts to Not Running"/> + </menu> + <menu label="Options" name="Options"> + <menu_item_check label="Show Advanced Permissions" name="DebugPermissions"/> + <menu_item_check label="Select Only My Objects" name="Select Only My Objects"/> + <menu_item_check label="Select Only Movable Objects" name="Select Only Movable Objects"/> + <menu_item_check label="Select By Surrounding" name="Select By Surrounding"/> + <menu_item_check label="Show Selection Outlines" name="Show Selection Outlines"/> + <menu_item_check label="Show Hidden Selection" name="Show Hidden Selection"/> + <menu_item_check label="Show Light Radius for Selection" name="Show Light Radius for Selection"/> + <menu_item_check label="Show Selection Beam" name="Show Selection Beam"/> + <menu_item_check label="è²¼é½Šæ ¼ç·š" name="Snap to Grid"/> + <menu_item_call label="Snap Object XY to Grid" name="Snap Object XY to Grid"/> + <menu_item_call label="Use Selection for Grid" name="Use Selection for Grid"/> + <menu_item_call label="Grid Options" name="Grid Options"/> + </menu> + <menu label="Upload" name="Upload"> + <menu_item_call label="Image (L$[COST])..." name="Upload Image"/> + <menu_item_call label="Sound (L$[COST])..." name="Upload Sound"/> + <menu_item_call label="Animation (L$[COST])..." name="Upload Animation"/> + <menu_item_call label="Bulk (L$[COST] per file)..." name="Bulk Upload"/> + <menu_item_call label="Set Default Upload Permissions" name="perm prefs"/> + </menu> + <menu_item_call label="復原" name="Undo"/> + <menu_item_call label="Redo" name="Redo"/> + </menu> + <menu label="Help" name="Help"> + <menu_item_call label="[SECOND_LIFE] Help" name="Second Life Help"/> + <menu_item_check label="Enable Hints" name="Enable Hints"/> + <menu_item_call label="Report Abuse" name="Report Abuse"/> + <menu_item_call label="Report Bug" name="Report Bug"/> + <menu_item_call label="About [APP_NAME]" name="About Second Life"/> + </menu> + <menu label="Advanced" name="Advanced"> + <menu_item_call label="Rebake Textures" name="Rebake Texture"/> + <menu_item_call label="Set UI Size to Default" name="Set UI Size to Default"/> + <menu_item_call label="Set Window Size..." name="Set Window Size..."/> + <menu_item_check label="Limit Select Distance" name="Limit Select Distance"/> + <menu_item_check label="Disable Camera Constraints" name="Disable Camera Distance"/> + <menu_item_check label="High-res Snapshot" name="HighResSnapshot"/> + <menu_item_check label="Quiet Snapshots to Disk" name="QuietSnapshotsToDisk"/> + <menu_item_check label="Compress Snapshots to Disk" name="CompressSnapshotsToDisk"/> + <menu label="Performance Tools" name="Performance Tools"> + <menu_item_call label="Lag Meter" name="Lag Meter"/> + <menu_item_check label="Statistics Bar" name="Statistics Bar"/> + <menu_item_check label="Show Avatar Rendering Cost" name="Avatar Rendering Cost"/> + </menu> + <menu label="Highlighting and Visibility" name="Highlighting and Visibility"> + <menu_item_check label="Cheesy Beacon" name="Cheesy Beacon"/> + <menu_item_check label="Hide Particles" name="Hide Particles"/> + <menu_item_check label="Hide Selected" name="Hide Selected"/> + <menu_item_check label="Highlight Transparent" name="Highlight Transparent"/> + <menu_item_check label="Show HUD Attachments" name="Show HUD Attachments"/> + <menu_item_check label="Show Mouselook Crosshairs" name="ShowCrosshairs"/> + </menu> + <menu label="Rendering Types" name="Rendering Types"> + <menu_item_check label="Simple" name="Simple"/> + <menu_item_check label="Alpha" name="Alpha"/> + <menu_item_check label="Tree" name="Tree"/> + <menu_item_check label="Avatars" name="Character"/> + <menu_item_check label="SurfacePath" name="SurfacePath"/> + <menu_item_check label="Sky" name="Sky"/> + <menu_item_check label="Water" name="Water"/> + <menu_item_check label="Ground" name="Ground"/> + <menu_item_check label="Volume" name="Volume"/> + <menu_item_check label="Grass" name="Grass"/> + <menu_item_check label="Clouds" name="Clouds"/> + <menu_item_check label="Particles" name="Particles"/> + <menu_item_check label="Bump" name="Bump"/> + </menu> + <menu label="Rendering Features" name="Rendering Features"> + <menu_item_check label="UI" name="UI"/> + <menu_item_check label="Selected" name="Selected"/> + <menu_item_check label="Highlighted" name="Highlighted"/> + <menu_item_check label="Dynamic Textures" name="Dynamic Textures"/> + <menu_item_check label="Foot Shadows" name="Foot Shadows"/> + <menu_item_check label="Fog" name="Fog"/> + <menu_item_check label="Test FRInfo" name="Test FRInfo"/> + <menu_item_check label="Flexible Objects" name="Flexible Objects"/> + </menu> + <menu_item_check label="Use Plugin Read Thread" name="Use Plugin Read Thread"/> + <menu_item_call label="Clear Group Cache" name="ClearGroupCache"/> + <menu_item_check label="Mouse Smoothing" name="Mouse Smoothing"/> + <menu label="Shortcuts" name="Shortcuts"> + <menu_item_call label="Image (L$[COST])..." name="Upload Image"/> + <menu_item_check label="Search" name="Search"/> + <menu_item_call label="Release Keys" name="Release Keys"/> + <menu_item_call label="Set UI Size to Default" name="Set UI Size to Default"/> + <menu_item_check label="Show Advanced Menu - legacy shortcut" name="Show Advanced Menu - legacy shortcut"/> + <menu_item_call label="關閉視窗" name="Close Window"/> + <menu_item_call label="關閉全部視窗" name="Close All Windows"/> + <menu_item_call label="Snapshot to Disk" name="Snapshot to Disk"/> + <menu_item_call label="Mouselook" name="Mouselook"/> + <menu_item_check label="Joystick Flycam" name="Joystick Flycam"/> + <menu_item_call label="Reset View" name="Reset View"/> + <menu_item_call label="Look at Last Chatter" name="Look at Last Chatter"/> + <menu label="é¸æ“‡å»ºé€ 工具" name="Select Tool"> + <menu_item_call label="èšç„¦å·¥å…·" name="Focus"/> + <menu_item_call label="移動工具" name="Move"/> + <menu_item_call label="編輯工具" name="Edit"/> + <menu_item_call label="å‰µé€ å·¥å…·" name="Create"/> + <menu_item_call label="土地工具" name="Land"/> + </menu> + <menu_item_call label="Zoom In" name="Zoom In"/> + <menu_item_call label="Zoom Default" name="Zoom Default"/> + <menu_item_call label="Zoom Out" name="Zoom Out"/> + </menu> + <menu_item_call label="顯示除錯è¨å®š" name="Debug Settings"/> + <menu_item_check label="顯示開發é¸å–®" name="Debug Mode"/> + </menu> + <menu label="開發" name="Develop"> + <menu label="Consoles" name="Consoles"> + <menu_item_check label="Texture Console" name="Texture Console"/> + <menu_item_check label="Debug Console" name="Debug Console"/> + <menu_item_call label="Notifications Console" name="Notifications"/> + <menu_item_check label="Texture Size Console" name="Texture Size"/> + <menu_item_check label="Texture Category Console" name="Texture Category"/> + <menu_item_check label="Fast Timers" name="Fast Timers"/> + <menu_item_check label="記憶體" name="Memory"/> + <menu_item_call label="Region Info to Debug Console" name="Region Info to Debug Console"/> + <menu_item_call label="Group Info to Debug Console" name="Group Info to Debug Console"/> + <menu_item_call label="Capabilities Info to Debug Console" name="Capabilities Info to Debug Console"/> + <menu_item_check label="Camera" name="Camera"/> + <menu_item_check label="Wind" name="Wind"/> + <menu_item_check label="FOV" name="FOV"/> + <menu_item_check label="Badge" name="Badge"/> + </menu> + <menu label="顯示資訊" name="Display Info"> + <menu_item_check label="Show Time" name="Show Time"/> + <menu_item_check label="Show Render Info" name="Show Render Info"/> + <menu_item_check label="Show Texture Info" name="Show Texture Info"/> + <menu_item_check label="Show Matrices" name="Show Matrices"/> + <menu_item_check label="Show Color Under Cursor" name="Show Color Under Cursor"/> + <menu_item_check label="顯示記憶體" name="Show Memory"/> + <menu_item_check label="Show Updates to Objects" name="Show Updates"/> + </menu> + <menu label="Force an Error" name="Force Errors"> + <menu_item_call label="Force Breakpoint" name="Force Breakpoint"/> + <menu_item_call label="Force LLError And Crash" name="Force LLError And Crash"/> + <menu_item_call label="Force Bad Memory Access" name="Force Bad Memory Access"/> + <menu_item_call label="Force Infinite Loop" name="Force Infinite Loop"/> + <menu_item_call label="Force Driver Crash" name="Force Driver Carsh"/> + <menu_item_call label="Force Software Exception" name="Force Software Exception"/> + <menu_item_call label="Force Disconnect Viewer" name="Force Disconnect Viewer"/> + <menu_item_call label="Simulate a Memory Leak" name="Memory Leaking Simulation"/> + </menu> + <menu label="Render Tests" name="Render Tests"> + <menu_item_check label="Camera Offset" name="Camera Offset"/> + <menu_item_check label="Randomize Framerate" name="Randomize Framerate"/> + <menu_item_check label="Periodic Slow Frame" name="Periodic Slow Frame"/> + <menu_item_check label="Frame Test" name="Frame Test"/> + </menu> + <menu label="Render Metadata" name="Render Metadata"> + <menu_item_check label="Bounding Boxes" name="Bounding Boxes"/> + <menu_item_check label="Octree" name="Octree"/> + <menu_item_check label="Shadow Frusta" name="Shadow Frusta"/> + <menu_item_check label="Occlusion" name="Occlusion"/> + <menu_item_check label="Render Batches" name="Render Batches"/> + <menu_item_check label="Update Type" name="Update Type"/> + <menu_item_check label="Texture Anim" name="Texture Anim"/> + <menu_item_check label="Texture Priority" name="Texture Priority"/> + <menu_item_check label="Texture Area" name="Texture Area"/> + <menu_item_check label="Face Area" name="Face Area"/> + <menu_item_check label="Lights" name="Lights"/> + <menu_item_check label="Collision Skeleton" name="Collision Skeleton"/> + <menu_item_check label="Raycast" name="Raycast"/> + </menu> + <menu label="Rendering" name="Rendering"> + <menu_item_check label="Axes" name="Axes"/> + <menu_item_check label="Tangent Basis" name="Tangent Basis"/> + <menu_item_call label="Selected Texture Info Basis" name="Selected Texture Info Basis"/> + <menu_item_check label="Wireframe" name="Wireframe"/> + <menu_item_check label="Object-Object Occlusion" name="Object-Object Occlusion"/> + <menu_item_check label="Framebuffer Objects" name="Framebuffer Objects"/> + <menu_item_check label="Lighting and Shadows" name="Lighting and Shadows"/> + <menu_item_check label="Shadows from Sun/Moon/Projectors" name="Shadows from Sun/Moon/Projectors"/> + <menu_item_check label="SSAO and Shadow Smoothing" name="SSAO and Shadow Smoothing"/> + <menu_item_check label="Global Illumination (experimental)" name="Global Illumination"/> + <menu_item_check label="Debug GL" name="Debug GL"/> + <menu_item_check label="Debug Pipeline" name="Debug Pipeline"/> + <menu_item_check label="Automatic Alpha Masks (deferred)" name="Automatic Alpha Masks (deferred)"/> + <menu_item_check label="Automatic Alpha Masks (non-deferred)" name="Automatic Alpha Masks (non-deferred)"/> + <menu_item_check label="Animation Textures" name="Animation Textures"/> + <menu_item_check label="Disable Textures" name="Disable Textures"/> + <menu_item_check label="Full Res Textures" name="Rull Res Textures"/> + <menu_item_check label="Audit Textures" name="Audit Textures"/> + <menu_item_check label="Texture Atlas (experimental)" name="Texture Atlas"/> + <menu_item_check label="Render Attached Lights" name="Render Attached Lights"/> + <menu_item_check label="Render Attached Particles" name="Render Attached Particles"/> + <menu_item_check label="Hover Glow Objects" name="Hover Glow Objects"/> + </menu> + <menu label="網路" name="Network"> + <menu_item_check label="Pause Agent" name="AgentPause"/> + <menu_item_call label="Enable Message Log" name="Enable Message Log"/> + <menu_item_call label="Disable Message Log" name="Disable Message Log"/> + <menu_item_check label="Velocity Interpolate Objects" name="Velocity Interpolate Objects"/> + <menu_item_check label="Ping Interpolate Object Positions" name="Ping Interpolate Object Positions"/> + <menu_item_call label="Drop a Packet" name="Drop a Packet"/> + </menu> + <menu_item_call label="Dump Scripted Camera" name="Dump Scripted Camera"/> + <menu_item_call label="Bumps, Pushes & Hits" name="Bumps, Pushes &amp; Hits"/> + <menu label="Recorder" name="Recorder"> + <menu_item_call label="Start Playback" name="Start Playback"/> + <menu_item_call label="Stop Playback" name="Stop Playback"/> + <menu_item_check label="Loop Playback" name="Loop Playback"/> + <menu_item_call label="Start Record" name="Start Record"/> + <menu_item_call label="Stop Record" name="Stop Record"/> + </menu> + <menu label="World" name="World"> + <menu_item_check label="Sim Sun Override" name="Sim Sun Override"/> + <menu_item_check label="Cheesy Beacon" name="Cheesy Beacon"/> + <menu_item_check label="Fixed Weather" name="Fixed Weather"/> + <menu_item_call label="Dump Region Object Cache" name="Dump Region Object Cache"/> + </menu> + <menu label="UI" name="UI"> + <menu_item_call label="Media Browser Test" name="Web Browser Test"/> + <menu_item_call label="Web Content Browser" name="Web Content Browser"/> + <menu_item_call label="Dump SelectMgr" name="Dump SelectMgr"/> + <menu_item_call label="Dump Inventory" name="Dump Inventory"/> + <menu_item_call label="Dump Timers" name="Dump Timers"/> + <menu_item_call label="Dump Focus Holder" name="Dump Focus Holder"/> + <menu_item_call label="Print Selected Object Info" name="Print Selected Object Info"/> + <menu_item_call label="Print Agent Info" name="Print Agent Info"/> + <menu_item_call label="Memory Stats" name="Memory Stats"/> + <menu_item_check label="Region Debug Console" name="Region Debug Console"/> + <menu_item_check label="Debug SelectMgr" name="Debug SelectMgr"/> + <menu_item_check label="Debug Clicks" name="Debug Clicks"/> + <menu_item_check label="Debug Views" name="Debug Views"/> + <menu_item_check label="Debug Name Tooltips" name="Debug Name Tooltips"/> + <menu_item_check label="Debug Mouse Events" name="Debug Mouse Events"/> + <menu_item_check label="Debug Keys" name="Debug Keys"/> + <menu_item_check label="Debug WindowProc" name="Debug WindowProc"/> + </menu> + <menu label="XUI" name="XUI"> + <menu_item_call label="Reload Color Settings" name="Reload Color Settings"/> + <menu_item_call label="Show Font Test" name="Show Font Test"/> + <menu_item_check label="Show XUI Names" name="Show XUI Names"/> + <menu_item_call label="Send Test IMs" name="Send Test IMs"/> + <menu_item_call label="Flush Names Caches" name="Flush Names Caches"/> + </menu> + <menu label="Avatar" name="Character"> + <menu label="Grab Baked Texture" name="Grab Baked Texture"> + <menu_item_call label="Iris" name="Iris"/> + <menu_item_call label="Head" name="Head"/> + <menu_item_call label="Upper Body" name="Upper Body"/> + <menu_item_call label="Lower Body" name="Lower Body"/> + <menu_item_call label="裙å" name="Skirt"/> + </menu> + <menu label="Character Tests" name="Character Tests"> + <menu_item_call label="Appearance To XML" name="Appearance To XML"/> + <menu_item_call label="Toggle Character Geometry" name="Toggle Character Geometry"/> + <menu_item_call label="Test Male" name="Test Male"/> + <menu_item_call label="Test Female" name="Test Female"/> + <menu_item_call label="Toggle PG" name="Toggle PG"/> + <menu_item_check label="Allow Select Avatar" name="Allow Select Avatar"/> + </menu> + <menu_item_call label="Force Params to Default" name="Force Params to Default"/> + <menu_item_check label="Animation Info" name="Animation Info"/> + <menu_item_check label="Slow Motion Animations" name="Slow Motion Animations"/> + <menu_item_check label="Show Look At" name="Show Look At"/> + <menu_item_check label="Show Point At" name="Show Point At"/> + <menu_item_check label="Debug Joint Updates" name="Debug Joint Updates"/> + <menu_item_check label="Disable LOD" name="Disable LOD"/> + <menu_item_check label="Debug Character Vis" name="Debug Character Vis"/> + <menu_item_check label="Show Collision Skeleton" name="Show Collision Skeleton"/> + <menu_item_check label="Display Agent Target" name="Display Agent Target"/> + --> + <menu_item_call label="Dump Attachments" name="Dump Attachments"/> + <menu_item_call label="Debug Avatar Textures" name="Debug Avatar Textures"/> + <menu_item_call label="Dump Local Textures" name="Dump Local Textures"/> + </menu> + <menu_item_check label="HTTP Textures" name="HTTP Textures"/> + <menu_item_call label="Compress Images" name="Compress Images"/> + <menu_item_check label="Output Debug Minidump" name="Output Debug Minidump"/> + <menu_item_check label="Console Window on next Run" name="Console Window"/> + <menu_item_call label="Request Admin Status" name="Request Admin Options"/> + <menu_item_call label="Leave Admin Status" name="Leave Admin Options"/> + <menu_item_check label="Show Admin Menu" name="View Admin Options"/> + </menu> + <menu label="Admin" name="Admin"> + <menu label="Object"> + <menu_item_call label="å–得副本" name="Take Copy"/> + <menu_item_call label="Force Owner To Me" name="Force Owner To Me"/> + <menu_item_call label="Force Owner Permissive" name="Force Owner Permissive"/> + <menu_item_call label="刪除" name="Delete"/> + <menu_item_call label="Lock" name="Lock"/> + <menu_item_call label="Get Assets IDs" name="Get Assets IDs"/> + </menu> + <menu label="地段" name="Parcel"> + <menu_item_call label="Force Owner To Me" name="Owner To Me"/> + <menu_item_call label="Set to Linden Content" name="Set to Linden Content"/> + <menu_item_call label="Claim Public Land" name="Claim Public Land"/> + </menu> + <menu label="地å€" name="Region"> + <menu_item_call label="Dump Temp Asset Data" name="Dump Temp Asset Data"/> + <menu_item_call label="Save Region State" name="Save Region State"/> + </menu> + <menu_item_call label="God Tools" name="God Tools"/> + </menu> + <menu label="Admin" name="Deprecated"> + <menu label="Attach Object" name="Attach Object"/> + <menu label="Detach Object" name="Detach Object"/> + <menu label="Take Off Clothing" name="Take Off Clothing"> + <menu_item_call label="襯衫" name="Shirt"/> + <menu_item_call label="褲å" name="Pants"/> + <menu_item_call label="éž‹å" name="Shoes"/> + <menu_item_call label="襪å" name="Socks"/> + <menu_item_call label="夾克" name="Jacket"/> + <menu_item_call label="手套" name="Gloves"/> + <menu_item_call label="內衣" name="Menu Undershirt"/> + <menu_item_call label="內褲" name="Menu Underpants"/> + <menu_item_call label="裙å" name="Skirt"/> + <menu_item_call label="Alpha" name="Alpha"/> + <menu_item_call label="Tattoo" name="Tattoo"/> + <menu_item_call label="Physics" name="Physics"/> + <menu_item_call label="All Clothes" name="All Clothes"/> + </menu> + <menu label="Help" name="Help"> + <menu_item_call label="Official Linden Blog" name="Official Linden Blog"/> + <menu_item_call label="Scripting Portal" name="Scripting Portal"/> + <menu label="Bug Reporting" name="Bug Reporting"> + <menu_item_call label="Public Issue Tracker" name="Public Issue Tracker"/> + <menu_item_call label="Public Issue Tracker Help" name="Publc Issue Tracker Help"/> + <menu_item_call label="Bug Reporting 101" name="Bug Reporing 101"/> + <menu_item_call label="Security Issues" name="Security Issues"/> + <menu_item_call label="QA Wiki" name="QA Wiki"/> + </menu> + </menu> + </menu> +</menu_bar> diff --git a/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml new file mode 100644 index 0000000000..97f18f0936 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Outfit Wearable Context Menu"> + <menu_item_call label="å–代" name="wear_replace"/> + <menu_item_call label="Wear" name="wear_wear"/> + <menu_item_call label="Add" name="wear_add"/> + <menu_item_call label="Take Off / Detach" name="take_off_or_detach"/> + <menu_item_call label="å¸ä¸‹" name="detach"/> + <context_menu label="Attach to" name="wearable_attach_to"/> + <context_menu label="Attach to HUD" name="wearable_attach_to_hud"/> + <menu_item_call label="脫下" name="take_off"/> + <menu_item_call label="編輯" name="edit"/> + <menu_item_call label="Item Profile" name="object_profile"/> + <menu_item_call label="Show Original" name="show_original"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml b/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml new file mode 100644 index 0000000000..ebf9b80d27 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_wearing_gear.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu name="Gear Wearing"> + <menu_item_call label="Edit Outfit" name="edit"/> + <menu_item_call label="脫下" name="takeoff"/> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/zh/menu_wearing_tab.xml b/indra/newview/skins/default/xui/zh/menu_wearing_tab.xml new file mode 100644 index 0000000000..5e82cb087f --- /dev/null +++ b/indra/newview/skins/default/xui/zh/menu_wearing_tab.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<context_menu name="Wearing"> + <menu_item_call label="脫下" name="take_off"/> + <menu_item_call label="å¸ä¸‹" name="detach"/> + <menu_item_call label="Edit Outfit" name="edit"/> +</context_menu> diff --git a/indra/newview/skins/default/xui/zh/mime_types.xml b/indra/newview/skins/default/xui/zh/mime_types.xml new file mode 100644 index 0000000000..1c9b68da1a --- /dev/null +++ b/indra/newview/skins/default/xui/zh/mime_types.xml @@ -0,0 +1,217 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<mimetypes name="default"> + <widgetset name="web"> + <label name="web_label"> + 網é 內容 + </label> + <tooltip name="web_tooltip"> + This location has Web content + </tooltip> + <playtip name="web_playtip"> + 顯示網é 內容 + </playtip> + </widgetset> + <widgetset name="movie"> + <label name="movie_label"> + Movie + </label> + <tooltip name="movie_tooltip"> + There is a movie to play here + </tooltip> + <playtip name="movie_playtip"> + Play movie + </playtip> + </widgetset> + <widgetset name="image"> + <label name="image_label"> + Image + </label> + <tooltip name="image_tooltip"> + There is an image at this location + </tooltip> + <playtip name="image_playtip"> + View this location's image + </playtip> + </widgetset> + <widgetset name="audio"> + <label name="audio_label"> + Audio + </label> + <tooltip name="audio_tooltip"> + There is audio at this location + </tooltip> + <playtip name="audio_playtip"> + Play this location's audio + </playtip> + </widgetset> + <scheme name="rtsp"> + <label name="rtsp_label"> + å³æ™‚ä¸²æµ + </label> + </scheme> + <mimetype name="blank"> + <label name="blank_label"> + - ç„¡ - + </label> + </mimetype> + <mimetype name="none/none"> + <label name="none/none_label"> + - ç„¡ - + </label> + </mimetype> + <mimetype name="audio/*"> + <label name="audio2_label"> + Audio + </label> + </mimetype> + <mimetype name="video/*"> + <label name="video2_label"> + Video + </label> + </mimetype> + <mimetype name="image/*"> + <label name="image2_label"> + Image + </label> + </mimetype> + <mimetype name="video/vnd.secondlife.qt.legacy"> + <label name="vnd.secondlife.qt.legacy_label"> + Movie (QuickTime) + </label> + </mimetype> + <mimetype name="application/javascript"> + <label name="application/javascript_label"> + Javascript + </label> + </mimetype> + <mimetype name="application/ogg"> + <label name="application/ogg_label"> + Ogg Audio/Video + </label> + </mimetype> + <mimetype name="application/pdf"> + <label name="application/pdf_label"> + PDF Document + </label> + </mimetype> + <mimetype name="application/postscript"> + <label name="application/postscript_label"> + Postscript Document + </label> + </mimetype> + <mimetype name="application/rtf"> + <label name="application/rtf_label"> + Rich Text (RTF) + </label> + </mimetype> + <mimetype name="application/smil"> + <label name="application/smil_label"> + Synchronized Multimedia Integration Language (SMIL) + </label> + </mimetype> + <mimetype name="application/xhtml+xml"> + <label name="application/xhtml+xml_label"> + Web Page (XHTML) + </label> + </mimetype> + <mimetype name="application/x-director"> + <label name="application/x-director_label"> + Macromedia Director + </label> + </mimetype> + <mimetype name="audio/mid"> + <label name="audio/mid_label"> + Audio (MIDI) + </label> + </mimetype> + <mimetype name="audio/mpeg"> + <label name="audio/mpeg_label"> + Audio (MP3) + </label> + </mimetype> + <mimetype name="audio/x-aiff"> + <label name="audio/x-aiff_label"> + Audio (AIFF) + </label> + </mimetype> + <mimetype name="audio/x-wav"> + <label name="audio/x-wav_label"> + Audio (WAV) + </label> + </mimetype> + <mimetype name="image/bmp"> + <label name="image/bmp_label"> + Image (BMP) + </label> + </mimetype> + <mimetype name="image/gif"> + <label name="image/gif_label"> + Image (GIF) + </label> + </mimetype> + <mimetype name="image/jpeg"> + <label name="image/jpeg_label"> + Image (JPEG) + </label> + </mimetype> + <mimetype name="image/png"> + <label name="image/png_label"> + Image (PNG) + </label> + </mimetype> + <mimetype name="image/svg+xml"> + <label name="image/svg+xml_label"> + Image (SVG) + </label> + </mimetype> + <mimetype name="image/tiff"> + <label name="image/tiff_label"> + Image (TIFF) + </label> + </mimetype> + <mimetype name="text/html"> + <label name="text/html_label"> + Web Page + </label> + </mimetype> + <mimetype name="text/plain"> + <label name="text/plain_label"> + Text + </label> + </mimetype> + <mimetype name="text/xml"> + <label name="text/xml_label"> + XML + </label> + </mimetype> + <mimetype name="video/mpeg"> + <label name="video/mpeg_label"> + Movie (MPEG) + </label> + </mimetype> + <mimetype name="video/mp4"> + <label name="video/mp4_label"> + Movie (MP4) + </label> + </mimetype> + <mimetype name="video/quicktime"> + <label name="video/quicktime_label"> + Movie (QuickTime) + </label> + </mimetype> + <mimetype name="video/x-ms-asf"> + <label name="video/x-ms-asf_label"> + Movie (Windows Media ASF) + </label> + </mimetype> + <mimetype name="video/x-ms-wmv"> + <label name="video/x-ms-wmv_label"> + Movie (Windows Media WMV) + </label> + </mimetype> + <mimetype name="video/x-msvideo"> + <label name="video/x-msvideo_label"> + Movie (AVI) + </label> + </mimetype> +</mimetypes> diff --git a/indra/newview/skins/default/xui/zh/mime_types_linux.xml b/indra/newview/skins/default/xui/zh/mime_types_linux.xml new file mode 100644 index 0000000000..1c9b68da1a --- /dev/null +++ b/indra/newview/skins/default/xui/zh/mime_types_linux.xml @@ -0,0 +1,217 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<mimetypes name="default"> + <widgetset name="web"> + <label name="web_label"> + 網é 內容 + </label> + <tooltip name="web_tooltip"> + This location has Web content + </tooltip> + <playtip name="web_playtip"> + 顯示網é 內容 + </playtip> + </widgetset> + <widgetset name="movie"> + <label name="movie_label"> + Movie + </label> + <tooltip name="movie_tooltip"> + There is a movie to play here + </tooltip> + <playtip name="movie_playtip"> + Play movie + </playtip> + </widgetset> + <widgetset name="image"> + <label name="image_label"> + Image + </label> + <tooltip name="image_tooltip"> + There is an image at this location + </tooltip> + <playtip name="image_playtip"> + View this location's image + </playtip> + </widgetset> + <widgetset name="audio"> + <label name="audio_label"> + Audio + </label> + <tooltip name="audio_tooltip"> + There is audio at this location + </tooltip> + <playtip name="audio_playtip"> + Play this location's audio + </playtip> + </widgetset> + <scheme name="rtsp"> + <label name="rtsp_label"> + å³æ™‚ä¸²æµ + </label> + </scheme> + <mimetype name="blank"> + <label name="blank_label"> + - ç„¡ - + </label> + </mimetype> + <mimetype name="none/none"> + <label name="none/none_label"> + - ç„¡ - + </label> + </mimetype> + <mimetype name="audio/*"> + <label name="audio2_label"> + Audio + </label> + </mimetype> + <mimetype name="video/*"> + <label name="video2_label"> + Video + </label> + </mimetype> + <mimetype name="image/*"> + <label name="image2_label"> + Image + </label> + </mimetype> + <mimetype name="video/vnd.secondlife.qt.legacy"> + <label name="vnd.secondlife.qt.legacy_label"> + Movie (QuickTime) + </label> + </mimetype> + <mimetype name="application/javascript"> + <label name="application/javascript_label"> + Javascript + </label> + </mimetype> + <mimetype name="application/ogg"> + <label name="application/ogg_label"> + Ogg Audio/Video + </label> + </mimetype> + <mimetype name="application/pdf"> + <label name="application/pdf_label"> + PDF Document + </label> + </mimetype> + <mimetype name="application/postscript"> + <label name="application/postscript_label"> + Postscript Document + </label> + </mimetype> + <mimetype name="application/rtf"> + <label name="application/rtf_label"> + Rich Text (RTF) + </label> + </mimetype> + <mimetype name="application/smil"> + <label name="application/smil_label"> + Synchronized Multimedia Integration Language (SMIL) + </label> + </mimetype> + <mimetype name="application/xhtml+xml"> + <label name="application/xhtml+xml_label"> + Web Page (XHTML) + </label> + </mimetype> + <mimetype name="application/x-director"> + <label name="application/x-director_label"> + Macromedia Director + </label> + </mimetype> + <mimetype name="audio/mid"> + <label name="audio/mid_label"> + Audio (MIDI) + </label> + </mimetype> + <mimetype name="audio/mpeg"> + <label name="audio/mpeg_label"> + Audio (MP3) + </label> + </mimetype> + <mimetype name="audio/x-aiff"> + <label name="audio/x-aiff_label"> + Audio (AIFF) + </label> + </mimetype> + <mimetype name="audio/x-wav"> + <label name="audio/x-wav_label"> + Audio (WAV) + </label> + </mimetype> + <mimetype name="image/bmp"> + <label name="image/bmp_label"> + Image (BMP) + </label> + </mimetype> + <mimetype name="image/gif"> + <label name="image/gif_label"> + Image (GIF) + </label> + </mimetype> + <mimetype name="image/jpeg"> + <label name="image/jpeg_label"> + Image (JPEG) + </label> + </mimetype> + <mimetype name="image/png"> + <label name="image/png_label"> + Image (PNG) + </label> + </mimetype> + <mimetype name="image/svg+xml"> + <label name="image/svg+xml_label"> + Image (SVG) + </label> + </mimetype> + <mimetype name="image/tiff"> + <label name="image/tiff_label"> + Image (TIFF) + </label> + </mimetype> + <mimetype name="text/html"> + <label name="text/html_label"> + Web Page + </label> + </mimetype> + <mimetype name="text/plain"> + <label name="text/plain_label"> + Text + </label> + </mimetype> + <mimetype name="text/xml"> + <label name="text/xml_label"> + XML + </label> + </mimetype> + <mimetype name="video/mpeg"> + <label name="video/mpeg_label"> + Movie (MPEG) + </label> + </mimetype> + <mimetype name="video/mp4"> + <label name="video/mp4_label"> + Movie (MP4) + </label> + </mimetype> + <mimetype name="video/quicktime"> + <label name="video/quicktime_label"> + Movie (QuickTime) + </label> + </mimetype> + <mimetype name="video/x-ms-asf"> + <label name="video/x-ms-asf_label"> + Movie (Windows Media ASF) + </label> + </mimetype> + <mimetype name="video/x-ms-wmv"> + <label name="video/x-ms-wmv_label"> + Movie (Windows Media WMV) + </label> + </mimetype> + <mimetype name="video/x-msvideo"> + <label name="video/x-msvideo_label"> + Movie (AVI) + </label> + </mimetype> +</mimetypes> diff --git a/indra/newview/skins/default/xui/zh/mime_types_mac.xml b/indra/newview/skins/default/xui/zh/mime_types_mac.xml new file mode 100644 index 0000000000..b6c8784759 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/mime_types_mac.xml @@ -0,0 +1,217 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<mimetypes name="default"> + <widgetset name="web"> + <label name="web_label"> + 網é 內容 + </label> + <tooltip name="web_tooltip"> + This location has Web content + </tooltip> + <playtip name="web_playtip"> + 顯示網é 內容 + </playtip> + </widgetset> + <widgetset name="movie"> + <label name="movie_label"> + Movie + </label> + <tooltip name="movie_tooltip"> + There is a movie to play here + </tooltip> + <playtip name="movie_playtip"> + Play movie + </playtip> + </widgetset> + <widgetset name="image"> + <label name="image_label"> + Image + </label> + <tooltip name="image_tooltip"> + There is an image at this location + </tooltip> + <playtip name="image_playtip"> + View this location's image + </playtip> + </widgetset> + <widgetset name="audio"> + <label name="audio_label"> + Audio + </label> + <tooltip name="audio_tooltip"> + There is audio at this location + </tooltip> + <playtip name="audio_playtip"> + Play this location's audio + </playtip> + </widgetset> + <scheme name="rtsp"> + <label name="rtsp_label"> + å³æ™‚ä¸²æµ + </label> + </scheme> + <mimetype name="blank"> + <label name="blank_label"> + - ç„¡ - + </label> + </mimetype> + <mimetype name="none/none"> + <label name="none/none_label"> + - ç„¡ - + </label> + </mimetype> + <mimetype name="audio/*"> + <label name="audio2_label"> + Audio + </label> + </mimetype> + <mimetype name="video/*"> + <label name="video2_label"> + Video + </label> + </mimetype> + <mimetype name="image/*"> + <label name="image2_label"> + Image + </label> + </mimetype> + <mimetype name="video/vnd.secondlife.qt.legacy"> + <label name="vnd.secondlife.qt.legacy_label"> + Movie (QuickTime) + </label> + </mimetype> + <mimetype name="application/javascript"> + <label name="application/javascript_label"> + Javascript + </label> + </mimetype> + <mimetype name="application/ogg"> + <label name="application/ogg_label"> + Ogg Audio/Video + </label> + </mimetype> + <mimetype name="application/pdf"> + <label name="application/pdf_label"> + PDF Document + </label> + </mimetype> + <mimetype name="application/postscript"> + <label name="application/postscript_label"> + Postscript Document + </label> + </mimetype> + <mimetype name="application/rtf"> + <label name="application/rtf_label"> + Rich Text (RTF) + </label> + </mimetype> + <mimetype name="application/smil"> + <label name="application/smil_label"> + Synchronized Multimedia Integration Language (SMIL) + </label> + </mimetype> + <mimetype name="application/xhtml+xml"> + <label name="application/xhtml+xml_label"> + Web Page (XHTML) + </label> + </mimetype> + <mimetype name="application/x-director"> + <label name="application/x-director_label"> + Macromedia Director + </label> + </mimetype> + <mimetype name="audio/mid"> + <label name="audio/mid_label"> + Audio (MIDI) + </label> + </mimetype> + <mimetype name="audio/mpeg"> + <label name="audio/mpeg_label"> + Audio (MP3) + </label> + </mimetype> + <mimetype name="audio/x-aiff"> + <label name="audio/x-aiff_label"> + Audio (AIFF) + </label> + </mimetype> + <mimetype name="audio/x-wav"> + <label name="audio/x-wav_label"> + Audio (WAV) + </label> + </mimetype> + <mimetype name="image/bmp"> + <label name="image/bmp_label"> + Image (BMP) + </label> + </mimetype> + <mimetype name="image/gif"> + <label name="image/gif_label"> + Image (GIF) + </label> + </mimetype> + <mimetype name="image/jpeg"> + <label name="image/jpeg_label"> + Image (JPEG) + </label> + </mimetype> + <mimetype name="image/png"> + <label name="image/png_label"> + Image (PNG) + </label> + </mimetype> + <mimetype name="image/svg+xml"> + <label name="image/svg+xml_label"> + Image (SVG) + </label> + </mimetype> + <mimetype name="image/tiff"> + <label name="image/tiff_label"> + Image (TIFF) + </label> + </mimetype> + <mimetype name="text/html"> + <label name="text/html_label"> + 網é + </label> + </mimetype> + <mimetype name="text/plain"> + <label name="text/plain_label"> + æ–‡å— + </label> + </mimetype> + <mimetype name="text/xml"> + <label name="text/xml_label"> + XML + </label> + </mimetype> + <mimetype name="video/mpeg"> + <label name="video/mpeg_label"> + Movie (MPEG) + </label> + </mimetype> + <mimetype name="video/mp4"> + <label name="video/mp4_label"> + Movie (MP4) + </label> + </mimetype> + <mimetype name="video/quicktime"> + <label name="video/quicktime_label"> + Movie (QuickTime) + </label> + </mimetype> + <mimetype name="video/x-ms-asf"> + <label name="video/x-ms-asf_label"> + Movie (Windows Media ASF) + </label> + </mimetype> + <mimetype name="video/x-ms-wmv"> + <label name="video/x-ms-wmv_label"> + Movie (Windows Media WMV) + </label> + </mimetype> + <mimetype name="video/x-msvideo"> + <label name="video/x-msvideo_label"> + Movie (AVI) + </label> + </mimetype> +</mimetypes> diff --git a/indra/newview/skins/default/xui/zh/notifications.xml b/indra/newview/skins/default/xui/zh/notifications.xml new file mode 100644 index 0000000000..8b26c70430 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/notifications.xml @@ -0,0 +1,2952 @@ +<?xml version="1.0" encoding="utf-8"?> +<notifications> + <global name="skipnexttime"> + Don't show me this again + </global> + <global name="alwayschoose"> + Always choose this option + </global> + <global name="implicitclosebutton"> + 關閉 + </global> + <template name="okbutton"> + <form> + <button name="OK_okbutton" text="$yestext"/> + </form> + </template> + <template name="okignore"> + <form> + <button name="OK_okignore" text="$yestext"/> + </form> + </template> + <template name="okcancelbuttons"> + <form> + <button name="OK_okcancelbuttons" text="$yestext"/> + <button name="Cancel_okcancelbuttons" text="$notext"/> + </form> + </template> + <template name="okcancelignore"> + <form> + <button name="OK_okcancelignore" text="$yestext"/> + <button name="Cancel_okcancelignore" text="$notext"/> + </form> + </template> + <template name="okhelpbuttons"> + <form> + <button name="OK_okhelpbuttons" text="$yestext"/> + <button name="Help" text="$helptext"/> + </form> + </template> + <template name="yesnocancelbuttons"> + <form> + <button name="Yes" text="$yestext"/> + <button name="No" text="$notext"/> + <button name="Cancel_yesnocancelbuttons" text="$canceltext"/> + </form> + </template> + <notification label="Unknown Notification Message" name="MissingAlert"> + Your version of [APP_NAME] does not know how to display the notification it just received. Please verify that you have the latest Viewer installed. + +Error details: The notification called '[_NAME]' was not found in notifications.xml. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="FloaterNotFound"> + Floater error: Could not find the following controls: + +[CONTROLS] + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="TutorialNotFound"> + No tutorial is currently available. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="GenericAlert"> + [MESSAGE] + </notification> + <notification name="GenericAlertYesCancel"> + [MESSAGE] + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="是"/> + </notification> + <notification name="BadInstallation"> + An error occurred while updating [APP_NAME]. Please [http://get.secondlife.com download the latest version] of the Viewer. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="LoginFailedNoNetwork"> + Could not connect to the [SECOND_LIFE_GRID]. + '[DIAGNOSTIC]' +Make sure your Internet connection is working properly. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="MessageTemplateNotFound"> + Message Template [PATH] not found. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="WearableSave"> + Save changes to current clothing/body part? + <usetemplate canceltext="å–銷" name="yesnocancelbuttons" notext="ä¸è¦å„²å˜" yestext="儲å˜"/> + </notification> + <notification name="CompileQueueSaveText"> + There was a problem uploading the text for a script due to the following reason: [REASON]. Please try again later. + </notification> + <notification name="CompileQueueSaveBytecode"> + There was a problem uploading the compiled script due to the following reason: [REASON]. Please try again later. + </notification> + <notification name="WriteAnimationFail"> + There was a problem writing animation data. Please try again later. + </notification> + <notification name="UploadAuctionSnapshotFail"> + There was a problem uploading the auction snapshot due to the following reason: [REASON] + </notification> + <notification name="UnableToViewContentsMoreThanOne"> + Unable to view the contents of more than one item at a time. +Please select only one object and try again. + </notification> + <notification name="SaveClothingBodyChanges"> + Save all changes to clothing/body parts? + <usetemplate canceltext="å–銷" name="yesnocancelbuttons" notext="ä¸è¦å„²å˜" yestext="全部儲å˜"/> + </notification> + <notification name="FriendsAndGroupsOnly"> + Non-friends won't know that you've choosen to ignore their calls and instant messages. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="FavoritesOnLogin"> + Note: When you turn on this option, anyone who uses this computer can see your list of favorite locations. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="GrantModifyRights"> + Granting modify rights to another Resident allows them to change, delete or take ANY objects you may have in-world. Be VERY careful when handing out this permission. +Do you want to grant modify rights for [NAME]? + <usetemplate name="okcancelbuttons" notext="No" yestext="是"/> + </notification> + <notification name="GrantModifyRightsMultiple"> + Granting modify rights to another Resident allows them to change ANY objects you may have in-world. Be VERY careful when handing out this permission. +Do you want to grant modify rights for the selected Residents? + <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/> + </notification> + <notification name="RevokeModifyRights"> + Do you want to revoke modify rights for [NAME]? + <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/> + </notification> + <notification name="RevokeModifyRightsMultiple"> + Do you want to revoke modify rights for the selected Residents? + <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/> + </notification> + <notification name="UnableToCreateGroup"> + Unable to create group. +[MESSAGE] + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="PanelGroupApply"> + [NEEDS_APPLY_MESSAGE] +[WANT_APPLY_MESSAGE] + <usetemplate canceltext="å–銷" name="yesnocancelbuttons" notext="忽視變更" yestext="套用變更"/> + </notification> + <notification name="MustSpecifyGroupNoticeSubject"> + You must specify a subject to send a group notice. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="AddGroupOwnerWarning"> + You are about to add group members to the role of [ROLE_NAME]. +Members cannot be removed from that role. +The members must resign from the role themselves. +Are you sure you want to continue? + <usetemplate ignoretext="Confirm before I add a new group Owner" name="okcancelignore" notext="å¦" yestext="是"/> + </notification> + <notification name="AssignDangerousActionWarning"> + You are about to add the Ability '[ACTION_NAME]' to the Role '[ROLE_NAME]'. + + *WARNING* + Any Member in a Role with this Ability can assign themselves -- and any other member -- to Roles that have more powers than they currently have, potentially elevating themselves to near-Owner power. Be sure you know what you're doing before assigning this Ability. + +Add this Ability to '[ROLE_NAME]'? + <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/> + </notification> + <notification name="AssignDangerousAbilityWarning"> + You are about to add the Ability '[ACTION_NAME]' to the Role '[ROLE_NAME]'. + + *WARNING* + Any Member in a Role with this Ability can assign themselves -- and any other member -- all Abilities, elevating themselves to near-Owner power. + +Add this Ability to '[ROLE_NAME]'? + <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/> + </notification> + <notification name="AttachmentDrop"> + You are about to drop your attachment. + Are you sure you want to continue? + <usetemplate ignoretext="Confirm before dropping attachments" name="okcancelignore" notext="å¦" yestext="是"/> + </notification> + <notification name="JoinGroupCanAfford"> + Joining this group costs L$[COST]. +Do you wish to proceed? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="Join"/> + </notification> + <notification name="JoinGroupNoCost"> + You are joining group [NAME]. +Do you wish to proceed? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="Join"/> + </notification> + <notification name="JoinGroupCannotAfford"> + Joining this group costs L$[COST]. +You do not have enough L$ to join this group. + </notification> + <notification name="CreateGroupCost"> + Creating this group will cost L$100. +Groups need more than one member, or they are deleted forever. +Please invite members within 48 hours. + <usetemplate canceltext="å–銷" name="okcancelbuttons" notext="å–銷" yestext="Create group for L$100"/> + </notification> + <notification name="LandBuyPass"> + For L$[COST] you can enter this land ('[PARCEL_NAME]') for [TIME] hours. Buy a pass? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="SalePriceRestriction"> + Sale price must be set to more than L$0 if selling to anyone. +Please select an individual to sell to if selling for L$0. + </notification> + <notification name="ConfirmLandSaleChange"> + The selected [LAND_SIZE] m² land is being set for sale. +Your selling price will be L$[SALE_PRICE] and will be authorized for sale to [NAME]. + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ConfirmLandSaleToAnyoneChange"> + ATTENTION: Clicking 'sell to anyone' makes your land available to the entire [SECOND_LIFE] community, even those not in this region. + +The selected [LAND_SIZE] m² land is being set for sale. +Your selling price will be L$[SALE_PRICE] and will be authorized for sale to [NAME]. + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ReturnObjectsDeededToGroup"> + Are you sure you want to return all objects shared with the group '[NAME]' on this parcel of land back to their previous owner's inventory? + +*WARNING* This will delete the non-transferable objects deeded to the group! + +Objects: [N] + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ReturnObjectsOwnedByUser"> + Are you sure you want to return all objects owned by the Resident '[NAME]' on this parcel of land back to their inventory? + +Objects: [N] + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ReturnObjectsOwnedBySelf"> + Are you sure you want to return all objects owned by you on this parcel of land back to your inventory? + +Objects: [N] + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ReturnObjectsNotOwnedBySelf"> + Are you sure you want to return all objects NOT owned by you on this parcel of land back to their owner's inventory? +Transferable objects deeded to a group will be returned to their previous owners. + +*WARNING* This will delete the non-transferable objects deeded to the group! + +Objects: [N] + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ReturnObjectsNotOwnedByUser"> + Are you sure you want to return all objects NOT owned by [NAME] on this parcel of land back to their owner's inventory? +Transferable objects deeded to a group will be returned to their previous owners. + +*WARNING* This will delete the non-transferable objects deeded to the group! + +Objects: [N] + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ReturnAllTopObjects"> + Are you sure you want to return all listed objects back to their owner's inventory? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="DisableAllTopObjects"> + Are you sure you want to disable all objects in this region? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ReturnObjectsNotOwnedByGroup"> + Return the objects on this parcel of land that are NOT shared with the group [NAME] back to their owners? + +Objects: [N] + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="UnableToDisableOutsideScripts"> + Can not disable scripts. +This entire region is damage enabled. +Scripts must be allowed to run for weapons to work. + </notification> + <notification name="MultipleFacesSelected"> + Multiple faces are currently selected. +If you continue this action, separate instances of media will be set on multiple faces of the object. +To place the media on only one face, choose Select Face and click on the desired face of that object then click Add. + <usetemplate ignoretext="Media will be set on multiple selected faces" name="okcancelignore" notext="å–銷" yestext="確定"/> + </notification> + <notification name="MustBeInParcel"> + You must be standing inside the land parcel to set its Landing Point. + </notification> + <notification name="PromptRecipientEmail"> + Please enter a valid email address for the recipient(s). + </notification> + <notification name="PromptSelfEmail"> + Please enter your email address. + </notification> + <notification name="PromptMissingSubjMsg"> + Email snapshot with the default subject or message? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ErrorProcessingSnapshot"> + Error processing snapshot data + </notification> + <notification name="ErrorEncodingSnapshot"> + Error encoding snapshot. + </notification> + <notification name="ErrorUploadingPostcard"> + There was a problem sending a snapshot due to the following reason: [REASON] + </notification> + <notification name="ErrorUploadingReportScreenshot"> + There was a problem uploading a report screenshot due to the following reason: [REASON] + </notification> + <notification name="MustAgreeToLogIn"> + You must agree to the Terms of Service to continue logging into [SECOND_LIFE]. + </notification> + <notification name="CouldNotPutOnOutfit"> + Could not put on outfit. +The outfit folder contains no clothing, body parts, or attachments. + </notification> + <notification name="CannotWearTrash"> + You can not wear clothes or body parts that are in the trash + </notification> + <notification name="MaxAttachmentsOnOutfit"> + Could not attach object. +Exceeds the attachments limit of [MAX_ATTACHMENTS] objects. Please detach another object first. + </notification> + <notification name="CannotWearInfoNotComplete"> + You can not wear that item because it has not yet loaded. Please try again in a minute. + </notification> + <notification name="MustHaveAccountToLogIn"> + Oops! Something was left blank. +You need to enter the Username name of your avatar. + +You need an account to enter [SECOND_LIFE]. Would you like to create one now? + <url name="url"> + http://join.secondlife.com/ + </url> + <usetemplate name="okcancelbuttons" notext="Try again" yestext="Create a new account"/> + </notification> + <notification name="InvalidCredentialFormat"> + You need to enter either the Username or both the First and Last name of your avatar into the Username field, then login again. + </notification> + <notification name="DeleteClassified"> + Delete classified '[NAME]'? +There is no reimbursement for fees paid. + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="DeleteMedia"> + You have selected to delete the media associated with this face. +Are you sure you want to continue? + <usetemplate ignoretext="Confirm before I delete media from an object" name="okcancelignore" notext="å¦" yestext="是"/> + </notification> + <notification name="ClassifiedSave"> + Save changes to classified [NAME]? + <usetemplate canceltext="å–銷" name="yesnocancelbuttons" notext="ä¸è¦å„²å˜" yestext="儲å˜"/> + </notification> + <notification name="ClassifiedInsufficientFunds"> + Insufficient funds to create classified. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="DeleteAvatarPick"> + Delete pick <nolink>[PICK]</nolink>? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="DeleteOutfits"> + Delete the selected outfit? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="PromptGoToEventsPage"> + Go to the [SECOND_LIFE] events web page? + <url name="url"> + http://secondlife.com/events/ + </url> + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="SelectProposalToView"> + Please select a proposal to view. + </notification> + <notification name="SelectHistoryItemToView"> + Please select a history item to view. + </notification> + <notification name="CacheWillClear"> + Cache will be cleared after you restart [APP_NAME]. + </notification> + <notification name="CacheWillBeMoved"> + Cache will be moved after you restart [APP_NAME]. +Note: This will clear the cache. + </notification> + <notification name="ChangeConnectionPort"> + Port settings take effect after you restart [APP_NAME]. + </notification> + <notification name="ChangeSkin"> + The new skin will appear after you restart [APP_NAME]. + </notification> + <notification name="ChangeLanguage"> + Changing language will take effect after you restart [APP_NAME]. + </notification> + <notification name="GoToAuctionPage"> + Go to the [SECOND_LIFE] web page to see auction details or make a bid? + <url name="url"> + http://secondlife.com/auctions/auction-detail.php?id=[AUCTION_ID] + </url> + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="SaveChanges"> + Save Changes? + <usetemplate canceltext="å–銷" name="yesnocancelbuttons" notext="ä¸è¦å„²å˜" yestext="儲å˜"/> + </notification> + <notification name="GestureSaveFailedTooManySteps"> + Gesture save failed. +This gesture has too many steps. +Try removing some steps, then save again. + </notification> + <notification name="GestureSaveFailedTryAgain"> + Gesture save failed. Please try again in a minute. + </notification> + <notification name="GestureSaveFailedObjectNotFound"> + Could not save gesture because the object or the associated object inventory could not be found. +The object may be out of range or may have been deleted. + </notification> + <notification name="GestureSaveFailedReason"> + There was a problem saving a gesture due to the following reason: [REASON]. Please try resaving the gesture later. + </notification> + <notification name="SaveNotecardFailObjectNotFound"> + Could not save notecard because the object or the associated object inventory could not be found. +The object may be out of range or may have been deleted. + </notification> + <notification name="SaveNotecardFailReason"> + There was a problem saving a notecard due to the following reason: [REASON]. Please try re-saving the notecard later. + </notification> + <notification name="ScriptCannotUndo"> + Could not undo all changes in your version of the script. +Would you like to load the server's last saved version? +(**Warning** This operation cannot be undone.) + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="SaveScriptFailReason"> + There was a problem saving a script due to the following reason: [REASON]. Please try re-saving the script later. + </notification> + <notification name="SaveScriptFailObjectNotFound"> + Could not save the script because the object it is in could not be found. +The object may be out of range or may have been deleted. + </notification> + <notification name="SaveBytecodeFailReason"> + There was a problem saving a compiled script due to the following reason: [REASON]. Please try re-saving the script later. + </notification> + <notification name="StartRegionEmpty"> + Oops, Your Start Region is not defined. +Please type the Region name in Start Location box or choose My Last Location or My Home as your Start Location. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="CouldNotStartStopScript"> + Could not start or stop the script because the object it is on could not be found. +The object may be out of range or may have been deleted. + </notification> + <notification name="CannotDownloadFile"> + Unable to download file + </notification> + <notification name="CannotWriteFile"> + Unable to write file [[FILE]] + </notification> + <notification name="UnsupportedHardware"> + Just so you know, your computer does not meet [APP_NAME]'s minimum system requirements. You may experience poor performance. Unfortunately, the [SUPPORT_SITE] can't provide technical support for unsupported system configurations. + +Visit [_URL] for more information? + <url name="url"> + http://www.secondlife.com/corporate/sysreqs.php + </url> + <usetemplate ignoretext="My computer hardware is not supported" name="okcancelignore" notext="å¦" yestext="是"/> + </notification> + <notification name="UnknownGPU"> + Your system contains a graphics card that [APP_NAME] doesn't recognize. +This is often the case with new hardware that hasn't been tested yet with [APP_NAME]. It will probably be ok, but you may need to adjust your graphics settings. +(Me > Preferences > Graphics). + <form name="form"> + <ignore name="ignore" text="My graphics card could not be identified"/> + </form> + </notification> + <notification name="DisplaySettingsNoShaders"> + [APP_NAME] crashed while initializing graphics drivers. +Graphics Quality will be set to Low to avoid some common driver errors. This will disable some graphics features. +We recommend updating your graphics card drivers. +Graphics Quality can be raised in Preferences > Graphics. + </notification> + <notification name="RegionNoTerraforming"> + The region [REGION] does not allow terraforming. + </notification> + <notification name="CannotCopyWarning"> + You do not have permission to copy the following items: +[ITEMS] +and will lose it from your inventory if you give it away. Do you really want to offer these items? + <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/> + </notification> + <notification name="CannotGiveItem"> + Unable to give inventory item. + </notification> + <notification name="TransactionCancelled"> + Transaction cancelled. + </notification> + <notification name="TooManyItems"> + Cannot give more than 42 items in a single inventory transfer. + </notification> + <notification name="NoItems"> + You do not have permission to transfer the selected items. + </notification> + <notification name="CannotCopyCountItems"> + You do not have permission to copy [COUNT] of the selected items. You will lose these items from your inventory. +Do you really want to give these items? + <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/> + </notification> + <notification name="CannotGiveCategory"> + You do not have permission to transfer the selected folder. + </notification> + <notification name="FreezeAvatar"> + Freeze this avatar? +He or she will temporarily be unable to move, chat, or interact with the world. + <usetemplate canceltext="å–銷" name="yesnocancelbuttons" notext="Unfreeze" yestext="Freeze"/> + </notification> + <notification name="FreezeAvatarFullname"> + Freeze [AVATAR_NAME]? +He or she will temporarily be unable to move, chat, or interact with the world. + <usetemplate canceltext="å–銷" name="yesnocancelbuttons" notext="Unfreeze" yestext="Freeze"/> + </notification> + <notification name="EjectAvatarFullname"> + Eject [AVATAR_NAME] from your land? + <usetemplate canceltext="å–銷" name="yesnocancelbuttons" notext="Eject and Ban" yestext="Eject"/> + </notification> + <notification name="EjectAvatarNoBan"> + Eject this avatar from your land? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="Eject"/> + </notification> + <notification name="EjectAvatarFullnameNoBan"> + Eject [AVATAR_NAME] from your land? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="Eject"/> + </notification> + <notification name="EjectAvatarFromGroup"> + You ejected [AVATAR_NAME] from group [GROUP_NAME] + </notification> + <notification name="AcquireErrorTooManyObjects"> + ACQUIRE ERROR: Too many objects selected. + </notification> + <notification name="AcquireErrorObjectSpan"> + ACQUIRE ERROR: Objects span more than one region. +Please move all objects to be acquired onto the same region. + </notification> + <notification name="PromptGoToCurrencyPage"> + [EXTRA] + +Go to [_URL] for information on purchasing L$? + <url name="url"> + http://secondlife.com/app/currency/ + </url> + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="UnableToLinkObjects"> + Unable to link these [COUNT] objects. +You can link a maximum of [MAX] objects. + </notification> + <notification name="CannotLinkIncompleteSet"> + You can only link complete sets of objects, and must select more than one object. + </notification> + <notification name="CannotLinkModify"> + Unable to link because you don't have modify permission on all the objects. + +Please make sure none are locked, and that you own all of them. + </notification> + <notification name="CannotLinkDifferentOwners"> + Unable to link because not all of the objects have the same owner. + +Please make sure you own all of the selected objects. + </notification> + <notification name="NoFileExtension"> + No file extension for the file: '[FILE]' + +Please make sure the file has a correct file extension. + </notification> + <notification name="InvalidFileExtension"> + Invalid file extension [EXTENSION] +Expected [VALIDS] + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="CannotUploadSoundFile"> + Couldn't open uploaded sound file for reading: +[FILE] + </notification> + <notification name="SoundFileNotRIFF"> + File does not appear to be a RIFF WAVE file: +[FILE] + </notification> + <notification name="SoundFileNotPCM"> + File does not appear to be a PCM WAVE audio file: +[FILE] + </notification> + <notification name="SoundFileInvalidChannelCount"> + File has invalid number of channels (must be mono or stereo): +[FILE] + </notification> + <notification name="SoundFileInvalidSampleRate"> + File does not appear to be a supported sample rate (must be 44.1k): +[FILE] + </notification> + <notification name="SoundFileInvalidWordSize"> + File does not appear to be a supported word size (must be 8 or 16 bit): +[FILE] + </notification> + <notification name="SoundFileInvalidHeader"> + Could not find 'data' chunk in WAV header: +[FILE] + </notification> + <notification name="SoundFileInvalidChunkSize"> + Wrong chunk size in WAV file: +[FILE] + </notification> + <notification name="SoundFileInvalidTooLong"> + Audio file is too long (10 second maximum): +[FILE] + </notification> + <notification name="ProblemWithFile"> + Problem with file [FILE]: + +[ERROR] + </notification> + <notification name="CannotOpenTemporarySoundFile"> + Couldn't open temporary compressed sound file for writing: [FILE] + </notification> + <notification name="UnknownVorbisEncodeFailure"> + Unknown Vorbis encode failure on: [FILE] + </notification> + <notification name="CannotEncodeFile"> + Unable to encode file: [FILE] + </notification> + <notification name="CorruptedProtectedDataStore"> + We can't fill in your username and password. This may happen when you change network setup + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="CorruptResourceFile"> + Corrupt resource file: [FILE] + </notification> + <notification name="UnknownResourceFileVersion"> + Unknown Linden resource file version in file: [FILE] + </notification> + <notification name="UnableToCreateOutputFile"> + Unable to create output file: [FILE] + </notification> + <notification name="DoNotSupportBulkAnimationUpload"> + [APP_NAME] does not currently support bulk upload of animation files. + </notification> + <notification name="CannotUploadReason"> + Unable to upload [FILE] due to the following reason: [REASON] +Please try again later. + </notification> + <notification name="LandmarkCreated"> + You have added "[LANDMARK_NAME]" to your [FOLDER_NAME] folder. + </notification> + <notification name="LandmarkAlreadyExists"> + You already have a landmark for this location. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="CannotCreateLandmarkNotOwner"> + You cannot create a landmark here because the owner of the land doesn't allow it. + </notification> + <notification name="CannotRecompileSelectObjectsNoScripts"> + Not able to perform 'recompilation'. +Select an object with a script. + </notification> + <notification name="CannotRecompileSelectObjectsNoPermission"> + Not able to perform 'recompilation'. + +Select objects with scripts that you have permission to modify. + </notification> + <notification name="CannotResetSelectObjectsNoScripts"> + Not able to perform 'reset'. + +Select objects with scripts. + </notification> + <notification name="CannotResetSelectObjectsNoPermission"> + Not able to perform 'reset'. + +Select objects with scripts that you have permission to modify. + </notification> + <notification name="CannotOpenScriptObjectNoMod"> + Unable to open script in object without modify permissions. + </notification> + <notification name="CannotSetRunningSelectObjectsNoScripts"> + Not able to set any scripts to 'running'. + +Select objects with scripts. + </notification> + <notification name="CannotSetRunningNotSelectObjectsNoScripts"> + Unable to set any scripts to 'not running'. + +Select objects with scripts. + </notification> + <notification name="NoFrontmostFloater"> + No frontmost floater to save. + </notification> + <notification name="SeachFilteredOnShortWords"> + Your search query was modified and the words that were too short were removed. + +Searched for: [FINALQUERY] + </notification> + <notification name="SeachFilteredOnShortWordsEmpty"> + Your search terms were too short so no search was performed. + </notification> + <notification name="CouldNotTeleportReason"> + Teleport failed. +[REASON] + </notification> + <notification name="invalid_tport"> + Problem encountered processing your teleport request. You may need to log back in before you can teleport. +If you continue to get this message, please check the [SUPPORT_SITE]. + </notification> + <notification name="invalid_region_handoff"> + Problem encountered processing your region crossing. You may need to log back in before you can cross regions. +If you continue to get this message, please check the [SUPPORT_SITE]. + </notification> + <notification name="blocked_tport"> + Sorry, teleport is currently blocked. Try again in a moment. If you still cannot teleport, please log out and log back in to resolve the problem. + </notification> + <notification name="nolandmark_tport"> + Sorry, but system was unable to locate landmark destination. + </notification> + <notification name="timeout_tport"> + Sorry, but system was unable to complete the teleport connection. Try again in a moment. + </notification> + <notification name="noaccess_tport"> + Sorry, you do not have access to that teleport destination. + </notification> + <notification name="missing_attach_tport"> + Your attachments have not arrived yet. Try waiting for a few more seconds or log out and back in again before attempting to teleport. + </notification> + <notification name="too_many_uploads_tport"> + The asset queue in this region is currently clogged so your teleport request will not be able to succeed in a timely manner. Please try again in a few minutes or go to a less busy area. + </notification> + <notification name="expired_tport"> + Sorry, but the system was unable to complete your teleport request in a timely fashion. Please try again in a few minutes. + </notification> + <notification name="expired_region_handoff"> + Sorry, but the system was unable to complete your region crossing in a timely fashion. Please try again in a few minutes. + </notification> + <notification name="no_host"> + Unable to find teleport destination. The destination may be temporarily unavailable or no longer exists. Please try again in a few minutes. + </notification> + <notification name="no_inventory_host"> + The inventory system is currently unavailable. + </notification> + <notification name="CannotSetLandOwnerNothingSelected"> + Unable to set land owner: +No parcel selected. + </notification> + <notification name="CannotSetLandOwnerMultipleRegions"> + Unable to force land ownership because selection spans multiple regions. Please select a smaller area and try again. + </notification> + <notification name="ForceOwnerAuctionWarning"> + This parcel is up for auction. Forcing ownership will cancel the auction and potentially make some Residents unhappy if bidding has begun. +Force ownership? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="CannotContentifyNothingSelected"> + Unable to contentify: +No parcel selected. + </notification> + <notification name="CannotContentifyNoRegion"> + Unable to contentify: +No region selected. + </notification> + <notification name="CannotReleaseLandNothingSelected"> + Unable to abandon land: +No parcel selected. + </notification> + <notification name="CannotReleaseLandNoRegion"> + Unable to abandon land: +Cannot find region. + </notification> + <notification name="CannotBuyLandNothingSelected"> + Unable to buy land: +No parcel selected. + </notification> + <notification name="CannotBuyLandNoRegion"> + Unable to buy land: +Cannot find the region this land is in. + </notification> + <notification name="CannotCloseFloaterBuyLand"> + You cannot close the Buy Land window until [APP_NAME] estimates the price of this transaction. + </notification> + <notification name="CannotDeedLandNothingSelected"> + Unable to deed land: +No parcel selected. + </notification> + <notification name="CannotDeedLandNoGroup"> + Unable to deed land: +No Group selected. + </notification> + <notification name="CannotDeedLandNoRegion"> + Unable to deed land: +Cannot find the region this land is in. + </notification> + <notification name="CannotDeedLandMultipleSelected"> + Unable to deed land: +Multiple parcels selected. + +Try selecting a single parcel. + </notification> + <notification name="CannotDeedLandWaitingForServer"> + Unable to deed land: +Waiting for server to report ownership. + +Please try again. + </notification> + <notification name="CannotDeedLandNoTransfer"> + Unable to deed land: +The region [REGION] does not allow transfer of land. + </notification> + <notification name="CannotReleaseLandWatingForServer"> + Unable to abandon land: +Waiting for server to update parcel information. + +Try again in a few seconds. + </notification> + <notification name="CannotReleaseLandSelected"> + Unable to abandon land: +You do not own all the parcels selected. + +Please select a single parcel. + </notification> + <notification name="CannotReleaseLandDontOwn"> + Unable to abandon land: +You don't have permission to release this parcel. +Parcels you own appear in green. + </notification> + <notification name="CannotReleaseLandRegionNotFound"> + Unable to abandon land: +Cannot find the region this land is in. + </notification> + <notification name="CannotReleaseLandNoTransfer"> + Unable to abandon land: +The region [REGION] does not allow transfer of land. + </notification> + <notification name="CannotReleaseLandPartialSelection"> + Unable to abandon land: +You must select an entire parcel to release it. + +Select an entire parcel, or divide your parcel first. + </notification> + <notification name="ReleaseLandWarning"> + You are about to release [AREA] m² of land. +Releasing this parcel will remove it from your land holdings, but will not grant any L$. + +Release this land? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="CannotDivideLandNothingSelected"> + Unable to divide land: + +No parcels selected. + </notification> + <notification name="CannotDivideLandPartialSelection"> + Unable to divide land: + +You have an entire parcel selected. +Try selecting a part of the parcel. + </notification> + <notification name="LandDivideWarning"> + Dividing this land will split this parcel into two and each parcel can have its own settings. Some settings will be reset to defaults after the operation. + +Divide land? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="CannotDivideLandNoRegion"> + Unable to divide land: +Cannot find the region this land is in. + </notification> + <notification name="CannotJoinLandNoRegion"> + Unable to join land: +Cannot find the region this land is in. + </notification> + <notification name="CannotJoinLandNothingSelected"> + Unable to join land: +No parcels selected. + </notification> + <notification name="CannotJoinLandEntireParcelSelected"> + Unable to join land: +You only have one parcel selected. + +Select land across both parcels. + </notification> + <notification name="CannotJoinLandSelection"> + Unable to join land: +You must select more than one parcel. + +Select land across both parcels. + </notification> + <notification name="JoinLandWarning"> + Joining this land will create one large parcel out of all parcels intersecting the selected rectangle. +You will need to reset the name and options of the new parcel. + +Join land? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ConfirmNotecardSave"> + This notecard needs to be saved before the item can be copied or viewed. Save notecard? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ConfirmItemCopy"> + Copy this item to your inventory? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="Copy"/> + </notification> + <notification name="ResolutionSwitchFail"> + Failed to switch resolution to [RESX] by [RESY] + </notification> + <notification name="ErrorUndefinedGrasses"> + Error: Undefined grasses: [SPECIES] + </notification> + <notification name="ErrorUndefinedTrees"> + Error: Undefined trees: [SPECIES] + </notification> + <notification name="CannotSaveWearableOutOfSpace"> + Unable to save '[NAME]' to wearable file. You will need to free up some space on your computer and save the wearable again. + </notification> + <notification name="CannotSaveToAssetStore"> + Unable to save [NAME] to central asset store. +This is usually a temporary failure. Please customize and save the wearable again in a few minutes. + </notification> + <notification name="YouHaveBeenLoggedOut"> + Darn. You have been logged out of [SECOND_LIFE] + [MESSAGE] + <usetemplate name="okcancelbuttons" notext="Quit" yestext="View IM & Chat"/> + </notification> + <notification name="OnlyOfficerCanBuyLand"> + Unable to buy land for the group: +You do not have permission to buy land for your active group. + </notification> + <notification label="åŠ ç‚ºæœ‹å‹" name="AddFriendWithMessage"> + Friends can give permissions to track each other on the map and receive online status updates. + +Offer friendship to [NAME]? + <form name="form"> + <input name="message"> + Would you be my friend? + </input> + <button name="Offer" text="確定"/> + <button name="Cancel" text="å–銷"/> + </form> + </notification> + <notification label="Save Outfit" name="SaveOutfitAs"> + Save what I'm wearing as a new Outfit: + <form name="form"> + <input name="message"> + [DESC] (new) + </input> + <button name="OK" text="確定"/> + <button name="Cancel" text="å–銷"/> + </form> + </notification> + <notification label="Save Wearable" name="SaveWearableAs"> + Save item to my inventory as: + <form name="form"> + <input name="message"> + [DESC] (新) + </input> + <button name="OK" text="確定"/> + <button name="Cancel" text="å–銷"/> + </form> + </notification> + <notification label="Rename Outfit" name="RenameOutfit"> + New outfit name: + <form name="form"> + <input name="new_name"> + [NAME] + </input> + <button name="OK" text="確定"/> + <button name="Cancel" text="å–銷"/> + </form> + </notification> + <notification name="RemoveFromFriends"> + Do you want to remove [NAME] from your Friends List? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="RemoveMultipleFromFriends"> + Do you want to remove multiple friends from your Friends list? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="GodDeleteAllScriptedPublicObjectsByUser"> + Are you sure you want to delete all scripted objects owned by +** [AVATAR_NAME] ** +on all others land in this sim? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="GodDeleteAllScriptedObjectsByUser"> + Are you sure you want to DELETE ALL scripted objects owned by +** [AVATAR_NAME] ** +on ALL LAND in this sim? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="GodDeleteAllObjectsByUser"> + Are you sure you want to DELETE ALL objects (scripted or not) owned by +** [AVATAR_NAME] ** +on ALL LAND in this sim? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="BlankClassifiedName"> + You must specify a name for your classified. + </notification> + <notification name="MinClassifiedPrice"> + Price to pay for listing must be at least L$[MIN_PRICE]. + +Please enter a higher price. + </notification> + <notification name="ConfirmItemDeleteHasLinks"> + At least one of the items you has link items that point to it. If you delete this item, its links will permanently stop working. It is strongly advised to delete the links first. + +Are you sure you want to delete these items? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ConfirmObjectDeleteLock"> + At least one of the items you have selected is locked. + +Are you sure you want to delete these items? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ConfirmObjectDeleteNoCopy"> + At least one of the items you have selected is not copyable. + +Are you sure you want to delete these items? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ConfirmObjectDeleteNoOwn"> + You do not own least one of the items you have selected. + +Are you sure you want to delete these items? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ConfirmObjectDeleteLockNoCopy"> + At least one object is locked. +At least one object is not copyable. + +Are you sure you want to delete these items? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ConfirmObjectDeleteLockNoOwn"> + At least one object is locked. +You do not own least one object. + +Are you sure you want to delete these items? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ConfirmObjectDeleteNoCopyNoOwn"> + At least one object is not copyable. +You do not own least one object. + +Are you sure you want to delete these items? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ConfirmObjectDeleteLockNoCopyNoOwn"> + At least one object is locked. +At least one object is not copyable. +You do not own least one object. + +Are you sure you want to delete these items? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ConfirmObjectTakeLock"> + At least one object is locked. + +Are you sure you want to take these items? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ConfirmObjectTakeNoOwn"> + You do not own all of the objects you are taking. +If you continue, next owner permissions will be applied and possibly restrict your ability to modify or copy them. + +Are you sure you want to take these items? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ConfirmObjectTakeLockNoOwn"> + At least one object is locked. +You do not own all of the objects you are taking. +If you continue, next owner permissions will be applied and possibly restrict your ability to modify or copy them. +However, you can take the current selection. + +Are you sure you want to take these items? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="CantBuyLandAcrossMultipleRegions"> + Unable to buy land because selection spans multiple regions. + +Please select a smaller area and try again. + </notification> + <notification name="DeedLandToGroup"> + By deeding this parcel, the group will be required to have and maintain sufficient land use credits. +The purchase price of the land is not refunded to the owner. If a deeded parcel is sold, the sale price will be divided evenly among group members. + +Deed this [AREA] m² of land to the group '[GROUP_NAME]'? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="DeedLandToGroupWithContribution"> + By deeding this parcel, the group will be required to have and maintain sufficient land use credits. +The deed will include a simultaneous land contribution to the group from '[NAME]'. +The purchase price of the land is not refunded to the owner. If a deeded parcel is sold, the sale price will be divided evenly among group members. + +Deed this [AREA] m² of land to the group '[GROUP_NAME]'? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="DisplaySetToSafe"> + Display settings have been set to safe levels because you have specified the -safe option. + </notification> + <notification name="DisplaySetToRecommended"> + Display settings have been set to recommended levels based on your system configuration. + </notification> + <notification name="ErrorMessage"> + [ERROR_MESSAGE] + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="AvatarMovedDesired"> + Your desired location is not currently available. +You have been moved into a nearby region. + </notification> + <notification name="AvatarMovedLast"> + Your last location is not currently available. +You have been moved into a nearby region. + </notification> + <notification name="AvatarMovedHome"> + Your home location is not currently available. +You have been moved into a nearby region. +You may want to set a new home location. + </notification> + <notification name="ClothingLoading"> + Your clothing is still downloading. +You can use [SECOND_LIFE] normally and other people will see you correctly. + <form name="form"> + <ignore name="ignore" text="Clothing is taking a long time to download"/> + </form> + </notification> + <notification name="FirstRun"> + [APP_NAME] installation is complete. + +If this is your first time using [SECOND_LIFE], you will need to create an account before you can log in. +Return to [http://join.secondlife.com secondlife.com] to create a new account? + <usetemplate name="okcancelbuttons" notext="繼續" yestext="New Account..."/> + </notification> + <notification name="LoginPacketNeverReceived"> + We're having trouble connecting. There may be a problem with your Internet connection or the [SECOND_LIFE_GRID]. + +You can either check your Internet connection and try again in a few minutes, click Help to view the [SUPPORT_SITE], or click Teleport to attempt to teleport home. + <url name="url"> + http://secondlife.com/support/ + </url> + <form name="form"> + <button name="OK" text="確定"/> + <button name="Help" text="Help"/> + <button name="Teleport" text="Teleport"/> + </form> + </notification> + <notification name="WelcomeChooseSex"> + Your character will appear in a moment. + +Use arrow keys to walk. +Press the F1 key at any time for help or to learn more about [SECOND_LIFE]. +Please choose the male or female avatar. You can change your mind later. + <usetemplate name="okcancelbuttons" notext="女性" yestext="男性"/> + </notification> + <notification name="CantTeleportToGrid"> + Could not teleport to [SLURL] as it's on a different grid ([GRID]) than the current grid ([CURRENT_GRID]). Please close your viewer and try again. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="GeneralCertificateError"> + 無法連接到伺æœå™¨ã€‚ +[REASON] + +SubjectName: [SUBJECT_NAME_STRING] +IssuerName: [ISSUER_NAME_STRING] +Valid From: [VALID_FROM] +Valid To: [VALID_TO] +MD5 Fingerprint: [SHA1_DIGEST] +SHA1 Fingerprint: [MD5_DIGEST] +Key Usage: [KEYUSAGE] +Extended Key Usage: [EXTENDEDKEYUSAGE] +Subject Key Identifier: [SUBJECTKEYIDENTIFIER] + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="TrustCertificateError"> + The certification authority for this server is not known. + +Certificate Information: +SubjectName: [SUBJECT_NAME_STRING] +IssuerName: [ISSUER_NAME_STRING] +Valid From: [VALID_FROM] +Valid To: [VALID_TO] +MD5 Fingerprint: [SHA1_DIGEST] +SHA1 Fingerprint: [MD5_DIGEST] +Key Usage: [KEYUSAGE] +Extended Key Usage: [EXTENDEDKEYUSAGE] +Subject Key Identifier: [SUBJECTKEYIDENTIFIER] + +Would you like to trust this authority? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="Trust"/> + </notification> + <notification name="NotEnoughCurrency"> + [NAME] L$ [PRICE] You don't have enough L$ to do that. + </notification> + <notification name="GrantedModifyRights"> + [NAME] has given you permission to edit their objects. + </notification> + <notification name="RevokedModifyRights"> + Your privilege to modify [NAME]'s objects has been revoked + </notification> + <notification name="FlushMapVisibilityCaches"> + This will flush the map caches on this region. +This is really only useful for debugging. +(In production, wait 5 minutes, then everyone's map will update after they relog.) + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="BuyOneObjectOnly"> + Unable to buy more than one object at a time. Please select only one object and try again. + </notification> + <notification name="OnlyCopyContentsOfSingleItem"> + Unable to copy the contents of more than one item at a time. +Please select only one object and try again. + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="KickUsersFromRegion"> + Teleport all Residents in this region home? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="EstateObjectReturn"> + Are you sure you want to return objects owned by [USER_NAME]? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="InvalidTerrainBitDepth"> + Couldn't set region textures: +Terrain texture [TEXTURE_NUM] has an invalid bit depth of [TEXTURE_BIT_DEPTH]. + +Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click "Apply" again. + </notification> + <notification name="InvalidTerrainSize"> + Couldn't set region textures: +Terrain texture [TEXTURE_NUM] is too large at [TEXTURE_SIZE_X]x[TEXTURE_SIZE_Y]. + +Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click "Apply" again. + </notification> + <notification name="RawUploadStarted"> + Upload started. It may take up to two minutes, depending on your connection speed. + </notification> + <notification name="ConfirmBakeTerrain"> + Do you really want to bake the current terrain, make it the center for terrain raise/lower limits and the default for the 'Revert' tool? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="MaxAllowedAgentOnRegion"> + You can only have [MAX_AGENTS] Allowed Residents. + </notification> + <notification name="MaxBannedAgentsOnRegion"> + You can only have [MAX_BANNED] Banned Residents. + </notification> + <notification name="MaxAgentOnRegionBatch"> + Failure while attempting to add [NUM_ADDED] agents: +Exceeds the [MAX_AGENTS] [LIST_TYPE] limit by [NUM_EXCESS]. + </notification> + <notification name="MaxAllowedGroupsOnRegion"> + You can only have [MAX_GROUPS] Allowed Groups. + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="Bake"/> + </notification> + <notification name="MaxManagersOnRegion"> + You can only have [MAX_MANAGER] Estate Managers. + </notification> + <notification name="OwnerCanNotBeDenied"> + Can't add estate owner to estate 'Banned Resident' list. + </notification> + <notification name="CanNotChangeAppearanceUntilLoaded"> + Can't change appearance until clothing and shape are loaded. + </notification> + <notification name="ClassifiedMustBeAlphanumeric"> + The name of your classified must start with a letter from A to Z or a number. No punctuation is allowed. + </notification> + <notification name="CantSetBuyObject"> + Can't set Buy Object, because the object is not for sale. +Please set the object for sale and try again. + </notification> + <notification name="FinishedRawDownload"> + Finished download of raw terrain file to: +[DOWNLOAD_PATH]. + </notification> + <notification name="DownloadWindowsMandatory"> + A new version of [APP_NAME] is available. +[MESSAGE] +You must download this update to use [APP_NAME]. + <usetemplate name="okcancelbuttons" notext="Quit" yestext="下載"/> + </notification> + <notification name="DownloadWindows"> + An updated version of [APP_NAME] is available. +[MESSAGE] +This update is not required, but we suggest you install it to improve performance and stability. + <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> + </notification> + <notification name="DownloadWindowsReleaseForDownload"> + An updated version of [APP_NAME] is available. +[MESSAGE] +This update is not required, but we suggest you install it to improve performance and stability. + <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> + </notification> + <notification name="DownloadLinuxMandatory"> + A new version of [APP_NAME] is available. +[MESSAGE] +You must download this update to use [APP_NAME]. + <usetemplate name="okcancelbuttons" notext="Quit" yestext="下載"/> + </notification> + <notification name="DownloadLinux"> + An updated version of [APP_NAME] is available. +[MESSAGE] +This update is not required, but we suggest you install it to improve performance and stability. + <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> + </notification> + <notification name="DownloadLinuxReleaseForDownload"> + An updated version of [APP_NAME] is available. +[MESSAGE] +This update is not required, but we suggest you install it to improve performance and stability. + <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> + </notification> + <notification name="DownloadMacMandatory"> + A new version of [APP_NAME] is available. +[MESSAGE] +You must download this update to use [APP_NAME]. + +Download to your Applications folder? + <usetemplate name="okcancelbuttons" notext="Quit" yestext="下載"/> + </notification> + <notification name="DownloadMac"> + An updated version of [APP_NAME] is available. +[MESSAGE] +This update is not required, but we suggest you install it to improve performance and stability. + +Download to your Applications folder? + <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> + </notification> + <notification name="DownloadMacReleaseForDownload"> + An updated version of [APP_NAME] is available. +[MESSAGE] +This update is not required, but we suggest you install it to improve performance and stability. + +Download to your Applications folder? + <usetemplate name="okcancelbuttons" notext="繼續" yestext="下載"/> + </notification> + <notification name="FailedUpdateInstall"> + An error occurred installing the viewer update. +Please download and install the latest viewer from +http://secondlife.com/download. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="FailedRequiredUpdateInstall"> + We were unable to install a required update. +You will be unable to log in until [APP_NAME] has been updated. + +Please download and install the latest viewer from +http://secondlife.com/download. + <usetemplate name="okbutton" yestext="Quit"/> + </notification> + <notification name="UpdaterServiceNotRunning"> + There is a required update for your Second Life Installation. + +You may download this update from http://www.secondlife.com/downloads +or you can install it now. + <usetemplate name="okcancelbuttons" notext="Quit Second Life" yestext="Download and install now"/> + </notification> + <notification name="DownloadBackgroundTip"> + We have downloaded an update to your [APP_NAME] installation. +Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update] + <usetemplate name="okcancelbuttons" notext="Later..." yestext="Install now and restart [APP_NAME]"/> + </notification> + <notification name="DownloadBackgroundDialog"> + We have downloaded an update to your [APP_NAME] installation. +Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update] + <usetemplate name="okcancelbuttons" notext="Later..." yestext="Install now and restart [APP_NAME]"/> + </notification> + <notification name="RequiredUpdateDownloadedVerboseDialog"> + We have downloaded a required software update. +Version [VERSION] + +We must restart [APP_NAME] to install the update. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="RequiredUpdateDownloadedDialog"> + We must restart [APP_NAME] to install the update. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="DeedObjectToGroup"> + Deeding this object will cause the group to: +* Receive L$ paid into the object + <usetemplate ignoretext="Confirm before I deed an object to a group" name="okcancelignore" notext="å–銷" yestext="Deed"/> + </notification> + <notification name="WebLaunchExternalTarget"> + Do you want to open your Web browser to view this content? + <usetemplate ignoretext="Launch my browser to view a web page" name="okcancelignore" notext="å–銷" yestext="確定"/> + </notification> + <notification name="WebLaunchJoinNow"> + Go to your [http://secondlife.com/account/ Dashboard] to manage your account? + <usetemplate ignoretext="Launch my browser to manage my account" name="okcancelignore" notext="å–銷" yestext="確定"/> + </notification> + <notification name="WebLaunchSecurityIssues"> + Visit the [SECOND_LIFE] Wiki for details of how to report a security issue. + <usetemplate ignoretext="Launch my browser to learn how to report a Security Issue" name="okcancelignore" notext="å–銷" yestext="確定"/> + </notification> + <notification name="WebLaunchQAWiki"> + Visit the [SECOND_LIFE] QA Wiki. + <usetemplate ignoretext="Launch my browser to view the QA Wiki" name="okcancelignore" notext="å–銷" yestext="確定"/> + </notification> + <notification name="WebLaunchPublicIssue"> + Visit the [SECOND_LIFE] Public Issue Tracker, where you can report bugs and other issues. + <usetemplate ignoretext="Launch my browser to use the Public Issue Tracker" name="okcancelignore" notext="å–銷" yestext="Go to page"/> + </notification> + <notification name="WebLaunchSupportWiki"> + Go to the Official Linden Blog, for the latest news and information. + <usetemplate ignoretext="Launch my browser to view the blog" name="okcancelignore" notext="å–銷" yestext="確定"/> + </notification> + <notification name="WebLaunchLSLGuide"> + Do you want to open the Scripting Guide for help with scripting? + <usetemplate ignoretext="Launch my browser to view the Scripting Guide" name="okcancelignore" notext="å–銷" yestext="確定"/> + </notification> + <notification name="WebLaunchLSLWiki"> + Do you want to visit the LSL Portal for help with scripting? + <usetemplate ignoretext="Launch my browser to view the LSL Portal" name="okcancelignore" notext="å–銷" yestext="Go to page"/> + </notification> + <notification name="ReturnToOwner"> + Are you sure you want to return the selected objects to their owners? Transferable deeded objects will be returned to their previous owners. + +*WARNING* No-transfer deeded objects will be deleted! + <usetemplate ignoretext="Confirm before I return objects to their owners" name="okcancelignore" notext="å–銷" yestext="確定"/> + </notification> + <notification name="GroupLeaveConfirmMember"> + You are currently a member of the group [GROUP]. +Leave Group? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ConfirmKick"> + Do you REALLY want to kick all Residents off the grid? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="Kick All Residents"/> + </notification> + <notification name="MuteLinden"> + Sorry, you cannot block a Linden. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="CannotStartAuctionAlreadyForSale"> + You cannot start an auction on a parcel which is already set for sale. Disable the land sale if you are sure you want to start an auction. + </notification> + <notification label="Block object by name failed" name="MuteByNameFailed"> + You already have blocked this name. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="RemoveItemWarn"> + Though permitted, deleting contents may damage the object. Do you want to delete that item? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="CantOfferCallingCard"> + Cannot offer a calling card at this time. Please try again in a moment. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="CantOfferFriendship"> + Cannot offer friendship at this time. Please try again in a moment. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="BusyModeSet"> + Busy mode is set. +Chat and instant messages will be hidden. Instant messages will get your Busy mode response. All teleportation offers will be declined. All inventory offers will go to your Trash. + <usetemplate ignoretext="I change my status to Busy mode" name="okignore" yestext="確定"/> + </notification> + <notification name="JoinedTooManyGroupsMember"> + You have reached your maximum number of groups. Please leave another group before joining this one, or decline the offer. +[NAME] has invited you to join a group as a member. + <usetemplate name="okcancelbuttons" notext="Decline" yestext="Join"/> + </notification> + <notification name="JoinedTooManyGroups"> + You have reached your maximum number of groups. Please leave some group before joining or creating a new one. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="KickUser"> + Kick this Resident with what message? + <form name="form"> + <input name="message"> + An administrator has logged you off. + </input> + <button name="OK" text="確定"/> + <button name="Cancel" text="å–銷"/> + </form> + </notification> + <notification name="KickAllUsers"> + Kick everyone currently on the grid with what message? + <form name="form"> + <input name="message"> + An administrator has logged you off. + </input> + <button name="OK" text="確定"/> + <button name="Cancel" text="å–銷"/> + </form> + </notification> + <notification name="FreezeUser"> + Freeze this Resident with what message? + <form name="form"> + <input name="message"> + You have been frozen. You cannot move or chat. An administrator will contact you via instant message (IM). + </input> + <button name="OK" text="確定"/> + <button name="Cancel" text="å–銷"/> + </form> + </notification> + <notification name="UnFreezeUser"> + Unfreeze this Resident with what message? + <form name="form"> + <input name="message"> + You are no longer frozen. + </input> + <button name="OK" text="確定"/> + <button name="Cancel" text="å–銷"/> + </form> + </notification> + <notification name="SetDisplayNameSuccess"> + Hi [DISPLAY_NAME]! + +Just like in real life, it takes a while for everyone to learn about a new name. Please allow several days for [http://wiki.secondlife.com/wiki/Setting_your_display_name your name to update] in objects, scripts, search, etc. + </notification> + <notification name="SetDisplayNameBlocked"> + Sorry, you cannot change your display name. If you feel this is in error, please contact support. + </notification> + <notification name="SetDisplayNameFailedLength"> + Sorry, that name is too long. Display names can have a maximum of [LENGTH] characters. + +Please try a shorter name. + </notification> + <notification name="SetDisplayNameFailedGeneric"> + Sorry, we could not set your display name. Please try again later. + </notification> + <notification name="SetDisplayNameMismatch"> + The display names you entered do not match. Please re-enter. + </notification> + <notification name="AgentDisplayNameUpdateThresholdExceeded"> + Sorry, you have to wait longer before you can change your display name. + +See http://wiki.secondlife.com/wiki/Setting_your_display_name + +Please try again later. + </notification> + <notification name="AgentDisplayNameSetBlocked"> + Sorry, we could not set your requested name because it contains a banned word. + + Please try a different name. + </notification> + <notification name="AgentDisplayNameSetInvalidUnicode"> + The display name you wish to set contains invalid characters. + </notification> + <notification name="AgentDisplayNameSetOnlyPunctuation"> + Your display name must contain letters other than punctuation. + </notification> + <notification name="DisplayNameUpdate"> + [OLD_NAME] ([SLID]) is now known as [NEW_NAME]. + </notification> + <notification name="OfferTeleport"> + Offer a teleport to your location with the following message? + <form name="form"> + <input name="message"> + Join me in [REGION] + </input> + <button name="OK" text="確定"/> + <button name="Cancel" text="å–銷"/> + </form> + </notification> + <notification name="OfferTeleportFromGod"> + God summon Resident to your location? + <form name="form"> + <input name="message"> + Join me in [REGION] + </input> + <button name="OK" text="確定"/> + <button name="Cancel" text="å–銷"/> + </form> + </notification> + <notification name="TeleportFromLandmark"> + Are you sure you want to teleport to <nolink>[LOCATION]</nolink>? + <usetemplate ignoretext="Confirm that I want to teleport to a landmark" name="okcancelignore" notext="å–銷" yestext="Teleport"/> + </notification> + <notification name="TeleportToPick"> + Teleport to [PICK]? + <usetemplate ignoretext="Confirm that I want to teleport to a location in Picks" name="okcancelignore" notext="å–銷" yestext="Teleport"/> + </notification> + <notification name="TeleportToClassified"> + Teleport to [CLASSIFIED]? + <usetemplate ignoretext="Confirm that I want to teleport to a location in Classifieds" name="okcancelignore" notext="å–銷" yestext="Teleport"/> + </notification> + <notification name="TeleportToHistoryEntry"> + Teleport to [HISTORY_ENTRY]? + <usetemplate ignoretext="Confirm that I want to teleport to a history location" name="okcancelignore" notext="å–銷" yestext="Teleport"/> + </notification> + <notification label="Message everyone in your Estate" name="MessageEstate"> + Type a short announcement which will be sent to everyone currently in your estate. + <form name="form"> + <button name="OK" text="確定"/> + <button name="Cancel" text="å–銷"/> + </form> + </notification> + <notification label="Change Linden Estate" name="ChangeLindenEstate"> + You are about to change a Linden owned estate (mainland, teen grid, orientation, etc.). + +This is EXTREMELY DANGEROUS because it can fundamentally affect the Resident experience. On the mainland, it will change thousands of regions and make the spaceserver hiccup. + +Proceed? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification label="Change Linden Estate Access" name="ChangeLindenAccess"> + You are about to change the access list for a Linden owned estate (mainland, teen grid, orientation, etc.). + +This is DANGEROUS and should only be done to invoke the hack allowing objects/L$ to be transfered in/out of a grid. +It will change thousands of regions and make the spaceserver hiccup. + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification label="é¸æ“‡é ˜åœ°" name="EstateAllowedAgentAdd"> + Add to allowed list for this estate only or for [ALL_ESTATES]? + <usetemplate canceltext="å–銷" name="yesnocancelbuttons" notext="å…¨éƒ¨é ˜åœ°" yestext="é€™å€‹é ˜åœ°"/> + </notification> + <notification label="é¸æ“‡é ˜åœ°" name="EstateAllowedAgentRemove"> + Remove from allowed list for this estate only or for [ALL_ESTATES]? + <usetemplate canceltext="å–銷" name="yesnocancelbuttons" notext="å…¨éƒ¨é ˜åœ°" yestext="é€™å€‹é ˜åœ°"/> + </notification> + <notification label="é¸æ“‡é ˜åœ°" name="EstateAllowedGroupAdd"> + Add to group allowed list for this estate only or for [ALL_ESTATES]? + <usetemplate canceltext="å–銷" name="yesnocancelbuttons" notext="å…¨éƒ¨é ˜åœ°" yestext="é€™å€‹é ˜åœ°"/> + </notification> + <notification label="é¸æ“‡é ˜åœ°" name="EstateAllowedGroupRemove"> + Remove from group allowed list for this estate only or [ALL_ESTATES]? + <usetemplate canceltext="å–銷" name="yesnocancelbuttons" notext="å…¨éƒ¨é ˜åœ°" yestext="é€™å€‹é ˜åœ°"/> + </notification> + <notification label="é¸æ“‡é ˜åœ°" name="EstateBannedAgentAdd"> + Deny access for this estate only or for [ALL_ESTATES]? + <usetemplate canceltext="å–銷" name="yesnocancelbuttons" notext="å…¨éƒ¨é ˜åœ°" yestext="é€™å€‹é ˜åœ°"/> + </notification> + <notification label="é¸æ“‡é ˜åœ°" name="EstateBannedAgentRemove"> + Remove this Resident from the ban list for access for this estate only or for [ALL_ESTATES]? + <usetemplate canceltext="å–銷" name="yesnocancelbuttons" notext="å…¨éƒ¨é ˜åœ°" yestext="é€™å€‹é ˜åœ°"/> + </notification> + <notification label="é¸æ“‡é ˜åœ°" name="EstateManagerAdd"> + Add estate manager for this estate only or for [ALL_ESTATES]? + <usetemplate canceltext="å–銷" name="yesnocancelbuttons" notext="å…¨éƒ¨é ˜åœ°" yestext="é€™å€‹é ˜åœ°"/> + </notification> + <notification label="é¸æ“‡é ˜åœ°" name="EstateManagerRemove"> + Remove estate manager for this estate only or for [ALL_ESTATES]? + <usetemplate canceltext="å–銷" name="yesnocancelbuttons" notext="å…¨éƒ¨é ˜åœ°" yestext="é€™å€‹é ˜åœ°"/> + </notification> + <notification label="Confirm Kick" name="EstateKickUser"> + Kick [EVIL_USER] from this estate? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="EstateChangeCovenant"> + Are you sure you want to change the Estate Covenant? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="RegionEntryAccessBlocked"> + You are not allowed in that Region due to your maturity Rating. This may be a result of a lack of information validating your age. + +Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="RegionEntryAccessBlocked_KB"> + You are not allowed in that region due to your maturity Rating. + +Go to the Knowledge Base for more information about maturity Ratings? + <url name="url"> + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview + </url> + <usetemplate ignoretext="I can't enter this Region, due to restrictions of the maturity Rating" name="okcancelignore" notext="關閉" yestext="Go to Knowledge Base"/> + </notification> + <notification name="RegionEntryAccessBlocked_Notify"> + You are not allowed in that region due to your maturity Rating. + </notification> + <notification name="RegionEntryAccessBlocked_Change"> + You are not allowed in that Region due to your maturity Rating preference. + +To enter the desired region, please change your maturity Rating preference. This will allow you to search for and access [REGIONMATURITY] content. To undo any changes, go to Me > Preferences > General. + <form name="form"> + <button name="OK" text="Change Preference"/> + <button name="Cancel" text="Close"/> + <ignore name="ignore" text="My chosen Rating preference prevents me from entering a Region"/> + </form> + </notification> + <notification name="PreferredMaturityChanged"> + Your maturity Rating preference is now [RATING]. + </notification> + <notification name="LandClaimAccessBlocked"> + You cannot claim this land due to your maturity Rating. This may be a result of a lack of information validating your age. + +Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="LandClaimAccessBlocked_KB"> + You cannot claim this land due to your maturity Rating. + +Go to the Knowledge Base for more information about maturity Ratings? + <url name="url"> + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview + </url> + <usetemplate ignoretext="I can't claim this Land, due to restrictions of the maturity Rating" name="okcancelignore" notext="關閉" yestext="Go to Knowledge Base"/> + </notification> + <notification name="LandClaimAccessBlocked_Notify"> + You cannot claim this land due to your maturity Rating. + </notification> + <notification name="LandClaimAccessBlocked_Change"> + You cannot claim this land due to your maturity Rating preference. + +You can click 'Change Preference' to raise your maturity Rating preference now and allow you to enter. You will be able to search and access [REGIONMATURITY] content from now on. If you later want to change this setting back, go to Me > Preferences > General. + <usetemplate ignoretext="My chosen Rating preference prevents me from claiming Land" name="okcancelignore" notext="關閉" yestext="Change Preference"/> + </notification> + <notification name="LandBuyAccessBlocked"> + You cannot buy this land due to your maturity Rating. This may be a result of a lack of information validating your age. + +Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="LandBuyAccessBlocked_KB"> + You cannot buy this land due to your maturity Rating. + +Go to the Knowledge Base for more information about maturity Ratings? + <url name="url"> + http://wiki.secondlife.com/wiki/Linden_Lab_Official:Maturity_ratings:_an_overview + </url> + <usetemplate ignoretext="I can't buy this Land, due to restrictions of the maturity Rating" name="okcancelignore" notext="關閉" yestext="Go to Knowledge Base"/> + </notification> + <notification name="LandBuyAccessBlocked_Notify"> + You cannot buy this land due to your maturity Rating. + </notification> + <notification name="LandBuyAccessBlocked_Change"> + You cannot buy this land due to your maturity Rating preference. + +You can click 'Change Preference' to raise your maturity Rating preference now and allow you to enter. You will be able to search and access [REGIONMATURITY] content from now on. If you later want to change this setting back, go to Me > Preferences > General. + <usetemplate ignoretext="My chosen Rating preference prevents me from buying Land" name="okcancelignore" notext="關閉" yestext="變更å好è¨å®š"/> + </notification> + <notification name="TooManyPrimsSelected"> + There are too many prims selected. Please select [MAX_PRIM_COUNT] or fewer prims and try again + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="ProblemImportingEstateCovenant"> + Problem importing estate covenant. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="ProblemAddingEstateManager"> + Problems adding a new estate manager. One or more estates may have a full manager list. + </notification> + <notification name="ProblemAddingEstateGeneric"> + Problems adding to this estate list. One or more estates may have a full list. + </notification> + <notification name="UnableToLoadNotecardAsset"> + Unable to load notecard's asset at this time. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="NotAllowedToViewNotecard"> + Insufficient permissions to view notecard associated with asset ID requested. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="MissingNotecardAssetID"> + Asset ID for notecard is missing from database. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="PublishClassified"> + Remember: Classified ad fees are non-refundable. + +Publish this classified now for L$[AMOUNT]? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="SetClassifiedMature"> + Does this classified contain Moderate content? + <usetemplate canceltext="å–銷" name="yesnocancelbuttons" notext="å¦" yestext="是"/> + </notification> + <notification name="SetGroupMature"> + Does this group contain Moderate content? + <usetemplate canceltext="å–銷" name="yesnocancelbuttons" notext="å¦" yestext="是"/> + </notification> + <notification label="Confirm restart" name="ConfirmRestart"> + Do you really want to restart this region in 2 minutes? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification label="Message everyone in this region" name="MessageRegion"> + Type a short announcement which will be sent to everyone in this region. + <form name="form"> + <button name="OK" text="確定"/> + <button name="Cancel" text="å–銷"/> + </form> + </notification> + <notification label="Changed Region Maturity" name="RegionMaturityChange"> + The maturity rating for this region has been updated. +It may take some time for the change to be reflected on the map. + +To enter Adult regions, Residents must be Account Verified, either by age-verification or payment-verification. + </notification> + <notification label="Voice Version Mismatch" name="VoiceVersionMismatch"> + This version of [APP_NAME] is not compatible with the Voice Chat feature in this region. In order for Voice Chat to function correctly you will need to update [APP_NAME]. + </notification> + <notification label="Can't Buy Objects" name="BuyObjectOneOwner"> + Cannot buy objects from different owners at the same time. +Please select only one object and try again. + </notification> + <notification label="Can't Buy Contents" name="BuyContentsOneOnly"> + Unable to buy the contents of more than one object at a time. +Please select only one object and try again. + </notification> + <notification label="Can't Buy Contents" name="BuyContentsOneOwner"> + Cannot buy objects from different owners at the same time. +Please select only one object and try again. + </notification> + <notification name="BuyOriginal"> + Buy original object from [OWNER] for L$[PRICE]? +You will become the owner of this object. +You will be able to: + Modify: [MODIFYPERM] + Copy: [COPYPERM] + Resell or Give Away: [RESELLPERM] + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="BuyOriginalNoOwner"> + Buy original object for L$[PRICE]? +You will become the owner of this object. +You will be able to: + Modify: [MODIFYPERM] + Copy: [COPYPERM] + Resell or Give Away: [RESELLPERM] + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="BuyCopy"> + Buy a copy from [OWNER] for L$[PRICE]? +The object will be copied to your inventory. +You will be able to: + Modify: [MODIFYPERM] + Copy: [COPYPERM] + Resell or Give Away: [RESELLPERM] + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="BuyCopyNoOwner"> + Buy a copy for L$[PRICE]? +The object will be copied to your inventory. +You will be able to: + Modify: [MODIFYPERM] + Copy: [COPYPERM] + Resell or Give Away: [RESELLPERM] + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="BuyContents"> + Buy contents from [OWNER] for L$[PRICE]? +They will be copied to your inventory. + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="BuyContentsNoOwner"> + Buy contents for L$[PRICE]? +They will be copied to your inventory. + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ConfirmPurchase"> + This transaction will: +[ACTION] + +Are you sure you want to proceed with this purchase? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ConfirmPurchasePassword"> + This transaction will: +[ACTION] + +Are you sure you want to proceed with this purchase? +Please re-enter your password and click OK. + <form name="form"> + <button name="ConfirmPurchase" text="確定"/> + <button name="Cancel" text="å–銷"/> + </form> + </notification> + <notification name="SetPickLocation"> + Note: +You have updated the location of this pick but the other details will retain their original values. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="MoveInventoryFromObject"> + You have selected 'no copy' inventory items. +These items will be moved to your inventory, not copied. + +Move the inventory item(s)? + <usetemplate ignoretext="Warn me before I move 'no-copy' items from an object" name="okcancelignore" notext="å–銷" yestext="確定"/> + </notification> + <notification name="MoveInventoryFromScriptedObject"> + You have selected 'no copy' inventory items. These items will be moved to your inventory, not copied. +Because this object is scripted, moving these items to your inventory may cause the script to malfunction. + +Move the inventory item(s)? + <usetemplate ignoretext="Warn me before I move 'no-copy' items which might break a scripted object" name="okcancelignore" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ClickActionNotPayable"> + Warning: The 'Pay object' click action has been set, but it will only work if a script is added with a money() event. + <form name="form"> + <ignore name="ignore" text="I set the action 'Pay object' when building an object without a money() script"/> + </form> + </notification> + <notification name="OpenObjectCannotCopy"> + There are no items in this object that you are allowed to copy. + </notification> + <notification name="WebLaunchAccountHistory"> + Go to your [http://secondlife.com/account/ Dashboard] to see your account history? + <usetemplate ignoretext="Launch my browser to see my account history" name="okcancelignore" notext="å–銷" yestext="Go to page"/> + </notification> + <notification name="ConfirmQuit"> + Are you sure you want to quit? + <usetemplate ignoretext="Confirm before I quit" name="okcancelignore" notext="Don't Quit" yestext="Quit"/> + </notification> + <notification name="DeleteItems"> + [QUESTION] + <usetemplate ignoretext="Confirm before deleting items" name="okcancelignore" notext="å–銷" yestext="確定"/> + </notification> + <notification name="HelpReportAbuseEmailLL"> + Use this tool to report violations of the [http://secondlife.com/corporate/tos.php Terms of Service] and [http://secondlife.com/corporate/cs.php Community Standards]. + +All reported abuses are investigated and resolved. + </notification> + <notification name="HelpReportAbuseSelectCategory"> + Please select a category for this abuse report. +Selecting a category helps us file and process abuse reports. + </notification> + <notification name="HelpReportAbuseAbuserNameEmpty"> + Please enter the name of the abuser. +Entering an accurate value helps us file and process abuse reports. + </notification> + <notification name="HelpReportAbuseAbuserLocationEmpty"> + Please enter the location where the abuse took place. +Entering an accurate value helps us file and process abuse reports. + </notification> + <notification name="HelpReportAbuseSummaryEmpty"> + Please enter a summary of the abuse that took place. +Entering an accurate summary helps us file and process abuse reports. + </notification> + <notification name="HelpReportAbuseDetailsEmpty"> + Please enter a detailed description of the abuse that took place. +Be as specific as you can, including names and the details of the incident you are reporting. +Entering an accurate description helps us file and process abuse reports. + </notification> + <notification name="HelpReportAbuseContainsCopyright"> + Dear Resident, + +You appear to be reporting intellectual property infringement. Please make sure you are reporting it correctly: + +(1) The Abuse Process. You may submit an abuse report if you believe a Resident is exploiting the [SECOND_LIFE] permissions system, for example, by using CopyBot or similar copying tools, to infringe intellectual property rights. The Abuse Team investigates and issues appropriate disciplinary action for behavior that violates the [SECOND_LIFE] [http://secondlife.com/corporate/tos.php Terms of Service] or [http://secondlife.com/corporate/cs.php Community Standards]. However, the Abuse Team does not handle and will not respond to requests to remove content from the [SECOND_LIFE] world. + +(2) The DMCA or Content Removal Process. To request removal of content from [SECOND_LIFE], you MUST submit a valid notification of infringement as provided in our [http://secondlife.com/corporate/dmca.php DMCA Policy]. + +If you still wish to continue with the abuse process, please close this window and finish submitting your report. You may need to select the specific category 'CopyBot or Permissions Exploit'. + +Thank you, + +Linden Lab + </notification> + <notification name="FailedRequirementsCheck"> + The following required components are missing from [FLOATER]: +[COMPONENTS] + </notification> + <notification label="Replace Existing Attachment" name="ReplaceAttachment"> + There is already an object attached to this point on your body. +Do you want to replace it with the selected object? + <form name="form"> + <ignore name="ignore" text="Replace an existing attachment with the selected item"/> + <button ignore="Replace Automatically" name="Yes" text="確定"/> + <button ignore="Never Replace" name="No" text="å–銷"/> + </form> + </notification> + <notification label="Busy Mode Warning" name="BusyModePay"> + You are in Busy Mode, which means you will not receive any items offered in exchange for this payment. + +Would you like to leave Busy Mode before completing this transaction? + <form name="form"> + <ignore name="ignore" text="I am about to pay a person or object while I am in Busy mode"/> + <button ignore="Always leave Busy Mode" name="Yes" text="確定"/> + <button ignore="Never leave Busy Mode" name="No" text="å–銷"/> + </form> + </notification> + <notification name="ConfirmDeleteProtectedCategory"> + The folder '[FOLDERNAME]' is a system folder. Deleting system folders can cause instability. Are you sure you want to delete it? + <usetemplate ignoretext="Confirm before I delete a system folder" name="okcancelignore" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ConfirmEmptyTrash"> + Are you sure you want to permanently delete the contents of your Trash? + <usetemplate ignoretext="Confirm before I empty the inventory Trash folder" name="okcancelignore" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ConfirmClearBrowserCache"> + Are you sure you want to delete your travel, web, and search history? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ConfirmClearCookies"> + Are you sure you want to clear your cookies? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="是"/> + </notification> + <notification name="ConfirmClearMediaUrlList"> + Are you sure you want to clear your list of saved URLs? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="是"/> + </notification> + <notification name="ConfirmEmptyLostAndFound"> + Are you sure you want to permanently delete the contents of your Lost And Found? + <usetemplate ignoretext="Confirm before I empty the inventory Lost And Found folder" name="okcancelignore" notext="å¦" yestext="是"/> + </notification> + <notification name="CopySLURL"> + The following SLurl has been copied to your clipboard: + [SLURL] + +Link to this from a web page to give others easy access to this location, or try it out yourself by pasting it into the address bar of any web browser. + <form name="form"> + <ignore name="ignore" text="SLurl is copied to my clipboard"/> + </form> + </notification> + <notification name="WLSavePresetAlert"> + Do you wish to overwrite the saved preset? + <usetemplate name="okcancelbuttons" notext="No" yestext="是"/> + </notification> + <notification name="WLDeletePresetAlert"> + Do you wish to delete [SKY]? + <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/> + </notification> + <notification name="WLNoEditDefault"> + You cannot edit or delete a default preset. + </notification> + <notification name="WLMissingSky"> + This day cycle file references a missing sky file: [SKY]. + </notification> + <notification name="PPSaveEffectAlert"> + PostProcess Effect exists. Do you still wish overwrite it? + <usetemplate name="okcancelbuttons" notext="å¦" yestext="是"/> + </notification> + <notification name="NewSkyPreset"> + Give me a name for the new sky. + <form name="form"> + <input name="message"> + New Preset + </input> + <button name="OK" text="確定"/> + <button name="Cancel" text="å–銷"/> + </form> + </notification> + <notification name="ExistsSkyPresetAlert"> + Preset already exists! + </notification> + <notification name="NewWaterPreset"> + Give me a name for the new water preset. + <form name="form"> + <input name="message"> + New Preset + </input> + <button name="OK" text="確定"/> + <button name="Cancel" text="å–銷"/> + </form> + </notification> + <notification name="ExistsWaterPresetAlert"> + Preset already exists! + </notification> + <notification name="WaterNoEditDefault"> + You cannot edit or delete a default preset. + </notification> + <notification name="ChatterBoxSessionStartError"> + Unable to start a new chat session with [RECIPIENT]. +[REASON] + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="ChatterBoxSessionEventError"> + [EVENT] +[REASON] + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="ForceCloseChatterBoxSession"> + Your chat session with [NAME] must close. +[REASON] + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="Cannot_Purchase_an_Attachment"> + You can't buy an object while it is attached. + </notification> + <notification label="About Requests for the Debit Permission" name="DebitPermissionDetails"> + Granting this request gives a script ongoing permission to take Linden dollars (L$) from your account. To revoke this permission, the object owner must delete the object or reset the scripts in the object. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="AutoWearNewClothing"> + Would you like to automatically wear the clothing you are about to create? + <usetemplate ignoretext="Wear the clothing I create while editing My Appearance" name="okcancelignore" notext="å¦" yestext="是"/> + </notification> + <notification name="NotAgeVerified"> + You must be age-verified to visit this area. Do you want to go to the [SECOND_LIFE] website and verify your age? + +[_URL] + <url name="url"> + https://secondlife.com/account/verification.php + </url> + <usetemplate ignoretext="I have not verified my age" name="okcancelignore" notext="å¦" yestext="是"/> + </notification> + <notification name="Cannot enter parcel: no payment info on file"> + You must have payment information on file to visit this area. Do you want to go to the [SECOND_LIFE] website and set this up? + +[_URL] + <url name="url"> + https://secondlife.com/account/ + </url> + <usetemplate ignoretext="I lack payment information on file" name="okcancelignore" notext="å¦" yestext="是"/> + </notification> + <notification name="MissingString"> + The string [STRING_NAME] is missing from strings.xml + </notification> + <notification name="SystemMessageTip"> + [MESSAGE] + </notification> + <notification name="IMSystemMessageTip"> + [MESSAGE] + </notification> + <notification name="Cancelled"> + Cancelled + </notification> + <notification name="CancelledSit"> + Cancelled Sit + </notification> + <notification name="CancelledAttach"> + Cancelled Attach + </notification> + <notification name="ReplacedMissingWearable"> + Replaced missing clothing/body part with default. + </notification> + <notification name="GroupNotice"> + Topic: [SUBJECT], Message: [MESSAGE] + </notification> + <notification name="FriendOnline"> + [NAME] is Online + </notification> + <notification name="FriendOffline"> + [NAME] is Offline + </notification> + <notification name="AddSelfFriend"> + Although you're very nice, you can't add yourself as a friend. + </notification> + <notification name="UploadingAuctionSnapshot"> + Uploading in-world and web site snapshots... +(Takes about 5 minutes.) + </notification> + <notification name="UploadPayment"> + You paid L$[AMOUNT] to upload. + </notification> + <notification name="UploadWebSnapshotDone"> + Web site snapshot upload done. + </notification> + <notification name="UploadSnapshotDone"> + In-world snapshot upload done + </notification> + <notification name="TerrainDownloaded"> + Terrain.raw downloaded + </notification> + <notification name="GestureMissing"> + Hmm. Gesture [NAME] is missing from the database. + </notification> + <notification name="UnableToLoadGesture"> + Unable to load gesture [NAME]. + </notification> + <notification name="LandmarkMissing"> + Landmark is missing from database. + </notification> + <notification name="UnableToLoadLandmark"> + Unable to load landmark. Please try again. + </notification> + <notification name="CapsKeyOn"> + Your Caps Lock key is on. +This might affect your password. + </notification> + <notification name="NotecardMissing"> + Notecard is missing from database. + </notification> + <notification name="NotecardNoPermissions"> + You don't have permission to view this notecard. + </notification> + <notification name="RezItemNoPermissions"> + Insufficient permissions to rez object. + </notification> + <notification name="UnableToLoadNotecard"> + Unable to load notecard. +Please try again. + </notification> + <notification name="ScriptMissing"> + Script is missing from database. + </notification> + <notification name="ScriptNoPermissions"> + Insufficient permissions to view script. + </notification> + <notification name="UnableToLoadScript"> + Unable to load script. Please try again. + </notification> + <notification name="IncompleteInventory"> + The complete contents you are offering are not yet locally available. Please try offering those items again in a minute. + </notification> + <notification name="CannotModifyProtectedCategories"> + You cannot modify protected categories. + </notification> + <notification name="CannotRemoveProtectedCategories"> + You cannot remove protected categories. + </notification> + <notification name="UnableToBuyWhileDownloading"> + Unable to buy while downloading object data. +Please try again. + </notification> + <notification name="UnableToLinkWhileDownloading"> + Unable to link while downloading object data. +Please try again. + </notification> + <notification name="CannotBuyObjectsFromDifferentOwners"> + You can only buy objects from one owner at a time. +Please select a single object. + </notification> + <notification name="ObjectNotForSale"> + This object is not for sale. + </notification> + <notification name="EnteringGodMode"> + Entering god mode, level [LEVEL] + </notification> + <notification name="LeavingGodMode"> + Now leaving god mode, level [LEVEL] + </notification> + <notification name="CopyFailed"> + You don't have permission to copy this. + </notification> + <notification name="InventoryAccepted"> + [NAME] received your inventory offer. + </notification> + <notification name="InventoryDeclined"> + [NAME] declined your inventory offer. + </notification> + <notification name="ObjectMessage"> + [NAME]: [MESSAGE] + </notification> + <notification name="CallingCardAccepted"> + Your calling card was accepted. + </notification> + <notification name="CallingCardDeclined"> + Your calling card was declined. + </notification> + <notification name="TeleportToLandmark"> + You can teleport to locations like '[NAME]' by opening the Places panel on the right side of your screen, and then select the Landmarks tab. +Click on any landmark to select it, then click 'Teleport' at the bottom of the panel. +(You can also double-click on the landmark, or right-click it and choose 'Teleport'.) + </notification> + <notification name="TeleportToPerson"> + You can contact Residents like '[NAME]' by opening the People panel on the right side of your screen. +Select the Resident from the list, then click 'IM' at the bottom of the panel. +(You can also double-click on their name in the list, or right-click and choose 'IM'). + </notification> + <notification name="CantSelectLandFromMultipleRegions"> + Can't select land across server boundaries. +Try selecting a smaller piece of land. + </notification> + <notification name="SearchWordBanned"> + Some terms in your search query were excluded due to content restrictions as clarified in the Community Standards. + </notification> + <notification name="NoContentToSearch"> + Please select at least one type of content to search (General, Moderate, or Adult). + </notification> + <notification name="SystemMessage"> + [MESSAGE] + </notification> + <notification name="PaymentReceived"> + [MESSAGE] + </notification> + <notification name="PaymentSent"> + [MESSAGE] + </notification> + <notification name="EventNotification"> + Event Notification: + +[NAME] +[DATE] + <form name="form"> + <button name="Details" text="Details"/> + <button name="Cancel" text="å–銷"/> + </form> + </notification> + <notification name="TransferObjectsHighlighted"> + All objects on this parcel that will transfer to the purchaser of this parcel are now highlighted. + +* Trees and grasses that will transfer are not highlighted. + <form name="form"> + <button name="Done" text="Done"/> + </form> + </notification> + <notification name="DeactivatedGesturesTrigger"> + Deactivated gestures with same trigger: +[NAMES] + </notification> + <notification name="NoQuickTime"> + Apple's QuickTime software does not appear to be installed on your system. +If you want to view streaming media on parcels that support it you should go to the [http://www.apple.com/quicktime QuickTime site] and install the QuickTime Player. + </notification> + <notification name="NoPlugin"> + No Media Plugin was found to handle the "[MIME_TYPE]" mime type. Media of this type will be unavailable. + </notification> + <notification name="MediaPluginFailed"> + The following Media Plugin has failed: + [PLUGIN] + +Please re-install the plugin or contact the vendor if you continue to experience problems. + <form name="form"> + <ignore name="ignore" text="A Media Plugin fails to run"/> + </form> + </notification> + <notification name="OwnedObjectsReturned"> + The objects you own on the selected parcel of land have been returned back to your inventory. + </notification> + <notification name="OtherObjectsReturned"> + The objects on the selected parcel of land that is owned by [NAME] have been returned to his or her inventory. + </notification> + <notification name="OtherObjectsReturned2"> + The objects on the selected parcel of land owned by the Resident '[NAME]' have been returned to their owner. + </notification> + <notification name="GroupObjectsReturned"> + The objects on the selected parcel of land shared with the group [GROUPNAME] have been returned back to their owner's inventory. +Transferable deeded objects have been returned to their previous owners. +Non-transferable objects that are deeded to the group have been deleted. + </notification> + <notification name="UnOwnedObjectsReturned"> + The objects on the selected parcel that are NOT owned by you have been returned to their owners. + </notification> + <notification name="ServerObjectMessage"> + Message from [NAME]: +<nolink>[MSG]</nolink> + </notification> + <notification name="NotSafe"> + This land has damage enabled. +You can be hurt here. If you die, you will be teleported to your home location. + </notification> + <notification name="NoFly"> + This area has flying disabled. +You can't fly here. + </notification> + <notification name="PushRestricted"> + This area does not allow pushing. You can't push others here unless you own the land. + </notification> + <notification name="NoVoice"> + This area has voice chat disabled. You won't be able to hear anyone talking. + </notification> + <notification name="NoBuild"> + This area has building disabled. You can't build or rez objects here. + </notification> + <notification name="ScriptsStopped"> + An administrator has temporarily stopped scripts in this region. + </notification> + <notification name="ScriptsNotRunning"> + This region is not running any scripts. + </notification> + <notification name="NoOutsideScripts"> + This land has outside scripts disabled. + +No scripts will work here except those belonging to the land owner. + </notification> + <notification name="ClaimPublicLand"> + You can only claim public land in the Region you're in. + </notification> + <notification name="RegionTPAccessBlocked"> + You aren't allowed in that Region due to your maturity Rating. You may need to validate your age and/or install the latest Viewer. + +Please go to the Knowledge Base for details on accessing areas with this maturity Rating. + </notification> + <notification name="URBannedFromRegion"> + You are banned from the region. + </notification> + <notification name="NoTeenGridAccess"> + Your account cannot connect to this teen grid region. + </notification> + <notification name="ImproperPaymentStatus"> + You do not have proper payment status to enter this region. + </notification> + <notification name="MustGetAgeRgion"> + You must be age-verified to enter this region. + </notification> + <notification name="MustGetAgeParcel"> + You must be age-verified to enter this parcel. + </notification> + <notification name="NoDestRegion"> + No destination region found. + </notification> + <notification name="NotAllowedInDest"> + You are not allowed into the destination. + </notification> + <notification name="RegionParcelBan"> + Cannot region cross into banned parcel. Try another way. + </notification> + <notification name="TelehubRedirect"> + You have been redirected to a telehub. + </notification> + <notification name="CouldntTPCloser"> + Could not teleport closer to destination. + </notification> + <notification name="TPCancelled"> + Teleport cancelled. + </notification> + <notification name="FullRegionTryAgain"> + The region you are attempting to enter is currently full. +Please try again in a few moments. + </notification> + <notification name="GeneralFailure"> + General failure. + </notification> + <notification name="RoutedWrongRegion"> + Routed to wrong region. Please try again. + </notification> + <notification name="NoValidAgentID"> + No valid agent id. + </notification> + <notification name="NoValidSession"> + No valid session id. + </notification> + <notification name="NoValidCircuit"> + No valid circuit code. + </notification> + <notification name="NoValidTimestamp"> + No valid timestamp. + </notification> + <notification name="NoPendingConnection"> + Unable to create pending connection. + </notification> + <notification name="InternalUsherError"> + Internal error attempting to connect agent usher. + </notification> + <notification name="NoGoodTPDestination"> + Unable to find a good teleport destination in this region. + </notification> + <notification name="InternalErrorRegionResolver"> + Internal error attempting to activate region resolver. + </notification> + <notification name="NoValidLanding"> + A valid landing point could not be found. + </notification> + <notification name="NoValidParcel"> + No valid parcel could be found. + </notification> + <notification name="ObjectGiveItem"> + An object named <nolink>[OBJECTFROMNAME]</nolink> owned by [NAME_SLURL] has given you this [OBJECTTYPE]: +[ITEM_SLURL] + <form name="form"> + <button name="Keep" text="Keep"/> + <button name="Discard" text="Discard"/> + <button name="Mute" text="Block"/> + </form> + </notification> + <notification name="UserGiveItem"> + [NAME_SLURL] has given you this [OBJECTTYPE]: +[ITEM_SLURL] + <form name="form"> + <button name="Show" text="Show"/> + <button name="Discard" text="Discard"/> + <button name="Mute" text="Block"/> + </form> + </notification> + <notification name="GodMessage"> + [NAME] + +[MESSAGE] + </notification> + <notification name="JoinGroup"> + [MESSAGE] + <form name="form"> + <button name="Join" text="Join"/> + <button name="Decline" text="Decline"/> + <button name="Info" text="資訊"/> + </form> + </notification> + <notification name="TeleportOffered"> + [NAME_SLURL] has offered to teleport you to their location: + +[MESSAGE] - [MATURITY_STR] <icon>[MATURITY_ICON]</icon> + <form name="form"> + <button name="Teleport" text="Teleport"/> + <button name="Cancel" text="å–銷"/> + </form> + </notification> + <notification name="TeleportOfferSent"> + Teleport offer sent to [TO_NAME] + </notification> + <notification name="GotoURL"> + [MESSAGE] +[URL] + <form name="form"> + <button name="Later" text="Later"/> + <button name="GoNow..." text="Go Now..."/> + </form> + </notification> + <notification name="OfferFriendship"> + [NAME_SLURL] is offering friendship. + +[MESSAGE] + +(By default, you will be able to see each other's online status.) + <form name="form"> + <button name="Accept" text="接å—"/> + <button name="Decline" text="Decline"/> + </form> + </notification> + <notification name="FriendshipOffered"> + You have offered friendship to [TO_NAME] + </notification> + <notification name="OfferFriendshipNoMessage"> + [NAME_SLURL] is offering friendship. + +(By default, you will be able to see each other's online status.) + <form name="form"> + <button name="Accept" text="接å—"/> + <button name="Decline" text="Decline"/> + </form> + </notification> + <notification name="FriendshipAccepted"> + [NAME] accepted your friendship offer. + </notification> + <notification name="FriendshipDeclined"> + [NAME] declined your friendship offer. + </notification> + <notification name="FriendshipAcceptedByMe"> + Friendship offer accepted. + </notification> + <notification name="FriendshipDeclinedByMe"> + Friendship offer declined. + </notification> + <notification name="OfferCallingCard"> + [NAME] is offering their calling card. +This will add a bookmark in your inventory so you can quickly IM this Resident. + <form name="form"> + <button name="Accept" text="接å—"/> + <button name="Decline" text="Decline"/> + </form> + </notification> + <notification name="RegionRestartMinutes"> + This region will restart in [MINUTES] minutes. +If you stay in this region you will be logged out. + </notification> + <notification name="RegionRestartSeconds"> + This region will restart in [SECONDS] seconds. +If you stay in this region you will be logged out. + </notification> + <notification name="LoadWebPage"> + Load web page [URL]? + +[MESSAGE] + +From object: <nolink>[OBJECTNAME]</nolink>, owner: [NAME]? + <form name="form"> + <button name="Gotopage" text="Go to page"/> + <button name="Cancel" text="å–銷"/> + </form> + </notification> + <notification name="FailedToFindWearableUnnamed"> + Failed to find [TYPE] in database. + </notification> + <notification name="FailedToFindWearable"> + Failed to find [TYPE] named [DESC] in database. + </notification> + <notification name="InvalidWearable"> + The item you are trying to wear uses a feature that your Viewer can't read. Please upgrade your version of [APP_NAME] to wear this item. + </notification> + <notification name="ScriptQuestion"> + '<nolink>[OBJECTNAME]</nolink>', an object owned by '[NAME]', would like to: + +[QUESTIONS] +Is this OK? + <form name="form"> + <button name="Yes" text="是"/> + <button name="No" text="å¦"/> + <button name="Mute" text="Block"/> + </form> + </notification> + <notification name="ScriptQuestionCaution"> + An object named '<nolink>[OBJECTNAME]</nolink>', owned by '[NAME]' would like to: + +[QUESTIONS] +If you do not trust this object and its creator, you should deny the request. + +Grant this request? + <form name="form"> + <button name="Grant" text="Grant"/> + <button name="Deny" text="Deny"/> + <button name="Details" text="Details..."/> + </form> + </notification> + <notification name="ScriptDialog"> + [NAME]'s '<nolink>[TITLE]</nolink>' +[MESSAGE] + <form name="form"> + <button name="Ignore" text="忽視"/> + </form> + </notification> + <notification name="ScriptDialogGroup"> + [GROUPNAME]'s '<nolink>[TITLE]</nolink>' +[MESSAGE] + <form name="form"> + <button name="Ignore" text="忽視"/> + </form> + </notification> + <notification name="BuyLindenDollarSuccess"> + Thank you for your payment! + +Your L$ balance will be updated when processing completes. If processing takes more than 20 mins, your transaction may be cancelled. In that case, the purchase amount will be credited to your US$ balance. + +The status of your payment can be checked on your Transaction History page on your [http://secondlife.com/account/ Dashboard] + </notification> + <notification name="FirstOverrideKeys"> + Your movement keys are now being handled by an object. +Try the arrow keys or AWSD to see what they do. +Some objects (like guns) require you to go into mouselook to use them. +Press 'M' to do this. + </notification> + <notification name="FirstSandbox"> + This is a sandbox area, and is meant to help Residents learn how to build. + +Things you build here will be deleted after you leave, so don't forget to right-click and choose 'Take' to move your creation to your Inventory. + </notification> + <notification name="MaxListSelectMessage"> + You may only select up to [MAX_SELECT] items from this list. + </notification> + <notification name="VoiceInviteP2P"> + [NAME] is inviting you to a Voice Chat call. +Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller. + <form name="form"> + <button name="Accept" text="接å—"/> + <button name="Decline" text="Decline"/> + <button name="Mute" text="Block"/> + </form> + </notification> + <notification name="AutoUnmuteByIM"> + [NAME] was sent an instant message and has been automatically unblocked. + </notification> + <notification name="AutoUnmuteByMoney"> + [NAME] was given money and has been automatically unblocked. + </notification> + <notification name="AutoUnmuteByInventory"> + [NAME] was offered inventory and has been automatically unblocked. + </notification> + <notification name="VoiceInviteGroup"> + [NAME] has joined a Voice Chat call with the group [GROUP]. +Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller. + <form name="form"> + <button name="Accept" text="接å—"/> + <button name="Decline" text="Decline"/> + <button name="Mute" text="Block"/> + </form> + </notification> + <notification name="VoiceInviteAdHoc"> + [NAME] has joined a voice chat call with a conference chat. +Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller. + <form name="form"> + <button name="Accept" text="接å—"/> + <button name="Decline" text="Decline"/> + <button name="Mute" text="Block"/> + </form> + </notification> + <notification name="InviteAdHoc"> + [NAME] is inviting you to a conference chat. +Click Accept to join the chat or Decline to decline the invitation. Click Block to block this caller. + <form name="form"> + <button name="Accept" text="接å—"/> + <button name="Decline" text="Decline"/> + <button name="Mute" text="Block"/> + </form> + </notification> + <notification name="VoiceChannelFull"> + The voice call you are trying to join, [VOICE_CHANNEL_NAME], has reached maximum capacity. Please try again later. + </notification> + <notification name="ProximalVoiceChannelFull"> + We're sorry. This area has reached maximum capacity for voice conversations. Please try to use voice in another area. + </notification> + <notification name="VoiceChannelDisconnected"> + You have been disconnected from [VOICE_CHANNEL_NAME]. You will now be reconnected to Nearby Voice Chat. + </notification> + <notification name="VoiceChannelDisconnectedP2P"> + [VOICE_CHANNEL_NAME] has ended the call. You will now be reconnected to Nearby Voice Chat. + </notification> + <notification name="P2PCallDeclined"> + [VOICE_CHANNEL_NAME] has declined your call. You will now be reconnected to Nearby Voice Chat. + </notification> + <notification name="P2PCallNoAnswer"> + [VOICE_CHANNEL_NAME] is not available to take your call. You will now be reconnected to Nearby Voice Chat. + </notification> + <notification name="VoiceChannelJoinFailed"> + Failed to connect to [VOICE_CHANNEL_NAME], please try again later. You will now be reconnected to Nearby Voice Chat. + </notification> + <notification name="VoiceLoginRetry"> + We are creating a voice channel for you. This may take up to one minute. + </notification> + <notification name="VoiceEffectsExpired"> + One or more of your subscribed Voice Morphs has expired. +[[URL] Click here] to renew your subscription. + </notification> + <notification name="VoiceEffectsExpiredInUse"> + The active Voice Morph has expired, your normal voice settings have been applied. +[[URL] Click here] to renew your subscription. + </notification> + <notification name="VoiceEffectsWillExpire"> + One or more of your Voice Morphs will expire in less than [INTERVAL] days. +[[URL] Click here] to renew your subscription. + </notification> + <notification name="VoiceEffectsNew"> + New Voice Morphs are available! + </notification> + <notification name="Cannot enter parcel: not a group member"> + Only members of a certain group can visit this area. + </notification> + <notification name="Cannot enter parcel: banned"> + Cannot enter parcel, you have been banned. + </notification> + <notification name="Cannot enter parcel: not on access list"> + Cannot enter parcel, you are not on the access list. + </notification> + <notification name="VoiceNotAllowed"> + You do not have permission to connect to voice chat for [VOICE_CHANNEL_NAME]. + </notification> + <notification name="VoiceCallGenericError"> + An error has occurred while trying to connect to voice chat for [VOICE_CHANNEL_NAME]. Please try again later. + </notification> + <notification name="UnsupportedCommandSLURL"> + The SLurl you clicked on is not supported. + </notification> + <notification name="BlockedSLURL"> + A SLurl was received from an untrusted browser and has been blocked for your security. + </notification> + <notification name="ThrottledSLURL"> + Multiple SLurls were received from an untrusted browser within a short period. +They will be blocked for a few seconds for your security. + </notification> + <notification name="IMToast"> + [MESSAGE] + <form name="form"> + <button name="respondbutton" text="Respond"/> + </form> + </notification> + <notification name="ConfirmCloseAll"> + Are you sure you want to close all IMs? + <usetemplate ignoretext="Confirm before I close all IMs" name="okcancelignore" notext="å–銷" yestext="確定"/> + </notification> + <notification name="AttachmentSaved"> + Attachment has been saved. + </notification> + <notification name="UnableToFindHelpTopic"> + Unable to find the help topic for this element. + </notification> + <notification name="ObjectMediaFailure"> + Server Error: Media update or get failed. +'[ERROR]' + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="TextChatIsMutedByModerator"> + Your text chat has been muted by moderator. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="VoiceIsMutedByModerator"> + Your voice has been muted by moderator. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="ConfirmClearTeleportHistory"> + Are you sure you want to delete your teleport history? + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="BottomTrayButtonCanNotBeShown"> + Selected button can not be shown right now. +The button will be shown when there is enough space for it. + </notification> + <notification name="ShareNotification"> + Select residents to share with. + </notification> + <notification name="ShareItemsConfirmation"> + Are you sure you want to share the following items: + +<nolink>[ITEMS]</nolink> + +With the following Residents: + +[RESIDENTS] + <usetemplate name="okcancelbuttons" notext="å–銷" yestext="確定"/> + </notification> + <notification name="ItemsShared"> + Items successfully shared. + </notification> + <notification name="DeedToGroupFail"> + Deed to group failed. + </notification> + <notification name="AvatarRezNotification"> + ( [EXISTENCE] seconds alive ) +Avatar '[NAME]' declouded after [TIME] seconds. + </notification> + <notification name="AvatarRezSelfBakedDoneNotification"> + ( [EXISTENCE] seconds alive ) +You finished baking your outfit after [TIME] seconds. + </notification> + <notification name="AvatarRezSelfBakedUpdateNotification"> + ( [EXISTENCE] seconds alive ) +You sent out an update of your appearance after [TIME] seconds. +[STATUS] + </notification> + <notification name="AvatarRezCloudNotification"> + ( [EXISTENCE] seconds alive ) +Avatar '[NAME]' became cloud. + </notification> + <notification name="AvatarRezArrivedNotification"> + ( [EXISTENCE] seconds alive ) +Avatar '[NAME]' appeared. + </notification> + <notification name="AvatarRezLeftCloudNotification"> + ( [EXISTENCE] seconds alive ) +Avatar '[NAME]' left after [TIME] seconds as cloud. + </notification> + <notification name="AvatarRezEnteredAppearanceNotification"> + ( [EXISTENCE] seconds alive ) +Avatar '[NAME]' entered appearance mode. + </notification> + <notification name="AvatarRezLeftAppearanceNotification"> + ( [EXISTENCE] seconds alive ) +Avatar '[NAME]' left appearance mode. + </notification> + <notification name="NoConnect"> + We're having trouble connecting using [PROTOCOL] [HOSTID]. +Please check your network and firewall setup. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="NoVoiceConnect"> + We're having trouble connecting to your voice server: + +[HOSTID] + +Voice communications will not be available. +Please check your network and firewall setup. + <usetemplate name="okbutton" yestext="確定"/> + </notification> + <notification name="AvatarRezLeftNotification"> + ( [EXISTENCE] seconds alive ) +Avatar '[NAME]' left as fully loaded. + </notification> + <notification name="AvatarRezSelfBakedTextureUploadNotification"> + ( [EXISTENCE] seconds alive ) +You uploaded a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME] seconds. + </notification> + <notification name="AvatarRezSelfBakedTextureUpdateNotification"> + ( [EXISTENCE] seconds alive ) +You locally updated a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME] seconds. + </notification> + <notification name="ConfirmLeaveCall"> + Are you sure you want to leave this call? + <usetemplate ignoretext="Confirm before I leave call" name="okcancelignore" notext="å¦" yestext="是"/> + </notification> + <notification name="ConfirmMuteAll"> + You have selected to mute all participants in a group call. +This will also cause all residents that later join the call to be +muted, even after you have left the call. + +Mute everyone? + <usetemplate ignoretext="Confirm before I mute all participants in a group call" name="okcancelignore" notext="å–銷" yestext="確定"/> + </notification> + <notification label="èŠå¤©" name="HintChat"> + To join the conversation, type into the chat field below. + </notification> + <notification label="Stand" name="HintSit"> + To stand up and exit the sitting position, click the Stand button. + </notification> + <notification label="Speak" name="HintSpeak"> + Click the Speak button to turn your microphone on and off. + +Click on the up arrow to see the voice control panel. + +Hiding the Speak button will disable the voice feature. + </notification> + <notification label="Explore the World" name="HintDestinationGuide"> + The Destination Guide contains thousands of new places to discover. Select a location and choose Teleport to start exploring. + </notification> + <notification label="å´é‚Šæ¬„" name="HintSidePanel"> + Get quick access to your inventory, outfits, profiles and more in the side panel. + </notification> + <notification label="移動" name="HintMove"> + To walk or run, open the Move Panel and use the directional arrows to navigate. You can also use the directional keys on your keyboard. + </notification> + <notification label="" name="HintMoveClick"> + 1. Click to Walk +Click anywhere on the ground to walk to that spot. + +2. Click and Drag to Rotate View +Click and drag anywhere on the world to rotate your view + </notification> + <notification label="Display Name" name="HintDisplayName"> + Set your customizable display name here. This is in addition to your unique username, which can't be changed. You can change how you see other people's names in your preferences. + </notification> + <notification label="View" name="HintView"> + To change your camera view, use the Orbit and Pan controls. Reset your view by pressing Escape or walking. + </notification> + <notification label="Inventory" name="HintInventory"> + Check your inventory to find items. Newest items can be easily found in the Recent tab. + </notification> + <notification label="You've got Linden Dollars!" name="HintLindenDollar"> + Here's your current balance of L$. Click Buy L$ to purchase more Linden Dollars. + </notification> + <notification name="PopupAttempt"> + A pop-up was prevented from opening. + <form name="form"> + <ignore name="ignore" text="Enable all pop-ups"/> + <button name="open" text="Open pop-up window"/> + </form> + </notification> + <notification name="AuthRequest"> + The site at '<nolink>[HOST_NAME]</nolink>' in realm '[REALM]' requires a user name and password. + <form name="form"> + <input name="username" text="User Name"/> + <input name="password" text="Password"/> + <button name="ok" text="Submit"/> + <button name="cancel" text="å–銷"/> + </form> + </notification> + <notification label="" name="ModeChange"> + Changing modes requires you to quit and restart. + <usetemplate name="okcancelbuttons" notext="Don't Quit" yestext="Quit"/> + </notification> + <notification label="" name="NoClassifieds"> + Creation and editing of Classifieds is only available in Advanced mode. Would you like to quit and change modes? The mode selector can be found on the login screen. + <usetemplate name="okcancelbuttons" notext="Don't Quit" yestext="Quit"/> + </notification> + <notification label="" name="NoGroupInfo"> + Creation and editing of Groups is only available in Advanced mode. Would you like to quit and change modes? The mode selector can be found on the login screen. + <usetemplate name="okcancelbuttons" notext="Don't Quit" yestext="Quit"/> + </notification> + <notification label="" name="NoPicks"> + Creation and editing of Picks is only available in Advanced mode. Would you like to quit and change modes? The mode selector can be found on the login screen. + <usetemplate name="okcancelbuttons" notext="Don't Quit" yestext="Quit"/> + </notification> + <notification label="" name="NoWorldMap"> + Viewing of the world map is only available in Advanced mode. Would you like to quit and change modes? The mode selector can be found on the login screen. + <usetemplate name="okcancelbuttons" notext="Don't Quit" yestext="Quit"/> + </notification> + <notification label="" name="NoVoiceCall"> + Voice calls are only available in Advanced mode. Would you like to logout and change modes? + <usetemplate name="okcancelbuttons" notext="Don't Quit" yestext="Quit"/> + </notification> + <notification label="" name="NoAvatarShare"> + Sharing is only available in Advanced mode. Would you like to logout and change modes? + <usetemplate name="okcancelbuttons" notext="Don't Quit" yestext="Quit"/> + </notification> + <notification label="" name="NoAvatarPay"> + Paying other residents is only available in Advanced mode. Would you like to logout and change modes? + <usetemplate name="okcancelbuttons" notext="Don't Quit" yestext="Quit"/> + </notification> + <global name="UnsupportedCPU"> + - Your CPU speed does not meet the minimum requirements. + </global> + <global name="UnsupportedGLRequirements"> + You do not appear to have the proper hardware requirements for [APP_NAME]. [APP_NAME] requires an OpenGL graphics card that has multitexture support. If this is the case, you may want to make sure that you have the latest drivers for your graphics card, and service packs and patches for your operating system. + +If you continue to have problems, please visit the [SUPPORT_SITE]. + </global> + <global name="UnsupportedCPUAmount"> + 796 + </global> + <global name="UnsupportedRAMAmount"> + 510 + </global> + <global name="UnsupportedGPU"> + - Your graphics card does not meet the minimum requirements. + </global> + <global name="UnsupportedRAM"> + - Your system memory does not meet the minimum requirements. + </global> + <global name="You can only set your 'Home Location' on your land or at a mainland Infohub."> + If you own a piece of land, you can make it your home location. +Otherwise, you can look at the Map and find places marked "Infohub". + </global> + <global name="You died and have been teleported to your home location"> + You died and have been teleported to your home location. + </global> +</notifications> diff --git a/indra/newview/skins/default/xui/zh/panel_active_object_row.xml b/indra/newview/skins/default/xui/zh/panel_active_object_row.xml new file mode 100644 index 0000000000..0905cc30b6 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_active_object_row.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_activeim_row"> + <text name="object_name"> + Unnamed Object + </text> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_adhoc_control_panel.xml b/indra/newview/skins/default/xui/zh/panel_adhoc_control_panel.xml new file mode 100644 index 0000000000..641d0eba93 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_adhoc_control_panel.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_im_control_panel"> + <layout_stack name="vertical_stack"> + <layout_panel name="call_btn_panel"> + <button label="Call" name="call_btn"/> + </layout_panel> + <layout_panel name="end_call_btn_panel"> + <button label="Leave Call" name="end_call_btn"/> + </layout_panel> + <layout_panel name="voice_ctrls_btn_panel"> + <button label="Voice Controls" name="voice_ctrls_btn"/> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/zh/panel_avatar_list_item.xml new file mode 100644 index 0000000000..e7a94eafa8 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_avatar_list_item.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="avatar_list_item"> + <string name="FormatSeconds"> + [COUNT]s + </string> + <string name="FormatMinutes"> + [COUNT]m + </string> + <string name="FormatHours"> + [COUNT]h + </string> + <string name="FormatDays"> + [COUNT]d + </string> + <string name="FormatWeeks"> + [COUNT]w + </string> + <string name="FormatMonths"> + [COUNT]mon + </string> + <string name="FormatYears"> + [COUNT]y + </string> + <text name="avatar_name" value="(loading)"/> + <text name="last_interaction" value="0s"/> + <icon name="permission_edit_theirs_icon" tool_tip="You can edit this friend's objects"/> + <icon name="permission_edit_mine_icon" tool_tip="This friend can edit, delete or take your objects"/> + <icon name="permission_map_icon" tool_tip="This friend can locate you on the map"/> + <icon name="permission_online_icon" tool_tip="This friend can see when you're online"/> + <button name="profile_btn" tool_tip="View profile"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_avatar_tag.xml b/indra/newview/skins/default/xui/zh/panel_avatar_tag.xml new file mode 100644 index 0000000000..fd91ea97d1 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_avatar_tag.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="avatar_tag_notification"> + <panel name="msg_caption"> + <text name="sender_tag_name"> + Angela Tester + </text> + <text name="tag_time" value="23:30"/> + </panel> + <text_editor name="msg_text"> + The quick brown fox jumps over the lazy dog. + </text_editor> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/zh/panel_block_list_sidetray.xml new file mode 100644 index 0000000000..d8327683dd --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_block_list_sidetray.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="block_list_panel"> + <text name="title_text"> + Block List + </text> + <scroll_list name="blocked" tool_tip="List of currently blocked Residents"/> + <button label="Block person" name="Block resident..." tool_tip="Pick a Resident to block"/> + <button label="Block object by name" name="Block object by name..." tool_tip="Pick an object to block by name"/> + <button label="Unblock" name="Unblock" tool_tip="Remove Resident or object from blocked list"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/zh/panel_body_parts_list_item.xml new file mode 100644 index 0000000000..1fb0f210fe --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_body_parts_list_item.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="wearable_item"> + <text name="item_name" value="..."/> + <panel name="btn_lock" tool_tip="You don't have permission to edit"/> + <panel name="btn_edit_panel"> + <button name="btn_edit" tool_tip="Edit this shape"/> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/zh/panel_bodyparts_list_button_bar.xml new file mode 100644 index 0000000000..5e269fcd09 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_bodyparts_list_button_bar.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="clothing_list_button_bar_panel"> + <button label="Switch" name="switch_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_bottomtray.xml b/indra/newview/skins/default/xui/zh/panel_bottomtray.xml new file mode 100644 index 0000000000..4e7f261e63 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_bottomtray.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="bottom_tray"> + <string name="DragIndicationImageName" value="Accordion_ArrowOpened_Off"/> + <string name="SpeakBtnToolTip" value="Turns microphone on/off"/> + <string name="VoiceControlBtnToolTip" value="顯示 / éš±è— èªžéŸ³æŽ§åˆ¶æ¿"/> + <layout_stack name="toolbar_stack"> + <layout_panel name="speak_panel"> + <talk_button name="talk"> + <speak_button label="Speak" label_selected="Speak" name="speak_btn"/> + </talk_button> + </layout_panel> + <layout_panel name="gesture_panel"> + <gesture_combo_list label="Gesture" name="Gesture" tool_tip="顯示 / éš±è— å§¿å‹¢"/> + </layout_panel> + <layout_panel name="movement_panel"> + <bottomtray_button label="移動" name="movement_btn" tool_tip="顯示 / éš±è— ç§»å‹•æŽ§åˆ¶"/> + </layout_panel> + <layout_panel name="cam_panel"> + <bottomtray_button label="View" name="camera_btn" tool_tip="顯示 / éš±è— æ”影機控制"/> + </layout_panel> + <layout_panel name="snapshot_panel"> + <bottomtray_button name="snapshots" tool_tip="æ‹æ”å¿«ç…§"/> + </layout_panel> + <layout_panel name="build_btn_panel"> + <bottomtray_button label="å»ºé€ " name="build_btn" tool_tip="顯示 / éš±è— å»ºé€ å·¥å…·"/> + </layout_panel> + <layout_panel name="search_btn_panel"> + <bottomtray_button label="æœå°‹" name="search_btn" tool_tip="顯示 / éš±è— æœå°‹"/> + </layout_panel> + <layout_panel name="world_map_btn_panel"> + <bottomtray_button label="地圖" name="world_map_btn" tool_tip="顯示 / éš±è— ä¸–ç•Œåœ°åœ–"/> + </layout_panel> + <layout_panel name="mini_map_btn_panel"> + <bottomtray_button label="è¿·ä½ åœ°åœ–" name="mini_map_btn" tool_tip="顯示 / éš±è— è¿·ä½ åœ°åœ–"/> + </layout_panel> + <layout_panel name="im_well_panel"> + <chiclet_im_well name="im_well"> + <button name="Unread IM messages" tool_tip="Conversations"/> + </chiclet_im_well> + </layout_panel> + <layout_panel name="notification_well_panel"> + <chiclet_notification name="notification_well"> + <button name="Unread" tool_tip="Notifications"/> + </chiclet_notification> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_bottomtray_lite.xml b/indra/newview/skins/default/xui/zh/panel_bottomtray_lite.xml new file mode 100644 index 0000000000..22f3731a6f --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_bottomtray_lite.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="bottom_tray_lite"> + <layout_stack name="toolbar_stack_lite"> + <layout_panel name="gesture_panel"> + <gesture_combo_list label="Gesture" name="Gesture" tool_tip="顯示 / éš±è— å§¿å‹¢"/> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_chat_header.xml b/indra/newview/skins/default/xui/zh/panel_chat_header.xml new file mode 100644 index 0000000000..7916bf5155 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_chat_header.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="im_header" name="im_header"> + <text name="time_box" value="23:30"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_classified_info.xml b/indra/newview/skins/default/xui/zh/panel_classified_info.xml new file mode 100644 index 0000000000..6ddfbdaf4f --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_classified_info.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_classified_info"> + <panel.string name="type_mature"> + Moderate + </panel.string> + <panel.string name="type_pg"> + General Content + </panel.string> + <panel.string name="l$_price"> + L$[PRICE] + </panel.string> + <panel.string name="click_through_text_fmt"> + [TELEPORT] teleport, [MAP] map, [PROFILE] profile + </panel.string> + <panel.string name="date_fmt"> + [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] + </panel.string> + <panel.string name="auto_renew_on"> + Enabled + </panel.string> + <panel.string name="auto_renew_off"> + Disabled + </panel.string> + <text name="title" value="Classified Info"/> + <scroll_container name="profile_scroll"> + <panel name="scroll_content_panel"> + <text_editor name="classified_name" value="[name]"/> + <text name="classified_location_label" value="ä½ç½®ï¼š"/> + <text_editor name="classified_location" value="[loading...]"/> + <text name="content_type_label" value="Content Type:"/> + <text_editor name="content_type" value="[content type]"/> + <text name="category_label" value="Category:"/> + <text_editor name="category" value="[category]"/> + <text name="creation_date_label" value="Creation date:"/> + <text_editor name="creation_date" tool_tip="Creation date" value="[date]"/> + <text name="price_for_listing_label" value="Price for listing:"/> + <text_editor name="price_for_listing" tool_tip="Price for listing." value="[price]"/> + <layout_stack name="descr_stack"> + <layout_panel name="clickthrough_layout_panel"> + <text name="click_through_label" value="Clicks:"/> + <text_editor name="click_through_text" tool_tip="Click through data" value="[clicks]"/> + </layout_panel> + <layout_panel name="price_layout_panel"> + <text name="auto_renew_label" value="Auto renew:"/> + <text name="auto_renew" value="Enabled"/> + </layout_panel> + <layout_panel name="descr_layout_panel"> + <text name="classified_desc_label" value="æ述:"/> + <text_editor name="classified_desc" value="[description]"/> + </layout_panel> + </layout_stack> + </panel> + </scroll_container> + <panel name="buttons"> + <layout_stack name="layout_stack1"> + <layout_panel name="layout_panel1"> + <button label="Teleport" name="teleport_btn"/> + </layout_panel> + <layout_panel name="show_on_map_btn_lp"> + <button label="地圖" name="show_on_map_btn"/> + </layout_panel> + <layout_panel name="edit_btn_lp"> + <button label="編輯" name="edit_btn"/> + </layout_panel> + </layout_stack> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_clothing_list_button_bar.xml b/indra/newview/skins/default/xui/zh/panel_clothing_list_button_bar.xml new file mode 100644 index 0000000000..7a74f07743 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_clothing_list_button_bar.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="clothing_list_button_bar_panel"> + <button label="Add +" name="add_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/zh/panel_clothing_list_item.xml new file mode 100644 index 0000000000..eba6fa7c29 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_clothing_list_item.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="wearable_item"> + <button name="btn_delete" tool_tip="Remove from outfit"/> + <text name="item_name" value="..."/> + <panel name="btn_lock" tool_tip="You don't have permission to edit"/> + <panel name="btn_edit_panel"> + <button name="btn_edit" tool_tip="Edit this wearable"/> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_cof_wearables.xml b/indra/newview/skins/default/xui/zh/panel_cof_wearables.xml new file mode 100644 index 0000000000..9e63b9a3a8 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_cof_wearables.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="cof_wearables"> + <accordion name="cof_wearables_accordion"> + <accordion_tab name="tab_clothing" title="Clothing"/> + <accordion_tab name="tab_attachments" title="Attachments"/> + <accordion_tab name="tab_body_parts" title="Body Parts"/> + </accordion> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_deletable_wearable_list_item.xml b/indra/newview/skins/default/xui/zh/panel_deletable_wearable_list_item.xml new file mode 100644 index 0000000000..59bff5f3e9 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_deletable_wearable_list_item.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="deletable_wearable_item"> + <button name="btn_delete" tool_tip="Remove from outfit"/> + <text name="item_name" value="..."/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/zh/panel_dummy_clothing_list_item.xml new file mode 100644 index 0000000000..6558eda253 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_dummy_clothing_list_item.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="dummy_clothing_item"> + <text name="item_name" value="..."/> + <panel name="btn_add_panel"> + <button name="btn_add" tool_tip="Add more items of this type"/> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_alpha.xml b/indra/newview/skins/default/xui/zh/panel_edit_alpha.xml new file mode 100644 index 0000000000..73c59d9ae3 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_edit_alpha.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="edit_alpha_panel"> + <scroll_container name="avatar_alpha_color_panel_scroll"> + <panel name="avatar_alpha_color_panel"> + <texture_picker label="Lower Alpha" name="Lower Alpha" tool_tip="點擊以挑é¸åœ–片"/> + <texture_picker label="Upper Alpha" name="Upper Alpha" tool_tip="點擊以挑é¸åœ–片"/> + <texture_picker label="Head Alpha" name="Head Alpha" tool_tip="點擊以挑é¸åœ–片"/> + <texture_picker label="Eye Alpha" name="Eye Alpha" tool_tip="點擊以挑é¸åœ–片"/> + <texture_picker label="Hair Alpha" name="Hair Alpha" tool_tip="點擊以挑é¸åœ–片"/> + </panel> + </scroll_container> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_classified.xml b/indra/newview/skins/default/xui/zh/panel_edit_classified.xml new file mode 100644 index 0000000000..9478ec49a6 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_edit_classified.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Edit Classified" name="panel_edit_classified"> + <panel.string name="location_notice"> + (will update after save) + </panel.string> + <string name="publish_label"> + Publish + </string> + <string name="save_label"> + å„²å˜ + </string> + <text name="title"> + Edit Classified + </text> + <scroll_container name="profile_scroll"> + <panel name="scroll_content_panel"> + <panel name="snapshot_panel"> + <icon label="" name="edit_icon" tool_tip="Click to select an image"/> + </panel> + <text name="Name:"> + Title: + </text> + <text name="description_label"> + æ述: + </text> + <text name="location_label"> + ä½ç½®ï¼š + </text> + <text name="classified_location"> + 載入ä¸... + </text> + <button label="Set to Current Location" name="set_to_curr_location_btn"/> + <text name="category_label" value="Category:"/> + <text name="content_type_label" value="Content type:"/> + <icons_combo_box label="General Content" name="content_type"> + <icons_combo_box.item label="Moderate Content" name="mature_ci" value="Mature"/> + <icons_combo_box.item label="General Content" name="pg_ci" value="PG"/> + </icons_combo_box> + <check_box label="Auto renew each week" name="auto_renew"/> + <text name="price_for_listing_label" value="Price for listing:"/> + <spinner label="L$" name="price_for_listing" tool_tip="Price for listing." value="50"/> + </panel> + </scroll_container> + <panel label="bottom_panel" name="bottom_panel"> + <layout_stack name="bottom_panel_ls"> + <layout_panel name="save_changes_btn_lp"> + <button label="[LABEL]" name="save_changes_btn"/> + </layout_panel> + <layout_panel name="show_on_map_btn_lp"> + <button label="å–銷" name="cancel_btn"/> + </layout_panel> + </layout_stack> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_eyes.xml b/indra/newview/skins/default/xui/zh/panel_edit_eyes.xml new file mode 100644 index 0000000000..99e2874319 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_edit_eyes.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="edit_eyes_panel"> + <panel name="avatar_eye_color_panel"> + <texture_picker label="Iris" name="Iris" tool_tip="點擊以挑é¸åœ–片"/> + </panel> + <panel name="accordion_panel"> + <accordion name="wearable_accordion"> + <accordion_tab name="eyes_main_tab" title="眼ç›"/> + </accordion> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_gloves.xml b/indra/newview/skins/default/xui/zh/panel_edit_gloves.xml new file mode 100644 index 0000000000..c664880898 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_edit_gloves.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="edit_gloves_panel"> + <panel name="avatar_gloves_color_panel"> + <texture_picker label="Texture" name="Fabric" tool_tip="點擊以挑é¸åœ–片"/> + <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open color picker"/> + </panel> + <panel name="accordion_panel"> + <accordion name="wearable_accordion"> + <accordion_tab name="gloves_main_tab" title="手套"/> + </accordion> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_hair.xml b/indra/newview/skins/default/xui/zh/panel_edit_hair.xml new file mode 100644 index 0000000000..0709ad4e67 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_edit_hair.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="edit_hair_panel"> + <panel name="avatar_hair_color_panel"> + <texture_picker label="Texture" name="Texture" tool_tip="點擊以挑é¸åœ–片"/> + </panel> + <panel name="accordion_panel"> + <accordion name="wearable_accordion"> + <accordion_tab name="hair_color_tab" title="Color"/> + <accordion_tab name="hair_style_tab" title="Style"/> + <accordion_tab name="hair_eyebrows_tab" title="Eyebrows"/> + <accordion_tab name="hair_facial_tab" title="Facial"/> + </accordion> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_jacket.xml b/indra/newview/skins/default/xui/zh/panel_edit_jacket.xml new file mode 100644 index 0000000000..388fee9eb3 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_edit_jacket.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="edit_jacket_panel"> + <panel name="avatar_jacket_color_panel"> + <texture_picker label="Upper Texture" name="Upper Fabric" tool_tip="點擊以挑é¸åœ–片"/> + <texture_picker label="Lower Texture" name="Lower Fabric" tool_tip="點擊以挑é¸åœ–片"/> + <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open color picker"/> + </panel> + <panel name="accordion_panel"> + <accordion name="wearable_accordion"> + <accordion_tab name="jacket_main_tab" title="夾克"/> + </accordion> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_pants.xml b/indra/newview/skins/default/xui/zh/panel_edit_pants.xml new file mode 100644 index 0000000000..d21c118195 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_edit_pants.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="edit_pants_panel"> + <panel name="avatar_pants_color_panel"> + <texture_picker label="Texture" name="Fabric" tool_tip="點擊以挑é¸åœ–片"/> + <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open color picker"/> + </panel> + <panel name="accordion_panel"> + <accordion name="wearable_accordion"> + <accordion_tab name="pants_main_tab" title="褲å"/> + </accordion> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_physics.xml b/indra/newview/skins/default/xui/zh/panel_edit_physics.xml new file mode 100644 index 0000000000..77ee4fd36d --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_edit_physics.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="edit_physics_panel"> + <panel label="" name="accordion_panel"> + <accordion name="physics_accordion"> + <accordion_tab name="physics_breasts_updown_tab" title="Breasts Bounce"/> + <accordion_tab name="physics_breasts_inout_tab" title="Breasts Cleavage"/> + <accordion_tab name="physics_breasts_leftright_tab" title="Breasts Sway"/> + <accordion_tab name="physics_belly_tab" title="Belly Bounce"/> + <accordion_tab name="physics_butt_tab" title="Butt Bounce"/> + <accordion_tab name="physics_butt_leftright_tab" title="Butt Sway"/> + <accordion_tab name="physics_advanced_tab" title="進階åƒæ•¸"/> + </accordion> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_pick.xml b/indra/newview/skins/default/xui/zh/panel_edit_pick.xml new file mode 100644 index 0000000000..2dd0ed2015 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_edit_pick.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Edit Pick" name="panel_edit_pick"> + <panel.string name="location_notice"> + (will update after save) + </panel.string> + <text name="title"> + Edit Pick + </text> + <scroll_container name="profile_scroll"> + <panel name="scroll_content_panel"> + <icon label="" name="edit_icon" tool_tip="Click to select an image"/> + <text name="Name:"> + Title: + </text> + <text name="description_label"> + æ述: + </text> + <text name="location_label"> + ä½ç½®ï¼š + </text> + <text name="pick_location"> + 載入ä¸... + </text> + <button label="Set to Current Location" name="set_to_curr_location_btn"/> + </panel> + </scroll_container> + <panel label="bottom_panel" name="bottom_panel"> + <layout_stack name="layout_stack1"> + <layout_panel name="layout_panel1"> + <button label="Save Pick" name="save_changes_btn"/> + </layout_panel> + <layout_panel name="layout_panel1"> + <button label="å–銷" name="cancel_btn"/> + </layout_panel> + </layout_stack> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_profile.xml b/indra/newview/skins/default/xui/zh/panel_edit_profile.xml new file mode 100644 index 0000000000..24ed9b9acb --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_edit_profile.xml @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Profile Edit" name="edit_profile_panel"> + <string name="CaptionTextAcctInfo"> + [ACCTTYPE] +[PAYMENTINFO] [AGEVERIFICATION] + </string> + <string name="RegisterDateFormat"> + [REG_DATE] ([AGE]) + </string> + <string name="AcctTypeResident" value="Resident"/> + <string name="AcctTypeTrial" value="Trial"/> + <string name="AcctTypeCharterMember" value="Charter Member"/> + <string name="AcctTypeEmployee" value="Linden Lab Employee"/> + <string name="PaymentInfoUsed" value="Payment Info Used"/> + <string name="PaymentInfoOnFile" value="Payment Info On File"/> + <string name="NoPaymentInfoOnFile" value="No Payment Info On File"/> + <string name="AgeVerified" value="Age-verified"/> + <string name="NotAgeVerified" value="Not Age-verified"/> + <string name="partner_edit_link_url"> + http://www.secondlife.com/account/partners.php?lang=en + </string> + <string name="my_account_link_url"> + http://secondlife.com/my + </string> + <string name="no_partner_text" value="ç„¡"/> + <scroll_container name="profile_scroll"> + <panel name="scroll_content_panel"> + <panel name="data_panel"> + <text name="display_name_label" value="Display Name:"/> + <text name="solo_username_label" value="Username:"/> + <button name="set_name" tool_tip="Set Display Name"/> + <text name="user_label" value="Username:"/> + <panel name="lifes_images_panel"> + <panel name="second_life_image_panel"> + <text name="second_life_photo_title_text" value="[SECOND_LIFE]:"/> + </panel> + <icon label="" name="2nd_life_edit_icon" tool_tip="Click to select an image"/> + </panel> + <panel name="first_life_image_panel"> + <text name="real_world_photo_title_text" value="Real World:"/> + </panel> + <icon label="" name="real_world_edit_icon" tool_tip="Click to select an image"/> + <text name="title_homepage_text"> + Homepage: + </text> + <line_editor name="homepage_edit" value="http://"/> + <text name="title_acc_status_text" value="My Account:"/> + <text_editor name="acc_status_text" value="Resident. No payment info on file."/> + <text name="my_account_link" value="[[URL] Go to My Dashboard]"/> + <text name="title_partner_text" value="My Partner:"/> + <panel name="partner_data_panel"> + <text initial_value="(retrieving)" name="partner_text"/> + </panel> + <text name="partner_edit_link" value="[[URL] Edit]"/> + </panel> + </panel> + </scroll_container> + <panel name="profile_me_buttons_panel"> + <layout_stack name="bottom_panel_ls"> + <layout_panel name="save_changes_btn_lp"> + <button label="Save Changes" name="save_btn"/> + </layout_panel> + <layout_panel name="show_on_map_btn_lp"> + <button label="å–銷" name="cancel_btn"/> + </layout_panel> + </layout_stack> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_shape.xml b/indra/newview/skins/default/xui/zh/panel_edit_shape.xml new file mode 100644 index 0000000000..da6049ea75 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_edit_shape.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="edit_shape_panel"> + <string name="meters"> + Meters + </string> + <string name="feet"> + Feet + </string> + <string name="height"> + Height: + </string> + <panel label="襯衫" name="accordion_panel"> + <accordion name="wearable_accordion"> + <accordion_tab name="shape_body_tab" title="Body"/> + <accordion_tab name="shape_head_tab" title="Head"/> + <accordion_tab name="shape_eyes_tab" title="眼ç›"/> + <accordion_tab name="shape_ears_tab" title="Ears"/> + <accordion_tab name="shape_nose_tab" title="Nose"/> + <accordion_tab name="shape_mouth_tab" title="Mouth"/> + <accordion_tab name="shape_chin_tab" title="Chin"/> + <accordion_tab name="shape_torso_tab" title="Torso"/> + <accordion_tab name="shape_legs_tab" title="Legs"/> + </accordion> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_shirt.xml b/indra/newview/skins/default/xui/zh/panel_edit_shirt.xml new file mode 100644 index 0000000000..44b93504d1 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_edit_shirt.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="edit_shirt_panel"> + <panel name="avatar_shirt_color_panel"> + <texture_picker label="Texture" name="Fabric" tool_tip="點擊以挑é¸åœ–片"/> + <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open color picker"/> + </panel> + <panel name="accordion_panel"> + <accordion name="wearable_accordion"> + <accordion_tab name="shirt_main_tab" title="襯衫"/> + </accordion> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_shoes.xml b/indra/newview/skins/default/xui/zh/panel_edit_shoes.xml new file mode 100644 index 0000000000..d1ba9625f1 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_edit_shoes.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="edit_shoes_panel"> + <panel name="avatar_shoes_color_panel"> + <texture_picker label="Texture" name="Fabric" tool_tip="點擊以挑é¸åœ–片"/> + <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open color picker"/> + </panel> + <panel name="accordion_panel"> + <accordion name="wearable_accordion"> + <accordion_tab name="shoes_main_tab" title="éž‹å"/> + </accordion> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_skin.xml b/indra/newview/skins/default/xui/zh/panel_edit_skin.xml new file mode 100644 index 0000000000..22f0279060 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_edit_skin.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="edit_skin_panel"> + <panel name="avatar_skin_color_panel"> + <texture_picker label="Head Tattoos" name="Head Tattoos" tool_tip="點擊以挑é¸åœ–片"/> + <texture_picker label="Upper Tattoos" name="Upper Tattoos" tool_tip="點擊以挑é¸åœ–片"/> + <texture_picker label="Lower Tattoos" name="Lower Tattoos" tool_tip="點擊以挑é¸åœ–片"/> + </panel> + <panel name="accordion_panel"> + <accordion name="wearable_accordion"> + <accordion_tab name="skin_color_tab" title="Skin Color"/> + <accordion_tab name="skin_face_tab" title="Face Detail"/> + <accordion_tab name="skin_makeup_tab" title="Makeup"/> + <accordion_tab name="skin_body_tab" title="Body Detail"/> + </accordion> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_skirt.xml b/indra/newview/skins/default/xui/zh/panel_edit_skirt.xml new file mode 100644 index 0000000000..303aa80e11 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_edit_skirt.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="edit_skirt_panel"> + <panel name="avatar_skirt_color_panel"> + <texture_picker label="Texture" name="Fabric" tool_tip="點擊以挑é¸åœ–片"/> + <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open color picker"/> + </panel> + <panel name="accordion_panel"> + <accordion name="wearable_accordion"> + <accordion_tab name="skirt_main_tab" title="裙å"/> + </accordion> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_socks.xml b/indra/newview/skins/default/xui/zh/panel_edit_socks.xml new file mode 100644 index 0000000000..1e61a65788 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_edit_socks.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="edit_socks_panel"> + <panel name="avatar_socks_color_panel"> + <texture_picker label="Texture" name="Fabric" tool_tip="點擊以挑é¸åœ–片"/> + <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open color picker"/> + </panel> + <panel name="accordion_panel"> + <accordion name="wearable_accordion"> + <accordion_tab name="socks_main_tab" title="襪å"/> + </accordion> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml new file mode 100644 index 0000000000..d183e6897d --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="edit_tattoo_panel"> + <panel name="avatar_tattoo_color_panel"> + <texture_picker label="Head Tattoo" name="Head Tattoo" tool_tip="點擊以挑é¸åœ–片"/> + <texture_picker label="Upper Tattoo" name="Upper Tattoo" tool_tip="Click to choose a picture"/> + <texture_picker label="Lower Tattoo" name="Lower Tattoo" tool_tip="點擊以挑é¸åœ–片"/> + <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open color picker"/> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_underpants.xml b/indra/newview/skins/default/xui/zh/panel_edit_underpants.xml new file mode 100644 index 0000000000..47d5db4fca --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_edit_underpants.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="edit_underpants_panel"> + <panel name="avatar_underpants_color_panel"> + <texture_picker label="Texture" name="Fabric" tool_tip="點擊以挑é¸åœ–片"/> + <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open color picker"/> + </panel> + <panel name="accordion_panel"> + <accordion name="wearable_accordion"> + <accordion_tab name="underpants_main_tab" title="內褲"/> + </accordion> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/zh/panel_edit_undershirt.xml new file mode 100644 index 0000000000..cbfdcaae8e --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_edit_undershirt.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="edit_undershirt_panel"> + <panel name="avatar_undershirt_color_panel"> + <texture_picker label="Texture" name="Fabric" tool_tip="點擊以挑é¸åœ–片"/> + <color_swatch label="Color/Tint" name="Color/Tint" tool_tip="Click to open Color Picker"/> + </panel> + <panel name="accordion_panel"> + <accordion name="wearable_accordion"> + <accordion_tab name="undershirt_main_tab" title="內衣"/> + </accordion> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_edit_wearable.xml b/indra/newview/skins/default/xui/zh/panel_edit_wearable.xml new file mode 100644 index 0000000000..d68767d4d2 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_edit_wearable.xml @@ -0,0 +1,120 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Wearable" name="panel_edit_wearable"> + <string name="edit_shape_title"> + Editing Shape + </string> + <string name="edit_skin_title"> + Editing Skin + </string> + <string name="edit_hair_title"> + Editing Hair + </string> + <string name="edit_eyes_title"> + Editing Eyes + </string> + <string name="edit_shirt_title"> + Editing Shirt + </string> + <string name="edit_pants_title"> + Editing Pants + </string> + <string name="edit_shoes_title"> + Editing Shoes + </string> + <string name="edit_socks_title"> + Editing Socks + </string> + <string name="edit_jacket_title"> + Editing Jacket + </string> + <string name="edit_skirt_title"> + Editing Skirt + </string> + <string name="edit_gloves_title"> + Editing Gloves + </string> + <string name="edit_undershirt_title"> + Editing Undershirt + </string> + <string name="edit_underpants_title"> + Editing Underpants + </string> + <string name="edit_alpha_title"> + Editing Alpha Mask + </string> + <string name="edit_tattoo_title"> + Editing Tattoo + </string> + <string name="edit_physics_title"> + Editing Physics + </string> + <string name="shape_desc_text"> + Shape: + </string> + <string name="skin_desc_text"> + Skin: + </string> + <string name="hair_desc_text"> + Hair: + </string> + <string name="eyes_desc_text"> + Eyes: + </string> + <string name="shirt_desc_text"> + 襯衫: + </string> + <string name="pants_desc_text"> + 褲å: + </string> + <string name="shoes_desc_text"> + éž‹å: + </string> + <string name="socks_desc_text"> + 襪å: + </string> + <string name="jacket_desc_text"> + 夾克: + </string> + <string name="skirt_desc_text"> + 裙å: + </string> + <string name="gloves_desc_text"> + 手套: + </string> + <string name="undershirt_desc_text"> + 內衣: + </string> + <string name="underpants_desc_text"> + 內褲: + </string> + <string name="alpha_desc_text"> + Alpha Mask: + </string> + <string name="tattoo_desc_text"> + 刺é’: + </string> + <string name="physics_desc_text"> + Physics: + </string> + <labeled_back_button label="儲å˜" name="back_btn" tool_tip="Return to Edit Outfit"/> + <text name="edit_wearable_title" value="Editing Shape"/> + <panel label="襯衫" name="wearable_type_panel"> + <text name="description_text" value="Shape:"/> + <radio_group name="sex_radio"> + <radio_item label="" name="sex_male" tool_tip="男性" value="1"/> + <radio_item label="" name="sex_female" tool_tip="Female" value="0"/> + </radio_group> + <icon name="male_icon" tool_tip="男性"/> + <icon name="female_icon" tool_tip="Female"/> + </panel> + <panel name="button_panel"> + <layout_stack name="button_panel_ls"> + <layout_panel name="save_as_btn_lp"> + <button label="å¦å˜" name="save_as_button"/> + </layout_panel> + <layout_panel name="revert_btn_lp"> + <button label="復原變更" name="revert_button"/> + </layout_panel> + </layout_stack> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_group_control_panel.xml b/indra/newview/skins/default/xui/zh/panel_group_control_panel.xml new file mode 100644 index 0000000000..9ba578c1a1 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_group_control_panel.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_im_control_panel"> + <layout_stack name="vertical_stack"> + <layout_panel name="group_info_btn_panel"> + <button label="Group Profile" name="group_info_btn"/> + </layout_panel> + <layout_panel name="call_btn_panel"> + <button label="Call Group" name="call_btn"/> + </layout_panel> + <layout_panel name="end_call_btn_panel"> + <button label="Leave Call" name="end_call_btn"/> + </layout_panel> + <layout_panel name="voice_ctrls_btn_panel"> + <button label="Open Voice Controls" name="voice_ctrls_btn"/> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_group_general.xml b/indra/newview/skins/default/xui/zh/panel_group_general.xml new file mode 100644 index 0000000000..c65b139cb5 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_group_general.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="一般" name="general_tab"> + <panel.string name="help_text"> + The General tab contains general information about this group, a list of members, general Group Preferences and member options. + +Hover your mouse over the options for more help. + </panel.string> + <panel.string name="group_info_unchanged"> + General group information has changed + </panel.string> + <panel.string name="incomplete_member_data_str"> + Retrieving member data + </panel.string> + <panel name="group_info_top"> + <texture_picker label="" name="insignia" tool_tip="點擊以挑é¸åœ–片"/> + <text name="prepend_founded_by"> + 創辦人: + </text> + <text name="join_cost_text"> + Free + </text> + <button label="ç¾åœ¨å°±åŠ å…¥!!" name="btn_join"/> + </panel> + <text_editor name="charter"> + Group Charter + </text_editor> + <name_list name="visible_members"> + <name_list.columns label="Member" name="name"/> + <name_list.columns label="Title" name="title"/> + <name_list.columns label="Status" name="status"/> + </name_list> + <text name="my_group_settngs_label"> + 自己 + </text> + <text name="active_title_label"> + My title: + </text> + <combo_box name="active_title" tool_tip="Sets the title that appears in your avatar's name tag when this group is active."/> + <check_box label="Receive group notices" name="receive_notices" tool_tip="Sets whether you want to receive Notices from this group. Uncheck this box if this group is spamming you."/> + <check_box label="Show in my profile" name="list_groups_in_profile" tool_tip="Sets whether you want to show this group in your profile"/> + <panel name="preferences_container"> + <text name="group_settngs_label"> + Group + </text> + <check_box label="Anyone can join" name="open_enrollement" tool_tip="Sets whether this group allows new members to join without being invited."/> + <check_box label="Cost to join" name="check_enrollment_fee" tool_tip="Sets whether to require an enrollment fee to join the group"/> + <spinner label="L$" name="spin_enrollment_fee" tool_tip="New members must pay this fee to join the group when Enrollment Fee is checked."/> + <combo_box name="group_mature_check" tool_tip="Sets whether your group contains information rated as Moderate"> + <combo_item name="select_mature"> + - Select maturity rating - + </combo_item> + <combo_box.item label="Moderate Content" name="mature"/> + <combo_box.item label="General Content" name="pg"/> + </combo_box> + <check_box initial_value="true" label="Show in search" name="show_in_group_list" tool_tip="Let people see this group in search results"/> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/zh/panel_group_info_sidetray.xml new file mode 100644 index 0000000000..90797e1473 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_group_info_sidetray.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Group Profile" name="GroupInfo"> + <panel.string name="default_needs_apply_text"> + There are unsaved changes + </panel.string> + <panel.string name="want_apply_text"> + Do you want to save these changes? + </panel.string> + <panel.string name="group_join_btn"> + Join (L$[AMOUNT]) + </panel.string> + <panel.string name="group_join_free"> + Free + </panel.string> + <panel name="group_info_top"> + <text_editor name="group_name" value="(載入ä¸...)"/> + <line_editor label="Type your new group name here" name="group_name_editor"/> + </panel> + <layout_stack name="layout"> + <layout_panel name="group_accordions"> + <accordion name="groups_accordion"> + <accordion_tab name="group_general_tab" title="一般"/> + <accordion_tab name="group_roles_tab" title="Roles"/> + <accordion_tab name="group_notices_tab" title="Notices"/> + <accordion_tab name="group_land_tab" title="Land/Assets"/> + </accordion> + </layout_panel> + </layout_stack> + <layout_stack name="button_row_ls"> + <layout_panel name="btn_chat_lp"> + <button label="èŠå¤©" name="btn_chat"/> + </layout_panel> + <layout_panel name="call_btn_lp"> + <button label="Group Call" name="btn_call" tool_tip="Call this group"/> + </layout_panel> + <layout_panel name="btn_apply_lp"> + <button label="儲å˜" label_selected="儲å˜" name="btn_apply"/> + <button label="Create Group" name="btn_create" tool_tip="Create a new Group"/> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_group_invite.xml b/indra/newview/skins/default/xui/zh/panel_group_invite.xml new file mode 100644 index 0000000000..576760f747 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_group_invite.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Invite a Member" name="invite_panel"> + <panel.string name="confirm_invite_owner_str"> + Are you sure you want to invite new owner(s)? This action is permanent! + </panel.string> + <panel.string name="loading"> + (載入ä¸...) + </panel.string> + <panel.string name="already_in_group"> + Some Residents you chose are already in the group, and so were not sent an invitation. + </panel.string> + <text name="help_text"> + You can select multiple Residents to invite to your group. Click 'Open Resident Chooser' to start. + </text> + <button label="Open Resident Chooser" name="add_button"/> + <name_list name="invitee_list" tool_tip="Hold the Ctrl key and click Resident names to multi-select"/> + <button label="Remove Selected from List" name="remove_button" tool_tip="Removes the Residents selected above from the invite list"/> + <text name="role_text"> + Choose what Role to assign them to: + </text> + <combo_box name="role_name" tool_tip="Choose from the list of Roles you are allowed to assign members to"/> + <button label="Send Invitations" name="ok_button"/> + <button label="å–銷" name="cancel_button"/> + <string name="GroupInvitation"> + Group Invitation + </string> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_group_land_money.xml b/indra/newview/skins/default/xui/zh/panel_group_land_money.xml new file mode 100644 index 0000000000..08a5e711d1 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_group_land_money.xml @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Land & L$" name="land_money_tab"> + <panel.string name="help_text"> + A warning appears until the Total Land in Use is less than or = to the Total Contribution. + </panel.string> + <panel.string name="cant_view_group_land_text"> + You don't have permission to view group owned land + </panel.string> + <panel.string name="epmty_view_group_land_text"> + No entries + </panel.string> + <panel.string name="cant_view_group_accounting_text"> + You don't have permission to view the group's accounting information. + </panel.string> + <panel.string name="loading_txt"> + 載入ä¸... + </panel.string> + <panel.string name="land_contrib_error"> + Unable to set your land contribution + </panel.string> + <panel name="layout_panel_landmoney"> + <scroll_list name="group_parcel_list"> + <scroll_list.columns label="地段" name="name"/> + <scroll_list.columns label="地å€" name="location"/> + <scroll_list.columns label="Type" name="type"/> + <scroll_list.columns label="Area" name="area"/> + <scroll_list.columns label="Hidden" name="hidden"/> + </scroll_list> + <text name="total_contributed_land_label"> + Total contribution: + </text> + <text name="total_contributed_land_value"> + [AREA] m² + </text> + <button label="地圖" label_selected="地圖" name="map_button"/> + <text name="total_land_in_use_label"> + Total land in use: + </text> + <text name="total_land_in_use_value"> + [AREA] m² + </text> + <text name="land_available_label"> + Land available: + </text> + <text name="land_available_value"> + [AREA] m² + </text> + <text name="your_contribution_label"> + Your contribution: + </text> + <text name="your_contribution_units"> + m² + </text> + <text name="your_contribution_max_value"> + ([AMOUNT] max) + </text> + <text name="group_over_limit_text"> + More land credits are needed to support land in use + </text> + <text name="group_money_heading"> + Group L$ + </text> + </panel> + <tab_container name="group_money_tab_container"> + <panel label="PLANNING" name="group_money_planning_tab"> + <text_editor name="group_money_planning_text"> + 載入ä¸... + </text_editor> + </panel> + <panel label="DETAILS" name="group_money_details_tab"> + <text_editor name="group_money_details_text"> + 載入ä¸... + </text_editor> + <button name="earlier_details_button" tool_tip="Back"/> + <button name="later_details_button" tool_tip="Next"/> + </panel> + <panel label="SALES" name="group_money_sales_tab"> + <text_editor name="group_money_sales_text"> + 載入ä¸... + </text_editor> + <button name="earlier_sales_button" tool_tip="Back"/> + <button name="later_sales_button" tool_tip="Next"/> + </panel> + </tab_container> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_group_list_item.xml b/indra/newview/skins/default/xui/zh/panel_group_list_item.xml new file mode 100644 index 0000000000..147c4859c6 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_group_list_item.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="group_list_item"> + <text name="group_name" value="未知"/> + <button name="profile_btn" tool_tip="View profile"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_group_notices.xml b/indra/newview/skins/default/xui/zh/panel_group_notices.xml new file mode 100644 index 0000000000..a007c86063 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_group_notices.xml @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Notices" name="notices_tab"> + <panel.string name="help_text"> + Notices let you send a message and an optionally attached item. +Notices only go to group members in Roles with the ability to receive Notices. +You can turn off Notices on the General tab. + </panel.string> + <panel.string name="no_notices_text"> + There are no past notices + </panel.string> + <text name="lbl2"> + Notices are kept for 14 days. +Maximum 200 per group daily + </text> + <scroll_list name="notice_list"> + <scroll_list.columns label="Subject" name="subject"/> + <scroll_list.columns label="From" name="from"/> + <scroll_list.columns label="Date" name="date"/> + </scroll_list> + <text name="notice_list_none_found"> + None found + </text> + <button label="New Notice" name="create_new_notice" tool_tip="Create a new notice"/> + <button name="refresh_notices" tool_tip="Refresh list of notices"/> + <panel label="Create New Notice" name="panel_create_new_notice"> + <text name="lbl"> + Create a Notice + </text> + <text name="lbl3"> + 主旨: + </text> + <text name="lbl4"> + 訊æ¯ï¼š + </text> + <text name="lbl5"> + 附件: + </text> + <text name="string"> + Drag and drop item here to attach it: + </text> + <button label="Inventory" name="open_inventory" tool_tip="Open Inventory"/> + <button name="remove_attachment" tool_tip="Remove attachment from your notification"/> + <button label="Send" label_selected="Send" name="send_notice"/> + <group_drop_target name="drop_target" tool_tip="Drag an inventory item onto this target box to send it with this notice. You must have permission to copy and transfer the item in order to attach it."/> + </panel> + <panel label="View Past Notice" name="panel_view_past_notice"> + <text name="lbl"> + Archived Notice + </text> + <text name="lbl2"> + To send a new notice, click the + button + </text> + <text name="lbl3"> + Subject: + </text> + <text name="lbl4"> + Message: + </text> + <button label="Open Attachment" name="open_attachment"/> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_group_notify.xml b/indra/newview/skins/default/xui/zh/panel_group_notify.xml new file mode 100644 index 0000000000..803f34d5a7 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_group_notify.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="instant_message" name="panel_group_notify"> + <string name="message_max_lines_count" value="7"/> + <string name="subject_font" value="SANSSERIF_BIG"/> + <string name="date_font" value="SANSSERIF"/> + <panel label="header" name="header"> + <text name="title" value="Sender Name / Group Name"/> + </panel> + <text_editor name="message" value="message"/> + <text name="attachment" value="Attachment"/> + <button label="確定" name="btn_ok"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_group_roles.xml b/indra/newview/skins/default/xui/zh/panel_group_roles.xml new file mode 100644 index 0000000000..2b15f4813a --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_group_roles.xml @@ -0,0 +1,95 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Members & Roles" name="roles_tab"> + <panel.string name="default_needs_apply_text"> + There are unsaved changes + </panel.string> + <panel.string name="want_apply_text"> + Do you want to save your changes? + </panel.string> + <tab_container name="roles_tab_container"> + <panel label="MEMBERS" name="members_sub_tab" tool_tip="Members"> + <panel.string name="help_text"> + You can add or remove Roles assigned to Members. +Select multiple Members by holding the Ctrl key and +clicking on their names. + </panel.string> + <panel.string name="donation_area"> + [AREA] m² + </panel.string> + <filter_editor label="Filter Members" name="filter_input"/> + <name_list name="member_list"> + <name_list.columns label="Member" name="name"/> + <name_list.columns label="Donation" name="donated"/> + <name_list.columns label="Status" name="online"/> + </name_list> + <button label="Invite" name="member_invite"/> + <button label="Eject" name="member_eject"/> + </panel> + <panel label="ROLES" name="roles_sub_tab"> + <panel.string name="help_text"> + Roles have a title and an allowed list of Abilities +that Members can perform. Members can belong to +one or more Roles. A group can have up to 10 Roles, +including the Everyone and Owner Roles. + </panel.string> + <panel.string name="cant_delete_role"> + The 'Everyone' and 'Owners' Roles are special and can't be deleted. + </panel.string> + <filter_editor label="Filter Roles" name="filter_input"/> + <scroll_list name="role_list"> + <scroll_list.columns label="Role" name="name"/> + <scroll_list.columns label="Title" name="title"/> + <scroll_list.columns label="#" name="members"/> + </scroll_list> + <button label="New Role" name="role_create"/> + <button label="Delete Role" name="role_delete"/> + </panel> + <panel label="ABILITIES" name="actions_sub_tab" tool_tip="You can view an Ability's Description and which Roles and Members can execute the Ability."> + <panel.string name="help_text"> + Abilities allow Members in Roles to do specific +things in this group. There's a broad variety of Abilities. + </panel.string> + <filter_editor label="Filter Abilities" name="filter_input"/> + <scroll_list name="action_list" tool_tip="Select an Ability to view more details"/> + </panel> + </tab_container> + <panel name="members_footer"> + <text name="static"> + Assigned Roles + </text> + <text name="static2"> + Allowed Abilities + </text> + <scroll_list name="member_allowed_actions" tool_tip="For details of each allowed ability see the abilities tab"/> + </panel> + <panel name="roles_footer"> + <text name="static"> + Role Name + </text> + <text name="static3"> + Role Title + </text> + <text name="static2"> + Description + </text> + <text name="static4"> + Assigned Members + </text> + <check_box label="Reveal members" name="role_visible_in_list" tool_tip="Sets whether members of this role are visible in the General tab to people outside of the group."/> + <text name="static5"> + Allowed Abilities + </text> + <scroll_list name="role_allowed_actions" tool_tip="For details of each allowed ability see the abilities tab"/> + </panel> + <panel name="actions_footer"> + <text_editor name="action_description"> + This Ability is 'Eject Members from this Group'. Only an Owner can eject another Owner. + </text_editor> + <text name="static2"> + Roles with this ability + </text> + <text name="static3"> + Members with this ability + </text> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_im_control_panel.xml b/indra/newview/skins/default/xui/zh/panel_im_control_panel.xml new file mode 100644 index 0000000000..8fdecad420 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_im_control_panel.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_im_control_panel"> + <layout_stack name="button_stack"> + <layout_panel name="view_profile_btn_panel"> + <button label="Profile" name="view_profile_btn"/> + </layout_panel> + <layout_panel name="add_friend_btn_panel"> + <button label="åŠ ç‚ºæœ‹å‹" name="add_friend_btn"/> + </layout_panel> + <layout_panel name="teleport_btn_panel"> + <button label="Teleport" name="teleport_btn" tool_tip="Offer to teleport this person"/> + </layout_panel> + <layout_panel name="share_btn_panel"> + <button label="分享" name="share_btn"/> + </layout_panel> + <layout_panel name="pay_btn_panel"> + <button label="Pay" name="pay_btn"/> + </layout_panel> + <layout_panel name="call_btn_panel"> + <button label="Call" name="call_btn"/> + </layout_panel> + <layout_panel name="end_call_btn_panel"> + <button label="End Call" name="end_call_btn"/> + </layout_panel> + <layout_panel name="voice_ctrls_btn_panel"> + <button label="Voice Controls" name="voice_ctrls_btn"/> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_instant_message.xml b/indra/newview/skins/default/xui/zh/panel_instant_message.xml new file mode 100644 index 0000000000..cf9bc7fccb --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_instant_message.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="im_panel" name="im_panel"> + <string name="message_max_lines_count"> + 6 + </string> + <panel label="im_header" name="im_header"> + <text name="time_box" value="23:30"/> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_inventory_item.xml b/indra/newview/skins/default/xui/zh/panel_inventory_item.xml new file mode 100644 index 0000000000..d18047fbcf --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_inventory_item.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="inventory_item"> + <text name="item_name" value="..."/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_landmark_info.xml b/indra/newview/skins/default/xui/zh/panel_landmark_info.xml new file mode 100644 index 0000000000..16119f9e2c --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_landmark_info.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="landmark_info"> + <string name="title_create_landmark" value="Create Landmark"/> + <string name="title_edit_landmark" value="Edit Landmark"/> + <string name="title_landmark" value="Landmark"/> + <string name="not_available" value="(N\A)"/> + <string name="unknown" value="(未知)"/> + <string name="public" value="(公開)"/> + <string name="server_update_text"> + Place information not available without server update. + </string> + <string name="server_error_text"> + Information about this location is unavailable at this time, please try again later. + </string> + <string name="server_forbidden_text"> + Information about this location is unavailable due to access restrictions. Please check your permissions with the parcel owner. + </string> + <string name="acquired_date"> + [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] + </string> + <button name="back_btn" tool_tip="Back"/> + <text name="title" value="Place Profile"/> + <scroll_container name="place_scroll"> + <panel name="scrolling_panel"> + <text name="region_title" value="SampleRegion"/> + <text name="parcel_title" value="SampleParcel, Name Long (145, 228, 26)"/> + <expandable_text name="description" value="Du waltz die spritz"/> + <text name="maturity_value" value="未知"/> + <panel name="landmark_info_panel"> + <text name="owner_label" value="æ“有者:"/> + <text name="creator_label" value="å‰µé€ è€…ï¼š"/> + <text name="created_label" value="Created:"/> + </panel> + <panel name="landmark_edit_panel"> + <text name="title_label" value="Title:"/> + <text name="notes_label" value="My notes:"/> + <text name="folder_label" value="Landmark location:"/> + </panel> + </panel> + </scroll_container> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_landmarks.xml b/indra/newview/skins/default/xui/zh/panel_landmarks.xml new file mode 100644 index 0000000000..45f8edc355 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_landmarks.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="Landmarks"> + <accordion name="landmarks_accordion"> + <accordion_tab name="tab_favorites" title="Favorites bar"/> + <accordion_tab name="tab_landmarks" title="My Landmarks"/> + <accordion_tab name="tab_inventory" title="My Inventory"/> + <accordion_tab name="tab_library" title="Library"/> + </accordion> + <panel name="bottom_panel"> + <layout_stack name="bottom_panel"> + <layout_panel name="options_gear_btn_panel"> + <menu_button name="options_gear_btn" tool_tip="Show additional options"/> + </layout_panel> + <layout_panel name="add_btn_panel"> + <button name="add_btn" tool_tip="Add new landmark"/> + </layout_panel> + <layout_panel name="trash_btn_panel"> + <dnd_button name="trash_btn" tool_tip="Remove selected landmark"/> + </layout_panel> + </layout_stack> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_login.xml b/indra/newview/skins/default/xui/zh/panel_login.xml index 9d094ff731..b227fbcfc8 100644 --- a/indra/newview/skins/default/xui/zh/panel_login.xml +++ b/indra/newview/skins/default/xui/zh/panel_login.xml @@ -1,29 +1,36 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="panel_login"> +<panel name="panel_login"> + <panel.string name="create_account_url"> + http://join.secondlife.com/ + </panel.string> + <panel.string name="forgot_password_url"> + http://secondlife.com/account/request.php + </panel.string> <layout_stack name="login_widgets"> <layout_panel name="login"> <text name="username_text"> 使用者å稱: - </text> + </text> + <combo_box name="username_combo" tool_tip="使用者åç¨±æ˜¯ä½ è¨»å†Šæ™‚æ‰€æŒ‘é¸çš„,åƒæ˜¯ bobsmith12 或 Steller Sunshine"/> <text name="password_text"> 密碼: </text> - <check_box label="記ä½å¯†ç¢¼" name="remember_check"/> + <check_box label="記ä½å¯†ç¢¼ï¼š" name="remember_check"/> <button label="登入" name="connect_btn"/> <text name="mode_selection_text"> 模å¼ï¼š </text> - <combo_box name="mode_combo" tool_tip="é¸æ“‡ä¸€å€‹ç™»å…¥æ¨¡å¼"> - <combo_box.item label="基礎" name="Basic"/> + <combo_box name="mode_combo" tool_tip="è«‹é¸æ“‡ä½ 的模å¼ã€‚é¸ç”¨åŸºæœ¬æ¨¡å¼å¯ä»¥å¿«é€Ÿã€ç°¡å–®åœ°æŽ¢ç´¢èˆ‡èŠå¤©ï¼›é¸ç”¨é€²éšŽæ¨¡å¼å‰‡å¯ä»¥ä½¿ç”¨æ›´å¤šåŠŸèƒ½ã€‚"> + <combo_box.item label="基本" name="Basic"/> <combo_box.item label="進階" name="Advanced"/> </combo_box> <text name="start_location_text"> 開始地點: </text> <combo_box name="start_location_combo"> - <combo_box.item label="上一次的地點" name="MyLastLocation"/> + <combo_box.item label="我上一次ä½ç½®" name="MyLastLocation"/> <combo_box.item label="我的家" name="MyHome"/> - <combo_box.item label="<輸入å€åŸŸå>" name="Typeregionname"/> + <combo_box.item label="< 請輸入地å€å稱 >" name="Typeregionname"/> </combo_box> </layout_panel> <layout_panel name="links"> @@ -31,10 +38,10 @@ 註冊 </text> <text name="forgot_password_text"> - 忘記使用者å稱或密碼? + å¿˜è¨˜ä½ çš„ä½¿ç”¨è€…å稱或密碼? </text> <text name="login_help"> - 如何登入? + 登入時需è¦å¹«åŠ©ï¼Ÿ </text> </layout_panel> </layout_stack> diff --git a/indra/newview/skins/default/xui/zh/panel_main_inventory.xml b/indra/newview/skins/default/xui/zh/panel_main_inventory.xml new file mode 100644 index 0000000000..2533b90203 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_main_inventory.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Things" name="main inventory panel"> + <panel.string name="ItemcountFetching"> + Fetching [ITEM_COUNT] Items... [FILTER] + </panel.string> + <panel.string name="ItemcountCompleted"> + [ITEM_COUNT] Items [FILTER] + </panel.string> + <text name="ItemcountText"> + Items: + </text> + <filter_editor label="Filter Inventory" name="inventory search editor"/> + <tab_container name="inventory filter tabs"> + <inventory_panel label="MY INVENTORY" name="All Items"/> + <recent_inventory_panel label="RECENT" name="Recent Items"/> + </tab_container> + <layout_stack name="bottom_panel"> + <layout_panel name="options_gear_btn_panel"> + <menu_button name="options_gear_btn" tool_tip="Show additional options"/> + </layout_panel> + <layout_panel name="add_btn_panel"> + <button name="add_btn" tool_tip="Add new item"/> + </layout_panel> + <layout_panel name="trash_btn_panel"> + <dnd_button name="trash_btn" tool_tip="Remove selected item"/> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_me.xml b/indra/newview/skins/default/xui/zh/panel_me.xml new file mode 100644 index 0000000000..7a176a92c6 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_me.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="My Profile" name="panel_me"> + <tab_container name="tabs"> + <panel label="MY PROFILE" name="panel_profile"/> + <panel label="MY PICKS" name="panel_picks"/> + </tab_container> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_media_settings_general.xml b/indra/newview/skins/default/xui/zh/panel_media_settings_general.xml new file mode 100644 index 0000000000..9e72dc9daf --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_media_settings_general.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="一般" name="Media Settings General"> + <text name="home_label"> + 首é : + </text> + <text name="home_fails_whitelist_label"> + (This page does not pass the specified whitelist) + </text> + <line_editor name="home_url" tool_tip="The home page for this media source"/> + <text name="preview_label"> + é 覽 + </text> + <text name="current_url_label"> + Current Page: + </text> + <text name="current_url" tool_tip="The current page for this media source" value=""/> + <button label="Reset" name="current_url_reset_btn"/> + <check_box initial_value="false" label="Auto Loop" name="auto_loop"/> + <check_box initial_value="false" label="First Click Interacts" name="first_click_interact"/> + <check_box initial_value="false" label="Auto Zoom" name="auto_zoom"/> + <check_box initial_value="false" label="Auto Play Media" name="auto_play"/> + <text name="media_setting_note"> + Note: Residents can override this setting + </text> + <check_box initial_value="false" label="Auto Scale Media on Face of Object" name="auto_scale"/> + <text name="size_label"> + Size: + </text> + <text name="X_label"> + X + </text> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_media_settings_permissions.xml b/indra/newview/skins/default/xui/zh/panel_media_settings_permissions.xml new file mode 100644 index 0000000000..b682ffda7d --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_media_settings_permissions.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="自訂" name="Media settings for controls"> + <text name="controls_label"> + Controls: + </text> + <combo_box name="controls"> + <combo_item name="Standard"> + Standard + </combo_item> + <combo_item name="Mini"> + Mini + </combo_item> + </combo_box> + <text name="owner_label"> + Owner + </text> + <check_box initial_value="false" label="Allow Navigation & Interactivity" name="perms_owner_interact"/> + <check_box initial_value="false" label="Show Control Bar" name="perms_owner_control"/> + <text name="group_label"> + Group: + </text> + <check_box initial_value="false" label="Allow Navigation & Interactivity" name="perms_group_interact"/> + <check_box initial_value="false" label="Show Control Bar" name="perms_group_control"/> + <text name="anyone_label"> + Anyone + </text> + <check_box initial_value="false" label="Allow Navigation & Interactivity" name="perms_anyone_interact"/> + <check_box initial_value="false" label="Show Control Bar" name="perms_anyone_control"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_media_settings_security.xml b/indra/newview/skins/default/xui/zh/panel_media_settings_security.xml new file mode 100644 index 0000000000..ef56c34b5c --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_media_settings_security.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Security" name="Media Settings Security"> + <check_box initial_value="false" label="Only Allow Access to Specified URL patterns" name="whitelist_enable"/> + <text name="home_url_fails_some_items_in_whitelist"> + Entries that the home page fails against are marked: + </text> + <button label="Add" name="whitelist_add"/> + <button label="刪除" name="whitelist_del"/> + <text name="home_url_fails_whitelist"> + Warning: the home page specified in the General tab fails to pass this whitelist. It has been disabled until a valid entry has been added. + </text> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_my_profile.xml b/indra/newview/skins/default/xui/zh/panel_my_profile.xml new file mode 100644 index 0000000000..f36608efb5 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_my_profile.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Profile" name="panel_profile"> + <string name="CaptionTextAcctInfo"> + [ACCTTYPE] +[PAYMENTINFO] [AGEVERIFICATION] + </string> + <string name="payment_update_link_url"> + http://www.secondlife.com/account/billing.php?lang=en + </string> + <string name="partner_edit_link_url"> + http://www.secondlife.com/account/partners.php?lang=en + </string> + <string name="my_account_link_url" value="http://secondlife.com/account"/> + <string name="no_partner_text" value="ç„¡"/> + <string name="no_group_text" value="ç„¡"/> + <string name="RegisterDateFormat"> + [REG_DATE] ([AGE]) + </string> + <string name="name_text_args"> + [NAME] + </string> + <string name="display_name_text_args"> + [DISPLAY_NAME] + </string> + <layout_stack name="layout"> + <layout_panel name="profile_stack"> + <scroll_container name="profile_scroll"> + <panel name="scroll_content_panel"> + <panel name="second_life_image_panel"> + <text name="display_name_descr_text"> + User name + </text> + <text name="name_descr_text"> + Display Name + </text> + <button label="Profile" name="see_profile_btn" tool_tip="See profile for this avatar"/> + </panel> + </panel> + </scroll_container> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_navigation_bar.xml b/indra/newview/skins/default/xui/zh/panel_navigation_bar.xml new file mode 100644 index 0000000000..c4bcf605e3 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_navigation_bar.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="navigation_bar"> + <panel name="navigation_panel"> + <pull_button name="back_btn" tool_tip="Go back to previous location"/> + <pull_button name="forward_btn" tool_tip="Go forward one location"/> + <button name="home_btn" tool_tip="Teleport to my home location"/> + <location_input label="Location" name="location_combo"/> + <search_combo_box label="Search" name="search_combo_box" tool_tip="Search"> + <combo_editor label="Search [SECOND_LIFE]" name="search_combo_editor"/> + </search_combo_box> + </panel> + <favorites_bar name="favorite" tool_tip="Drag Landmarks here for quick access to your favorite places in Second Life!"> + <label name="favorites_bar_label" tool_tip="Drag Landmarks here for quick access to your favorite places in Second Life!"> + Favorites Bar + </label> + <chevron_button name=">>" tool_tip="Show more of My Favorites"/> + </favorites_bar> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml new file mode 100644 index 0000000000..724cd54bf1 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="chat_bar"> + <line_editor label="點擊æ¤è™•é–‹å§‹èŠå¤©ã€‚" name="chat_box" tool_tip="Press Enter to say, Ctrl+Enter to shout"/> + <button name="show_nearby_chat" tool_tip="顯示 / éš±è— é™„è¿‘èŠå¤©ç´€éŒ„"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_nearby_media.xml b/indra/newview/skins/default/xui/zh/panel_nearby_media.xml new file mode 100644 index 0000000000..0b8a7a5f42 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_nearby_media.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="nearby_media"> + <string name="media_item_count_format"> + (%ld media items) + </string> + <string name="empty_item_text"> + <empty> + </string> + <string name="parcel_media_name"> + 地段串æµåª’é«” + </string> + <string name="parcel_audio_name"> + 地段串æµéŸ³æ¨‚ + </string> + <string name="playing_suffix"> + (æ’放ä¸ï¼‰ + </string> + <panel name="minimized_controls"> + <button label="全部åœæ¢" name="all_nearby_media_disable_btn" tool_tip="關閉附近全部的媒體"/> + <button label="全部開始" name="all_nearby_media_enable_btn" tool_tip="開啟附近全部的媒體"/> + <button name="open_prefs_btn" tool_tip="Bring up media prefs"/> + <button label="更多 >>" label_selected="<< æ›´å°‘" name="more_btn" tool_tip="進階控制"/> + </panel> + <panel name="nearby_media_panel"> + <text name="nearby_media_title"> + 附近媒體 + </text> + <text name="show_text"> + 顯示: + </text> + <combo_box name="show_combo"> + <combo_box.item label="全部" name="All"/> + <combo_box.item label="In this Parcel" name="WithinParcel"/> + <combo_box.item label="Outside this Parcel" name="OutsideParcel"/> + <combo_box.item label="On other Avatars" name="OnOthers"/> + </combo_box> + <scroll_list name="media_list"> + <scroll_list.columns label="Proximity" name="media_proximity"/> + <scroll_list.columns label="Visible" name="media_visibility"/> + <scroll_list.columns label="Class" name="media_class"/> + <scroll_list.columns label="å稱" name="media_name"/> + <scroll_list.columns label="除錯" name="media_debug"/> + </scroll_list> + <panel name="media_controls_panel"> + <layout_stack name="media_controls"> + <layout_panel name="stop"> + <button name="stop_btn" tool_tip="Stop selected media"/> + </layout_panel> + <layout_panel name="play"> + <button name="play_btn" tool_tip="Play selected media"/> + </layout_panel> + <layout_panel name="pause"> + <button name="pause_btn" tool_tip="Pause selected media"/> + </layout_panel> + <layout_panel name="volume_slider_ctrl"> + <slider_bar initial_value="0.5" name="volume_slider" tool_tip="Audio volume for selected media"/> + </layout_panel> + <layout_panel name="mute"> + <button name="mute_btn" tool_tip="Mute audio on selected media"/> + </layout_panel> + <layout_panel name="zoom"> + <button name="zoom_btn" tool_tip="Zoom into selected media"/> + </layout_panel> + <layout_panel name="unzoom"> + <button name="unzoom_btn" tool_tip="Zoom back from selected media"/> + </layout_panel> + </layout_stack> + </panel> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_notes.xml b/indra/newview/skins/default/xui/zh/panel_notes.xml new file mode 100644 index 0000000000..12182b521e --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_notes.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Notes & Privacy" name="panel_notes"> + <layout_stack name="layout"> + <layout_panel name="notes_stack"> + <scroll_container name="profile_scroll"> + <panel name="profile_scroll_panel"> + <text name="status_message" value="My private notes:"/> + <text name="status_message2" value="Allow this person to:"/> + <check_box label="See my online status" name="status_check"/> + <check_box label="See me on the map" name="map_check"/> + <check_box label="Edit, delete or take my objects" name="objects_check"/> + </panel> + </scroll_container> + </layout_panel> + <layout_panel name="notes_buttons_panel"> + <layout_stack name="bottom_bar_ls"> + <layout_panel name="add_friend_btn_lp"> + <button label="åŠ ç‚ºæœ‹å‹" name="add_friend" tool_tip="Offer friendship to the Resident"/> + </layout_panel> + <layout_panel name="im_btn_lp"> + <button label="IM" name="im" tool_tip="Open instant message session"/> + </layout_panel> + <layout_panel name="call_btn_lp"> + <button label="Call" name="call" tool_tip="Call this Resident"/> + </layout_panel> + <layout_panel name="show_on_map_btn_lp"> + <button label="地圖" name="show_on_map_btn" tool_tip="Show the Resident on the map"/> + </layout_panel> + <layout_panel name="teleport_btn_lp"> + <button label="Teleport" name="teleport" tool_tip="Offer teleport"/> + </layout_panel> + </layout_stack> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_notify_textbox.xml b/indra/newview/skins/default/xui/zh/panel_notify_textbox.xml new file mode 100644 index 0000000000..bdbc89f71c --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_notify_textbox.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="instant_message" name="panel_notify_textbox"> + <string name="message_max_lines_count" value="7"/> + <panel label="info_panel" name="info_panel"> + <text_editor name="message" value="message"/> + </panel> + <panel label="control_panel" name="control_panel"> + <button label="Submit" name="btn_submit"/> + <button label="忽視" name="ignore_btn"/> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_online_status_toast.xml b/indra/newview/skins/default/xui/zh/panel_online_status_toast.xml new file mode 100644 index 0000000000..fdc489f375 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_online_status_toast.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="friend_online_status" name="friend_online_status"/> diff --git a/indra/newview/skins/default/xui/zh/panel_outfit_edit.xml b/indra/newview/skins/default/xui/zh/panel_outfit_edit.xml new file mode 100644 index 0000000000..97e423b8cc --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_outfit_edit.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<!-- Side tray Outfit Edit panel --> +<panel name="outfit_edit"> + <string name="No Outfit" value="No Outfit"/> + <string name="unsaved_changes" value="Unsaved Changes"/> + <string name="now_editing" value="Now Editing"/> + <panel.string name="not_available"> + (N\A) + </panel.string> + <panel.string name="unknown"> + (未知) + </panel.string> + <string name="Filter.All" value="全部"/> + <string name="Filter.Clothes/Body" value="Clothes/Body"/> + <string name="Filter.Objects" value="Objects"/> + <string name="Filter.Clothing" value="Clothing"/> + <string name="Filter.Bodyparts" value="Body parts"/> + <string name="replace_body_part" value="Click to replace your existing shape"/> + <text name="title" value="Edit Outfit"/> + <panel name="header_panel"> + <panel name="outfit_name_and_status"> + <text name="status" value="Now editing..."/> + <text name="curr_outfit_name" value="[Current Outfit]"/> + </panel> + </panel> + <layout_stack name="im_panels"> + <layout_panel name="outfit_wearables_panel"> + <layout_stack name="filter_panels"> + <layout_panel name="add_button_and_combobox"> + <button label="Add More..." name="show_add_wearables_btn" tool_tip="Open/Close"/> + </layout_panel> + <layout_panel name="filter_panel"> + <filter_editor label="Filter Inventory Wearables" name="look_item_filter"/> + </layout_panel> + </layout_stack> + </layout_panel> + <layout_panel name="add_wearables_panel"> + <button label="Wear Item" name="plus_btn"/> + </layout_panel> + </layout_stack> + <panel name="no_add_wearables_button_bar"> + <button name="shop_btn_1" tool_tip="Visit the SL Marketplace. You can also select something you are wearing, then click here to see more things like it"/> + </panel> + <panel name="add_wearables_button_bar"> + <button name="shop_btn_2" tool_tip="Visit the SL Marketplace. You can also select something you are wearing, then click here to see more things like it"/> + </panel> + <panel name="save_revert_button_bar"> + <layout_stack name="button_bar_ls"> + <layout_panel name="save_btn_lp"> + <button label="儲å˜" name="save_btn"/> + </layout_panel> + <layout_panel name="revert_btn_lp"> + <button label="復原變更" name="revert_btn" tool_tip="Revert to last saved version"/> + </layout_panel> + </layout_stack> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/zh/panel_outfits_inventory.xml new file mode 100644 index 0000000000..486b81e024 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_outfits_inventory.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Things" name="Outfits"> + <panel.string name="wear_outfit_tooltip"> + Wear selected outfit + </panel.string> + <panel.string name="wear_items_tooltip"> + Wear selected items + </panel.string> + <tab_container name="appearance_tabs"> + <panel label="MY OUTFITS" name="outfitslist_tab"/> + <panel label="WEARING" name="cof_tab"/> + </tab_container> + <panel name="bottom_panel"> + <layout_stack name="bottom_panel_ls"> + <layout_panel name="save_btn_lp"> + <button label="å¦å˜" name="save_btn"/> + </layout_panel> + <layout_panel name="wear_btn_lp"> + <button label="Wear" name="wear_btn"/> + </layout_panel> + </layout_stack> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_outfits_inventory_gear_default.xml b/indra/newview/skins/default/xui/zh/panel_outfits_inventory_gear_default.xml new file mode 100644 index 0000000000..af417a79ef --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_outfits_inventory_gear_default.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="menu_gear_default"> + <menu_item_call label="Replace Current Outfit" name="wear"/> + <menu_item_call label="Remove From Current Outfit" name="remove"/> + <menu_item_call label="æ›´å" name="rename"/> + <menu_item_call label="Remove Link" name="remove_link"/> + <menu_item_call label="Delete Outfit" name="delete"/> +</menu> diff --git a/indra/newview/skins/default/xui/zh/panel_outfits_list.xml b/indra/newview/skins/default/xui/zh/panel_outfits_list.xml new file mode 100644 index 0000000000..36770c52c7 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_outfits_list.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="Outfits"> + <panel name="bottom_panel"> + <menu_button name="options_gear_btn" tool_tip="Show additional options"/> + <button name="trash_btn" tool_tip="Delete selected outfit"/> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/zh/panel_outfits_wearing.xml new file mode 100644 index 0000000000..39a9bcb848 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_outfits_wearing.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="Wearing"> + <panel name="bottom_panel"> + <menu_button name="options_gear_btn" tool_tip="Show additional options"/> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_people.xml b/indra/newview/skins/default/xui/zh/panel_people.xml new file mode 100644 index 0000000000..49c36614db --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_people.xml @@ -0,0 +1,94 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<!-- Side tray panel --> +<panel label="People" name="people_panel"> + <string name="no_recent_people" value="No recent people. Looking for people to hang out with? Try [secondlife:///app/search/people Search] or the [secondlife:///app/worldmap World Map]."/> + <string name="no_filtered_recent_people" value="Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search]."/> + <string name="no_one_near" value="No one nearby. Looking for people to hang out with? Try [secondlife:///app/search/people Search] or the [secondlife:///app/worldmap World Map]."/> + <string name="no_one_filtered_near" value="Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search]."/> + <string name="no_friends_online" value="No friends online"/> + <string name="no_friends" value="No friends"/> + <string name="no_friends_msg"> + Find friends using [secondlife:///app/search/people Search] or right-click on a Resident to add them as a friend. +Looking for people to hang out with? Try the [secondlife:///app/worldmap World Map]. + </string> + <string name="no_filtered_friends_msg"> + Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search]. + </string> + <string name="people_filter_label" value="Filter People"/> + <string name="groups_filter_label" value="Filter Groups"/> + <string name="no_filtered_groups_msg" value="Didn't find what you're looking for? Try [secondlife:///app/search/groups/[SEARCH_TERM] Search]."/> + <string name="no_groups_msg" value="Looking for Groups to join? Try [secondlife:///app/search/groups Search]."/> + <string name="MiniMapToolTipMsg" value="[REGION](Double-click to open Map, shift-drag to pan)"/> + <string name="AltMiniMapToolTipMsg" value="[REGION](Double-click to teleport, shift-drag to pan)"/> + <filter_editor label="Filter" name="filter_input"/> + <tab_container name="tabs"> + <panel label="NEARBY" name="nearby_panel"> + <panel label="bottom_panel" name="bottom_panel"> + <menu_button name="nearby_view_sort_btn" tool_tip="Options"/> + <button name="add_friend_btn" tool_tip="Add selected Resident to your friends List"/> + </panel> + </panel> + <panel label="MY FRIENDS" name="friends_panel"> + <accordion name="friends_accordion"> + <accordion_tab name="tab_online" title="上線"/> + <accordion_tab name="tab_all" title="全部"/> + </accordion> + <panel label="bottom_panel" name="bottom_panel"> + <layout_stack name="bottom_panel"> + <layout_panel name="options_gear_btn_panel"> + <menu_button name="friends_viewsort_btn" tool_tip="Show additional options"/> + </layout_panel> + <layout_panel name="add_btn_panel"> + <button name="add_btn" tool_tip="Offer friendship to a Resident"/> + </layout_panel> + <layout_panel name="trash_btn_panel"> + <dnd_button name="del_btn" tool_tip="Remove selected person from your Friends list"/> + </layout_panel> + </layout_stack> + </panel> + </panel> + <panel label="MY GROUPS" name="groups_panel"> + <panel label="bottom_panel" name="bottom_panel"> + <menu_button name="groups_viewsort_btn" tool_tip="Options"/> + <button name="plus_btn" tool_tip="Join group/Create new group"/> + <button name="activate_btn" tool_tip="Activate selected group"/> + </panel> + </panel> + <panel label="RECENT" name="recent_panel"> + <panel label="bottom_panel" name="bottom_panel"> + <menu_button name="recent_viewsort_btn" tool_tip="Options"/> + <button name="add_friend_btn" tool_tip="Add selected Resident to your friends List"/> + </panel> + </panel> + </tab_container> + <panel name="button_bar"> + <layout_stack name="bottom_bar_ls"> + <layout_panel name="view_profile_btn_lp"> + <button label="Profile" name="view_profile_btn" tool_tip="Show picture, groups, and other Residents information"/> + </layout_panel> + <layout_panel name="chat_btn_lp"> + <button label="IM" name="im_btn" tool_tip="Open instant message session"/> + </layout_panel> + <layout_panel name="chat_btn_lp"> + <button label="Call" name="call_btn" tool_tip="Call this Resident"/> + </layout_panel> + <layout_panel name="chat_btn_lp"> + <button label="分享" name="share_btn" tool_tip="Share an inventory item"/> + </layout_panel> + <layout_panel name="chat_btn_lp"> + <button label="Teleport" name="teleport_btn" tool_tip="Offer teleport"/> + </layout_panel> + </layout_stack> + <layout_stack name="bottom_bar_ls1"> + <layout_panel name="group_info_btn_lp"> + <button label="Group Profile" name="group_info_btn" tool_tip="Show group information"/> + </layout_panel> + <layout_panel name="chat_btn_lp"> + <button label="Group Chat" name="chat_btn" tool_tip="Open chat session"/> + </layout_panel> + <layout_panel name="group_call_btn_lp"> + <button label="Group Call" name="group_call_btn" tool_tip="Call this group"/> + </layout_panel> + </layout_stack> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_pick_info.xml b/indra/newview/skins/default/xui/zh/panel_pick_info.xml new file mode 100644 index 0000000000..75ecdb99a5 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_pick_info.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_pick_info"> + <text name="title" value="Pick Info"/> + <scroll_container name="profile_scroll"> + <panel name="scroll_content_panel"> + <text_editor name="pick_name" value="[name]"/> + <text_editor name="pick_location" value="[loading...]"/> + <text_editor name="pick_desc" value="[description]"/> + </panel> + </scroll_container> + <panel name="buttons"> + <layout_stack name="layout_stack1"> + <layout_panel name="layout_panel1"> + <button label="Teleport" name="teleport_btn"/> + </layout_panel> + <layout_panel name="show_on_map_btn_lp"> + <button label="地圖" name="show_on_map_btn"/> + </layout_panel> + <layout_panel name="edit_btn_lp"> + <button label="編輯" name="edit_btn"/> + </layout_panel> + </layout_stack> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_picks.xml b/indra/newview/skins/default/xui/zh/panel_picks.xml new file mode 100644 index 0000000000..28a47ed003 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_picks.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Picks" name="panel_picks"> + <string name="no_picks" value="No Picks"/> + <string name="no_classifieds" value="No Classifieds"/> + <accordion name="accordion"> + <accordion_tab name="tab_picks" title="Picks"/> + <accordion_tab name="tab_classifieds" title="Classifieds"/> + </accordion> + <panel label="bottom_panel" name="edit_panel"> + <layout_stack name="edit_panel_ls"> + <layout_panel name="gear_menu_btn"> + <button name="new_btn" tool_tip="Create a new pick or classified at the current location"/> + </layout_panel> + </layout_stack> + </panel> + <panel name="buttons_cucks"> + <layout_stack name="buttons_cucks_ls"> + <layout_panel name="info_btn_lp"> + <button label="資訊" name="info_btn" tool_tip="Show pick information"/> + </layout_panel> + <layout_panel name="teleport_btn_lp"> + <button label="Teleport" name="teleport_btn" tool_tip="Teleport to the corresponding area"/> + </layout_panel> + <layout_panel name="show_on_map_btn_lp"> + <button label="地圖" name="show_on_map_btn" tool_tip="Show the corresponding area on the World Map"/> + </layout_panel> + </layout_stack> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_place_profile.xml b/indra/newview/skins/default/xui/zh/panel_place_profile.xml new file mode 100644 index 0000000000..cef56eb907 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_place_profile.xml @@ -0,0 +1,116 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="place_profile"> + <string name="on" value="On"/> + <string name="off" value="Off"/> + <string name="anyone" value="Anyone"/> + <string name="available" value="available"/> + <string name="allocated" value="allocated"/> + <string name="title_place" value="Place Profile"/> + <string name="title_teleport_history" value="Teleport History"/> + <string name="not_available" value="(N\A)"/> + <string name="unknown" value="(未知)"/> + <string name="public" value="(公開)"/> + <string name="none_text" value="(無)"/> + <string name="sale_pending_text" value="(Sale Pending)"/> + <string name="group_owned_text" value="(Group Owned)"/> + <string name="price_text" value="L$"/> + <string name="area_text" value="m²"/> + <string name="all_residents_text" value="全部居民"/> + <string name="group_text" value="Group"/> + <string name="can_resell"> + Purchased land in this region may be resold. + </string> + <string name="can_not_resell"> + Purchased land in this region may not be resold. + </string> + <string name="can_change"> + Purchased land in this region may be joined or subdivided. + </string> + <string name="can_not_change"> + Purchased land in this region may not be joined or subdivided. + </string> + <string name="server_update_text"> + Place information not available without server update. + </string> + <string name="server_error_text"> + Information about this location is unavailable at this time, please try again later. + </string> + <string name="server_forbidden_text"> + Information about this location is unavailable due to access restrictions. Please check your permissions with the parcel owner. + </string> + <string name="acquired_date"> + [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] + </string> + <button name="back_btn" tool_tip="Back"/> + <text name="title" value="Place Profile"/> + <scroll_container name="place_scroll"> + <panel name="scrolling_panel"> + <text name="region_title" value="SampleRegion"/> + <text name="parcel_title" value="SampleParcel, Name Long (145, 228, 26)"/> + <expandable_text name="description" value="Du waltz die spritz"/> + <text name="owner_label" value="æ“有者:"/> + <text name="owner_value" value="Alex Superduperlongenamenton"/> + <text name="maturity_value" value="未知"/> + <accordion name="advanced_info_accordion"> + <accordion_tab name="parcel_characteristics_tab" title="地段"> + <panel name="parcel_characteristics_panel"> + <text name="rating_label" value="分級:"/> + <text name="rating_value" value="未知"/> + <text name="voice_label" value="Voice:"/> + <text name="voice_value" value="On"/> + <text name="fly_label" value="Fly:"/> + <text name="fly_value" value="On"/> + <text name="push_label" value="Push:"/> + <text name="push_value" value="Off"/> + <text name="build_label" value="Build:"/> + <text name="build_value" value="On"/> + <text name="scripts_label" value="Scripts:"/> + <text name="scripts_value" value="On"/> + <text name="damage_label" value="Damage:"/> + <text name="damage_value" value="Off"/> + <button label="關於土地" name="about_land_btn"/> + </panel> + </accordion_tab> + <accordion_tab name="region_information_tab" title="地å€"> + <panel name="region_information_panel"> + <text name="region_name_label" value="地å€ï¼š"/> + <text name="region_name" value="Mooseland"/> + <text name="region_type_label" value="類型:"/> + <text name="region_type" value="Moose"/> + <text name="region_rating_label" value="分級:"/> + <text name="region_rating" value="Adult"/> + <text name="region_owner_label" value="æ“有者:"/> + <text name="region_owner" value="moose Van Moose extra long name moose"/> + <text name="region_group_label" value="Group:"/> + <text name="region_group"> + The Mighty Moose of mooseville soundvillemoose + </text> + <button label="åœ°å€ / é ˜åœ°" name="region_info_btn"/> + </panel> + </accordion_tab> + <accordion_tab name="estate_information_tab" title="é ˜åœ°"> + <panel name="estate_information_panel"> + <text name="estate_name_label" value="é ˜åœ°ï¼š"/> + <text name="estate_rating_label" value="分級:"/> + <text name="estate_owner_label" value="æ“有者:"/> + <text name="estate_owner" value="Testing owner name length with long name"/> + <text name="covenant_label" value="契約:"/> + </panel> + </accordion_tab> + <accordion_tab name="sales_tab" title="出售"> + <panel name="sales_panel"> + <text name="sales_price_label" value="åƒ¹æ ¼ï¼š"/> + <text name="area_label" value="é¢ç©ï¼š"/> + <text name="traffic_label" value="æµé‡ï¼š"/> + <text name="primitives_label" value="Primitives:"/> + <text name="parcel_scripts_label" value="Scripts:"/> + <text name="terraform_limits_label" value="Terraform limits:"/> + <text name="subdivide_label" value="Subdivide/Join ability:"/> + <text name="resale_label" value="ReSale ability:"/> + <text name="sale_to_label" value="出售給:"/> + </panel> + </accordion_tab> + </accordion> + </panel> + </scroll_container> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_places.xml b/indra/newview/skins/default/xui/zh/panel_places.xml new file mode 100644 index 0000000000..9a038c8b04 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_places.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Places" name="places panel"> + <string name="landmarks_tab_title" value="MY LANDMARKS"/> + <string name="teleport_history_tab_title" value="TELEPORT HISTORY"/> + <filter_editor label="Filter My Places" name="Filter"/> + <panel name="button_panel"> + <layout_stack name="bottom_bar_ls0"> + <layout_panel name="lp1"> + <layout_stack name="bottom_bar_ls1"> + <layout_panel name="teleport_btn_lp"> + <button label="Teleport" name="teleport_btn" tool_tip="Teleport to the selected area"/> + </layout_panel> + <layout_panel name="chat_btn_lp"> + <button label="地圖" name="map_btn" tool_tip="Show the corresponding area on the World Map"/> + </layout_panel> + </layout_stack> + </layout_panel> + <layout_panel name="lp2"> + <layout_stack name="bottom_bar_ls3"> + <layout_panel name="edit_btn_lp"> + <button label="編輯" name="edit_btn" tool_tip="Edit landmark information"/> + </layout_panel> + <layout_panel name="overflow_btn_lp"> + <menu_button name="overflow_btn" tool_tip="Show additional options"/> + </layout_panel> + </layout_stack> + <layout_stack name="bottom_bar_ls3"> + <layout_panel name="profile_btn_lp"> + <button label="Profile" name="profile_btn" tool_tip="Show place profile"/> + </layout_panel> + </layout_stack> + <layout_stack name="bottom_bar_close_ls3"> + <layout_panel name="close_btn_lp"> + <button label="關閉" name="close_btn"/> + </layout_panel> + </layout_stack> + </layout_panel> + </layout_stack> + <layout_stack name="bottom_bar_ls2"> + <layout_panel name="save_btn_lp"> + <button label="儲å˜" name="save_btn"/> + </layout_panel> + <layout_panel name="cancel_btn_lp"> + <button label="å–銷" name="cancel_btn"/> + </layout_panel> + </layout_stack> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/zh/panel_preferences_advanced.xml new file mode 100644 index 0000000000..ad137e9dd4 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_preferences_advanced.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<panel label="進階" name="advanced"> + <panel.string name="aspect_ratio_text"> + [NUM]:[DEN] + </panel.string> + <text name="UI Size:"> + 使用者界é¢å°ºå¯¸ï¼š + </text> + <check_box label="顯示腳本錯誤訊æ¯æ–¼ï¼š" name="show_script_errors"/> + <radio_group name="show_location"> + <radio_item label="附近的èŠå¤©ä¸" name="0"/> + <radio_item label="分開的試窗ä¸" name="1"/> + </radio_group> + <check_box label="å…許åŒæ™‚執行多個ç€è¦½å™¨" name="allow_multiple_viewer_check"/> + <check_box label="ç™»å…¥æ™‚é¡¯ç¤ºç¶²æ ¼é¸æ“‡" name="show_grid_selection_check"/> + <check_box label="顯示進階é¸å–®" name="show_advanced_menu_check"/> + <check_box label="顯示開發é¸å–®" name="show_develop_menu_check"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_alerts.xml b/indra/newview/skins/default/xui/zh/panel_preferences_alerts.xml new file mode 100644 index 0000000000..94eb3c1389 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_preferences_alerts.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="çªé¡¯å¼è¦–窗" name="popups"> + <text name="tell_me_label"> + 告訴我: + </text> + <check_box label="當我花費或å–å¾— L$" name="notify_money_change_checkbox"/> + <check_box label="當我的朋å‹ä¸Šç·šæˆ–離線" name="friends_online_notify_checkbox"/> + <text name="show_label"> + 總是顯示: + </text> + <text name="dont_show_label"> + 絕ä¸é¡¯ç¤ºï¼š + </text> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_chat.xml b/indra/newview/skins/default/xui/zh/panel_preferences_chat.xml new file mode 100644 index 0000000000..cad8d75470 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_preferences_chat.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="æ–‡å—èŠå¤©" name="chat"> + <text name="font_size"> + å—型尺寸: + </text> + <radio_group name="chat_font_size"> + <radio_item label="å°" name="radio" value="0"/> + <radio_item label="ä¸" name="radio2" value="1"/> + <radio_item label="大" name="radio3" value="2"/> + </radio_group> + <check_box initial_value="true" label="èŠå¤©æ™‚æ’放打å—動作" name="play_typing_animation"/> + <check_box label="Email me IMs when I'm offline" name="send_im_to_email"/> + <check_box label="Enable plain text IM and chat history" name="plain_text_chat_history"/> + <check_box label="èŠå¤©æ³¡æ³¡" name="bubble_text_chat"/> + <text name="show_ims_in_label"> + Show IMs in: + </text> + <text name="requires_restart_label"> + ï¼ˆé ˆé‡æ–°å•Ÿå‹•ï¼‰ + </text> + <radio_group name="chat_window" tool_tip="Show your Instant Messages in separate floaters, or in one floater with many tabs (Requires restart)"> + <radio_item label="分開視窗" name="radio" value="0"/> + <radio_item label="é 籤" name="radio2" value="1"/> + </radio_group> + <text name="disable_toast_label"> + Enable incoming chat popups: + </text> + <check_box label="Group Chats" name="EnableGroupChatPopups" tool_tip="Check to see popups when a Group Chat message arrives"/> + <check_box label="IM Chats" name="EnableIMChatPopups" tool_tip="Check to see popups when an instant message arrives"/> + <spinner label="Nearby chat toasts life time:" name="nearby_toasts_lifetime"/> + <spinner label="Nearby chat toasts fading time:" name="nearby_toasts_fadingtime"/> + <text name="translate_chb_label"> + Use machine translation while chatting (powered by Google) + </text> + <text name="translate_language_text"> + Translate chat into: + </text> + <combo_box name="translate_language_combobox"> + <combo_box.item label="系統é è¨" name="System Default Language"/> + <combo_box.item label="English" name="English"/> + <combo_box.item label="Dansk (Danish)" name="Danish"/> + <combo_box.item label="Deutsch (German)" name="German"/> + <combo_box.item label="Español (Spanish)" name="Spanish"/> + <combo_box.item label="Français (French)" name="French"/> + <combo_box.item label="Italiano (Italian)" name="Italian"/> + <combo_box.item label="Magyar (Hungarian)" name="Hungarian"/> + <combo_box.item label="Nederlands (Dutch)" name="Dutch"/> + <combo_box.item label="Polski (Polish)" name="Polish"/> + <combo_box.item label="Português (Portuguese)" name="Portugese"/> + <combo_box.item label="РуÑÑкий (Russian)" name="Russian"/> + <combo_box.item label="Türkçe (Turkish)" name="Turkish"/> + <combo_box.item label="УкраїнÑька (Ukrainian)" name="Ukrainian"/> + <combo_box.item label="ä¸æ–‡ (简体) (Chinese)" name="Chinese"/> + <combo_box.item label="日本語 (Japanese)" name="Japanese"/> + <combo_box.item label="í•œêµì–´ (Korean)" name="Korean"/> + </combo_box> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_colors.xml b/indra/newview/skins/default/xui/zh/panel_preferences_colors.xml new file mode 100644 index 0000000000..261622d136 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_preferences_colors.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="é¡è‰²" name="colors_panel"> + <text name="effects_color_textbox"> + 我的效果(é¸æ“‡æŒ‡æ¨™ï¼‰ï¼š + </text> + <color_swatch name="effect_color_swatch" tool_tip="點擊以開啟é¡è‰²æŒ‘é¸å™¨"/> + <text name="font_colors"> + èŠå¤©å—åž‹é¡è‰²ï¼š + </text> + <text name="text_box1"> + 自己 + </text> + <text name="text_box2"> + 其他人 + </text> + <text name="text_box3"> + 物件 + </text> + <text name="text_box4"> + 系統 + </text> + <text name="text_box5"> + 錯誤 + </text> + <text name="text_box7"> + æ“有者 + </text> + <text name="text_box9"> + URLs + </text> + <text name="bubble_chat"> + å稱標籤背景色(亦會影響èŠå¤©æ³¡æ³¡ï¼‰ï¼š + </text> + <color_swatch name="background" tool_tip="挑é¸å稱標籤é¡è‰²"/> + <slider label="ä¸é€æ˜Žåº¦ï¼š" name="bubble_chat_opacity" tool_tip="挑é¸å稱標籤ä¸é€æ˜Žåº¦"/> + <text name="floater_opacity"> + Floater Opacity: + </text> + <slider label="啟用:" name="active"/> + <slider label="åœç”¨ï¼š" name="inactive"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_general.xml b/indra/newview/skins/default/xui/zh/panel_preferences_general.xml new file mode 100644 index 0000000000..32b3508af5 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_preferences_general.xml @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="一般" name="general_panel"> + <text name="language_textbox"> + 語言: + </text> + <combo_box name="language_combobox"> + <combo_box.item label="系統é è¨" name="System Default Language"/> + <combo_box.item label="英語" name="English"/> + <combo_box.item label="Dansk (Danish) - Beta" name="Danish"/> + <combo_box.item label="Deutsch (German) - Beta" name="Deutsch(German)"/> + <combo_box.item label="Español (Spanish) - Beta" name="Spanish"/> + <combo_box.item label="Français (French) - Beta" name="French"/> + <combo_box.item label="Italiano (Italian) - Beta" name="Italian"/> + <combo_box.item label="Nederlands (Dutch) - Beta" name="Dutch"/> + <combo_box.item label="Polski (Polish) - Beta" name="Polish"/> + <combo_box.item label="Português (Portuguese) - Beta" name="Portugese"/> + <combo_box.item label="日本語 (Japanese) - Beta" name="(Japanese)"/> + </combo_box> + <text name="language_textbox2"> + (Requires restart) + </text> + <text name="maturity_desired_prompt"> + I want to access content rated: + </text> + <combo_box name="maturity_desired_combobox"> + <combo_box.item label="General, Moderate, Adult" name="Desired_Adult"/> + <combo_box.item label="General and Moderate" name="Desired_Mature"/> + <combo_box.item label="一般" name="Desired_PG"/> + </combo_box> + <text name="start_location_textbox"> + 開始ä½ç½®ï¼š + </text> + <combo_box name="start_location_combo"> + <combo_box.item label="我上一次ä½ç½®" name="MyLastLocation"/> + <combo_box.item label="我的家" name="MyHome"/> + </combo_box> + <check_box initial_value="true" label="登入時顯示" name="show_location_checkbox"/> + <text name="name_tags_textbox"> + Name tags: + </text> + <radio_group name="Name_Tag_Preference"> + <radio_item label="Off" name="radio" value="0"/> + <radio_item label="On" name="radio2" value="1"/> + <radio_item label="Show briefly" name="radio3" value="2"/> + </radio_group> + <check_box label="My name" name="show_my_name_checkbox1"/> + <check_box label="Usernames" name="show_slids" tool_tip="Show username, like bobsmith123"/> + <check_box label="Group titles" name="show_all_title_checkbox1" tool_tip="Show group titles, like Officer or Member"/> + <check_box label="Highlight friends" name="show_friends" tool_tip="Highlight the name tags of your friends"/> + <check_box label="View Display Names" name="display_names_check" tool_tip="Check to use display names in chat, IM, name tags, etc."/> + <text name="inworld_typing_rg_label"> + Pressing letter keys: + </text> + <radio_group name="inworld_typing_preference"> + <radio_item label="Starts local chat" name="radio_start_chat" value="1"/> + <radio_item label="Affects movement (i.e. WASD)" name="radio_move" value="0"/> + </radio_group> + <text name="title_afk_text"> + Away timeout: + </text> + <combo_box label="Away timeout:" name="afk"> + <combo_box.item label="2 minutes" name="item0"/> + <combo_box.item label="5 minutes" name="item1"/> + <combo_box.item label="10 minutes" name="item2"/> + <combo_box.item label="30 minutes" name="item3"/> + <combo_box.item label="never" name="item4"/> + </combo_box> + <text name="text_box3"> + 忙碌模å¼å›žæ‡‰ï¼š + </text> + <text_editor name="busy_response"> + log_in_to_change + </text_editor> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml new file mode 100644 index 0000000000..642edff336 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml @@ -0,0 +1,102 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Graphics" name="Display panel"> + <text name="QualitySpeed"> + Quality and speed: + </text> + <text name="FasterText"> + Faster + </text> + <text name="BetterText"> + Better + </text> + <text name="ShadersPrefText"> + Low + </text> + <text name="ShadersPrefText2"> + Mid + </text> + <text name="ShadersPrefText3"> + High + </text> + <text name="ShadersPrefText4"> + Ultra + </text> + <panel label="CustomGraphics" name="CustomGraphics Panel"> + <text name="ShadersText"> + Shaders: + </text> + <check_box initial_value="true" label="Transparent Water" name="TransparentWater"/> + <check_box initial_value="true" label="Bump mapping and shiny" name="BumpShiny"/> + <check_box initial_value="true" label="Basic shaders" name="BasicShaders" tool_tip="Disabling this option may prevent some graphics card drivers from crashing"/> + <check_box initial_value="true" label="Atmospheric shaders" name="WindLightUseAtmosShaders"/> + <text name="reflection_label"> + Water Reflections: + </text> + <combo_box name="Reflections"> + <combo_box.item label="Minimal" name="0"/> + <combo_box.item label="Terrain and trees" name="1"/> + <combo_box.item label="All static objects" name="2"/> + <combo_box.item label="All avatars and objects" name="3"/> + <combo_box.item label="Everything" name="4"/> + </combo_box> + <slider label="Avatar Physics:" name="AvatarPhysicsDetail"/> + <text name="AvatarPhysicsDetailText"> + Low + </text> + <slider label="Draw distance:" name="DrawDistance"/> + <text name="DrawDistanceMeterText2"> + m + </text> + <slider label="Max. particle count:" name="MaxParticleCount"/> + <slider label="Max. # of non-impostor avatars:" name="MaxNumberAvatarDrawn"/> + <slider label="Post process quality:" name="RenderPostProcess"/> + <text name="MeshDetailText"> + Mesh detail: + </text> + <slider label="Objects:" name="ObjectMeshDetail"/> + <slider label="Flexiprims:" name="FlexibleMeshDetail"/> + <slider label="Trees:" name="TreeMeshDetail"/> + <slider label="Avatars:" name="AvatarMeshDetail"/> + <slider label="Terrain:" name="TerrainMeshDetail"/> + <slider label="Sky:" name="SkyMeshDetail"/> + <text name="PostProcessText"> + Low + </text> + <text name="ObjectMeshDetailText"> + Low + </text> + <text name="FlexibleMeshDetailText"> + Low + </text> + <text name="TreeMeshDetailText"> + Low + </text> + <text name="AvatarMeshDetailText"> + Low + </text> + <text name="TerrainMeshDetailText"> + Low + </text> + <text name="SkyMeshDetailText"> + Low + </text> + <text name="AvatarRenderingText"> + Avatar Rendering: + </text> + <check_box initial_value="true" label="Avatar impostors" name="AvatarImpostors"/> + <check_box initial_value="true" label="Hardware skinning" name="AvatarVertexProgram"/> + <check_box initial_value="true" label="Avatar cloth" name="AvatarCloth"/> + <text name="TerrainDetailText"> + Terrain detail: + </text> + <radio_group name="TerrainDetailRadio"> + <radio_item label="Low" name="0"/> + <radio_item label="High" name="2"/> + </radio_group> + --> + </panel> + <button label="套用" label_selected="套用" name="Apply"/> + <button label="Reset" name="Defaults"/> + <button label="進階" name="Advanced"/> + <button label="硬體" label_selected="硬體" name="GraphicsHardwareButton"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_move.xml b/indra/newview/skins/default/xui/zh/panel_preferences_move.xml new file mode 100644 index 0000000000..acd0a54ebf --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_preferences_move.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="移動" name="move_panel"> + <slider label="視角" name="camera_fov"/> + <slider label="è·é›¢" name="camera_offset_scale"/> + <text name="heading2"> + 自動ä½ç§»ï¼š + </text> + <check_box label="å»ºé€ / 編輯" name="edit_camera_movement" tool_tip="Use automatic camera positioning when entering and exiting edit mode"/> + <check_box label="編輯外觀" name="appearance_camera_movement" tool_tip="Use automatic camera positioning while in edit mode"/> + <check_box initial_value="true" label="å´é‚Šæ¬„" name="appearance_sidebar_positioning" tool_tip="Use automatic camera positioning for sidebar"/> + <check_box label="將我顯示於第一人稱視角ä¸" name="first_person_avatar_visible"/> + <text name=" Mouse Sensitivity"> + Mouselook mouse sensitivity: + </text> + <check_box label="å轉" name="invert_mouse"/> + <check_box label="Arrow keys always move me" name="arrow_keys_move_avatar_check"/> + <check_box label="Tap-tap-hold to run" name="tap_tap_hold_to_run"/> + <check_box label="Double-Click to:" name="double_click_chkbox"/> + <radio_group name="double_click_action"> + <radio_item label="Teleport" name="radio_teleport"/> + <radio_item label="Auto-pilot" name="radio_autopilot"/> + </radio_group> + <button label="其他è¨å‚™" name="joystick_setup_button"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/zh/panel_preferences_privacy.xml new file mode 100644 index 0000000000..847798e7a0 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_preferences_privacy.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="æºé€š" name="im"> + <panel.string name="log_in_to_change"> + log in to change + </panel.string> + <button label="清除æ·å²ç´€éŒ„" name="clear_cache" tool_tip="清除登入圖åƒã€æœ€å¾Œä½ç½®ã€çž¬é–“傳é€ç´€éŒ„ã€ç¶²é åŠæ質快å–"/> + <text name="cache_size_label_l"> + (ä½ç½®ã€åœ–åƒã€ç¶²é ã€æœå°‹çš„æ·ä½¿ç´€éŒ„) + </text> + <check_box label="將我顯示在æœå°‹çš„çµæžœä¸" name="online_searchresults"/> + <check_box label="åªæœ‰æˆ‘的朋å‹å’Œç¤¾åœ˜çŸ¥é“我在線上" name="online_visibility"/> + <check_box label="Only friends and groups can call or IM me" name="voice_call_friends_only_check"/> + <check_box label="Switch off microphone when ending calls" name="auto_disengage_mic_check"/> + <check_box label="Show my Favorite Landmarks at Login (via 'Start At' drop-down menu)" name="favorites_on_login_check"/> + <text name="Logs:"> + èŠå¤©ç´€éŒ„: + </text> + <check_box label="儲å˜é™„è¿‘çš„èŠå¤©ç´€éŒ„到我的電腦" name="log_nearby_chat"/> + <check_box label="Save IM logs on my computer" name="log_instant_messages"/> + <check_box label="æ·»åŠ æ™‚é–“æˆ³è¨˜åˆ°èŠå¤©ç´€éŒ„çš„æ¯ä¸€è¡Œ" name="show_timestamps_check_im"/> + <check_box label="æ·»åŠ æ™‚é–“æˆ³è¨˜åˆ°ç´€éŒ„æª”æª”å。" name="logfile_name_datestamp"/> + <text name="log_path_desc"> + ä½ç½®ç´€éŒ„: + </text> + <button label="ç€è¦½" label_selected="ç€è¦½" name="log_path_button"/> + <button label="å°éŽ–清單" name="block_list"/> + <text name="block_list_label"> + ï¼ˆä½ æ‰€å°éŽ–的人 åŠ/或 物件) + </text> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml b/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml new file mode 100644 index 0000000000..e7a934c5cc --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="è¨å®š" name="Input panel"> + <text name="Network:"> + 網路: + </text> + <text name="Maximum bandwidth"> + æœ€å¤§é »å¯¬ + </text> + <text name="text_box2"> + kbps + </text> + <check_box label="è‡ªè¨‚åŸ " name="connection_port_enabled"/> + <spinner label="åŸ è™Ÿï¼š" name="connection_port"/> + <text name="cache_size_label_l"> + å¿«å–尺寸 + </text> + <text name="text_box5"> + MB + </text> + <text name="Cache location"> + å¿«å–ä½ç½®ï¼š + </text> + <button label="ç€è¦½" label_selected="ç€è¦½" name="set_cache"/> + <button label="é‡è¨" label_selected="é‡è¨" name="reset_cache"/> + <text name="Web:"> + 網é : + </text> + <radio_group name="use_external_browser"> + <radio_item label="使用我的網é ç€è¦½å™¨ï¼ˆä¾‹å¦‚ IE, Firefox, Safari)" name="external" tool_tip="Use the default system web browser for help, web links, etc. Not recommended if running full screen." value="1"/> + <radio_item label="使用內建網é ç€è¦½å™¨" name="internal" tool_tip="Use the built-in web browser for help, web links, etc. This browser opens as a new window inside [APP_NAME]." value=""/> + </radio_group> + <check_box initial_value="true" label="啟用外掛" name="browser_plugins_enabled"/> + <check_box initial_value="true" label="æŽ¥å— cookies" name="cookies_enabled"/> + <check_box initial_value="true" label="啟用 Javascript" name="browser_javascript_enabled"/> + <check_box initial_value="false" label="啟用媒體ç€è¦½çš„çªé¡¯å¼è¦–窗" name="media_popup_enabled"/> + <check_box initial_value="false" label="啟用網é 代ç†ä¼ºæœå™¨" name="web_proxy_enabled"/> + <text name="Proxy location"> + 代ç†ä¼ºæœå™¨ä½ç½®ï¼š + </text> + <line_editor name="web_proxy_editor" tool_tip="The name or IP address of the proxy you would like to use"/> + <spinner label="åŸ è™Ÿï¼š" name="web_proxy_port"/> + <text name="Software updates:"> + 軟體更新: + </text> + <combo_box name="updater_service_combobox"> + <combo_box.item label="自動安è£" name="Install_automatically"/> + <combo_box.item label="手動下載åŠå®‰è£" name="Install_manual"/> + </combo_box> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_preferences_sound.xml b/indra/newview/skins/default/xui/zh/panel_preferences_sound.xml new file mode 100644 index 0000000000..0c6d8386e4 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_preferences_sound.xml @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="è²éŸ³" name="Preference Media panel"> + <panel.string name="middle_mouse"> + Middle Mouse + </panel.string> + <slider label="主音é‡" name="System Volume"/> + <check_box initial_value="true" name="mute_when_minimized"/> + <text name="mute_chb_label"> + 最å°åŒ–時éœéŸ³ + </text> + <slider label="按éµéŸ³" name="UI Volume"/> + <slider label="Ambient" name="Wind Volume"/> + <slider label="Sound Effects" name="SFX Volume"/> + <slider label="Streaming music" name="Music Volume"/> + <check_box label="Enabled" name="enable_music"/> + <slider label="Media" name="Media Volume"/> + <check_box label="Enabled" name="enable_media"/> + <slider label="Voice Chat" name="Voice Volume"/> + <check_box label="Enabled" name="enable_voice_check"/> + <check_box label="Allow Media to auto-play" name="media_auto_play_btn" tool_tip="Check this to let media auto-play if it wants" value="true"/> + <check_box label="Play media attached to other avatars" name="media_show_on_others_btn" tool_tip="Uncheck this to hide media attached to other avatars nearby" value="true"/> + <text name="voice_chat_settings"> + Voice Chat Settings + </text> + <text name="Listen from"> + Listen from: + </text> + <radio_group name="ear_location"> + <radio_item label="Camera position" name="0"/> + <radio_item label="Avatar position" name="1"/> + </radio_group> + <check_box label="Move avatar lips when speaking" name="enable_lip_sync"/> + <check_box label="Toggle speak on/off when I press:" name="push_to_talk_toggle_check" tool_tip="When in toggle mode, press and release the trigger key ONCE to switch your microphone on or off. When not in toggle mode, the microphone broadcasts your voice only while the trigger is being held down."/> + <line_editor label="Push-to-Speak trigger" name="modifier_combo"/> + <button label="Set Key" name="set_voice_hotkey_button"/> + <button name="set_voice_middlemouse_button" tool_tip="Reset to Middle Mouse Button"/> + <button label="輸入 / 輸出è¨å‚™" name="device_settings_btn"/> + <panel label="è¨å‚™è¨å®š" name="device_settings_panel"> + <panel.string name="default_text"> + é è¨ + </panel.string> + <panel.string name="default system device"> + é è¨ç³»çµ±è¨å‚™ + </panel.string> + <panel.string name="no device"> + ç„¡è¨å‚™ + </panel.string> + <text name="Input"> + 輸入 + </text> + <text name="My volume label"> + My volume: + </text> + <slider_bar initial_value="1.0" name="mic_volume_slider" tool_tip="Change the volume using this slider"/> + <text name="wait_text"> + Please wait + </text> + <text name="Output"> + 輸出 + </text> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/zh/panel_prim_media_controls.xml new file mode 100644 index 0000000000..71de9f861a --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_prim_media_controls.xml @@ -0,0 +1,91 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="MediaControls"> + <string name="control_background_image_name"> + Inspector_Background + </string> + <string name="skip_step"> + 0.2 + </string> + <string name="min_width"> + 300 + </string> + <string name="min_height"> + 75 + </string> + <string name="zoom_near_padding"> + 1.0 + </string> + <string name="zoom_medium_padding"> + 1.1 + </string> + <string name="zoom_far_padding"> + 1.5 + </string> + <string name="top_world_view_avoid_zone"> + 50 + </string> + <layout_stack name="progress_indicator_area"> + <layout_panel name="media_progress_indicator"> + <progress_bar name="media_progress_bar" tool_tip="Media is Loading"/> + </layout_panel> + </layout_stack> + <layout_stack name="media_controls"> + <layout_panel name="back"> + <button name="back_btn" tool_tip="Navigate back"/> + </layout_panel> + <layout_panel name="fwd"> + <button name="fwd_btn" tool_tip="Navigate forward"/> + </layout_panel> + <layout_panel name="home"> + <button name="home_btn" tool_tip="Home page"/> + </layout_panel> + <layout_panel name="media_stop"> + <button name="media_stop_btn" tool_tip="Stop media"/> + </layout_panel> + <layout_panel name="reload"> + <button name="reload_btn" tool_tip="Reload"/> + </layout_panel> + <layout_panel name="stop"> + <button name="stop_btn" tool_tip="Stop loading"/> + </layout_panel> + <layout_panel name="play"> + <button name="play_btn" tool_tip="Play media"/> + </layout_panel> + <layout_panel name="pause"> + <button name="pause_btn" tool_tip="Pause media"/> + </layout_panel> + <layout_panel name="media_address"> + <line_editor name="media_address_url" tool_tip="Media URL"/> + <layout_stack name="media_address_url_icons"> + <layout_panel> + <icon name="media_whitelist_flag" tool_tip="White List enabled"/> + </layout_panel> + <layout_panel> + <icon name="media_secure_lock_flag" tool_tip="Secured Browsing"/> + </layout_panel> + </layout_stack> + </layout_panel> + <layout_panel name="media_play_position"> + <slider_bar initial_value="0.5" name="media_play_slider" tool_tip="Movie play progress"/> + </layout_panel> + <layout_panel name="skip_back"> + <button name="skip_back_btn" tool_tip="Step back"/> + </layout_panel> + <layout_panel name="skip_forward"> + <button name="skip_forward_btn" tool_tip="Step forward"/> + </layout_panel> + <layout_panel name="media_volume"> + <button name="media_mute_button" tool_tip="Mute This Media"/> + <slider name="volume_slider" tool_tip="Media Volume"/> + </layout_panel> + <layout_panel name="zoom_frame"> + <button name="zoom_frame_btn" tool_tip="Zoom into media"/> + </layout_panel> + <layout_panel name="close"> + <button name="close_btn" tool_tip="Zoom Back"/> + </layout_panel> + <layout_panel name="new_window"> + <button name="new_window_btn" tool_tip="Open URL in browser"/> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_profile.xml b/indra/newview/skins/default/xui/zh/panel_profile.xml new file mode 100644 index 0000000000..88cd3a0e16 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_profile.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Profile" name="panel_profile"> + <string name="CaptionTextAcctInfo"> + [ACCTTYPE] +[PAYMENTINFO] [AGEVERIFICATION] + </string> + <string name="payment_update_link_url"> + http://www.secondlife.com/account/billing.php?lang=en + </string> + <string name="partner_edit_link_url"> + http://www.secondlife.com/account/partners.php?lang=en + </string> + <string name="my_account_link_url" value="http://secondlife.com/account"/> + <string name="no_partner_text" value="ç„¡"/> + <string name="no_group_text" value="ç„¡"/> + <string name="RegisterDateFormat"> + [REG_DATE] ([AGE]) + </string> + <string name="name_text_args"> + [NAME] + </string> + <string name="display_name_text_args"> + [DISPLAY_NAME] + </string> + <layout_stack name="layout"> + <layout_panel name="profile_stack"> + <scroll_container name="profile_scroll"> + <panel name="profile_scroll_panel"> + <panel name="second_life_image_panel"> + <text name="title_sl_descr_text" value="[SECOND_LIFE]:"/> + </panel> + <panel name="first_life_image_panel"> + <text name="title_rw_descr_text" value="Real World:"/> + </panel> + <text name="title_member_text" value="Resident Since:"/> + <text name="title_acc_status_text" value="Account Status:"/> + <text name="title_partner_text" value="Partner:"/> + <panel name="partner_data_panel"> + <text initial_value="(retrieving)" name="partner_text"/> + </panel> + <text name="title_groups_text" value="Groups:"/> + </panel> + </scroll_container> + </layout_panel> + </layout_stack> + <layout_stack name="layout_verb_buttons"> + <layout_panel name="profile_buttons_panel"> + <layout_stack name="bottom_bar_ls"> + <layout_panel name="add_friend_btn_lp"> + <button label="åŠ ç‚ºæœ‹å‹" name="add_friend" tool_tip="Offer friendship to the Resident"/> + </layout_panel> + <layout_panel name="im_btn_lp"> + <button label="IM" name="im" tool_tip="Open instant message session"/> + </layout_panel> + <layout_panel name="call_btn_lp"> + <button label="Call" name="call" tool_tip="Call this Resident"/> + </layout_panel> + <layout_panel name="chat_btn_lp"> + <button label="Teleport" name="teleport" tool_tip="Offer teleport"/> + </layout_panel> + <layout_panel name="overflow_btn_lp"> + <menu_button label="â–¼" name="overflow_btn" tool_tip="Pay money to or share inventory with the Resident"/> + </layout_panel> + </layout_stack> + </layout_panel> + </layout_stack> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_profile_view.xml b/indra/newview/skins/default/xui/zh/panel_profile_view.xml new file mode 100644 index 0000000000..0f30d5dcbe --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_profile_view.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_target_profile"> + <string name="status_online"> + Online + </string> + <string name="status_offline"> + Offline + </string> + <text name="display_name_label" value="Display Name:"/> + <text name="solo_username_label" value="Username:"/> + <text name="status" value="Online"/> + <text name="user_name_small" value="Jack oh look at me this is a super duper long name"/> + <button name="copy_to_clipboard" tool_tip="覆製到剪貼簿"/> + <text name="user_label" value="Username:"/> + <tab_container name="tabs"> + <panel label="PROFILE" name="panel_profile"/> + <panel label="PICKS" name="panel_picks"/> + <panel label="NOTES & PRIVACY" name="panel_notes"/> + </tab_container> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_region_covenant.xml b/indra/newview/skins/default/xui/zh/panel_region_covenant.xml new file mode 100644 index 0000000000..2e52efb804 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_region_covenant.xml @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="契約" name="Covenant"> + <panel.string name="can_resell"> + Purchased land in this region may be resold. + </panel.string> + <panel.string name="can_not_resell"> + Purchased land in this region may not be resold. + </panel.string> + <panel.string name="can_change"> + Purchased land in this region may be joined or subdivided. + </panel.string> + <panel.string name="can_not_change"> + Purchased land in this region may not be joined or subdivided. + </panel.string> + <text name="estate_section_lbl"> + é ˜åœ° + </text> + <text name="estate_name_lbl"> + å稱: + </text> + <text name="estate_name_text"> + mainland + </text> + <text name="estate_owner_lbl"> + æ“有者: + </text> + <text name="estate_owner_text"> + (無) + </text> + <text name="estate_cov_lbl"> + 契約: + </text> + <text name="covenant_timestamp_text"> + Last Modified Wed Dec 31 16:00:00 1969 + </text> + <text_editor name="covenant_editor"> + There is no Covenant provided for this Estate. + </text_editor> + <button label="Reset" name="reset_covenant"/> + <text name="covenant_help_text"> + Changes to the covenant will show on all parcels in the estate. + </text> + <text name="covenant_instructions"> + Drag and drop a notecard to change the Covenant for this estate. + </text> + <text name="region_section_lbl"> + åœ°å€ + </text> + <text name="region_name_lbl"> + å稱: + </text> + <text name="region_name_text"> + Erica + </text> + <text name="region_landtype_lbl"> + 類型: + </text> + <text name="region_landtype_text"> + Mainland / Homestead + </text> + <text name="region_maturity_lbl"> + 分級: + </text> + <text name="region_maturity_text"> + Adult + </text> + <text name="resellable_lbl"> + Resale: + </text> + <text name="resellable_clause"> + Land in this region may not be resold. + </text> + <text name="changeable_lbl"> + Subdivide: + </text> + <text name="changeable_clause"> + Land in this region may not be joined/subdivided. + </text> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_region_debug.xml b/indra/newview/skins/default/xui/zh/panel_region_debug.xml new file mode 100644 index 0000000000..892b743f57 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_region_debug.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="除錯" name="Debug"> + <text name="region_text_lbl"> + 地å€ï¼š + </text> + <text name="region_text"> + 未知 + </text> + <check_box label="Disable Scripts" name="disable_scripts_check" tool_tip="Disable all scripts in this region"/> + <check_box label="Disable Collisions" name="disable_collisions_check" tool_tip="Disable non-avatar collisions in this region"/> + <check_box label="Disable Physics" name="disable_physics_check" tool_tip="Disable all physics in this region"/> + <button label="套用" name="apply_btn"/> + <text name="objret_text_lbl"> + Object Return + </text> + <text name="resident_text_lbl"> + Resident: + </text> + <line_editor name="target_avatar_name"> + (無) + </line_editor> + <button label="Choose" name="choose_avatar_btn"/> + <text name="options_text_lbl"> + Options: + </text> + <check_box label="With scripts" name="return_scripts" tool_tip="Return only objects which have scripts"/> + <check_box label="On someone else's land" name="return_other_land" tool_tip="Return only objects which are on land belonging to someone else"/> + <check_box label="In every region of this estate" name="return_estate_wide" tool_tip="Return objects in all of the regions that make up this estate"/> + <button label="Return" name="return_btn"/> + <button label="Get Top Colliders..." name="top_colliders_btn" tool_tip="List of objects experiencing the most potential collisions"/> + <button label="Get Top Scripts..." name="top_scripts_btn" tool_tip="List of objects spending the most time running scripts"/> + <button label="Restart Region" name="restart_btn" tool_tip="Give 2 minute countdown and restart region"/> + <button label="Delay Restart" name="cancel_restart_btn" tool_tip="Delay region restart by one hour"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_region_estate.xml b/indra/newview/skins/default/xui/zh/panel_region_estate.xml new file mode 100644 index 0000000000..687135bf65 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_region_estate.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="é ˜åœ°" name="Estate"> + <text name="estate_help_text"> + Changes to settings on this tab will affect all regions in the estate. + </text> + <text name="estate_text"> + é ˜åœ°ï¼š + </text> + <text name="estate_name"> + (未知) + </text> + <text name="owner_text"> + é ˜åœ°æ“有者: + </text> + <text name="estate_owner"> + (未知) + </text> + <check_box label="Use Global Time" name="use_global_time_check"/> + <check_box label="Fixed Sun" name="fixed_sun_check"/> + <slider label="Phase" name="sun_hour_slider"/> + <check_box label="Allow Public Access" name="externally_visible_check"/> + <text name="Only Allow"> + Restrict Access to accounts verified by: + </text> + <check_box label="Payment Information on File" name="limit_payment" tool_tip="Ban unidentified Residents"/> + <check_box label="年齡驗è‰" name="limit_age_verified" tool_tip="Ban Residents who have not verified their age. See the [SUPPORT_SITE] for more information."/> + <check_box label="Allow Voice Chat" name="voice_chat_check"/> + <check_box label="Allow Direct Teleport" name="allow_direct_teleport"/> + <button label="套用" name="apply_btn"/> + <button label="Send Message To Estate..." name="message_estate_btn"/> + <button label="Kick Resident from Estate..." name="kick_user_from_estate_btn"/> + <text name="estate_manager_label"> + é ˜åœ°ç®¡ç†å“¡ï¼š + </text> + <button label="Remove..." name="remove_estate_manager_btn"/> + <button label="Add..." name="add_estate_manager_btn"/> + <text name="allow_resident_label"> + Allowed Residents: + </text> + <button label="Remove..." name="remove_allowed_avatar_btn"/> + <button label="Add..." name="add_allowed_avatar_btn"/> + <text name="allow_group_label"> + Allowed Groups: + </text> + <button label="Remove..." name="remove_allowed_group_btn"/> + <button label="Add..." name="add_allowed_group_btn"/> + <text name="ban_resident_label"> + Banned Residents: + </text> + <button label="Remove..." name="remove_banned_avatar_btn"/> + <button label="Add..." name="add_banned_avatar_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_region_general.xml b/indra/newview/skins/default/xui/zh/panel_region_general.xml new file mode 100644 index 0000000000..ce69ec59c4 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_region_general.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="地å€" name="General"> + <text name="region_text_lbl"> + 地å€ï¼š + </text> + <text name="region_text"> + 未知 + </text> + <text name="version_channel_text_lbl"> + Version: + </text> + <text name="version_channel_text"> + 未知 + </text> + <text name="region_type_lbl"> + 類型: + </text> + <text name="region_type"> + 未知 + </text> + <check_box label="Block Terraform" name="block_terraform_check"/> + <check_box label="Block Fly" name="block_fly_check"/> + <check_box label="Allow Damage" name="allow_damage_check"/> + <check_box label="Restrict Pushing" name="restrict_pushobject"/> + <check_box label="Allow Land Resell" name="allow_land_resell_check"/> + <check_box label="Allow Land Join/Divide" name="allow_parcel_changes_check"/> + <check_box label="Block Land Show in Search" name="block_parcel_search_check" tool_tip="Let people see this region and its parcels in search results"/> + <spinner label="Agent Limit" name="agent_limit_spin"/> + <spinner label="Object Bonus" name="object_bonus_spin"/> + <text label="Maturity" name="access_text"> + 分級: + </text> + <icons_combo_box label="Moderate" name="access_combo"> + <icons_combo_box.item label="Adult" name="Adult" value="42"/> + <icons_combo_box.item label="Moderate" name="Mature" value="21"/> + <icons_combo_box.item label="一般" name="PG" value="13"/> + </icons_combo_box> + <button label="套用" name="apply_btn"/> + <button label="Teleport Home One Resident..." name="kick_btn"/> + <button label="Teleport Home All Residents..." name="kick_all_btn"/> + <button label="Send Message To Region..." name="im_btn"/> + <button label="Manage Telehub..." name="manage_telehub_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml new file mode 100644 index 0000000000..0269c8f734 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Terrain" name="Terrain"> + <text name="region_text_lbl"> + 地å€ï¼š + </text> + <text name="region_text"> + 未知 + </text> + <spinner label="Water Height" name="water_height_spin"/> + <spinner label="Terrain Raise Limit" name="terrain_raise_spin"/> + <spinner label="Terrain Lower Limit" name="terrain_lower_spin"/> + <check_box label="Use Estate Sun" name="use_estate_sun_check"/> + <check_box label="Fixed Sun" name="fixed_sun_check"/> + <slider label="Phase" name="sun_hour_slider"/> + <button label="套用" name="apply_btn"/> + <button label="Download RAW terrain..." name="download_raw_btn" tool_tip="Available only to estate owners, not managers"/> + <button label="Upload RAW terrain..." name="upload_raw_btn" tool_tip="Available only to estate owners, not managers"/> + <button label="Bake Terrain" name="bake_terrain_btn" tool_tip="Set current terrain as mid-point for raise/lower limits"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_region_texture.xml b/indra/newview/skins/default/xui/zh/panel_region_texture.xml new file mode 100644 index 0000000000..42d70fddb8 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_region_texture.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Ground Textures" name="Textures"> + <text name="region_text_lbl"> + 地å€ï¼š + </text> + <text name="region_text"> + 未知 + </text> + <text name="detail_texture_text"> + Terrain Textures (requires 512x512, 24 bit .tga files) + </text> + <text name="height_text_lbl"> + 1 (Low) + </text> + <text name="height_text_lbl2"> + 2 + </text> + <text name="height_text_lbl3"> + 3 + </text> + <text name="height_text_lbl4"> + 4 (High) + </text> + <text name="height_text_lbl5"> + Texture Elevation Ranges + </text> + <text name="height_text_lbl6"> + Northwest + </text> + <text name="height_text_lbl7"> + Northeast + </text> + <spinner label="Low" name="height_start_spin_1"/> + <spinner label="Low" name="height_start_spin_3"/> + <spinner label="High" name="height_range_spin_1"/> + <spinner label="High" name="height_range_spin_3"/> + <text name="height_text_lbl8"> + Southwest + </text> + <text name="height_text_lbl9"> + Southeast + </text> + <spinner label="Low" name="height_start_spin_0"/> + <spinner label="Low" name="height_start_spin_2"/> + <spinner label="High" name="height_range_spin_0"/> + <spinner label="High" name="height_range_spin_2"/> + <text name="height_text_lbl10"> + These values represent the blend range for the textures above. + </text> + <text name="height_text_lbl11"> + Measured in meters, the LOW value is the MAXIMUM height of Texture #1, and the HIGH value is the MINIMUM height of Texture #4. + </text> + <button label="套用" name="apply_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_script_ed.xml b/indra/newview/skins/default/xui/zh/panel_script_ed.xml new file mode 100644 index 0000000000..b0f1bdb337 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_script_ed.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="script panel"> + <panel.string name="loading"> + 載入ä¸... + </panel.string> + <panel.string name="can_not_view"> + You can not view or edit this script, since it has been set as "no copy". You need full permissions to view or edit a script inside an object. + </panel.string> + <panel.string name="public_objects_can_not_run"> + Public Objects cannot run scripts + </panel.string> + <panel.string name="script_running"> + Running + </panel.string> + <panel.string name="Title"> + Script: [NAME] + </panel.string> + <panel.string name="external_editor_not_set"> + Select an editor by setting the environment variable LL_SCRIPT_EDITOR or the ExternalEditor setting. + </panel.string> + <menu_bar name="script_menu"> + <menu label="File" name="File"> + <menu_item_call label="儲å˜" name="Save"/> + <menu_item_call label="Revert All Changes" name="Revert All Changes"/> + </menu> + <menu label="編輯" name="Edit"> + <menu_item_call label="復原" name="Undo"/> + <menu_item_call label="Redo" name="Redo"/> + <menu_item_call label="剪下" name="Cut"/> + <menu_item_call label="覆製" name="Copy"/> + <menu_item_call label="貼上" name="Paste"/> + <menu_item_call label="å…¨é¸" name="Select All"/> + <menu_item_call label="Deselect" name="Deselect"/> + <menu_item_call label="æœå°‹ / å–代..." name="Search / Replace..."/> + </menu> + <menu label="Help" name="Help"> + <menu_item_call label="Help..." name="Help..."/> + <menu_item_call label="Keyword Help..." name="Keyword Help..."/> + </menu> + </menu_bar> + <text_editor name="Script Editor"> + 載入ä¸... + </text_editor> + <combo_box label="Insert..." name="Insert..."/> + <button label="儲å˜" label_selected="儲å˜" name="Save_btn"/> + <button label="編輯..." name="Edit_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_script_limits_my_avatar.xml b/indra/newview/skins/default/xui/zh/panel_script_limits_my_avatar.xml new file mode 100644 index 0000000000..5276466117 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_script_limits_my_avatar.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="MY AVATAR" name="script_limits_my_avatar_panel"> + <text name="script_memory"> + Avatar Script Usage + </text> + <text name="loading_text"> + 載入ä¸... + </text> + <scroll_list name="scripts_list"> + <scroll_list.columns label="Size (kb)" name="size"/> + <scroll_list.columns label="URLs" name="urls"/> + <scroll_list.columns label="物件å稱" name="name"/> + <scroll_list.columns label="Location" name="location"/> + </scroll_list> + <button label="Refresh List" name="refresh_list_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_script_limits_region_memory.xml b/indra/newview/skins/default/xui/zh/panel_script_limits_region_memory.xml new file mode 100644 index 0000000000..1dc8278db1 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_script_limits_region_memory.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="REGION MEMORY" name="script_limits_region_memory_panel"> + <text name="script_memory"> + Parcel Script Memory + </text> + <text name="loading_text"> + 載入ä¸... + </text> + <scroll_list name="scripts_list"> + <scroll_list.columns label="Size (kb)" name="size"/> + <scroll_list.columns label="URLs" name="urls"/> + <scroll_list.columns label="物件å稱" name="name"/> + <scroll_list.columns label="Object Owner" name="owner"/> + <scroll_list.columns label="地段" name="parcel"/> + <scroll_list.columns label="Location" name="location"/> + </scroll_list> + <button label="Refresh List" name="refresh_list_btn"/> + <button label="Highlight" name="highlight_btn"/> + <button label="Return" name="return_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_scrolling_param.xml b/indra/newview/skins/default/xui/zh/panel_scrolling_param.xml new file mode 100644 index 0000000000..bc29058f77 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_scrolling_param.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="LLScrollingPanelParam"> + <text name="Loading..."> + 載入ä¸... + </text> + <text name="Loading...2"> + 載入ä¸... + </text> + <slider label="[DESC]" name="param slider"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_scrolling_param_base.xml b/indra/newview/skins/default/xui/zh/panel_scrolling_param_base.xml new file mode 100644 index 0000000000..fa659040ea --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_scrolling_param_base.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="LLScrollingPanelParamBase"> + <slider label="[DESC]" name="param slider"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_side_tray.xml b/indra/newview/skins/default/xui/zh/panel_side_tray.xml new file mode 100644 index 0000000000..d99450b5be --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_side_tray.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<!-- Side tray cannot show background because it is always + partially on screen to hold tab buttons. --> +<side_tray name="sidebar"> + <sidetray_tab description="Toggle Sidebar." name="sidebar_openclose" tab_title="Toggle Sidebar"/> + <sidetray_tab description="首é 。" name="sidebar_home" tab_title="首é "> + <panel label="首é " name="panel_home"/> + </sidetray_tab> + <sidetray_tab description="Edit your public profile and Picks." name="sidebar_me" tab_title="My Profile"> + <panel_container name="panel_container"> + <panel label="自己" name="panel_me"/> + </panel_container> + </sidetray_tab> + <sidetray_tab description="Find your friends, contacts and people nearby." name="sidebar_people" tab_title="People"> + <panel_container name="panel_container"> + <panel label="Group Profile" name="panel_group_info_sidetray"/> + <panel label="Blocked Residents & Objects" name="panel_block_list_sidetray"/> + </panel_container> + </sidetray_tab> + <sidetray_tab description="Find places to go and places you've visited before." label="Places" name="sidebar_places" tab_title="Places"> + <panel label="Places" name="panel_places"/> + </sidetray_tab> + <sidetray_tab description="Browse your inventory." name="sidebar_inventory" tab_title="My Inventory"> + <panel label="Edit Inventory" name="sidepanel_inventory"/> + </sidetray_tab> + <sidetray_tab description="Change your appearance and current look." name="sidebar_appearance" tab_title="My Appearance"> + <panel label="Edit Appearance" name="sidepanel_appearance"/> + </sidetray_tab> +</side_tray> diff --git a/indra/newview/skins/default/xui/zh/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/zh/panel_side_tray_tab_caption.xml new file mode 100644 index 0000000000..822b2b5894 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_side_tray_tab_caption.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="sidetray_tab_panel"> + <text name="sidetray_tab_title" value="å´é‚Šæ¬„"/> + <button name="undock" tool_tip="Undock"/> + <button name="dock" tool_tip="Dock"/> + <button name="show_help" tool_tip="Show Help"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_stand_stop_flying.xml b/indra/newview/skins/default/xui/zh/panel_stand_stop_flying.xml new file mode 100644 index 0000000000..279a9869a8 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_stand_stop_flying.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<!-- Width and height of this panel should be synchronized with "panel_modes" in the floater_moveview.xml--> +<panel name="panel_stand_stop_flying"> + <button label="Stand" name="stand_btn" tool_tip="Click here to stand up."/> + <button label="Stop Flying" name="stop_fly_btn" tool_tip="Stop flying"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_status_bar.xml b/indra/newview/skins/default/xui/zh/panel_status_bar.xml new file mode 100644 index 0000000000..65740f1b6d --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_status_bar.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="status"> + <panel.string name="packet_loss_tooltip"> + å°åŒ…æ失 + </panel.string> + <panel.string name="bandwidth_tooltip"> + é »å¯¬ + </panel.string> + <panel.string name="time"> + [hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt] + </panel.string> + <panel.string name="timeTooltip"> + [weekday, datetime, slt], [day, datetime, slt] [month, datetime, slt] [year, datetime, slt] + </panel.string> + <panel.string name="buycurrencylabel"> + L$ [AMT] + </panel.string> + <panel name="balance_bg"> + <text name="balance" tool_tip="Click to refresh your L$ balance" value="L$20"/> + <button label="購買 L$" name="buyL" tool_tip="Click to buy more L$"/> + </panel> + <text name="TimeText" tool_tip="Current time (Pacific)"> + 24:00 AM PST + </text> + <button name="media_toggle_btn" tool_tip="Start/Stop All Media (Music, Video, Web pages)"/> + <button name="volume_btn" tool_tip="Global Volume Control"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_teleport_history.xml b/indra/newview/skins/default/xui/zh/panel_teleport_history.xml new file mode 100644 index 0000000000..872a4584bf --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_teleport_history.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="Teleport History"> + <accordion name="history_accordion"> + <no_matched_tabs_text name="no_matched_teleports_msg" value="Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search]."/> + <no_visible_tabs_text name="no_teleports_msg" value="Teleport history is empty. Try [secondlife:///app/search/places/ Search]."/> + <accordion_tab name="today" title="今天"/> + <accordion_tab name="yesterday" title="昨天"/> + <accordion_tab name="2_days_ago" title="å‰å¤©"/> + <accordion_tab name="3_days_ago" title="三天å‰"/> + <accordion_tab name="4_days_ago" title="四天å‰"/> + <accordion_tab name="5_days_ago" title="五天å‰"/> + <accordion_tab name="6_days_and_older" title="å…天å‰æˆ–æ›´ä¹…"/> + <accordion_tab name="1_month_and_older" title="一個月或更久"/> + <accordion_tab name="6_months_and_older" title="åŠå¹´å‰æˆ–æ›´ä¹…"/> + </accordion> + <panel name="bottom_panel"> + <menu_button name="gear_btn" tool_tip="Show additional options"/> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_teleport_history_item.xml b/indra/newview/skins/default/xui/zh/panel_teleport_history_item.xml new file mode 100644 index 0000000000..c251994906 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_teleport_history_item.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="teleport_history_item"> + <text name="region" value="..."/> + <button name="profile_btn" tool_tip="顯示物å“資訊"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_voice_effect.xml b/indra/newview/skins/default/xui/zh/panel_voice_effect.xml new file mode 100644 index 0000000000..6c8a452014 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_voice_effect.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_voice_effect"> + <string name="no_voice_effect"> + 關閉變è²æ•ˆæžœ + </string> + <string name="preview_voice_effects"> + é 覽變è²æ•ˆæžœ â–¶ + </string> + <string name="get_voice_effects"> + å–得變è²æ•ˆæžœ â–¶ + </string> + <combo_box name="voice_effect" tool_tip="é¸å–一個變è²æ•ˆæžœä¾†æ”¹è®Šä½ çš„è²éŸ³"> + <combo_box.item label="關閉變è²æ•ˆæžœ" name="no_voice_effect"/> + </combo_box> +</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_world_map.xml b/indra/newview/skins/default/xui/zh/panel_world_map.xml new file mode 100644 index 0000000000..ad28361a7f --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_world_map.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="world_map"> + <panel.string name="Loading"> + 載入ä¸... + </panel.string> + <panel.string name="InvalidLocation"> + Invalid Location + </panel.string> + <panel.string name="world_map_north"> + N + </panel.string> + <panel.string name="world_map_east"> + E + </panel.string> + <panel.string name="world_map_west"> + W + </panel.string> + <panel.string name="world_map_south"> + S + </panel.string> + <panel.string name="world_map_southeast"> + SE + </panel.string> + <panel.string name="world_map_northeast"> + NE + </panel.string> + <panel.string name="world_map_southwest"> + SW + </panel.string> + <panel.string name="world_map_northwest"> + NW + </panel.string> + <panel.string name="world_map_person"> + 1 person + </panel.string> + <panel.string name="world_map_people"> + [NUMBER] people + </panel.string> + <text label="N" name="floater_map_north"> + N + </text> + <text label="E" name="floater_map_east"> + E + </text> + <text label="W" name="floater_map_west"> + W + </text> + <text label="S" name="floater_map_south"> + S + </text> + <text label="SE" name="floater_map_southeast"> + SE + </text> + <text label="NE" name="floater_map_northeast"> + NE + </text> + <text label="SW" name="floater_map_southwest"> + SW + </text> + <text label="NW" name="floater_map_northwest"> + NW + </text> +</panel> diff --git a/indra/newview/skins/default/xui/zh/role_actions.xml b/indra/newview/skins/default/xui/zh/role_actions.xml new file mode 100644 index 0000000000..196f8c7a6a --- /dev/null +++ b/indra/newview/skins/default/xui/zh/role_actions.xml @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<role_actions> + <action_set description="These Abilities include powers to add and remove group Members, and allow new Members to join without an invitation." name="Membership"> + <action description="Invite People to this Group" longdescription="Invite People to this Group using the 'Invite' button in the Roles section > Members tab." name="member invite" value="1"/> + <action description="Eject Members from this Group" longdescription="Eject Members from this Group using the 'Eject' button in the Roles section > Members tab. An Owner can eject anyone except another Owner. If you're not an Owner, a Member can be ejected from a group if, and only if, they're only in the Everyone Role, and NO other Roles. To remove Members from Roles, you need to have the 'Remove Members from Roles' Ability." name="member eject" value="2"/> + <action description="Toggle 'Open Enrollment' and change 'Enrollment fee'" longdescription="Toggle 'Open Enrollment' to let new Members join without an invitation, and change the 'Enrollment fee' in the General section." name="member options" value="3"/> + </action_set> + <action_set description="These Abilities include powers to add, remove, and change group Roles, add and remove Members in Roles, and assign Abilities to Roles." name="Roles"> + <action description="Create new Roles" longdescription="Create new Roles in the Roles section > Roles tab." name="role create" value="4"/> + <action description="Delete Roles" longdescription="Delete Roles in the Roles section > Roles tab." name="role delete" value="5"/> + <action description="Change Role names, titles, descriptions, and whether Role members are publicly revealed" longdescription="Change Role names, titles, descriptions, and whether Role members are publicly revealed. This is done at the bottom of the the Roles section > Roles tab after selecting a Role." name="role properties" value="6"/> + <action description="Assign Members to Assigner's Roles" longdescription="Assign Members to Roles in the list of Assigned Roles (Roles section > Members tab). A Member with this Ability can only add Members to a Role that the assigner is already in." name="role assign member limited" value="7"/> + <action description="Assign Members to Any Role" longdescription="Assign Members to Any Role in the list of Assigned Roles (Roles section > Members tab). *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--to Roles that have more powers than they currently have, potentially elevating themselves to near-Owner power. Be sure you know what you're doing before assigning this Ability." name="role assign member" value="8"/> + <action description="Remove Members from Roles" longdescription="Remove Members from Roles in the list of Assigned Roles (Roles section > Members tab). Owners can't be removed." name="role remove member" value="9"/> + <action description="Assign and Remove Abilities in Roles" longdescription="Assign and Remove Abilities for each Role in the list of Allowed Abilities (Roles section > Roles tab). *WARNING* Any Member in a Role with this Ability can assign themselves--and any other non-Owner Member--all Abilities, potentially elevating themselves to near-Owner power. Be sure you know what you're doing before assigning this Ability." name="role change actions" value="10"/> + </action_set> + <action_set description="These Abilities include powers to modify this group's identity, such as changing public visibility, charter, and insignia." name="Group Identity"> + <action description="Change Charter, Insignia, and 'Show in search'" longdescription="Change Charter, Insignia, and 'Show in search'. This is done in the General section." name="group change identity" value="11"/> + </action_set> + <action_set description="These Abilities include powers to deed, modify, and sell land in this group's land holdings. To get to the About Land window, right-click the ground and select 'About Land', or click the 'i' icon in the Navigation Bar." name="Parcel Management"> + <action description="Deed land and buy land for group" longdescription="Deed land and buy land for group. This is done in About Land > General tab." name="land deed" value="12"/> + <action description="Abandon land to Governor Linden" longdescription="Abandon land to Governor Linden. *WARNING* Any Member in a Role with this Ability can abandon group-owned land in About Land > General tab, reverting it to Linden ownership without a sale! Be sure you know what you're doing before assigning this Ability." name="land release" value="13"/> + <action description="Set land for sale info" longdescription="Set land for sale info. *WARNING* Any Member in a Role with this Ability can sell group-owned land in About Land > General tab as they wish! Be sure you know what you're doing before assigning this Ability." name="land set sale info" value="14"/> + <action description="Subdivide and join parcels" longdescription="Subdivide and join parcels. This is done by right-clicking the ground, 'Edit Terrain', and dragging your mouse on the land to make a selection. To subdivide, select what you want to split and click 'Subdivide'. To join, select two or more contiguous parcels and click 'Join'." name="land divide join" value="15"/> + </action_set> + <action_set description="These Abilities include powers to change the parcel name and publish settings, Find directory visibility, and landing point & TP routing options." name="Parcel Identity"> + <action description="Toggle 'Show Place in Search' and set category" longdescription="Toggle 'Show Place in Search' and setting a parcel's category in About Land > Options tab." name="land find places" value="17"/> + <action description="Change parcel name, description, and 'Show Place in Search' settings" longdescription="Change parcel name, description, and 'Show Place in Search' settings. This is done in About Land > Options tab." name="land change identity" value="18"/> + <action description="Set landing point and set teleport routing" longdescription="On a group-owned parcel, Members in a Role with this Ability can set a landing point to specify where incoming teleports arrive, and also set teleport routing for further control. This is done in About Land > Options tab." name="land set landing point" value="19"/> + </action_set> + <action_set description="These Abilities include powers which affect parcel options, such as 'Create Objects', 'Edit Terrain', and music & media settings." name="Parcel Settings"> + <action description="Change music & media settings" longdescription="Change streaming music and movie settings in About Land > Media tab." name="land change media" value="20"/> + <action description="Toggle 'Edit Terrain'" longdescription="Toggle 'Edit Terrain'. *WARNING* About Land > Options tab > Edit Terrain allows anyone to terraform your land's shape, and place and move Linden plants. Be sure you know what you're doing before assigning this Ability. Editing terrain is toggled in About Land > Options tab." name="land edit" value="21"/> + <action description="Toggle various About Land > Options settings" longdescription="Toggle 'Safe (no damage)', 'Fly', and allow other Residents to: 'Edit Terrain', 'Build', 'Create Landmarks', and 'Run Scripts' on group-owned land in About Land > Options tab." name="land options" value="22"/> + </action_set> + <action_set description="These Abilities include powers which allow Members to bypass restrictions on group-owned parcels." name="Parcel Powers"> + <action description="Always allow 'Edit Terrain'" longdescription="Members in a Role with this Ability can edit terrain on a group-owned parcel, even if it's turned off in About Land > Options tab." name="land allow edit land" value="23"/> + <action description="Always allow 'Fly'" longdescription="Members in a Role with this Ability can fly on a group-owned parcel, even if it's turned off in About Land > Options tab." name="land allow fly" value="24"/> + <action description="Always allow 'Create Objects'" longdescription="Members in a Role with this Ability can create objects on a group-owned parcel, even if it's turned off in About Land > Options tab." name="land allow create" value="25"/> + <action description="Always allow 'Create Landmark'" longdescription="Members in a Role with this Ability can landmark a group-owned parcel, even if it's turned off in About Land > Options tab." name="land allow landmark" value="26"/> + <action description="Allow 'Set Home to Here' on group land" longdescription="Members in a Role with this Ability can use World menu > Landmarks > Set Home to Here on a parcel deeded to this group." name="land allow set home" value="28"/> + <action description="Allow 'Event Hosting' on group land" longdescription="Members in a Role with this Ability can select group owned parcels as venus when hosting an event." name="land allow host event" value="41"/> + </action_set> + <action_set description="These Abilities include powers to allow or restrict access to group-owned parcels, including freezing and ejecting Residents." name="Parcel Access"> + <action description="Manage parcel Access lists" longdescription="Manage parcel Access lists in About Land > Access tab." name="land manage allowed" value="29"/> + <action description="Manage parcel Ban lists" longdescription="Manage parcel Ban lists in About Land > Access tab." name="land manage banned" value="30"/> + <action description="Change parcel 'Sell passes to' settings" longdescription="Change parcel 'Sell passes to' settings in About Land > Access tab." name="land manage passes" value="31"/> + <action description="Eject and freeze Residents on parcels" longdescription="Members in a Role with this Ability can handle an unwelcome Resident on a group-owned parcel by right-clicking them, then selecting 'Eject' or 'Freeze'." name="land admin" value="32"/> + </action_set> + <action_set description="These Abilities include powers to allow members to return objects and place and move Linden plants. This is useful for Members to clean up litter and do landscaping, but it should also be used with care, because there's no undo for returning objects." name="Parcel Content"> + <action description="Return objects owned by group" longdescription="Return objects on group-owned parcels that are owned by the group in About Land > Objects tab." name="land return group owned" value="48"/> + <action description="Return objects set to group" longdescription="Return objects on group-owned parcels that are set to the group in About Land > Objects tab." name="land return group set" value="33"/> + <action description="Return non-group objects" longdescription="Return objects on group-owned parcels that are non-group in About Land > Objects tab." name="land return non group" value="34"/> + <action description="Landscaping using Linden plants" longdescription="Landscaping ability to place and move Linden trees, plants, and grasses. These items can be found in your inventory's Library > Objects folder, or they can be created via the Build menu." name="land gardening" value="35"/> + </action_set> + <action_set description="These Abilities include powers to deed, modify, and sell group-owned objects. These changes are done in the Build Tools > General tab. Right-click an object and Edit to see its settings." name="Object Management"> + <action description="Deed objects to group" longdescription="Deed objects to group in the Build Tools > General tab." name="object deed" value="36"/> + <action description="Manipulate (move, copy, modify) group-owned objects" longdescription="Manipulate (move, copy, modify) group-owned objects in the Build Tools > General tab." name="object manipulate" value="38"/> + <action description="Set group-owned objects for sale" longdescription="Set group-owned objects for sale in the Build Tools > General tab." name="object set sale" value="39"/> + </action_set> + <action_set description="These Abilities include powers which require Members to pay group liabilities and receive group dividends, and restrict access to group account history." name="Accounting"> + <action description="Pay group liabilities and receive group dividends" longdescription="Members in a Role with this Ability will automatically pay group liabilities and receive group dividends. This means they will receive a portion of group-owned land sales which are distributed daily, as well as contribute towards things like parcel listing fees." name="accounting accountable" value="40"/> + </action_set> + <action_set description="These Abilities include powers to allow Members to send, receive, and view group Notices." name="Notices"> + <action description="Send Notices" longdescription="Members in a Role with this Ability can send Notices via the Group > Notices section." name="notices send" value="42"/> + <action description="Receive Notices and view past Notices" longdescription="Members in a Role with this Ability can receive Notices and view past Notices in Group > Notices section." name="notices receive" value="43"/> + </action_set> + <action_set description="These Abilities include powers to allow or restrict access to group chat sessions and group voice chat." name="Chat"> + <action description="Join Group Chat" longdescription="Members in a Role with this Ability can join group chat sessions, for text and voice." name="join group chat" value="16"/> + <action description="Join Group Voice Chat" longdescription="Members in a Role with this Ability can join group voice chat sessions. NOTE: The Join Group Chat ability is required to access the voice chat session." name="join voice chat" value="27"/> + <action description="Moderate Group Chat" longdescription="Members in a Role with this Ability can control access and participation in group voice and text chat sessions." name="moderate group chat" value="37"/> + </action_set> +</role_actions> diff --git a/indra/newview/skins/default/xui/zh/sidepanel_appearance.xml b/indra/newview/skins/default/xui/zh/sidepanel_appearance.xml new file mode 100644 index 0000000000..1832886135 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/sidepanel_appearance.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Outfits" name="appearance panel"> + <string name="No Outfit" value="No Outfit"/> + <string name="Unsaved Changes" value="Unsaved changes"/> + <string name="Now Wearing" value="Now wearing..."/> + <string name="Changing outfits" value="Changing outfits"/> + <panel name="panel_currentlook"> + <button label="E" name="editappearance_btn"/> + <button label="O" name="openoutfit_btn"/> + <text name="currentlook_status"> + (Status) + </text> + <text name="currentlook_name"> + MyOutfit With a really Long Name like MOOSE + </text> + <button label="" name="edit_outfit_btn" tool_tip="Edit this outfit"/> + </panel> + <filter_editor label="Filter Outfits" name="Filter"/> +</panel> diff --git a/indra/newview/skins/default/xui/zh/sidepanel_inventory.xml b/indra/newview/skins/default/xui/zh/sidepanel_inventory.xml new file mode 100644 index 0000000000..4230d60c45 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/sidepanel_inventory.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel label="Things" name="objects panel"> + <panel label="" name="sidepanel__inventory_panel"> + <panel name="button_panel"> + <layout_stack name="button_panel_ls"> + <layout_panel name="info_btn_lp"> + <button label="Profile" name="info_btn" tool_tip="Show object profile"/> + </layout_panel> + <layout_panel name="share_btn_lp"> + <button label="分享" name="share_btn" tool_tip="Share an inventory item"/> + </layout_panel> + <layout_panel name="shop_btn_lp"> + <button label="Shop" name="shop_btn" tool_tip="Open Marketplace webpage"/> + <button label="Wear" name="wear_btn" tool_tip="Wear seleceted outfit"/> + <button label="Play" name="play_btn"/> + <button label="Teleport" name="teleport_btn" tool_tip="Teleport to the selected area"/> + </layout_panel> + </layout_stack> + </panel> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/sidepanel_item_info.xml b/indra/newview/skins/default/xui/zh/sidepanel_item_info.xml new file mode 100644 index 0000000000..d1332ddb7c --- /dev/null +++ b/indra/newview/skins/default/xui/zh/sidepanel_item_info.xml @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="item properties" title="Item Profile"> + <panel.string name="unknown"> + (未知) + </panel.string> + <panel.string name="public"> + (公開) + </panel.string> + <panel.string name="you_can"> + ä½ å¯ä»¥ï¼š + </panel.string> + <panel.string name="owner_can"> + æ“有者å¯ä»¥ï¼š + </panel.string> + <panel.string name="acquiredDate"> + [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] + </panel.string> + <panel.string name="origin_inventory"> + (Inventory) + </panel.string> + <panel.string name="origin_inworld"> + (Inworld) + </panel.string> + <text name="title" value="Item Profile"/> + <text name="origin" value="(Inventory)"/> + <scroll_container name="item_profile_scroll"> + <panel label="" name="item_profile"> + <text name="LabelItemNameTitle"> + å稱: + </text> + <text name="LabelItemDescTitle"> + æ述: + </text> + <text name="LabelCreatorTitle"> + å‰µé€ è€…ï¼š + </text> + <text name="LabelOwnerTitle"> + æ“有者: + </text> + <text name="LabelAcquiredTitle"> + Acquired: + </text> + <panel name="perms_inv"> + <text name="perm_modify"> + ä½ å¯ä»¥ï¼š + </text> + <check_box label="修改" name="CheckOwnerModify"/> + <check_box label="覆製" name="CheckOwnerCopy"/> + <check_box label="轉移" name="CheckOwnerTransfer"/> + <text name="AnyoneLabel"> + 任何人: + </text> + <check_box label="覆製" name="CheckEveryoneCopy"/> + <text name="GroupLabel"> + Group: + </text> + <check_box label="分享" name="CheckShareWithGroup" tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions."/> + <text name="NextOwnerLabel"> + 下一個æ“有者: + </text> + <check_box label="修改" name="CheckNextOwnerModify"/> + <check_box label="覆製" name="CheckNextOwnerCopy"/> + <check_box label="轉移" name="CheckNextOwnerTransfer" tool_tip="Next owner can give away or resell this object"/> + </panel> + <check_box label="出售" name="CheckPurchase"/> + <combo_box name="combobox sale copy"> + <combo_box.item label="Copy" name="Copy"/> + <combo_box.item label="Original" name="Original"/> + </combo_box> + <spinner label="åƒ¹æ ¼ï¼š L$" name="Edit Cost"/> + </panel> + </scroll_container> + <panel name="button_panel"> + <button label="å–銷" name="cancel_btn"/> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/sidepanel_task_info.xml b/indra/newview/skins/default/xui/zh/sidepanel_task_info.xml new file mode 100644 index 0000000000..14d67d52b8 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/sidepanel_task_info.xml @@ -0,0 +1,123 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="object properties" title="Object Profile"> + <panel.string name="text deed continued"> + Deed + </panel.string> + <panel.string name="text deed"> + Deed + </panel.string> + <panel.string name="text modify info 1"> + You can modify this object + </panel.string> + <panel.string name="text modify info 2"> + You can modify these objects + </panel.string> + <panel.string name="text modify info 3"> + You can't modify this object + </panel.string> + <panel.string name="text modify info 4"> + You can't modify these objects + </panel.string> + <panel.string name="text modify warning"> + This object has linked parts + </panel.string> + <panel.string name="Cost Default"> + åƒ¹æ ¼ï¼š L$ + </panel.string> + <panel.string name="Cost Total"> + 總價: L$ + </panel.string> + <panel.string name="Cost Per Unit"> + Price Per: L$ + </panel.string> + <panel.string name="Cost Mixed"> + Mixed Price + </panel.string> + <panel.string name="Sale Mixed"> + Mixed Sale + </panel.string> + <text name="title" value="Object Profile"/> + <text name="where" value="(Inworld)"/> + <panel label="" name="properties_panel"> + <text name="Name:"> + å稱: + </text> + <text name="Description:"> + æ述: + </text> + <text name="CreatorNameLabel"> + å‰µé€ è€…ï¼š + </text> + <text name="Owner:"> + æ“有者: + </text> + <text name="Group_label"> + Group: + </text> + <button name="button set group" tool_tip="Choose a group to share this object's permissions"/> + <name_box initial_value="載入ä¸..." name="Group Name Proxy"/> + <button label="Deed" label_selected="Deed" name="button deed" tool_tip="Deeding gives this item away with next owner permissions. Group shared objects can be deeded by a group officer."/> + <text name="label click action"> + Click to: + </text> + <combo_box name="clickaction"> + <combo_box.item label="Touch (default)" name="Touch/grab(default)"/> + <combo_box.item label="Sit on object" name="Sitonobject"/> + <combo_box.item label="Buy object" name="Buyobject"/> + <combo_box.item label="Pay object" name="Payobject"/> + <combo_box.item label="Open" name="Open"/> + </combo_box> + <panel name="perms_inv"> + <text name="perm_modify"> + You can modify this object + </text> + <text name="Anyone can:"> + 任何人: + </text> + <check_box label="覆製" name="checkbox allow everyone copy"/> + <check_box label="移動" name="checkbox allow everyone move"/> + <text name="GroupLabel"> + Group: + </text> + <check_box label="分享" name="checkbox share with group" tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions."/> + <text name="NextOwnerLabel"> + 下一個æ“有者: + </text> + <check_box label="修改" name="checkbox next owner can modify"/> + <check_box label="覆製" name="checkbox next owner can copy"/> + <check_box label="轉移" name="checkbox next owner can transfer" tool_tip="Next owner can give away or resell this object"/> + </panel> + <check_box label="出售" name="checkbox for sale"/> + <combo_box name="sale type"> + <combo_box.item label="Copy" name="Copy"/> + <combo_box.item label="Contents" name="Contents"/> + <combo_box.item label="Original" name="Original"/> + </combo_box> + <spinner label="åƒ¹æ ¼ï¼š L$" name="Edit Cost"/> + <check_box label="Show in search" name="search_check" tool_tip="Let people see this object in search results"/> + <text name="B:"> + B: + </text> + <text name="O:"> + O: + </text> + <text name="G:"> + G: + </text> + <text name="E:"> + E: + </text> + <text name="N:"> + N: + </text> + <text name="F:"> + F: + </text> + </panel> + <panel name="button_panel"> + <button label="Open" name="open_btn"/> + <button label="Pay" name="pay_btn"/> + <button label="購買" name="buy_btn"/> + <button label="Details" name="details_btn"/> + </panel> +</panel> diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml new file mode 100644 index 0000000000..4eb845d791 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/strings.xml @@ -0,0 +1,4454 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<!-- This file contains strings that used to be hardcoded in the source. + It is only for those strings which do not belong in a floater. + For example, the strings used in avatar chat bubbles, and strings + that are returned from one component and may appear in many places--> +<strings> + <string name="SECOND_LIFE"> + Second Life + </string> + <string name="APP_NAME"> + Second Life + </string> + <string name="CAPITALIZED_APP_NAME"> + SECOND LIFE + </string> + <string name="SECOND_LIFE_GRID"> + Second Life Grid + </string> + <string name="SUPPORT_SITE"> + Second Life Support Portal + </string> + <string name="StartupDetectingHardware"> + Detecting hardware... + </string> + <string name="StartupLoading"> + Loading [APP_NAME]... + </string> + <string name="StartupClearingCache"> + Clearing cache... + </string> + <string name="StartupInitializingTextureCache"> + Initializing Texture Cache... + </string> + <string name="StartupInitializingVFS"> + Initializing VFS... + </string> + <string name="ProgressRestoring"> + Restoring... + </string> + <string name="ProgressChangingResolution"> + Changing Resolution... + </string> + <string name="Fullbright"> + Fullbright (Legacy) + </string> + <string name="LoginInProgress"> + Logging in. [APP_NAME] may appear frozen. Please wait. + </string> + <string name="LoginInProgressNoFrozen"> + Logging in... + </string> + <string name="LoginAuthenticating"> + Authenticating + </string> + <string name="LoginMaintenance"> + Performing account maintenance... + </string> + <string name="LoginAttempt"> + Previous login attempt failed. Logging in, attempt [NUMBER] + </string> + <string name="LoginPrecaching"> + Loading world... + </string> + <string name="LoginInitializingBrowser"> + Initializing embedded web browser... + </string> + <string name="LoginInitializingMultimedia"> + Initializing multimedia... + </string> + <string name="LoginInitializingFonts"> + Loading fonts... + </string> + <string name="LoginVerifyingCache"> + Verifying cache files (can take 60-90 seconds)... + </string> + <string name="LoginProcessingResponse"> + Processing Response... + </string> + <string name="LoginInitializingWorld"> + Initializing World... + </string> + <string name="LoginDecodingImages"> + Decoding images... + </string> + <string name="LoginInitializingQuicktime"> + Initializing QuickTime... + </string> + <string name="LoginQuicktimeNotFound"> + QuickTime not found - unable to initialize. + </string> + <string name="LoginQuicktimeOK"> + QuickTime initialized successfully. + </string> + <string name="LoginWaitingForRegionHandshake"> + Waiting for region handshake... + </string> + <string name="LoginConnectingToRegion"> + Connecting to region... + </string> + <string name="LoginDownloadingClothing"> + Downloading clothing... + </string> + <string name="InvalidCertificate"> + The server returned an invalid or corrupt certificate. Please contact the Grid administrator. + </string> + <string name="CertInvalidHostname"> + An invalid hostname was used to access the server, please check your SLURL or Grid hostname. + </string> + <string name="CertExpired"> + The certificate returned by the Grid appears to be expired. Please check your system clock, or contact your Grid administrator. + </string> + <string name="CertKeyUsage"> + The certificate returned by the server could not be used for SSL. Please contact your Grid administrator. + </string> + <string name="CertBasicConstraints"> + Too many certificates were in the servers Certificate chain. Please contact your Grid administrator. + </string> + <string name="CertInvalidSignature"> + The certificate signature returned by the Grid server could not be verified. Please contact your Grid administrator. + </string> + <string name="LoginFailedNoNetwork"> + Network Error: Could not establish connection, please check your network connection. + </string> + <string name="LoginFailed"> + Login failed. + </string> + <string name="Quit"> + Quit + </string> + <string name="create_account_url"> + http://join.secondlife.com/ + </string> + <string name="AgentLostConnection"> + This region may be experiencing trouble. Please check your connection to the Internet. + </string> + <string name="SavingSettings"> + Saving your settings... + </string> + <string name="LoggingOut"> + Logging out... + </string> + <string name="ShuttingDown"> + Shutting down... + </string> + <string name="YouHaveBeenDisconnected"> + You have been disconnected from the region you were in. + </string> + <string name="SentToInvalidRegion"> + You were sent to an invalid region. + </string> + <string name="TestingDisconnect"> + Testing viewer disconnect + </string> + <string name="TooltipPerson"> + Person + </string> + <string name="TooltipNoName"> + (no name) + </string> + <string name="TooltipOwner"> + æ“有者: + </string> + <string name="TooltipPublic"> + Public + </string> + <string name="TooltipIsGroup"> + (Group) + </string> + <string name="TooltipForSaleL$"> + 出售: L$[AMOUNT] + </string> + <string name="TooltipFlagGroupBuild"> + Group Build + </string> + <string name="TooltipFlagNoBuild"> + No Build + </string> + <string name="TooltipFlagNoEdit"> + Group Build + </string> + <string name="TooltipFlagNotSafe"> + Not Safe + </string> + <string name="TooltipFlagNoFly"> + No Fly + </string> + <string name="TooltipFlagGroupScripts"> + Group Scripts + </string> + <string name="TooltipFlagNoScripts"> + No Scripts + </string> + <string name="TooltipLand"> + Land: + </string> + <string name="TooltipMustSingleDrop"> + Only a single item can be dragged here + </string> + <string name="TooltipPrice" value="L$[AMOUNT]:"/> + <string name="TooltipHttpUrl"> + Click to view this web page + </string> + <string name="TooltipSLURL"> + Click to view this location's information + </string> + <string name="TooltipAgentUrl"> + Click to view this Resident's profile + </string> + <string name="TooltipAgentInspect"> + Learn more about this Resident + </string> + <string name="TooltipAgentMute"> + Click to mute this Resident + </string> + <string name="TooltipAgentUnmute"> + Click to unmute this Resident + </string> + <string name="TooltipAgentIM"> + Click to IM this Resident + </string> + <string name="TooltipAgentPay"> + Click to Pay this Resident + </string> + <string name="TooltipAgentOfferTeleport"> + Click to offer a teleport request to this Resident + </string> + <string name="TooltipAgentRequestFriend"> + Click to send a friend request to this Resident + </string> + <string name="TooltipGroupUrl"> + Click to view this group's description + </string> + <string name="TooltipEventUrl"> + Click to view this event's description + </string> + <string name="TooltipClassifiedUrl"> + Click to view this classified + </string> + <string name="TooltipParcelUrl"> + Click to view this parcel's description + </string> + <string name="TooltipTeleportUrl"> + Click to teleport to this location + </string> + <string name="TooltipObjectIMUrl"> + Click to view this object's description + </string> + <string name="TooltipMapUrl"> + Click to view this location on a map + </string> + <string name="TooltipSLAPP"> + Click to run the secondlife:// command + </string> + <string name="CurrentURL" value="CurrentURL: [CurrentURL]"/> + <string name="SLurlLabelTeleport"> + Teleport to + </string> + <string name="SLurlLabelShowOnMap"> + Show Map for + </string> + <string name="SLappAgentMute"> + Mute + </string> + <string name="SLappAgentUnmute"> + Unmute + </string> + <string name="SLappAgentIM"> + IM + </string> + <string name="SLappAgentPay"> + Pay + </string> + <string name="SLappAgentOfferTeleport"> + Offer Teleport to + </string> + <string name="SLappAgentRequestFriend"> + Friend Request + </string> + <string name="BUTTON_CLOSE_DARWIN"> + Close (⌘W) + </string> + <string name="BUTTON_CLOSE_WIN"> + Close (Ctrl+W) + </string> + <string name="BUTTON_CLOSE_CHROME"> + 關閉 + </string> + <string name="BUTTON_RESTORE"> + Restore + </string> + <string name="BUTTON_MINIMIZE"> + Minimize + </string> + <string name="BUTTON_TEAR_OFF"> + Tear Off + </string> + <string name="BUTTON_DOCK"> + Dock + </string> + <string name="BUTTON_HELP"> + Show Help + </string> + <string name="Searching"> + Searching... + </string> + <string name="NoneFound"> + None found. + </string> + <string name="RetrievingData"> + Retrieving... + </string> + <string name="ReleaseNotes"> + Release Notes + </string> + <string name="LoadingData"> + 載入ä¸... + </string> + <string name="AvatarNameNobody"> + (nobody) + </string> + <string name="AvatarNameWaiting"> + (waiting) + </string> + <string name="AvatarNameMultiple"> + (multiple) + </string> + <string name="GroupNameNone"> + (無) + </string> + <string name="AvalineCaller"> + Avaline Caller [ORDER] + </string> + <string name="AssetErrorNone"> + No error + </string> + <string name="AssetErrorRequestFailed"> + Asset request: failed + </string> + <string name="AssetErrorNonexistentFile"> + Asset request: non-existent file + </string> + <string name="AssetErrorNotInDatabase"> + Asset request: asset not found in database + </string> + <string name="AssetErrorEOF"> + End of file + </string> + <string name="AssetErrorCannotOpenFile"> + Cannot open file + </string> + <string name="AssetErrorFileNotFound"> + File not found + </string> + <string name="AssetErrorTCPTimeout"> + File transfer timeout + </string> + <string name="AssetErrorCircuitGone"> + Circuit gone + </string> + <string name="AssetErrorPriceMismatch"> + Viewer and server do not agree on price + </string> + <string name="AssetErrorUnknownStatus"> + Unknown status + </string> + <string name="texture"> + texture + </string> + <string name="sound"> + sound + </string> + <string name="calling card"> + calling card + </string> + <string name="landmark"> + landmark + </string> + <string name="legacy script"> + legacy script + </string> + <string name="clothing"> + clothing + </string> + <string name="object"> + object + </string> + <string name="note card"> + notecard + </string> + <string name="folder"> + 資料夾 + </string> + <string name="root"> + root + </string> + <string name="lsl2 script"> + LSL2 script + </string> + <string name="lsl bytecode"> + LSL bytecode + </string> + <string name="tga texture"> + tga texture + </string> + <string name="body part"> + body part + </string> + <string name="snapshot"> + snapshot + </string> + <string name="lost and found"> + Lost and Found + </string> + <string name="targa image"> + targa image + </string> + <string name="trash"> + Trash + </string> + <string name="jpeg image"> + jpeg image + </string> + <string name="animation"> + animation + </string> + <string name="gesture"> + gesture + </string> + <string name="simstate"> + simstate + </string> + <string name="favorite"> + favorite + </string> + <string name="symbolic link"> + link + </string> + <string name="symbolic folder link"> + folder link + </string> + <string name="AvatarEditingAppearance"> + (Editing Appearance) + </string> + <string name="AvatarAway"> + Away + </string> + <string name="AvatarBusy"> + Busy + </string> + <string name="AvatarMuted"> + Blocked + </string> + <string name="anim_express_afraid"> + Afraid + </string> + <string name="anim_express_anger"> + Angry + </string> + <string name="anim_away"> + Away + </string> + <string name="anim_backflip"> + Backflip + </string> + <string name="anim_express_laugh"> + Belly Laugh + </string> + <string name="anim_express_toothsmile"> + BigSmile + </string> + <string name="anim_blowkiss"> + Blow Kiss + </string> + <string name="anim_express_bored"> + Bored + </string> + <string name="anim_bow"> + Bow + </string> + <string name="anim_clap"> + Clap + </string> + <string name="anim_courtbow"> + Court Bow + </string> + <string name="anim_express_cry"> + Cry + </string> + <string name="anim_dance1"> + Dance 1 + </string> + <string name="anim_dance2"> + Dance 2 + </string> + <string name="anim_dance3"> + Dance 3 + </string> + <string name="anim_dance4"> + Dance 4 + </string> + <string name="anim_dance5"> + Dance 5 + </string> + <string name="anim_dance6"> + Dance 6 + </string> + <string name="anim_dance7"> + Dance 7 + </string> + <string name="anim_dance8"> + Dance 8 + </string> + <string name="anim_express_disdain"> + Disdain + </string> + <string name="anim_drink"> + Drink + </string> + <string name="anim_express_embarrased"> + Embarrassed + </string> + <string name="anim_angry_fingerwag"> + Finger Wag + </string> + <string name="anim_fist_pump"> + Fist Pump + </string> + <string name="anim_yoga_float"> + Floating Yoga + </string> + <string name="anim_express_frown"> + Frown + </string> + <string name="anim_impatient"> + Impatient + </string> + <string name="anim_jumpforjoy"> + Jump For Joy + </string> + <string name="anim_kissmybutt"> + Kiss My Butt + </string> + <string name="anim_express_kiss"> + Kiss + </string> + <string name="anim_laugh_short"> + Laugh + </string> + <string name="anim_musclebeach"> + Muscle Beach + </string> + <string name="anim_no_unhappy"> + No (Unhappy) + </string> + <string name="anim_no_head"> + No + </string> + <string name="anim_nyanya"> + Nya-nya-nya + </string> + <string name="anim_punch_onetwo"> + One-Two Punch + </string> + <string name="anim_express_open_mouth"> + Open Mouth + </string> + <string name="anim_peace"> + Peace + </string> + <string name="anim_point_you"> + Point at Other + </string> + <string name="anim_point_me"> + Point at Self + </string> + <string name="anim_punch_l"> + Punch Left + </string> + <string name="anim_punch_r"> + Punch Right + </string> + <string name="anim_rps_countdown"> + RPS count + </string> + <string name="anim_rps_paper"> + RPS paper + </string> + <string name="anim_rps_rock"> + RPS rock + </string> + <string name="anim_rps_scissors"> + RPS scissors + </string> + <string name="anim_express_repulsed"> + Repulsed + </string> + <string name="anim_kick_roundhouse_r"> + Roundhouse Kick + </string> + <string name="anim_express_sad"> + Sad + </string> + <string name="anim_salute"> + Salute + </string> + <string name="anim_shout"> + Shout + </string> + <string name="anim_express_shrug"> + Shrug + </string> + <string name="anim_express_smile"> + Smile + </string> + <string name="anim_smoke_idle"> + Smoke Idle + </string> + <string name="anim_smoke_inhale"> + Smoke Inhale + </string> + <string name="anim_smoke_throw_down"> + Smoke Throw Down + </string> + <string name="anim_express_surprise"> + Surprise + </string> + <string name="anim_sword_strike_r"> + Sword Strike + </string> + <string name="anim_angry_tantrum"> + Tantrum + </string> + <string name="anim_express_tongue_out"> + TongueOut + </string> + <string name="anim_hello"> + Wave + </string> + <string name="anim_whisper"> + Whisper + </string> + <string name="anim_whistle"> + Whistle + </string> + <string name="anim_express_wink"> + Wink + </string> + <string name="anim_wink_hollywood"> + Wink (Hollywood) + </string> + <string name="anim_express_worry"> + Worry + </string> + <string name="anim_yes_happy"> + Yes (Happy) + </string> + <string name="anim_yes_head"> + 是 + </string> + <string name="texture_loading"> + 載入ä¸... + </string> + <string name="worldmap_offline"> + Offline + </string> + <string name="worldmap_item_tooltip_format"> + [AREA] m² L$[PRICE] + </string> + <string name="worldmap_results_none_found"> + None found. + </string> + <string name="Ok"> + 確定 + </string> + <string name="Premature end of file"> + Premature end of file + </string> + <string name="ST_NO_JOINT"> + Can't find ROOT or JOINT. + </string> + <string name="whisper"> + whispers: + </string> + <string name="shout"> + shouts: + </string> + <string name="ringing"> + Connecting to in-world Voice Chat... + </string> + <string name="connected"> + Connected + </string> + <string name="unavailable"> + Voice not available at your current location + </string> + <string name="hang_up"> + Disconnected from in-world Voice Chat + </string> + <string name="reconnect_nearby"> + You will now be reconnected to Nearby Voice Chat + </string> + <string name="ScriptQuestionCautionChatGranted"> + '[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been granted permission to: [PERMISSIONS]. + </string> + <string name="ScriptQuestionCautionChatDenied"> + '[OBJECTNAME]', an object owned by '[OWNERNAME]', located in [REGIONNAME] at [REGIONPOS], has been denied permission to: [PERMISSIONS]. + </string> + <string name="ScriptTakeMoney"> + Take Linden dollars (L$) from you + </string> + <string name="ActOnControlInputs"> + Act on your control inputs + </string> + <string name="RemapControlInputs"> + Remap your control inputs + </string> + <string name="AnimateYourAvatar"> + Animate your avatar + </string> + <string name="AttachToYourAvatar"> + Attach to your avatar + </string> + <string name="ReleaseOwnership"> + Release ownership and become public + </string> + <string name="LinkAndDelink"> + Link and delink from other objects + </string> + <string name="AddAndRemoveJoints"> + Add and remove joints with other objects + </string> + <string name="ChangePermissions"> + Change its permissions + </string> + <string name="TrackYourCamera"> + Track your camera + </string> + <string name="ControlYourCamera"> + Control your camera + </string> + <string name="NotConnected"> + Not Connected + </string> + <string name="SIM_ACCESS_PG"> + 一般 + </string> + <string name="SIM_ACCESS_MATURE"> + Moderate + </string> + <string name="SIM_ACCESS_ADULT"> + Adult + </string> + <string name="SIM_ACCESS_DOWN"> + Offline + </string> + <string name="SIM_ACCESS_MIN"> + 未知 + </string> + <string name="land_type_unknown"> + (未知) + </string> + <string name="Estate / Full Region"> + Estate / Full Region + </string> + <string name="Estate / Homestead"> + Estate / Homestead + </string> + <string name="Mainland / Homestead"> + Mainland / Homestead + </string> + <string name="Mainland / Full Region"> + Mainland / Full Region + </string> + <string name="all_files"> + All Files + </string> + <string name="sound_files"> + Sounds + </string> + <string name="animation_files"> + Animations + </string> + <string name="image_files"> + Images + </string> + <string name="save_file_verb"> + Save + </string> + <string name="load_file_verb"> + Load + </string> + <string name="targa_image_files"> + Targa Images + </string> + <string name="bitmap_image_files"> + Bitmap Images + </string> + <string name="avi_movie_file"> + AVI Movie File + </string> + <string name="xaf_animation_file"> + XAF Anim File + </string> + <string name="xml_file"> + XML File + </string> + <string name="raw_file"> + RAW File + </string> + <string name="compressed_image_files"> + Compressed Images + </string> + <string name="load_files"> + Load Files + </string> + <string name="choose_the_directory"> + Choose Directory + </string> + <string name="AvatarSetNotAway"> + Not Away + </string> + <string name="AvatarSetAway"> + Away + </string> + <string name="AvatarSetNotBusy"> + Not Busy + </string> + <string name="AvatarSetBusy"> + Busy + </string> + <string name="shape"> + Shape + </string> + <string name="skin"> + Skin + </string> + <string name="hair"> + Hair + </string> + <string name="eyes"> + çœ¼ç› + </string> + <string name="shirt"> + 襯衫 + </string> + <string name="pants"> + 褲å + </string> + <string name="shoes"> + éž‹å + </string> + <string name="socks"> + 襪å + </string> + <string name="jacket"> + 夾克 + </string> + <string name="gloves"> + 手套 + </string> + <string name="undershirt"> + 內衣 + </string> + <string name="underpants"> + 內褲 + </string> + <string name="skirt"> + 裙å + </string> + <string name="alpha"> + Alpha + </string> + <string name="tattoo"> + åˆºé’ + </string> + <string name="physics"> + Physics + </string> + <string name="invalid"> + invalid + </string> + <string name="none"> + ç„¡ + </string> + <string name="shirt_not_worn"> + Shirt not worn + </string> + <string name="pants_not_worn"> + Pants not worn + </string> + <string name="shoes_not_worn"> + Shoes not worn + </string> + <string name="socks_not_worn"> + Socks not worn + </string> + <string name="jacket_not_worn"> + Jacket not worn + </string> + <string name="gloves_not_worn"> + Gloves not worn + </string> + <string name="undershirt_not_worn"> + Undershirt not worn + </string> + <string name="underpants_not_worn"> + Underpants not worn + </string> + <string name="skirt_not_worn"> + Skirt not worn + </string> + <string name="alpha_not_worn"> + Alpha not worn + </string> + <string name="tattoo_not_worn"> + Tattoo not worn + </string> + <string name="physics_not_worn"> + Physics not worn + </string> + <string name="invalid_not_worn"> + invalid + </string> + <string name="create_new_shape"> + Create new shape + </string> + <string name="create_new_skin"> + Create new skin + </string> + <string name="create_new_hair"> + Create new hair + </string> + <string name="create_new_eyes"> + Create new eyes + </string> + <string name="create_new_shirt"> + Create new shirt + </string> + <string name="create_new_pants"> + Create new pants + </string> + <string name="create_new_shoes"> + Create new shoes + </string> + <string name="create_new_socks"> + Create new socks + </string> + <string name="create_new_jacket"> + Create new jacket + </string> + <string name="create_new_gloves"> + Create new gloves + </string> + <string name="create_new_undershirt"> + Create new undershirt + </string> + <string name="create_new_underpants"> + Create new underpants + </string> + <string name="create_new_skirt"> + Create new skirt + </string> + <string name="create_new_alpha"> + Create new alpha + </string> + <string name="create_new_tattoo"> + Create new tattoo + </string> + <string name="create_new_physics"> + Create new physics + </string> + <string name="create_new_invalid"> + invalid + </string> + <string name="NewWearable"> + New [WEARABLE_ITEM] + </string> + <string name="next"> + Next + </string> + <string name="ok"> + 確定 + </string> + <string name="GroupNotifyGroupNotice"> + Group Notice + </string> + <string name="GroupNotifyGroupNotices"> + Group Notices + </string> + <string name="GroupNotifySentBy"> + Sent by + </string> + <string name="GroupNotifyAttached"> + Attached: + </string> + <string name="GroupNotifyViewPastNotices"> + View past notices or opt-out of receiving these messages here. + </string> + <string name="GroupNotifyOpenAttachment"> + Open Attachment + </string> + <string name="GroupNotifySaveAttachment"> + Save Attachment + </string> + <string name="TeleportOffer"> + Teleport offering + </string> + <string name="StartUpNotifications"> + New notifications arrived while you were away. + </string> + <string name="OverflowInfoChannelString"> + You have %d more notification + </string> + <string name="BodyPartsRightArm"> + Right Arm + </string> + <string name="BodyPartsHead"> + Head + </string> + <string name="BodyPartsLeftArm"> + Left Arm + </string> + <string name="BodyPartsLeftLeg"> + Left Leg + </string> + <string name="BodyPartsTorso"> + Torso + </string> + <string name="BodyPartsRightLeg"> + Right Leg + </string> + <string name="GraphicsQualityLow"> + Low + </string> + <string name="GraphicsQualityMid"> + Mid + </string> + <string name="GraphicsQualityHigh"> + High + </string> + <string name="LeaveMouselook"> + Press ESC to return to World View + </string> + <string name="InventoryNoMatchingItems"> + Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search]. + </string> + <string name="PlacesNoMatchingItems"> + Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search]. + </string> + <string name="FavoritesNoMatchingItems"> + Drag a landmark here to add it to your favorites. + </string> + <string name="InventoryNoTexture"> + You do not have a copy of this texture in your inventory + </string> + <string name="no_transfer" value="(no transfer)"/> + <string name="no_modify" value="(no modify)"/> + <string name="no_copy" value="(no copy)"/> + <string name="worn" value="(worn)"/> + <string name="link" value="(link)"/> + <string name="broken_link" value="(broken_link)"/> + <string name="LoadingContents"> + Loading contents... + </string> + <string name="NoContents"> + No contents + </string> + <string name="WornOnAttachmentPoint" value="(worn on [ATTACHMENT_POINT])"/> + <string name="ActiveGesture" value="[GESLABEL] (active)"/> + <string name="PermYes"> + 是 + </string> + <string name="PermNo"> + å¦ + </string> + <string name="Chat Message" value="Chat :"/> + <string name="Sound" value="Sound :"/> + <string name="Wait" value="--- Wait :"/> + <string name="AnimFlagStop" value="Stop Animation :"/> + <string name="AnimFlagStart" value="Start Animation :"/> + <string name="Wave" value="Wave"/> + <string name="GestureActionNone" value="ç„¡"/> + <string name="HelloAvatar" value="Hello, avatar!"/> + <string name="ViewAllGestures" value="察看全部 >>"/> + <string name="GetMoreGestures" value="Get More >>"/> + <string name="Animations" value="Animations,"/> + <string name="Calling Cards" value="Calling Cards,"/> + <string name="Clothing" value="Clothing,"/> + <string name="Gestures" value="Gestures,"/> + <string name="Landmarks" value="Landmarks,"/> + <string name="Notecards" value="Notecards,"/> + <string name="Objects" value="Objects,"/> + <string name="Scripts" value="Scripts,"/> + <string name="Sounds" value="Sounds,"/> + <string name="Textures" value="Textures,"/> + <string name="Snapshots" value="Snapshots,"/> + <string name="No Filters" value="No"/> + <string name="Since Logoff" value="- Since Logoff"/> + <string name="InvFolder My Inventory"> + My Inventory + </string> + <string name="InvFolder My Favorites"> + My Favorites + </string> + <string name="InvFolder Library"> + Library + </string> + <string name="InvFolder Textures"> + Textures + </string> + <string name="InvFolder Sounds"> + Sounds + </string> + <string name="InvFolder Calling Cards"> + Calling Cards + </string> + <string name="InvFolder Landmarks"> + Landmarks + </string> + <string name="InvFolder Scripts"> + Scripts + </string> + <string name="InvFolder Clothing"> + Clothing + </string> + <string name="InvFolder Objects"> + Objects + </string> + <string name="InvFolder Notecards"> + Notecards + </string> + <string name="InvFolder New Folder"> + 新資料夾 + </string> + <string name="InvFolder Inventory"> + Inventory + </string> + <string name="InvFolder Uncompressed Images"> + Uncompressed Images + </string> + <string name="InvFolder Body Parts"> + Body Parts + </string> + <string name="InvFolder Trash"> + Trash + </string> + <string name="InvFolder Photo Album"> + Photo Album + </string> + <string name="InvFolder Lost And Found"> + Lost And Found + </string> + <string name="InvFolder Uncompressed Sounds"> + Uncompressed Sounds + </string> + <string name="InvFolder Animations"> + Animations + </string> + <string name="InvFolder Gestures"> + Gestures + </string> + <string name="InvFolder Favorite"> + Favorites + </string> + <string name="InvFolder favorite"> + Favorites + </string> + <string name="InvFolder Current Outfit"> + Current Outfit + </string> + <string name="InvFolder Initial Outfits"> + Initial Outfits + </string> + <string name="InvFolder My Outfits"> + My Outfits + </string> + <string name="InvFolder Accessories"> + Accessories + </string> + <string name="InvFolder Friends"> + Friends + </string> + <string name="InvFolder All"> + 全部 + </string> + <string name="Buy"> + 購買 + </string> + <string name="BuyforL$"> + Buy for L$ + </string> + <string name="Stone"> + Stone + </string> + <string name="Metal"> + Metal + </string> + <string name="Glass"> + Glass + </string> + <string name="Wood"> + Wood + </string> + <string name="Flesh"> + Flesh + </string> + <string name="Plastic"> + Plastic + </string> + <string name="Rubber"> + Rubber + </string> + <string name="Light"> + Light + </string> + <string name="KBShift"> + Shift + </string> + <string name="KBCtrl"> + Ctrl + </string> + <string name="Chest"> + Chest + </string> + <string name="Skull"> + Skull + </string> + <string name="Left Shoulder"> + Left Shoulder + </string> + <string name="Right Shoulder"> + Right Shoulder + </string> + <string name="Left Hand"> + Left Hand + </string> + <string name="Right Hand"> + Right Hand + </string> + <string name="Left Foot"> + Left Foot + </string> + <string name="Right Foot"> + Right Foot + </string> + <string name="Spine"> + Spine + </string> + <string name="Pelvis"> + Pelvis + </string> + <string name="Mouth"> + Mouth + </string> + <string name="Chin"> + Chin + </string> + <string name="Left Ear"> + Left Ear + </string> + <string name="Right Ear"> + Right Ear + </string> + <string name="Left Eyeball"> + Left Eyeball + </string> + <string name="Right Eyeball"> + Right Eyeball + </string> + <string name="Nose"> + Nose + </string> + <string name="R Upper Arm"> + R Upper Arm + </string> + <string name="R Forearm"> + R Forearm + </string> + <string name="L Upper Arm"> + L Upper Arm + </string> + <string name="L Forearm"> + L Forearm + </string> + <string name="Right Hip"> + Right Hip + </string> + <string name="R Upper Leg"> + R Upper Leg + </string> + <string name="R Lower Leg"> + R Lower Leg + </string> + <string name="Left Hip"> + Left Hip + </string> + <string name="L Upper Leg"> + L Upper Leg + </string> + <string name="L Lower Leg"> + L Lower Leg + </string> + <string name="Stomach"> + Stomach + </string> + <string name="Left Pec"> + Left Pec + </string> + <string name="Right Pec"> + Right Pec + </string> + <string name="Invalid Attachment"> + Invalid Attachment Point + </string> + <string name="YearsMonthsOld"> + [AGEYEARS] [AGEMONTHS] old + </string> + <string name="YearsOld"> + [AGEYEARS] old + </string> + <string name="MonthsOld"> + [AGEMONTHS] old + </string> + <string name="WeeksOld"> + [AGEWEEKS] old + </string> + <string name="DaysOld"> + [AGEDAYS] old + </string> + <string name="TodayOld"> + Joined today + </string> + <string name="AgeYearsA"> + [COUNT] year + </string> + <string name="AgeYearsB"> + [COUNT] years + </string> + <string name="AgeYearsC"> + [COUNT] years + </string> + <string name="AgeMonthsA"> + [COUNT] month + </string> + <string name="AgeMonthsB"> + [COUNT] months + </string> + <string name="AgeMonthsC"> + [COUNT] months + </string> + <string name="AgeWeeksA"> + [COUNT] week + </string> + <string name="AgeWeeksB"> + [COUNT] weeks + </string> + <string name="AgeWeeksC"> + [COUNT] weeks + </string> + <string name="AgeDaysA"> + [COUNT] day + </string> + <string name="AgeDaysB"> + [COUNT] days + </string> + <string name="AgeDaysC"> + [COUNT] days + </string> + <string name="GroupMembersA"> + [COUNT] member + </string> + <string name="GroupMembersB"> + [COUNT] members + </string> + <string name="GroupMembersC"> + [COUNT] members + </string> + <string name="AcctTypeResident"> + Resident + </string> + <string name="AcctTypeTrial"> + Trial + </string> + <string name="AcctTypeCharterMember"> + Charter Member + </string> + <string name="AcctTypeEmployee"> + Linden Lab Employee + </string> + <string name="PaymentInfoUsed"> + Payment Info Used + </string> + <string name="PaymentInfoOnFile"> + Payment Info On File + </string> + <string name="NoPaymentInfoOnFile"> + No Payment Info On File + </string> + <string name="AgeVerified"> + Age-verified + </string> + <string name="NotAgeVerified"> + Not Age-verified + </string> + <string name="Center 2"> + Center 2 + </string> + <string name="Top Right"> + Top Right + </string> + <string name="Top"> + Top + </string> + <string name="Top Left"> + Top Left + </string> + <string name="Center"> + Center + </string> + <string name="Bottom Left"> + Bottom Left + </string> + <string name="Bottom"> + Bottom + </string> + <string name="Bottom Right"> + Bottom Right + </string> + <string name="CompileQueueDownloadedCompiling"> + Downloaded, now compiling + </string> + <string name="CompileQueueScriptNotFound"> + Script not found on server. + </string> + <string name="CompileQueueProblemDownloading"> + Problem downloading + </string> + <string name="CompileQueueInsufficientPermDownload"> + Insufficient permissions to download a script. + </string> + <string name="CompileQueueInsufficientPermFor"> + Insufficient permissions for + </string> + <string name="CompileQueueUnknownFailure"> + Unknown failure to download + </string> + <string name="CompileQueueTitle"> + Recompilation Progress + </string> + <string name="CompileQueueStart"> + recompile + </string> + <string name="ResetQueueTitle"> + Reset Progress + </string> + <string name="ResetQueueStart"> + reset + </string> + <string name="RunQueueTitle"> + Set Running Progress + </string> + <string name="RunQueueStart"> + set running + </string> + <string name="NotRunQueueTitle"> + Set Not Running Progress + </string> + <string name="NotRunQueueStart"> + set not running + </string> + <string name="CompileSuccessful"> + Compile successful! + </string> + <string name="CompileSuccessfulSaving"> + Compile successful, saving... + </string> + <string name="SaveComplete"> + Save complete. + </string> + <string name="ObjectOutOfRange"> + Script (object out of range) + </string> + <string name="GodToolsObjectOwnedBy"> + Object [OBJECT] owned by [OWNER] + </string> + <string name="GroupsNone"> + ç„¡ + </string> + <string name="Group" value="(group)"/> + <string name="Unknown"> + (未知) + </string> + <string name="SummaryForTheWeek" value="Summary for this week, beginning on"/> + <string name="NextStipendDay" value="The next stipend day is"/> + <string name="GroupIndividualShare" value="Group Individual Share"/> + <string name="GroupColumn" value="Group"/> + <string name="Balance"> + Balance + </string> + <string name="Credits"> + Credits + </string> + <string name="Debits"> + Debits + </string> + <string name="Total"> + Total + </string> + <string name="NoGroupDataFound"> + No group data found for group + </string> + <string name="IMParentEstate"> + parent estate + </string> + <string name="IMMainland"> + mainland + </string> + <string name="IMTeen"> + teen + </string> + <string name="RegionInfoError"> + error + </string> + <string name="RegionInfoAllEstatesOwnedBy"> + all estates owned by [OWNER] + </string> + <string name="RegionInfoAllEstatesYouOwn"> + all estates that you own + </string> + <string name="RegionInfoAllEstatesYouManage"> + all estates that you manage for [OWNER] + </string> + <string name="RegionInfoAllowedResidents"> + Allowed Residents: ([ALLOWEDAGENTS], max [MAXACCESS]) + </string> + <string name="RegionInfoAllowedGroups"> + Allowed groups: ([ALLOWEDGROUPS], max [MAXACCESS]) + </string> + <string name="ScriptLimitsParcelScriptMemory"> + Parcel Script Memory + </string> + <string name="ScriptLimitsParcelsOwned"> + Parcels Listed: [PARCELS] + </string> + <string name="ScriptLimitsMemoryUsed"> + Memory used: [COUNT] kb out of [MAX] kb; [AVAILABLE] kb available + </string> + <string name="ScriptLimitsMemoryUsedSimple"> + Memory used: [COUNT] kb + </string> + <string name="ScriptLimitsParcelScriptURLs"> + Parcel Script URLs + </string> + <string name="ScriptLimitsURLsUsed"> + URLs used: [COUNT] out of [MAX]; [AVAILABLE] available + </string> + <string name="ScriptLimitsURLsUsedSimple"> + URLs used: [COUNT] + </string> + <string name="ScriptLimitsRequestError"> + Error requesting information + </string> + <string name="ScriptLimitsRequestNoParcelSelected"> + No Parcel Selected + </string> + <string name="ScriptLimitsRequestWrongRegion"> + Error: script information is only available in your current region + </string> + <string name="ScriptLimitsRequestWaiting"> + Retrieving information... + </string> + <string name="ScriptLimitsRequestDontOwnParcel"> + You do not have permission to examine this parcel + </string> + <string name="SITTING_ON"> + Sitting On + </string> + <string name="ATTACH_CHEST"> + Chest + </string> + <string name="ATTACH_HEAD"> + Head + </string> + <string name="ATTACH_LSHOULDER"> + Left Shoulder + </string> + <string name="ATTACH_RSHOULDER"> + Right Shoulder + </string> + <string name="ATTACH_LHAND"> + Left Hand + </string> + <string name="ATTACH_RHAND"> + Right Hand + </string> + <string name="ATTACH_LFOOT"> + Left Foot + </string> + <string name="ATTACH_RFOOT"> + Right Foot + </string> + <string name="ATTACH_BACK"> + Back + </string> + <string name="ATTACH_PELVIS"> + Pelvis + </string> + <string name="ATTACH_MOUTH"> + Mouth + </string> + <string name="ATTACH_CHIN"> + Chin + </string> + <string name="ATTACH_LEAR"> + Left Ear + </string> + <string name="ATTACH_REAR"> + Right Ear + </string> + <string name="ATTACH_LEYE"> + Left Eye + </string> + <string name="ATTACH_REYE"> + Right Eye + </string> + <string name="ATTACH_NOSE"> + Nose + </string> + <string name="ATTACH_RUARM"> + Right Upper Arm + </string> + <string name="ATTACH_RLARM"> + Right Lower Arm + </string> + <string name="ATTACH_LUARM"> + Left Upper Arm + </string> + <string name="ATTACH_LLARM"> + Left Lower Arm + </string> + <string name="ATTACH_RHIP"> + Right Hip + </string> + <string name="ATTACH_RULEG"> + Right Upper Leg + </string> + <string name="ATTACH_RLLEG"> + Right Lower Leg + </string> + <string name="ATTACH_LHIP"> + Left Hip + </string> + <string name="ATTACH_LULEG"> + Left Upper Leg + </string> + <string name="ATTACH_LLLEG"> + Left Lower Leg + </string> + <string name="ATTACH_BELLY"> + Belly + </string> + <string name="ATTACH_RPEC"> + Right Pec + </string> + <string name="ATTACH_LPEC"> + Left Pec + </string> + <string name="ATTACH_HUD_CENTER_2"> + HUD Center 2 + </string> + <string name="ATTACH_HUD_TOP_RIGHT"> + HUD Top Right + </string> + <string name="ATTACH_HUD_TOP_CENTER"> + HUD Top Center + </string> + <string name="ATTACH_HUD_TOP_LEFT"> + HUD Top Left + </string> + <string name="ATTACH_HUD_CENTER_1"> + HUD Center 1 + </string> + <string name="ATTACH_HUD_BOTTOM_LEFT"> + HUD Bottom Left + </string> + <string name="ATTACH_HUD_BOTTOM"> + HUD Bottom + </string> + <string name="ATTACH_HUD_BOTTOM_RIGHT"> + HUD Bottom Right + </string> + <string name="CursorPos"> + Line [LINE], Column [COLUMN] + </string> + <string name="PanelDirCountFound"> + [COUNT] found + </string> + <string name="PanelDirTimeStr"> + [hour12,datetime,slt]:[min,datetime,slt] [ampm,datetime,slt] + </string> + <string name="PanelDirEventsDateText"> + [mthnum,datetime,slt]/[day,datetime,slt] + </string> + <string name="PanelContentsTooltip"> + Content of object + </string> + <string name="PanelContentsNewScript"> + New Script + </string> + <string name="BusyModeResponseDefault"> + The Resident you messaged is in 'busy mode' which means they have requested not to be disturbed. Your message will still be shown in their IM panel for later viewing. + </string> + <string name="MuteByName"> + (By name) + </string> + <string name="MuteAgent"> + (Resident) + </string> + <string name="MuteObject"> + (Object) + </string> + <string name="MuteGroup"> + (Group) + </string> + <string name="MuteExternal"> + (External) + </string> + <string name="RegionNoCovenant"> + There is no Covenant provided for this Estate. + </string> + <string name="RegionNoCovenantOtherOwner"> + There is no Covenant provided for this Estate. The land on this estate is being sold by the Estate owner, not Linden Lab. Please contact the Estate Owner for sales details. + </string> + <string name="covenant_last_modified" value="Last Modified:"/> + <string name="none_text" value="(無)"/> + <string name="never_text" value="(never)"/> + <string name="GroupOwned"> + Group Owned + </string> + <string name="Public"> + Public + </string> + <string name="ClassifiedClicksTxt"> + Clicks: [TELEPORT] teleport, [MAP] map, [PROFILE] profile + </string> + <string name="ClassifiedUpdateAfterPublish"> + (will update after publish) + </string> + <string name="NoPicksClassifiedsText"> + You haven't created any Picks or Classifieds. Click the Plus button below to create a Pick or Classified. + </string> + <string name="NoAvatarPicksClassifiedsText"> + User has no picks or classifieds + </string> + <string name="PicksClassifiedsLoadingText"> + 載入ä¸... + </string> + <string name="MultiPreviewTitle"> + é 覽 + </string> + <string name="MultiPropertiesTitle"> + Properties + </string> + <string name="InvOfferAnObjectNamed"> + An object named + </string> + <string name="InvOfferOwnedByGroup"> + owned by the group + </string> + <string name="InvOfferOwnedByUnknownGroup"> + owned by an unknown group + </string> + <string name="InvOfferOwnedBy"> + owned by + </string> + <string name="InvOfferOwnedByUnknownUser"> + owned by an unknown user + </string> + <string name="InvOfferGaveYou"> + gave you + </string> + <string name="InvOfferDecline"> + You decline [DESC] from <nolink>[NAME]</nolink>. + </string> + <string name="GroupMoneyTotal"> + Total + </string> + <string name="GroupMoneyBought"> + bought + </string> + <string name="GroupMoneyPaidYou"> + paid you + </string> + <string name="GroupMoneyPaidInto"> + paid into + </string> + <string name="GroupMoneyBoughtPassTo"> + bought pass to + </string> + <string name="GroupMoneyPaidFeeForEvent"> + paid fee for event + </string> + <string name="GroupMoneyPaidPrizeForEvent"> + paid prize for event + </string> + <string name="GroupMoneyBalance"> + Balance + </string> + <string name="GroupMoneyCredits"> + Credits + </string> + <string name="GroupMoneyDebits"> + Debits + </string> + <string name="ViewerObjectContents"> + Contents + </string> + <string name="AcquiredItems"> + Acquired Items + </string> + <string name="Cancel"> + å–銷 + </string> + <string name="UploadingCosts"> + Uploading [NAME] costs L$ [AMOUNT] + </string> + <string name="BuyingCosts"> + Buying this costs L$ [AMOUNT] + </string> + <string name="UnknownFileExtension"> + Unknown file extension .%s +Expected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh + </string> + <string name="MuteObject2"> + Block + </string> + <string name="MuteAvatar"> + Block + </string> + <string name="UnmuteObject"> + Unblock + </string> + <string name="UnmuteAvatar"> + Unblock + </string> + <string name="AddLandmarkNavBarMenu"> + Add to My Landmarks... + </string> + <string name="EditLandmarkNavBarMenu"> + Edit my Landmark... + </string> + <string name="accel-mac-control"> + ⌃ + </string> + <string name="accel-mac-command"> + ⌘ + </string> + <string name="accel-mac-option"> + ⌥ + </string> + <string name="accel-mac-shift"> + ⇧ + </string> + <string name="accel-win-control"> + Ctrl+ + </string> + <string name="accel-win-alt"> + Alt+ + </string> + <string name="accel-win-shift"> + Shift+ + </string> + <string name="FileSaved"> + File Saved + </string> + <string name="Receiving"> + Receiving + </string> + <string name="AM"> + AM + </string> + <string name="PM"> + PM + </string> + <string name="PST"> + PST + </string> + <string name="PDT"> + PDT + </string> + <string name="Direction_Forward"> + Forward + </string> + <string name="Direction_Left"> + Left + </string> + <string name="Direction_Right"> + Right + </string> + <string name="Direction_Back"> + Back + </string> + <string name="Direction_North"> + North + </string> + <string name="Direction_South"> + South + </string> + <string name="Direction_West"> + West + </string> + <string name="Direction_East"> + East + </string> + <string name="Direction_Up"> + Up + </string> + <string name="Direction_Down"> + Down + </string> + <string name="Any Category"> + Any Category + </string> + <string name="Shopping"> + Shopping + </string> + <string name="Land Rental"> + Land Rental + </string> + <string name="Property Rental"> + Property Rental + </string> + <string name="Special Attraction"> + Special Attraction + </string> + <string name="New Products"> + New Products + </string> + <string name="Employment"> + Employment + </string> + <string name="Wanted"> + Wanted + </string> + <string name="Service"> + Service + </string> + <string name="Personal"> + Personal + </string> + <string name="None"> + ç„¡ + </string> + <string name="Linden Location"> + Linden Location + </string> + <string name="Adult"> + Adult + </string> + <string name="Arts&Culture"> + Arts & Culture + </string> + <string name="Business"> + Business + </string> + <string name="Educational"> + Educational + </string> + <string name="Gaming"> + Gaming + </string> + <string name="Hangout"> + èšæœƒæ‰€ + </string> + <string name="Newcomer Friendly"> + Newcomer Friendly + </string> + <string name="Parks&Nature"> + Parks & Nature + </string> + <string name="Residential"> + Residential + </string> + <string name="Stage"> + Stage + </string> + <string name="Other"> + Other + </string> + <string name="Rental"> + Rental + </string> + <string name="Any"> + Any + </string> + <string name="You"> + You + </string> + <string name=":"> + : + </string> + <string name=","> + , + </string> + <string name="..."> + ... + </string> + <string name="***"> + *** + </string> + <string name="("> + ( + </string> + <string name=")"> + ) + </string> + <string name="."> + . + </string> + <string name="'"> + ' + </string> + <string name="---"> + --- + </string> + <string name="Multiple Media"> + Multiple Media + </string> + <string name="Play Media"> + Play/Pause Media + </string> + <string name="MBCmdLineError"> + An error was found parsing the command line. +Please see: http://wiki.secondlife.com/wiki/Client_parameters +Error: + </string> + <string name="MBCmdLineUsg"> + [APP_NAME] Command line usage: + </string> + <string name="MBUnableToAccessFile"> + [APP_NAME] is unable to access a file that it needs. + +This can be because you somehow have multiple copies running, or your system incorrectly thinks a file is open. +If this message persists, restart your computer and try again. +If it continues to persist, you may need to completely uninstall [APP_NAME] and reinstall it. + </string> + <string name="MBFatalError"> + Fatal Error + </string> + <string name="MBRequiresAltiVec"> + [APP_NAME] requires a processor with AltiVec (G4 or later). + </string> + <string name="MBAlreadyRunning"> + [APP_NAME] is already running. +Check your task bar for a minimized copy of the program. +If this message persists, restart your computer. + </string> + <string name="MBFrozenCrashed"> + [APP_NAME] appears to have frozen or crashed on the previous run. +Would you like to send a crash report? + </string> + <string name="MBAlert"> + Notification + </string> + <string name="MBNoDirectX"> + [APP_NAME] is unable to detect DirectX 9.0b or greater. +[APP_NAME] uses DirectX to detect hardware and/or outdated drivers that can cause stability problems, poor performance and crashes. While you can run [APP_NAME] without it, we highly recommend running with DirectX 9.0b. + +Do you wish to continue? + </string> + <string name="MBWarning"> + Warning + </string> + <string name="MBNoAutoUpdate"> + Automatic updating is not yet implemented for Linux. +Please download the latest version from www.secondlife.com. + </string> + <string name="MBRegClassFailed"> + RegisterClass failed + </string> + <string name="MBError"> + Error + </string> + <string name="MBFullScreenErr"> + Unable to run fullscreen at [WIDTH] x [HEIGHT]. +Running in window. + </string> + <string name="MBDestroyWinFailed"> + Shutdown Error while destroying window (DestroyWindow() failed) + </string> + <string name="MBShutdownErr"> + Shutdown Error + </string> + <string name="MBDevContextErr"> + Can't make GL device context + </string> + <string name="MBPixelFmtErr"> + Can't find suitable pixel format + </string> + <string name="MBPixelFmtDescErr"> + Can't get pixel format description + </string> + <string name="MBTrueColorWindow"> + [APP_NAME] requires True Color (32-bit) to run. +Please go to your computer's display settings and set the color mode to 32-bit. + </string> + <string name="MBAlpha"> + [APP_NAME] is unable to run because it can't get an 8 bit alpha channel. Usually this is due to video card driver issues. +Please make sure you have the latest video card drivers installed. +Also be sure your monitor is set to True Color (32-bit) in Control Panels > Display > Settings. +If you continue to receive this message, contact the [SUPPORT_SITE]. + </string> + <string name="MBPixelFmtSetErr"> + Can't set pixel format + </string> + <string name="MBGLContextErr"> + Can't create GL rendering context + </string> + <string name="MBGLContextActErr"> + Can't activate GL rendering context + </string> + <string name="MBVideoDrvErr"> + [APP_NAME] is unable to run because your video card drivers did not install properly, are out of date, or are for unsupported hardware. Please make sure you have the latest video card drivers and even if you do have the latest, try reinstalling them. + +If you continue to receive this message, contact the [SUPPORT_SITE]. + </string> + <string name="5 O'Clock Shadow"> + 5 O'Clock Shadow + </string> + <string name="All White"> + All White + </string> + <string name="Anime Eyes"> + Anime Eyes + </string> + <string name="Arced"> + Arced + </string> + <string name="Arm Length"> + Arm Length + </string> + <string name="Attached"> + Attached + </string> + <string name="Attached Earlobes"> + Attached Earlobes + </string> + <string name="Back Fringe"> + Back Fringe + </string> + <string name="Baggy"> + Baggy + </string> + <string name="Bangs"> + Bangs + </string> + <string name="Beady Eyes"> + Beady Eyes + </string> + <string name="Belly Size"> + Belly Size + </string> + <string name="Big"> + Big + </string> + <string name="Big Butt"> + Big Butt + </string> + <string name="Big Hair Back"> + Big Hair: Back + </string> + <string name="Big Hair Front"> + Big Hair: Front + </string> + <string name="Big Hair Top"> + Big Hair: Top + </string> + <string name="Big Head"> + Big Head + </string> + <string name="Big Pectorals"> + Big Pectorals + </string> + <string name="Big Spikes"> + Big Spikes + </string> + <string name="Black"> + Black + </string> + <string name="Blonde"> + Blonde + </string> + <string name="Blonde Hair"> + Blonde Hair + </string> + <string name="Blush"> + Blush + </string> + <string name="Blush Color"> + Blush Color + </string> + <string name="Blush Opacity"> + Blush Opacity + </string> + <string name="Body Definition"> + Body Definition + </string> + <string name="Body Fat"> + Body Fat + </string> + <string name="Body Freckles"> + Body Freckles + </string> + <string name="Body Thick"> + Body Thick + </string> + <string name="Body Thickness"> + Body Thickness + </string> + <string name="Body Thin"> + Body Thin + </string> + <string name="Bow Legged"> + Bow Legged + </string> + <string name="Breast Buoyancy"> + Breast Buoyancy + </string> + <string name="Breast Cleavage"> + Breast Cleavage + </string> + <string name="Breast Size"> + Breast Size + </string> + <string name="Bridge Width"> + Bridge Width + </string> + <string name="Broad"> + Broad + </string> + <string name="Brow Size"> + Brow Size + </string> + <string name="Bug Eyes"> + Bug Eyes + </string> + <string name="Bugged Eyes"> + Bugged Eyes + </string> + <string name="Bulbous"> + Bulbous + </string> + <string name="Bulbous Nose"> + Bulbous Nose + </string> + <string name="Breast Physics Mass"> + Breast Mass + </string> + <string name="Breast Physics Smoothing"> + Breast Smoothing + </string> + <string name="Breast Physics Gravity"> + Breast Gravity + </string> + <string name="Breast Physics Drag"> + Breast Drag + </string> + <string name="Breast Physics InOut Max Effect"> + Max Effect + </string> + <string name="Breast Physics InOut Spring"> + Spring + </string> + <string name="Breast Physics InOut Gain"> + Gain + </string> + <string name="Breast Physics InOut Damping"> + Damping + </string> + <string name="Breast Physics UpDown Max Effect"> + Max Effect + </string> + <string name="Breast Physics UpDown Spring"> + Spring + </string> + <string name="Breast Physics UpDown Gain"> + Gain + </string> + <string name="Breast Physics UpDown Damping"> + Damping + </string> + <string name="Breast Physics LeftRight Max Effect"> + Max Effect + </string> + <string name="Breast Physics LeftRight Spring"> + Spring + </string> + <string name="Breast Physics LeftRight Gain"> + Gain + </string> + <string name="Breast Physics LeftRight Damping"> + Damping + </string> + <string name="Belly Physics Mass"> + Belly Mass + </string> + <string name="Belly Physics Smoothing"> + Belly Smoothing + </string> + <string name="Belly Physics Gravity"> + Belly Gravity + </string> + <string name="Belly Physics Drag"> + Belly Drag + </string> + <string name="Belly Physics UpDown Max Effect"> + Max Effect + </string> + <string name="Belly Physics UpDown Spring"> + Spring + </string> + <string name="Belly Physics UpDown Gain"> + Gain + </string> + <string name="Belly Physics UpDown Damping"> + Damping + </string> + <string name="Butt Physics Mass"> + Butt Mass + </string> + <string name="Butt Physics Smoothing"> + Butt Smoothing + </string> + <string name="Butt Physics Gravity"> + Butt Gravity + </string> + <string name="Butt Physics Drag"> + Butt Drag + </string> + <string name="Butt Physics UpDown Max Effect"> + Max Effect + </string> + <string name="Butt Physics UpDown Spring"> + Spring + </string> + <string name="Butt Physics UpDown Gain"> + Gain + </string> + <string name="Butt Physics UpDown Damping"> + Damping + </string> + <string name="Butt Physics LeftRight Max Effect"> + Max Effect + </string> + <string name="Butt Physics LeftRight Spring"> + Spring + </string> + <string name="Butt Physics LeftRight Gain"> + Gain + </string> + <string name="Butt Physics LeftRight Damping"> + Damping + </string> + <string name="Bushy Eyebrows"> + Bushy Eyebrows + </string> + <string name="Bushy Hair"> + Bushy Hair + </string> + <string name="Butt Size"> + Butt Size + </string> + <string name="Butt Gravity"> + Butt Gravity + </string> + <string name="bustle skirt"> + Bustle Skirt + </string> + <string name="no bustle"> + No Bustle + </string> + <string name="more bustle"> + More Bustle + </string> + <string name="Chaplin"> + Chaplin + </string> + <string name="Cheek Bones"> + Cheek Bones + </string> + <string name="Chest Size"> + Chest Size + </string> + <string name="Chin Angle"> + Chin Angle + </string> + <string name="Chin Cleft"> + Chin Cleft + </string> + <string name="Chin Curtains"> + Chin Curtains + </string> + <string name="Chin Depth"> + Chin Depth + </string> + <string name="Chin Heavy"> + Chin Heavy + </string> + <string name="Chin In"> + Chin In + </string> + <string name="Chin Out"> + Chin Out + </string> + <string name="Chin-Neck"> + Chin-Neck + </string> + <string name="Clear"> + 清除 + </string> + <string name="Cleft"> + Cleft + </string> + <string name="Close Set Eyes"> + Close Set Eyes + </string> + <string name="Closed"> + Closed + </string> + <string name="Closed Back"> + Closed Back + </string> + <string name="Closed Front"> + Closed Front + </string> + <string name="Closed Left"> + Closed Left + </string> + <string name="Closed Right"> + Closed Right + </string> + <string name="Coin Purse"> + Coin Purse + </string> + <string name="Collar Back"> + Collar Back + </string> + <string name="Collar Front"> + Collar Front + </string> + <string name="Corner Down"> + Corner Down + </string> + <string name="Corner Up"> + Corner Up + </string> + <string name="Creased"> + Creased + </string> + <string name="Crooked Nose"> + Crooked Nose + </string> + <string name="Cuff Flare"> + Cuff Flare + </string> + <string name="Dark"> + Dark + </string> + <string name="Dark Green"> + Dark Green + </string> + <string name="Darker"> + Darker + </string> + <string name="Deep"> + Deep + </string> + <string name="Default Heels"> + Default Heels + </string> + <string name="Dense"> + Dense + </string> + <string name="Double Chin"> + Double Chin + </string> + <string name="Downturned"> + Downturned + </string> + <string name="Duffle Bag"> + Duffle Bag + </string> + <string name="Ear Angle"> + Ear Angle + </string> + <string name="Ear Size"> + Ear Size + </string> + <string name="Ear Tips"> + Ear Tips + </string> + <string name="Egg Head"> + Egg Head + </string> + <string name="Eye Bags"> + Eye Bags + </string> + <string name="Eye Color"> + Eye Color + </string> + <string name="Eye Depth"> + Eye Depth + </string> + <string name="Eye Lightness"> + Eye Lightness + </string> + <string name="Eye Opening"> + Eye Opening + </string> + <string name="Eye Pop"> + Eye Pop + </string> + <string name="Eye Size"> + Eye Size + </string> + <string name="Eye Spacing"> + Eye Spacing + </string> + <string name="Eyebrow Arc"> + Eyebrow Arc + </string> + <string name="Eyebrow Density"> + Eyebrow Density + </string> + <string name="Eyebrow Height"> + Eyebrow Height + </string> + <string name="Eyebrow Points"> + Eyebrow Points + </string> + <string name="Eyebrow Size"> + Eyebrow Size + </string> + <string name="Eyelash Length"> + Eyelash Length + </string> + <string name="Eyeliner"> + Eyeliner + </string> + <string name="Eyeliner Color"> + Eyeliner Color + </string> + <string name="Eyes Bugged"> + Eyes Bugged + </string> + <string name="Face Shear"> + Face Shear + </string> + <string name="Facial Definition"> + Facial Definition + </string> + <string name="Far Set Eyes"> + Far Set Eyes + </string> + <string name="Fat Lips"> + Fat Lips + </string> + <string name="Female"> + Female + </string> + <string name="Fingerless"> + Fingerless + </string> + <string name="Fingers"> + Fingers + </string> + <string name="Flared Cuffs"> + Flared Cuffs + </string> + <string name="Flat"> + Flat + </string> + <string name="Flat Butt"> + Flat Butt + </string> + <string name="Flat Head"> + Flat Head + </string> + <string name="Flat Toe"> + Flat Toe + </string> + <string name="Foot Size"> + Foot Size + </string> + <string name="Forehead Angle"> + Forehead Angle + </string> + <string name="Forehead Heavy"> + Forehead Heavy + </string> + <string name="Freckles"> + Freckles + </string> + <string name="Front Fringe"> + Front Fringe + </string> + <string name="Full Back"> + Full Back + </string> + <string name="Full Eyeliner"> + Full Eyeliner + </string> + <string name="Full Front"> + Full Front + </string> + <string name="Full Hair Sides"> + Full Hair Sides + </string> + <string name="Full Sides"> + Full Sides + </string> + <string name="Glossy"> + Glossy + </string> + <string name="Glove Fingers"> + Glove Fingers + </string> + <string name="Glove Length"> + Glove Length + </string> + <string name="Hair"> + Hair + </string> + <string name="Hair Back"> + Hair: Back + </string> + <string name="Hair Front"> + Hair: Front + </string> + <string name="Hair Sides"> + Hair: Sides + </string> + <string name="Hair Sweep"> + Hair Sweep + </string> + <string name="Hair Thickess"> + Hair Thickness + </string> + <string name="Hair Thickness"> + Hair Thickness + </string> + <string name="Hair Tilt"> + Hair Tilt + </string> + <string name="Hair Tilted Left"> + Hair Tilted Left + </string> + <string name="Hair Tilted Right"> + Hair Tilted Right + </string> + <string name="Hair Volume"> + Hair: Volume + </string> + <string name="Hand Size"> + Hand Size + </string> + <string name="Handlebars"> + Handlebars + </string> + <string name="Head Length"> + Head Length + </string> + <string name="Head Shape"> + Head Shape + </string> + <string name="Head Size"> + Head Size + </string> + <string name="Head Stretch"> + Head Stretch + </string> + <string name="Heel Height"> + Heel Height + </string> + <string name="Heel Shape"> + Heel Shape + </string> + <string name="Height"> + Height + </string> + <string name="High"> + High + </string> + <string name="High Heels"> + High Heels + </string> + <string name="High Jaw"> + High Jaw + </string> + <string name="High Platforms"> + High Platforms + </string> + <string name="High and Tight"> + High and Tight + </string> + <string name="Higher"> + Higher + </string> + <string name="Hip Length"> + Hip Length + </string> + <string name="Hip Width"> + Hip Width + </string> + <string name="In"> + In + </string> + <string name="In Shdw Color"> + Inner Shadow Color + </string> + <string name="In Shdw Opacity"> + Inner Shadow Opacity + </string> + <string name="Inner Eye Corner"> + Inner Eye Corner + </string> + <string name="Inner Eye Shadow"> + Inner Eye Shadow + </string> + <string name="Inner Shadow"> + Inner Shadow + </string> + <string name="Jacket Length"> + Jacket Length + </string> + <string name="Jacket Wrinkles"> + Jacket Wrinkles + </string> + <string name="Jaw Angle"> + Jaw Angle + </string> + <string name="Jaw Jut"> + Jaw Jut + </string> + <string name="Jaw Shape"> + Jaw Shape + </string> + <string name="Join"> + Join + </string> + <string name="Jowls"> + Jowls + </string> + <string name="Knee Angle"> + Knee Angle + </string> + <string name="Knock Kneed"> + Knock Kneed + </string> + <string name="Large"> + Large + </string> + <string name="Large Hands"> + Large Hands + </string> + <string name="Left Part"> + Left Part + </string> + <string name="Leg Length"> + Leg Length + </string> + <string name="Leg Muscles"> + Leg Muscles + </string> + <string name="Less"> + Less + </string> + <string name="Less Body Fat"> + Less Body Fat + </string> + <string name="Less Curtains"> + Less Curtains + </string> + <string name="Less Freckles"> + Less Freckles + </string> + <string name="Less Full"> + Less Full + </string> + <string name="Less Gravity"> + Less Gravity + </string> + <string name="Less Love"> + Less Love + </string> + <string name="Less Muscles"> + Less Muscles + </string> + <string name="Less Muscular"> + Less Muscular + </string> + <string name="Less Rosy"> + Less Rosy + </string> + <string name="Less Round"> + Less Round + </string> + <string name="Less Saddle"> + Less Saddle + </string> + <string name="Less Square"> + Less Square + </string> + <string name="Less Volume"> + Less Volume + </string> + <string name="Less soul"> + Less soul + </string> + <string name="Lighter"> + Lighter + </string> + <string name="Lip Cleft"> + Lip Cleft + </string> + <string name="Lip Cleft Depth"> + Lip Cleft Depth + </string> + <string name="Lip Fullness"> + Lip Fullness + </string> + <string name="Lip Pinkness"> + Lip Pinkness + </string> + <string name="Lip Ratio"> + Lip Ratio + </string> + <string name="Lip Thickness"> + Lip Thickness + </string> + <string name="Lip Width"> + Lip Width + </string> + <string name="Lipgloss"> + Lipgloss + </string> + <string name="Lipstick"> + Lipstick + </string> + <string name="Lipstick Color"> + Lipstick Color + </string> + <string name="Long"> + Long + </string> + <string name="Long Head"> + Long Head + </string> + <string name="Long Hips"> + Long Hips + </string> + <string name="Long Legs"> + Long Legs + </string> + <string name="Long Neck"> + Long Neck + </string> + <string name="Long Pigtails"> + Long Pigtails + </string> + <string name="Long Ponytail"> + Long Ponytail + </string> + <string name="Long Torso"> + Long Torso + </string> + <string name="Long arms"> + Long arms + </string> + <string name="Loose Pants"> + Loose Pants + </string> + <string name="Loose Shirt"> + Loose Shirt + </string> + <string name="Loose Sleeves"> + Loose Sleeves + </string> + <string name="Love Handles"> + Love Handles + </string> + <string name="Low"> + Low + </string> + <string name="Low Heels"> + Low Heels + </string> + <string name="Low Jaw"> + Low Jaw + </string> + <string name="Low Platforms"> + Low Platforms + </string> + <string name="Low and Loose"> + Low and Loose + </string> + <string name="Lower"> + Lower + </string> + <string name="Lower Bridge"> + Lower Bridge + </string> + <string name="Lower Cheeks"> + Lower Cheeks + </string> + <string name="Male"> + 男性 + </string> + <string name="Middle Part"> + Middle Part + </string> + <string name="More"> + More + </string> + <string name="More Blush"> + More Blush + </string> + <string name="More Body Fat"> + More Body Fat + </string> + <string name="More Curtains"> + More Curtains + </string> + <string name="More Eyeshadow"> + More Eyeshadow + </string> + <string name="More Freckles"> + More Freckles + </string> + <string name="More Full"> + More Full + </string> + <string name="More Gravity"> + More Gravity + </string> + <string name="More Lipstick"> + More Lipstick + </string> + <string name="More Love"> + More Love + </string> + <string name="More Lower Lip"> + More Lower Lip + </string> + <string name="More Muscles"> + More Muscles + </string> + <string name="More Muscular"> + More Muscular + </string> + <string name="More Rosy"> + More Rosy + </string> + <string name="More Round"> + More Round + </string> + <string name="More Saddle"> + More Saddle + </string> + <string name="More Sloped"> + More Sloped + </string> + <string name="More Square"> + More Square + </string> + <string name="More Upper Lip"> + More Upper Lip + </string> + <string name="More Vertical"> + More Vertical + </string> + <string name="More Volume"> + More Volume + </string> + <string name="More soul"> + More soul + </string> + <string name="Moustache"> + Moustache + </string> + <string name="Mouth Corner"> + Mouth Corner + </string> + <string name="Mouth Position"> + Mouth Position + </string> + <string name="Mowhawk"> + Mowhawk + </string> + <string name="Muscular"> + Muscular + </string> + <string name="Mutton Chops"> + Mutton Chops + </string> + <string name="Nail Polish"> + Nail Polish + </string> + <string name="Nail Polish Color"> + Nail Polish Color + </string> + <string name="Narrow"> + Narrow + </string> + <string name="Narrow Back"> + Narrow Back + </string> + <string name="Narrow Front"> + Narrow Front + </string> + <string name="Narrow Lips"> + Narrow Lips + </string> + <string name="Natural"> + Natural + </string> + <string name="Neck Length"> + Neck Length + </string> + <string name="Neck Thickness"> + Neck Thickness + </string> + <string name="No Blush"> + No Blush + </string> + <string name="No Eyeliner"> + No Eyeliner + </string> + <string name="No Eyeshadow"> + No Eyeshadow + </string> + <string name="No Lipgloss"> + No Lipgloss + </string> + <string name="No Lipstick"> + No Lipstick + </string> + <string name="No Part"> + No Part + </string> + <string name="No Polish"> + No Polish + </string> + <string name="No Red"> + No Red + </string> + <string name="No Spikes"> + No Spikes + </string> + <string name="No White"> + No White + </string> + <string name="No Wrinkles"> + No Wrinkles + </string> + <string name="Normal Lower"> + Normal Lower + </string> + <string name="Normal Upper"> + Normal Upper + </string> + <string name="Nose Left"> + Nose Left + </string> + <string name="Nose Right"> + Nose Right + </string> + <string name="Nose Size"> + Nose Size + </string> + <string name="Nose Thickness"> + Nose Thickness + </string> + <string name="Nose Tip Angle"> + Nose Tip Angle + </string> + <string name="Nose Tip Shape"> + Nose Tip Shape + </string> + <string name="Nose Width"> + Nose Width + </string> + <string name="Nostril Division"> + Nostril Division + </string> + <string name="Nostril Width"> + Nostril Width + </string> + <string name="Opaque"> + Opaque + </string> + <string name="Open"> + Open + </string> + <string name="Open Back"> + Open Back + </string> + <string name="Open Front"> + Open Front + </string> + <string name="Open Left"> + Open Left + </string> + <string name="Open Right"> + Open Right + </string> + <string name="Orange"> + Orange + </string> + <string name="Out"> + Out + </string> + <string name="Out Shdw Color"> + Outer Shadow Color + </string> + <string name="Out Shdw Opacity"> + Outer Shadow Opacity + </string> + <string name="Outer Eye Corner"> + Outer Eye Corner + </string> + <string name="Outer Eye Shadow"> + Outer Eye Shadow + </string> + <string name="Outer Shadow"> + Outer Shadow + </string> + <string name="Overbite"> + Overbite + </string> + <string name="Package"> + Package + </string> + <string name="Painted Nails"> + Painted Nails + </string> + <string name="Pale"> + Pale + </string> + <string name="Pants Crotch"> + Pants Crotch + </string> + <string name="Pants Fit"> + Pants Fit + </string> + <string name="Pants Length"> + Pants Length + </string> + <string name="Pants Waist"> + Pants Waist + </string> + <string name="Pants Wrinkles"> + Pants Wrinkles + </string> + <string name="Part"> + Part + </string> + <string name="Part Bangs"> + Part Bangs + </string> + <string name="Pectorals"> + Pectorals + </string> + <string name="Pigment"> + Pigment + </string> + <string name="Pigtails"> + Pigtails + </string> + <string name="Pink"> + Pink + </string> + <string name="Pinker"> + Pinker + </string> + <string name="Platform Height"> + Platform Height + </string> + <string name="Platform Width"> + Platform Width + </string> + <string name="Pointy"> + Pointy + </string> + <string name="Pointy Heels"> + Pointy Heels + </string> + <string name="Ponytail"> + Ponytail + </string> + <string name="Poofy Skirt"> + Poofy Skirt + </string> + <string name="Pop Left Eye"> + Pop Left Eye + </string> + <string name="Pop Right Eye"> + Pop Right Eye + </string> + <string name="Puffy"> + Puffy + </string> + <string name="Puffy Eyelids"> + Puffy Eyelids + </string> + <string name="Rainbow Color"> + Rainbow Color + </string> + <string name="Red Hair"> + Red Hair + </string> + <string name="Regular"> + Regular + </string> + <string name="Right Part"> + Right Part + </string> + <string name="Rosy Complexion"> + Rosy Complexion + </string> + <string name="Round"> + Round + </string> + <string name="Ruddiness"> + Ruddiness + </string> + <string name="Ruddy"> + Ruddy + </string> + <string name="Rumpled Hair"> + Rumpled Hair + </string> + <string name="Saddle Bags"> + Saddle Bags + </string> + <string name="Scrawny Leg"> + Scrawny Leg + </string> + <string name="Separate"> + Separate + </string> + <string name="Shallow"> + Shallow + </string> + <string name="Shear Back"> + Shear Back + </string> + <string name="Shear Face"> + Shear Face + </string> + <string name="Shear Front"> + Shear Front + </string> + <string name="Shear Left Up"> + Shear Left Up + </string> + <string name="Shear Right Up"> + Shear Right Up + </string> + <string name="Sheared Back"> + Sheared Back + </string> + <string name="Sheared Front"> + Sheared Front + </string> + <string name="Shift Left"> + Shift Left + </string> + <string name="Shift Mouth"> + Shift Mouth + </string> + <string name="Shift Right"> + Shift Right + </string> + <string name="Shirt Bottom"> + Shirt Bottom + </string> + <string name="Shirt Fit"> + Shirt Fit + </string> + <string name="Shirt Wrinkles"> + Shirt Wrinkles + </string> + <string name="Shoe Height"> + Shoe Height + </string> + <string name="Short"> + Short + </string> + <string name="Short Arms"> + Short Arms + </string> + <string name="Short Legs"> + Short Legs + </string> + <string name="Short Neck"> + Short Neck + </string> + <string name="Short Pigtails"> + Short Pigtails + </string> + <string name="Short Ponytail"> + Short Ponytail + </string> + <string name="Short Sideburns"> + Short Sideburns + </string> + <string name="Short Torso"> + Short Torso + </string> + <string name="Short hips"> + Short hips + </string> + <string name="Shoulders"> + Shoulders + </string> + <string name="Side Fringe"> + Side Fringe + </string> + <string name="Sideburns"> + Sideburns + </string> + <string name="Sides Hair"> + Sides Hair + </string> + <string name="Sides Hair Down"> + Sides Hair Down + </string> + <string name="Sides Hair Up"> + Sides Hair Up + </string> + <string name="Skinny Neck"> + Skinny Neck + </string> + <string name="Skirt Fit"> + Skirt Fit + </string> + <string name="Skirt Length"> + Skirt Length + </string> + <string name="Slanted Forehead"> + Slanted Forehead + </string> + <string name="Sleeve Length"> + Sleeve Length + </string> + <string name="Sleeve Looseness"> + Sleeve Looseness + </string> + <string name="Slit Back"> + Slit: Back + </string> + <string name="Slit Front"> + Slit: Front + </string> + <string name="Slit Left"> + Slit: Left + </string> + <string name="Slit Right"> + Slit: Right + </string> + <string name="Small"> + Small + </string> + <string name="Small Hands"> + Small Hands + </string> + <string name="Small Head"> + Small Head + </string> + <string name="Smooth"> + Smooth + </string> + <string name="Smooth Hair"> + Smooth Hair + </string> + <string name="Socks Length"> + Socks Length + </string> + <string name="Soulpatch"> + Soulpatch + </string> + <string name="Sparse"> + Sparse + </string> + <string name="Spiked Hair"> + Spiked Hair + </string> + <string name="Square"> + Square + </string> + <string name="Square Toe"> + Square Toe + </string> + <string name="Squash Head"> + Squash Head + </string> + <string name="Stretch Head"> + Stretch Head + </string> + <string name="Sunken"> + Sunken + </string> + <string name="Sunken Chest"> + Sunken Chest + </string> + <string name="Sunken Eyes"> + Sunken Eyes + </string> + <string name="Sweep Back"> + Sweep Back + </string> + <string name="Sweep Forward"> + Sweep Forward + </string> + <string name="Tall"> + Tall + </string> + <string name="Taper Back"> + Taper Back + </string> + <string name="Taper Front"> + Taper Front + </string> + <string name="Thick Heels"> + Thick Heels + </string> + <string name="Thick Neck"> + Thick Neck + </string> + <string name="Thick Toe"> + Thick Toe + </string> + <string name="Thin"> + Thin + </string> + <string name="Thin Eyebrows"> + Thin Eyebrows + </string> + <string name="Thin Lips"> + Thin Lips + </string> + <string name="Thin Nose"> + Thin Nose + </string> + <string name="Tight Chin"> + Tight Chin + </string> + <string name="Tight Cuffs"> + Tight Cuffs + </string> + <string name="Tight Pants"> + Tight Pants + </string> + <string name="Tight Shirt"> + Tight Shirt + </string> + <string name="Tight Skirt"> + Tight Skirt + </string> + <string name="Tight Sleeves"> + Tight Sleeves + </string> + <string name="Toe Shape"> + Toe Shape + </string> + <string name="Toe Thickness"> + Toe Thickness + </string> + <string name="Torso Length"> + Torso Length + </string> + <string name="Torso Muscles"> + Torso Muscles + </string> + <string name="Torso Scrawny"> + Torso Scrawny + </string> + <string name="Unattached"> + Unattached + </string> + <string name="Uncreased"> + Uncreased + </string> + <string name="Underbite"> + Underbite + </string> + <string name="Unnatural"> + Unnatural + </string> + <string name="Upper Bridge"> + Upper Bridge + </string> + <string name="Upper Cheeks"> + Upper Cheeks + </string> + <string name="Upper Chin Cleft"> + Upper Chin Cleft + </string> + <string name="Upper Eyelid Fold"> + Upper Eyelid Fold + </string> + <string name="Upturned"> + Upturned + </string> + <string name="Very Red"> + Very Red + </string> + <string name="Waist Height"> + Waist Height + </string> + <string name="Well-Fed"> + Well-Fed + </string> + <string name="White Hair"> + White Hair + </string> + <string name="Wide"> + Wide + </string> + <string name="Wide Back"> + Wide Back + </string> + <string name="Wide Front"> + Wide Front + </string> + <string name="Wide Lips"> + Wide Lips + </string> + <string name="Wild"> + Wild + </string> + <string name="Wrinkles"> + Wrinkles + </string> + <string name="LocationCtrlAddLandmarkTooltip"> + Add to My Landmarks + </string> + <string name="LocationCtrlEditLandmarkTooltip"> + Edit my Landmark + </string> + <string name="LocationCtrlInfoBtnTooltip"> + See more info about the current location + </string> + <string name="LocationCtrlComboBtnTooltip"> + My location history + </string> + <string name="LocationCtrlForSaleTooltip"> + 購買這塊土地 + </string> + <string name="LocationCtrlVoiceTooltip"> + Voice not available here + </string> + <string name="LocationCtrlFlyTooltip"> + Flying not allowed + </string> + <string name="LocationCtrlPushTooltip"> + No pushing + </string> + <string name="LocationCtrlBuildTooltip"> + Building/dropping objects not allowed + </string> + <string name="LocationCtrlScriptsTooltip"> + Scripts not allowed + </string> + <string name="LocationCtrlDamageTooltip"> + Health + </string> + <string name="LocationCtrlAdultIconTooltip"> + Adult Region + </string> + <string name="LocationCtrlModerateIconTooltip"> + Moderate Region + </string> + <string name="LocationCtrlGeneralIconTooltip"> + General Region + </string> + <string name="UpdaterWindowTitle"> + [APP_NAME] Update + </string> + <string name="UpdaterNowUpdating"> + Now updating [APP_NAME]... + </string> + <string name="UpdaterNowInstalling"> + Installing [APP_NAME]... + </string> + <string name="UpdaterUpdatingDescriptive"> + Your [APP_NAME] Viewer is being updated to the latest release. This may take some time, so please be patient. + </string> + <string name="UpdaterProgressBarTextWithEllipses"> + Downloading update... + </string> + <string name="UpdaterProgressBarText"> + Downloading update + </string> + <string name="UpdaterFailDownloadTitle"> + Failed to download update + </string> + <string name="UpdaterFailUpdateDescriptive"> + An error occurred while updating [APP_NAME]. Please download the latest version from www.secondlife.com. + </string> + <string name="UpdaterFailInstallTitle"> + Failed to install update + </string> + <string name="UpdaterFailStartTitle"> + Failed to start viewer + </string> + <string name="ItemsComingInTooFastFrom"> + [APP_NAME]: Items coming in too fast from [FROM_NAME], automatic preview disabled for [TIME] seconds + </string> + <string name="ItemsComingInTooFast"> + [APP_NAME]: Items coming in too fast, automatic preview disabled for [TIME] seconds + </string> + <string name="IM_logging_string"> + -- Instant message logging enabled -- + </string> + <string name="IM_typing_start_string"> + [NAME] is typing... + </string> + <string name="Unnamed"> + (Unnamed) + </string> + <string name="IM_moderated_chat_label"> + (Moderated: Voices off by default) + </string> + <string name="IM_unavailable_text_label"> + Text chat is not available for this call. + </string> + <string name="IM_muted_text_label"> + Your text chat has been disabled by a Group Moderator. + </string> + <string name="IM_default_text_label"> + Click here to instant message. + </string> + <string name="IM_to_label"> + To + </string> + <string name="IM_moderator_label"> + (Moderator) + </string> + <string name="Saved_message"> + (Saved [LONG_TIMESTAMP]) + </string> + <string name="answered_call"> + Your call has been answered + </string> + <string name="you_started_call"> + You started a voice call + </string> + <string name="you_joined_call"> + You joined the voice call + </string> + <string name="name_started_call"> + [NAME] started a voice call + </string> + <string name="ringing-im"> + Joining voice call... + </string> + <string name="connected-im"> + Connected, click Leave Call to hang up + </string> + <string name="hang_up-im"> + Left voice call + </string> + <string name="answering-im"> + Connecting... + </string> + <string name="conference-title"> + Ad-hoc Conference + </string> + <string name="conference-title-incoming"> + Conference with [AGENT_NAME] + </string> + <string name="inventory_item_offered-im"> + Inventory item offered + </string> + <string name="share_alert"> + Drag items from inventory here + </string> + <string name="no_session_message"> + (IM Session Doesn't Exist) + </string> + <string name="only_user_message"> + You are the only user in this session. + </string> + <string name="offline_message"> + [NAME] is offline. + </string> + <string name="invite_message"> + Click the [BUTTON NAME] button to accept/connect to this voice chat. + </string> + <string name="muted_message"> + You have blocked this Resident. Sending a message will automatically unblock them. + </string> + <string name="generic"> + Error making request, please try again later. + </string> + <string name="generic_request_error"> + Error making request, please try again later. + </string> + <string name="insufficient_perms_error"> + You do not have sufficient permissions. + </string> + <string name="session_does_not_exist_error"> + The session no longer exists + </string> + <string name="no_ability_error"> + You do not have that ability. + </string> + <string name="no_ability"> + You do not have that ability. + </string> + <string name="not_a_mod_error"> + You are not a session moderator. + </string> + <string name="muted"> + A group moderator disabled your text chat. + </string> + <string name="muted_error"> + A group moderator disabled your text chat. + </string> + <string name="add_session_event"> + Unable to add users to chat session with [RECIPIENT]. + </string> + <string name="message"> + Unable to send your message to the chat session with [RECIPIENT]. + </string> + <string name="message_session_event"> + Unable to send your message to the chat session with [RECIPIENT]. + </string> + <string name="mute"> + Error while moderating. + </string> + <string name="removed"> + You have been removed from the group. + </string> + <string name="removed_from_group"> + You have been removed from the group. + </string> + <string name="close_on_no_ability"> + You no longer have the ability to be in the chat session. + </string> + <string name="unread_chat_single"> + [SOURCES] has said something new + </string> + <string name="unread_chat_multiple"> + [SOURCES] have said something new + </string> + <string name="session_initialization_timed_out_error"> + The session initialization is timed out + </string> + <string name="voice_morphing_url"> + http://secondlife.com/landing/voicemorphing + </string> + <string name="paid_you_ldollars"> + [NAME] paid you L$[AMOUNT] [REASON]. + </string> + <string name="paid_you_ldollars_no_reason"> + [NAME] paid you L$[AMOUNT]. + </string> + <string name="you_paid_ldollars"> + You paid [NAME] L$[AMOUNT] [REASON]. + </string> + <string name="you_paid_ldollars_no_info"> + You paid L$[AMOUNT]. + </string> + <string name="you_paid_ldollars_no_reason"> + You paid [NAME] L$[AMOUNT]. + </string> + <string name="you_paid_ldollars_no_name"> + You paid L$[AMOUNT] [REASON]. + </string> + <string name="for item"> + for [ITEM] + </string> + <string name="for a parcel of land"> + for a parcel of land + </string> + <string name="for a land access pass"> + for a land access pass + </string> + <string name="for deeding land"> + for deeding land + </string> + <string name="to create a group"> + to create a group + </string> + <string name="to join a group"> + to join a group + </string> + <string name="to upload"> + to upload + </string> + <string name="to publish a classified ad"> + to publish a classified ad + </string> + <string name="giving"> + Giving L$ [AMOUNT] + </string> + <string name="uploading_costs"> + Uploading costs L$ [AMOUNT] + </string> + <string name="this_costs"> + This costs L$ [AMOUNT] + </string> + <string name="buying_selected_land"> + Buying selected land for L$ [AMOUNT] + </string> + <string name="this_object_costs"> + This object costs L$ [AMOUNT] + </string> + <string name="group_role_everyone"> + Everyone + </string> + <string name="group_role_officers"> + Officers + </string> + <string name="group_role_owners"> + Owners + </string> + <string name="group_member_status_online"> + Online + </string> + <string name="uploading_abuse_report"> + Uploading... + +Abuse Report + </string> + <string name="New Shape"> + New Shape + </string> + <string name="New Skin"> + New Skin + </string> + <string name="New Hair"> + New Hair + </string> + <string name="New Eyes"> + New Eyes + </string> + <string name="New Shirt"> + 新襯衫 + </string> + <string name="New Pants"> + 新褲å + </string> + <string name="New Shoes"> + æ–°éž‹å + </string> + <string name="New Socks"> + 新襪å + </string> + <string name="New Jacket"> + 新夾克 + </string> + <string name="New Gloves"> + 新手套 + </string> + <string name="New Undershirt"> + 新內衣 + </string> + <string name="New Underpants"> + 新內褲 + </string> + <string name="New Skirt"> + 新裙å + </string> + <string name="New Alpha"> + New Alpha + </string> + <string name="New Tattoo"> + New Tattoo + </string> + <string name="New Physics"> + New Physics + </string> + <string name="Invalid Wearable"> + Invalid Wearable + </string> + <string name="New Gesture"> + New Gesture + </string> + <string name="New Script"> + New Script + </string> + <string name="New Note"> + New Note + </string> + <string name="New Folder"> + 新資料夾 + </string> + <string name="Contents"> + Contents + </string> + <string name="Gesture"> + Gesture + </string> + <string name="Male Gestures"> + Male Gestures + </string> + <string name="Female Gestures"> + Female Gestures + </string> + <string name="Other Gestures"> + Other Gestures + </string> + <string name="Speech Gestures"> + Speech Gestures + </string> + <string name="Common Gestures"> + Common Gestures + </string> + <string name="Male - Excuse me"> + Male - Excuse me + </string> + <string name="Male - Get lost"> + Male - Get lost + </string> + <string name="Male - Blow kiss"> + Male - Blow kiss + </string> + <string name="Male - Boo"> + Male - Boo + </string> + <string name="Male - Bored"> + Male - Bored + </string> + <string name="Male - Hey"> + Male - Hey + </string> + <string name="Male - Laugh"> + Male - Laugh + </string> + <string name="Male - Repulsed"> + Male - Repulsed + </string> + <string name="Male - Shrug"> + Male - Shrug + </string> + <string name="Male - Stick tougue out"> + Male - Stick tougue out + </string> + <string name="Male - Wow"> + Male - Wow + </string> + <string name="Female - Chuckle"> + Female - Chuckle + </string> + <string name="Female - Cry"> + Female - Cry + </string> + <string name="Female - Embarrassed"> + Female - Embarrassed + </string> + <string name="Female - Excuse me"> + Female - Excuse me + </string> + <string name="Female - Get lost"> + Female - Get lost + </string> + <string name="Female - Blow kiss"> + Female - Blow kiss + </string> + <string name="Female - Boo"> + Female - Boo + </string> + <string name="Female - Bored"> + Female - Bored + </string> + <string name="Female - Hey"> + Female - Hey + </string> + <string name="Female - Hey baby"> + Female - Hey baby + </string> + <string name="Female - Laugh"> + Female - Laugh + </string> + <string name="Female - Looking good"> + Female - Looking good + </string> + <string name="Female - Over here"> + Female - Over here + </string> + <string name="Female - Please"> + Female - Please + </string> + <string name="Female - Repulsed"> + Female - Repulsed + </string> + <string name="Female - Shrug"> + Female - Shrug + </string> + <string name="Female - Stick tougue out"> + Female - Stick tougue out + </string> + <string name="Female - Wow"> + Female - Wow + </string> + <string name="AvatarBirthDateFormat"> + [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] + </string> + <string name="DefaultMimeType"> + ç„¡/ç„¡ + </string> + <string name="texture_load_dimensions_error"> + Can't load images larger than [WIDTH]*[HEIGHT] + </string> + <string name="words_separator" value=","/> + <string name="server_is_down"> + Despite our best efforts, something unexpected has gone wrong. + + Please check status.secondlifegrid.net to see if there is a known problem with the service. + If you continue to experience problems, please check your network and firewall setup. + </string> + <string name="dateTimeWeekdaysNames"> + Sunday:Monday:Tuesday:Wednesday:Thursday:Friday:Saturday + </string> + <string name="dateTimeWeekdaysShortNames"> + Sun:Mon:Tue:Wed:Thu:Fri:Sat + </string> + <string name="dateTimeMonthNames"> + January:February:March:April:May:June:July:August:September:October:November:December + </string> + <string name="dateTimeMonthShortNames"> + Jan:Feb:Mar:Apr:May:Jun:Jul:Aug:Sep:Oct:Nov:Dec + </string> + <string name="dateTimeDayFormat"> + [MDAY] + </string> + <string name="dateTimeAM"> + AM + </string> + <string name="dateTimePM"> + PM + </string> + <string name="LocalEstimateUSD"> + US$ [AMOUNT] + </string> + <string name="Membership"> + Membership + </string> + <string name="Roles"> + Roles + </string> + <string name="Group Identity"> + Group Identity + </string> + <string name="Parcel Management"> + Parcel Management + </string> + <string name="Parcel Identity"> + Parcel Identity + </string> + <string name="Parcel Settings"> + Parcel Settings + </string> + <string name="Parcel Powers"> + Parcel Powers + </string> + <string name="Parcel Access"> + Parcel Access + </string> + <string name="Parcel Content"> + Parcel Content + </string> + <string name="Object Management"> + Object Management + </string> + <string name="Accounting"> + Accounting + </string> + <string name="Notices"> + Notices + </string> + <string name="Chat"> + èŠå¤© + </string> + <string name="DeleteItems"> + Delete selected items? + </string> + <string name="DeleteItem"> + Delete selected item? + </string> + <string name="EmptyOutfitText"> + There are no items in this outfit + </string> + <string name="ExternalEditorNotSet"> + Select an editor using the ExternalEditor setting. + </string> + <string name="ExternalEditorNotFound"> + Cannot find the external editor you specified. +Try enclosing path to the editor with double quotes. +(e.g. "/path to my/editor" "%s") + </string> + <string name="ExternalEditorCommandParseError"> + Error parsing the external editor command. + </string> + <string name="ExternalEditorFailedToRun"> + External editor failed to run. + </string> + <string name="Esc"> + Esc + </string> + <string name="Space"> + Space + </string> + <string name="Enter"> + Enter + </string> + <string name="Tab"> + Tab + </string> + <string name="Ins"> + Ins + </string> + <string name="Del"> + Del + </string> + <string name="Backsp"> + Backsp + </string> + <string name="Shift"> + Shift + </string> + <string name="Ctrl"> + Ctrl + </string> + <string name="Alt"> + Alt + </string> + <string name="CapsLock"> + CapsLock + </string> + <string name="Left"> + Left + </string> + <string name="Right"> + Right + </string> + <string name="Up"> + Up + </string> + <string name="Down"> + Down + </string> + <string name="Home"> + Home + </string> + <string name="End"> + End + </string> + <string name="PgUp"> + PgUp + </string> + <string name="PgDn"> + PgDn + </string> + <string name="F1"> + F1 + </string> + <string name="F2"> + F2 + </string> + <string name="F3"> + F3 + </string> + <string name="F4"> + F4 + </string> + <string name="F5"> + F5 + </string> + <string name="F6"> + F6 + </string> + <string name="F7"> + F7 + </string> + <string name="F8"> + F8 + </string> + <string name="F9"> + F9 + </string> + <string name="F10"> + F10 + </string> + <string name="F11"> + F11 + </string> + <string name="F12"> + F12 + </string> + <string name="Add"> + Add + </string> + <string name="Subtract"> + Subtract + </string> + <string name="Multiply"> + Multiply + </string> + <string name="Divide"> + Divide + </string> + <string name="PAD_DIVIDE"> + PAD_DIVIDE + </string> + <string name="PAD_LEFT"> + PAD_LEFT + </string> + <string name="PAD_RIGHT"> + PAD_RIGHT + </string> + <string name="PAD_DOWN"> + PAD_DOWN + </string> + <string name="PAD_UP"> + PAD_UP + </string> + <string name="PAD_HOME"> + PAD_HOME + </string> + <string name="PAD_END"> + PAD_END + </string> + <string name="PAD_PGUP"> + PAD_PGUP + </string> + <string name="PAD_PGDN"> + PAD_PGDN + </string> + <string name="PAD_CENTER"> + PAD_CENTER + </string> + <string name="PAD_INS"> + PAD_INS + </string> + <string name="PAD_DEL"> + PAD_DEL + </string> + <string name="PAD_Enter"> + PAD_Enter + </string> + <string name="PAD_BUTTON0"> + PAD_BUTTON0 + </string> + <string name="PAD_BUTTON1"> + PAD_BUTTON1 + </string> + <string name="PAD_BUTTON2"> + PAD_BUTTON2 + </string> + <string name="PAD_BUTTON3"> + PAD_BUTTON3 + </string> + <string name="PAD_BUTTON4"> + PAD_BUTTON4 + </string> + <string name="PAD_BUTTON5"> + PAD_BUTTON5 + </string> + <string name="PAD_BUTTON6"> + PAD_BUTTON6 + </string> + <string name="PAD_BUTTON7"> + PAD_BUTTON7 + </string> + <string name="PAD_BUTTON8"> + PAD_BUTTON8 + </string> + <string name="PAD_BUTTON9"> + PAD_BUTTON9 + </string> + <string name="PAD_BUTTON10"> + PAD_BUTTON10 + </string> + <string name="PAD_BUTTON11"> + PAD_BUTTON11 + </string> + <string name="PAD_BUTTON12"> + PAD_BUTTON12 + </string> + <string name="PAD_BUTTON13"> + PAD_BUTTON13 + </string> + <string name="PAD_BUTTON14"> + PAD_BUTTON14 + </string> + <string name="PAD_BUTTON15"> + PAD_BUTTON15 + </string> + <string name="-"> + - + </string> + <string name="="> + = + </string> + <string name="`"> + ` + </string> + <string name=";"> + ; + </string> + <string name="["> + [ + </string> + <string name="]"> + ] + </string> + <string name="\"> + \ + </string> + <string name="0"> + 0 + </string> + <string name="1"> + 1 + </string> + <string name="2"> + 2 + </string> + <string name="3"> + 3 + </string> + <string name="4"> + 4 + </string> + <string name="5"> + 5 + </string> + <string name="6"> + 6 + </string> + <string name="7"> + 7 + </string> + <string name="8"> + 8 + </string> + <string name="9"> + 9 + </string> + <string name="A"> + A + </string> + <string name="B"> + B + </string> + <string name="C"> + C + </string> + <string name="D"> + D + </string> + <string name="E"> + E + </string> + <string name="F"> + F + </string> + <string name="G"> + G + </string> + <string name="H"> + H + </string> + <string name="I"> + I + </string> + <string name="J"> + J + </string> + <string name="K"> + K + </string> + <string name="L"> + L + </string> + <string name="M"> + M + </string> + <string name="N"> + N + </string> + <string name="O"> + O + </string> + <string name="P"> + P + </string> + <string name="Q"> + Q + </string> + <string name="R"> + R + </string> + <string name="S"> + S + </string> + <string name="T"> + T + </string> + <string name="U"> + U + </string> + <string name="V"> + V + </string> + <string name="W"> + W + </string> + <string name="X"> + X + </string> + <string name="Y"> + Y + </string> + <string name="Z"> + Z + </string> + <string name="BeaconParticle"> + Viewing particle beacons (blue) + </string> + <string name="BeaconPhysical"> + Viewing physical object beacons (green) + </string> + <string name="BeaconScripted"> + Viewing scripted object beacons (red) + </string> + <string name="BeaconScriptedTouch"> + Viewing scripted object with touch function beacons (red) + </string> + <string name="BeaconSound"> + Viewing sound beacons (yellow) + </string> + <string name="BeaconMedia"> + Viewing media beacons (white) + </string> + <string name="ParticleHiding"> + Hiding Particles + </string> +</strings> diff --git a/indra/newview/skins/default/xui/zh/teleport_strings.xml b/indra/newview/skins/default/xui/zh/teleport_strings.xml new file mode 100644 index 0000000000..33640f5fee --- /dev/null +++ b/indra/newview/skins/default/xui/zh/teleport_strings.xml @@ -0,0 +1,80 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<teleport_messages> + <message_set name="errors"> + <message name="invalid_tport"> + Problem encountered processing your teleport request. You may need to log back in before you can teleport. +If you continue to get this message, please check the [SUPPORT_SITE]. + </message> + <message name="invalid_region_handoff"> + Problem encountered processing your region crossing. You may need to log back in before you can cross regions. +If you continue to get this message, please check the [SUPPORT_SITE]. + </message> + <message name="blocked_tport"> + Sorry, teleport is currently blocked. Try again in a moment. +If you still cannot teleport, please log out and log back in to resolve the problem. + </message> + <message name="nolandmark_tport"> + Sorry, but system was unable to locate landmark destination. + </message> + <message name="timeout_tport"> + Sorry, but system was unable to complete the teleport connection. +Try again in a moment. + </message> + <message name="noaccess_tport"> + Sorry, you do not have access to that teleport destination. + </message> + <message name="missing_attach_tport"> + Your attachments have not arrived yet. Try waiting for a few more seconds or log out and back in again before attempting to teleport. + </message> + <message name="too_many_uploads_tport"> + The asset queue in this region is currently clogged so your teleport request will not be able to succeed in a timely manner. Please try again in a few minutes or go to a less busy area. + </message> + <message name="expired_tport"> + Sorry, but the system was unable to complete your teleport request in a timely fashion. Please try again in a few minutes. + </message> + <message name="expired_region_handoff"> + Sorry, but the system was unable to complete your region crossing in a timely fashion. Please try again in a few minutes. + </message> + <message name="no_host"> + Unable to find teleport destination. The destination may be temporarily unavailable or no longer exists. Please try again in a few minutes. + </message> + <message name="no_inventory_host"> + The inventory system is currently unavailable. + </message> + </message_set> + <message_set name="progress"> + <message name="sending_dest"> + Sending to destination. + </message> + <message name="redirecting"> + Redirecting to different location. + </message> + <message name="relaying"> + Relaying to destination. + </message> + <message name="sending_home"> + Sending home location request. + </message> + <message name="sending_landmark"> + Sending landmark location request. + </message> + <message name="completing"> + Completing teleport. + </message> + <message name="completed_from"> + Teleport completed from [T_SLURL] + </message> + <message name="resolving"> + Resolving destination. + </message> + <message name="contacting"> + Contacting new region. + </message> + <message name="arriving"> + 抵é”ä¸... + </message> + <message name="requesting"> + Requesting Teleport... + </message> + </message_set> +</teleport_messages> diff --git a/indra/newview/tests/gpus_results.txt b/indra/newview/tests/gpus_results.txt new file mode 100644 index 0000000000..7e9a064921 --- /dev/null +++ b/indra/newview/tests/gpus_results.txt @@ -0,0 +1,1595 @@ +GPU String Supported? Class Recognizer +------------------------------------------------------------------------------------------------------ ----------- ----- ------------------------------------ +ATI UNRECOGNIZED +ATI 3D-Analyze unsupported 0 ATI 3D-Analyze +ATI ASUS A9xxx supported 1 ATI ASUS A9xxx +ATI ASUS AH24xx supported 1 ATI ASUS AH24xx +ATI ASUS AH26xx supported 3 ATI ASUS AH26xx +ATI ASUS AH34xx supported 1 ATI ASUS AH34xx +ATI ASUS AH36xx supported 3 ATI ASUS AH36xx +ATI ASUS AH46xx supported 3 ATI ASUS AH46xx +ATI ASUS AX3xx supported 1 ATI ASUS AX3xx +ATI ASUS AX5xx supported 1 ATI ASUS AX5xx +ATI ASUS AX8xx supported 2 ATI ASUS AX8xx +ATI ASUS EAH38xx supported 3 ATI ASUS EAH38xx +ATI ASUS EAH43xx supported 1 ATI ASUS EAH43xx +ATI ASUS EAH45xx supported 1 ATI ASUS EAH45xx +ATI ASUS EAH48xx supported 3 ATI ASUS EAH48xx +ATI ASUS EAH57xx supported 3 ATI ASUS EAH57xx +ATI ASUS EAH58xx supported 3 ATI ASUS EAH58xx +ATI ASUS X1xxx supported 3 ATI ASUS Radeon X1xxx +ATI All-in-Wonder 9xxx supported 1 ATI All-in-Wonder 9xxx +ATI All-in-Wonder HD supported 1 ATI All-in-Wonder HD +ATI All-in-Wonder PCI-E supported 1 ATI All-in-Wonder PCI-E +ATI All-in-Wonder X1800 supported 3 ATI All-in-Wonder X1800 +ATI All-in-Wonder X1900 supported 3 ATI All-in-Wonder X1900 +ATI All-in-Wonder X600 supported 1 ATI All-in-Wonder X600 +ATI All-in-Wonder X800 supported 2 ATI All-in-Wonder X800 +ATI Diamond X1xxx supported 0 ATI Radeon X1xxx +ATI Display Adapter UNRECOGNIZED +ATI FireGL supported 0 ATI FireGL +ATI FireGL 5200 supported 0 ATI FireGL +ATI FireGL 5xxx supported 0 ATI FireGL +ATI FireMV supported 0 ATI FireMV +ATI Generic unsupported 0 ATI Generic +ATI Hercules 9800 supported 1 ATI Hercules 9800 +ATI IGP 340M unsupported 0 ATI IGP 340M +ATI M52 supported 1 ATI M52 +ATI M54 supported 1 ATI M54 +ATI M56 supported 1 ATI M56 +ATI M71 supported 1 ATI M71 +ATI M72 supported 1 ATI M72 +ATI M76 supported 3 ATI M76 +ATI Mobility Radeon supported 0 ATI Mobility Radeon +ATI Mobility Radeon 7xxx supported 0 ATI Mobility Radeon 7xxx +ATI Mobility Radeon 9600 supported 0 ATI Mobility Radeon 9600 +ATI Mobility Radeon 9700 supported 1 ATI Mobility Radeon 9700 +ATI Mobility Radeon 9800 supported 1 ATI Mobility Radeon 9800 +ATI Mobility Radeon HD 2300 supported 1 ATI Mobility Radeon HD 2300 +ATI Mobility Radeon HD 2400 supported 1 ATI Mobility Radeon HD 2400 +ATI Mobility Radeon HD 2600 supported 3 ATI Mobility Radeon HD 2600 +ATI Mobility Radeon HD 2700 supported 3 ATI Mobility Radeon HD 2700 +ATI Mobility Radeon HD 3400 supported 2 ATI Mobility Radeon HD 3400 +ATI Mobility Radeon HD 3600 supported 3 ATI Mobility Radeon HD 3600 +ATI Mobility Radeon HD 3800 supported 3 ATI Mobility Radeon HD 3800 +ATI Mobility Radeon HD 4200 supported 2 ATI Mobility Radeon HD 4200 +ATI Mobility Radeon HD 4300 supported 2 ATI Mobility Radeon HD 4300 +ATI Mobility Radeon HD 4500 supported 3 ATI Mobility Radeon HD 4500 +ATI Mobility Radeon HD 4600 supported 3 ATI Mobility Radeon HD 4600 +ATI Mobility Radeon HD 4800 supported 3 ATI Mobility Radeon HD 4800 +ATI Mobility Radeon HD 5400 supported 2 ATI Mobility Radeon HD 5400 +ATI Mobility Radeon HD 5600 supported 2 ATI Mobility Radeon HD 5600 +ATI Mobility Radeon X1xxx supported 0 ATI Radeon X1xxx +ATI Mobility Radeon X2xxx supported 0 ATI Mobility Radeon X2xxx +ATI Mobility Radeon X3xx supported 1 ATI Mobility Radeon X3xx +ATI Mobility Radeon X6xx supported 1 ATI Mobility Radeon X6xx +ATI Mobility Radeon X7xx supported 1 ATI Mobility Radeon X7xx +ATI Mobility Radeon Xxxx supported 0 ATI Mobility Radeon Xxxx +ATI RV380 supported 0 ATI RV380 +ATI RV530 supported 1 ATI RV530 +ATI Radeon 2100 supported 0 ATI Radeon 2100 +ATI Radeon 3000 supported 0 ATI Radeon 3000 +ATI Radeon 3100 supported 1 ATI Radeon 3100 +ATI Radeon 7000 supported 0 ATI Radeon 7xxx +ATI Radeon 7xxx supported 0 ATI Radeon 7xxx +ATI Radeon 8xxx supported 0 ATI Radeon 8xxx +ATI Radeon 9000 supported 0 ATI Radeon 9000 +ATI Radeon 9100 supported 0 ATI Radeon 9100 +ATI Radeon 9200 supported 0 ATI Radeon 9200 +ATI Radeon 9500 supported 0 ATI Radeon 9500 +ATI Radeon 9600 supported 0 ATI Radeon 9600 +ATI Radeon 9700 supported 1 ATI Radeon 9700 +ATI Radeon 9800 supported 1 ATI Radeon 9800 +ATI Radeon HD 2300 supported 0 ATI Radeon HD 2300 +ATI Radeon HD 2400 supported 1 ATI Radeon HD 2400 +ATI Radeon HD 2600 supported 2 ATI Radeon HD 2600 +ATI Radeon HD 2900 supported 3 ATI Radeon HD 2900 +ATI Radeon HD 3000 supported 0 ATI Radeon HD 3000 +ATI Radeon HD 3100 supported 1 ATI Radeon HD 3100 +ATI Radeon HD 3200 supported 0 ATI Radeon HD 3200 +ATI Radeon HD 3300 supported 1 ATI Radeon HD 3300 +ATI Radeon HD 3400 supported 1 ATI Radeon HD 3400 +ATI Radeon HD 3600 supported 3 ATI Radeon HD 3600 +ATI Radeon HD 3800 supported 3 ATI Radeon HD 3800 +ATI Radeon HD 4200 supported 1 ATI Radeon HD 4200 +ATI Radeon HD 4300 supported 1 ATI Radeon HD 4300 +ATI Radeon HD 4500 supported 3 ATI Radeon HD 4500 +ATI Radeon HD 4600 supported 3 ATI Radeon HD 4600 +ATI Radeon HD 4700 supported 3 ATI Radeon HD 4700 +ATI Radeon HD 4800 supported 3 ATI Radeon HD 4800 +ATI Radeon HD 5400 supported 3 ATI Radeon HD 5400 +ATI Radeon HD 5500 supported 3 ATI Radeon HD 5500 +ATI Radeon HD 5600 supported 3 ATI Radeon HD 5600 +ATI Radeon HD 5700 supported 3 ATI Radeon HD 5700 +ATI Radeon HD 5800 supported 3 ATI Radeon HD 5800 +ATI Radeon HD 5900 supported 3 ATI Radeon HD 5900 +ATI Radeon HD 6200 supported 2 ATI Radeon HD 6200 +ATI Radeon HD 6300 supported 2 ATI Radeon HD 6300 +ATI Radeon HD 6500 supported 3 ATI Radeon HD 6500 +ATI Radeon HD 6800 supported 3 ATI Radeon HD 6800 +ATI Radeon HD 6900 supported 3 ATI Radeon HD 6900 +ATI Radeon OpenGL supported 0 ATI Radeon +ATI Radeon RV250 supported 0 ATI Radeon RV250 +ATI Radeon RV600 supported 1 ATI Radeon RV600 +ATI Radeon RX9550 supported 1 ATI Radeon RX9550 +ATI Radeon VE unsupported 0 ATI Radeon VE +ATI Radeon X1000 supported 0 ATI Radeon X1xxx +ATI Radeon X1200 supported 0 ATI Radeon X1xxx +ATI Radeon X1300 supported 0 ATI Radeon X1xxx +ATI Radeon X13xx supported 0 ATI Radeon X1xxx +ATI Radeon X1400 supported 0 ATI Radeon X1xxx +ATI Radeon X1500 supported 0 ATI Radeon X1xxx +ATI Radeon X1600 supported 0 ATI Radeon X1xxx +ATI Radeon X16xx supported 0 ATI Radeon X1xxx +ATI Radeon X1700 supported 0 ATI Radeon X1xxx +ATI Radeon X1800 supported 0 ATI Radeon X1xxx +ATI Radeon X1900 supported 0 ATI Radeon X1xxx +ATI Radeon X19xx supported 0 ATI Radeon X1xxx +ATI Radeon X1xxx supported 0 ATI Radeon X1xxx +ATI Radeon X300 supported 0 ATI Radeon X300 +ATI Radeon X500 supported 0 ATI Radeon X500 +ATI Radeon X600 supported 1 ATI Radeon X600 +ATI Radeon X700 supported 1 ATI Radeon X700 +ATI Radeon X7xx supported 1 ATI Radeon X700 +ATI Radeon X800 supported 2 ATI Radeon X800 +ATI Radeon Xpress supported 0 ATI Radeon Xpress +ATI Rage 128 supported 0 ATI Rage 128 +ATI Technologies Inc. supported 0 ATI Technologies +ATI Technologies Inc. x86 supported 0 ATI Technologies +ATI Technologies Inc. x86/SSE2 supported 0 ATI Technologies +ATI Technologies Inc. (Vista) ATI Mobility Radeon HD 5730 supported 3 ATI Mobility Radeon HD 5700 +ATI Technologies Inc. 256MB ATI Radeon X1300PRO x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. AMD 760G supported 1 ATI 760G/Radeon 3000 +ATI Technologies Inc. AMD 760G (Microsoft WDDM 1.1) supported 1 ATI 760G/Radeon 3000 +ATI Technologies Inc. AMD 780L supported 1 ATI 780L/Radeon 3000 +ATI Technologies Inc. AMD FirePro 2270 supported 1 ATI FirePro 2000 +ATI Technologies Inc. AMD M860G with ATI Mobility Radeon 4100 supported 0 ATI Mobility Radeon 4100 +ATI Technologies Inc. AMD M880G with ATI Mobility Radeon HD 4200 supported 2 ATI Mobility Radeon HD 4200 +ATI Technologies Inc. AMD M880G with ATI Mobility Radeon HD 4250 supported 2 ATI Mobility Radeon HD 4200 +ATI Technologies Inc. AMD RADEON HD 6450 supported 3 ATI Radeon HD 6400 +ATI Technologies Inc. AMD Radeon HD 6200 series Graphics supported 2 ATI Radeon HD 6200 +ATI Technologies Inc. AMD Radeon HD 6250 Graphics supported 2 ATI Radeon HD 6200 +ATI Technologies Inc. AMD Radeon HD 6300 series Graphics supported 2 ATI Radeon HD 6300 +ATI Technologies Inc. AMD Radeon HD 6300M Series supported 2 ATI Radeon HD 6300 +ATI Technologies Inc. AMD Radeon HD 6310 Graphics supported 2 ATI Radeon HD 6300 +ATI Technologies Inc. AMD Radeon HD 6310M supported 2 ATI Radeon HD 6300 +ATI Technologies Inc. AMD Radeon HD 6330M supported 2 ATI Radeon HD 6300 +ATI Technologies Inc. AMD Radeon HD 6350 supported 2 ATI Radeon HD 6300 +ATI Technologies Inc. AMD Radeon HD 6370M supported 2 ATI Radeon HD 6300 +ATI Technologies Inc. AMD Radeon HD 6400M Series supported 3 ATI Radeon HD 6400 +ATI Technologies Inc. AMD Radeon HD 6450 supported 3 ATI Radeon HD 6400 +ATI Technologies Inc. AMD Radeon HD 6470M supported 3 ATI Radeon HD 6400 +ATI Technologies Inc. AMD Radeon HD 6490M supported 3 ATI Radeon HD 6400 +ATI Technologies Inc. AMD Radeon HD 6500M/5600/5700 Series supported 3 ATI Radeon HD 6500 +ATI Technologies Inc. AMD Radeon HD 6530M supported 3 ATI Radeon HD 6500 +ATI Technologies Inc. AMD Radeon HD 6550M supported 3 ATI Radeon HD 6500 +ATI Technologies Inc. AMD Radeon HD 6570 supported 3 ATI Radeon HD 6500 +ATI Technologies Inc. AMD Radeon HD 6570M supported 3 ATI Radeon HD 6500 +ATI Technologies Inc. AMD Radeon HD 6570M/5700 Series supported 3 ATI Radeon HD 6500 +ATI Technologies Inc. AMD Radeon HD 6600M Series supported 3 ATI Radeon HD 66xx +ATI Technologies Inc. AMD Radeon HD 6650M supported 3 ATI Radeon HD 66xx +ATI Technologies Inc. AMD Radeon HD 6670 supported 3 ATI Radeon HD 66xx +ATI Technologies Inc. AMD Radeon HD 6700 Series supported 3 ATI Radeon HD 6700 +ATI Technologies Inc. AMD Radeon HD 6750 supported 3 ATI Radeon HD 6700 +ATI Technologies Inc. AMD Radeon HD 6750M supported 3 ATI Radeon HD 6700 +ATI Technologies Inc. AMD Radeon HD 6770 supported 3 ATI Radeon HD 6700 +ATI Technologies Inc. AMD Radeon HD 6800 Series supported 3 ATI Radeon HD 6800 +ATI Technologies Inc. AMD Radeon HD 6850M supported 3 ATI Radeon HD 6800 +ATI Technologies Inc. AMD Radeon HD 6870 supported 3 ATI Radeon HD 6800 +ATI Technologies Inc. AMD Radeon HD 6870M supported 3 ATI Radeon HD 6800 +ATI Technologies Inc. AMD Radeon HD 6900 Series supported 3 ATI Radeon HD 6900 +ATI Technologies Inc. AMD Radeon HD 6970M supported 3 ATI Radeon HD 6900 +ATI Technologies Inc. AMD Radeon HD 6990 supported 3 ATI Radeon HD 6900 +ATI Technologies Inc. AMD Radeon(TM) HD 6470M supported 0 ATI Technologies +ATI Technologies Inc. ASUS 5870 Eyefinity 6 supported 0 ATI Technologies +ATI Technologies Inc. ASUS AH2600 Series supported 3 ATI ASUS AH26xx +ATI Technologies Inc. ASUS AH3450 Series supported 1 ATI ASUS AH34xx +ATI Technologies Inc. ASUS AH3650 Series supported 3 ATI ASUS AH36xx +ATI Technologies Inc. ASUS AH4650 Series supported 3 ATI ASUS AH46xx +ATI Technologies Inc. ASUS ARES supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH2900 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH3450 Series supported 1 ATI ASUS AH34xx +ATI Technologies Inc. ASUS EAH3650 Series supported 3 ATI ASUS AH36xx +ATI Technologies Inc. ASUS EAH4350 series supported 1 ATI ASUS EAH43xx +ATI Technologies Inc. ASUS EAH4550 series supported 1 ATI ASUS EAH45xx +ATI Technologies Inc. ASUS EAH4650 series supported 3 ATI ASUS AH46xx +ATI Technologies Inc. ASUS EAH4670 series supported 3 ATI ASUS AH46xx +ATI Technologies Inc. ASUS EAH4750 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH4770 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH4770 series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH4850 series supported 3 ATI ASUS EAH48xx +ATI Technologies Inc. ASUS EAH5450 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH5550 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH5570 series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH5670 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH5750 Series supported 3 ATI ASUS EAH57xx +ATI Technologies Inc. ASUS EAH5770 Series supported 3 ATI ASUS EAH57xx +ATI Technologies Inc. ASUS EAH5830 Series supported 3 ATI ASUS EAH58xx +ATI Technologies Inc. ASUS EAH5850 Series supported 3 ATI ASUS EAH58xx +ATI Technologies Inc. ASUS EAH5870 Series supported 3 ATI ASUS EAH58xx +ATI Technologies Inc. ASUS EAH5970 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH6850 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH6870 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH6950 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAH6970 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS EAHG4670 series supported 0 ATI Technologies +ATI Technologies Inc. ASUS Extreme AX600 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS Extreme AX600XT-TD supported 0 ATI Technologies +ATI Technologies Inc. ASUS X1300 Series x86/SSE2 supported 3 ATI ASUS Radeon X1xxx +ATI Technologies Inc. ASUS X1550 Series supported 3 ATI ASUS Radeon X1xxx +ATI Technologies Inc. ASUS X1950 Series x86/SSE2 supported 3 ATI ASUS Radeon X1xxx +ATI Technologies Inc. ASUS X800 Series supported 0 ATI Technologies +ATI Technologies Inc. ASUS X850 Series supported 0 ATI Technologies +ATI Technologies Inc. ATI All-in-Wonder HD supported 1 ATI All-in-Wonder HD +ATI Technologies Inc. ATI FirePro 2260 supported 1 ATI FirePro 2000 +ATI Technologies Inc. ATI FirePro 2450 supported 1 ATI FirePro 2000 +ATI Technologies Inc. ATI FirePro M5800 supported 3 ATI FirePro M5800 +ATI Technologies Inc. ATI FirePro M7740 supported 3 ATI FirePro M7740 +ATI Technologies Inc. ATI FirePro M7820 supported 3 ATI FirePro M7820 +ATI Technologies Inc. ATI FirePro V3700 (FireGL) supported 0 ATI FireGL +ATI Technologies Inc. ATI FirePro V3800 supported 1 ATI FirePro 3000 +ATI Technologies Inc. ATI FirePro V4800 supported 2 ATI FirePro 4000 +ATI Technologies Inc. ATI FirePro V4800 (FireGL) supported 0 ATI FireGL +ATI Technologies Inc. ATI FirePro V5800 supported 3 ATI FirePro 5000 +ATI Technologies Inc. ATI FirePro V7800 supported 3 ATI FirePro 7000 +ATI Technologies Inc. ATI MOBILITY RADEON 9XXX x86/SSE2 supported 0 ATI Mobility Radeon Xxxx +ATI Technologies Inc. ATI MOBILITY RADEON HD 3450 supported 2 ATI Mobility Radeon HD 3400 +ATI Technologies Inc. ATI MOBILITY RADEON X1600 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI MOBILITY RADEON X2300 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI MOBILITY RADEON X2300 HD x86/SSE2 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI MOBILITY RADEON X2300 x86/MMX/3DNow!/SSE2 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI MOBILITY RADEON X2300 x86/SSE2 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI MOBILITY RADEON X300 supported 1 ATI Mobility Radeon X3xx +ATI Technologies Inc. ATI MOBILITY RADEON X600 supported 1 ATI Mobility Radeon X6xx +ATI Technologies Inc. ATI MOBILITY RADEON XPRESS 200 supported 0 ATI Mobility Radeon Xxxx +ATI Technologies Inc. ATI Mobility FireGL V5700 supported 1 ATI FireGL 5xxx +ATI Technologies Inc. ATI Mobility Radeon 4100 supported 0 ATI Mobility Radeon 4100 +ATI Technologies Inc. ATI Mobility Radeon Graphics supported 0 ATI Mobility Radeon +ATI Technologies Inc. ATI Mobility Radeon HD 2300 supported 1 ATI Mobility Radeon HD 2300 +ATI Technologies Inc. ATI Mobility Radeon HD 2400 supported 1 ATI Mobility Radeon HD 2400 +ATI Technologies Inc. ATI Mobility Radeon HD 2400 XT supported 1 ATI Mobility Radeon HD 2400 +ATI Technologies Inc. ATI Mobility Radeon HD 2600 supported 3 ATI Mobility Radeon HD 2600 +ATI Technologies Inc. ATI Mobility Radeon HD 2600 XT supported 3 ATI Mobility Radeon HD 2600 +ATI Technologies Inc. ATI Mobility Radeon HD 2700 supported 3 ATI Mobility Radeon HD 2700 +ATI Technologies Inc. ATI Mobility Radeon HD 3400 Series supported 2 ATI Mobility Radeon HD 3400 +ATI Technologies Inc. ATI Mobility Radeon HD 3430 supported 2 ATI Mobility Radeon HD 3400 +ATI Technologies Inc. ATI Mobility Radeon HD 3450 supported 2 ATI Mobility Radeon HD 3400 +ATI Technologies Inc. ATI Mobility Radeon HD 3470 supported 2 ATI Mobility Radeon HD 3400 +ATI Technologies Inc. ATI Mobility Radeon HD 3470 Hybrid X2 supported 2 ATI Mobility Radeon HD 3400 +ATI Technologies Inc. ATI Mobility Radeon HD 3650 supported 3 ATI Mobility Radeon HD 3600 +ATI Technologies Inc. ATI Mobility Radeon HD 4200 supported 2 ATI Mobility Radeon HD 4200 +ATI Technologies Inc. ATI Mobility Radeon HD 4200 Series supported 2 ATI Mobility Radeon HD 4200 +ATI Technologies Inc. ATI Mobility Radeon HD 4225 supported 2 ATI Mobility Radeon HD 4200 +ATI Technologies Inc. ATI Mobility Radeon HD 4225 Series supported 2 ATI Mobility Radeon HD 4200 +ATI Technologies Inc. ATI Mobility Radeon HD 4250 supported 2 ATI Mobility Radeon HD 4200 +ATI Technologies Inc. ATI Mobility Radeon HD 4250 Graphics supported 2 ATI Mobility Radeon HD 4200 +ATI Technologies Inc. ATI Mobility Radeon HD 4270 supported 2 ATI Mobility Radeon HD 4200 +ATI Technologies Inc. ATI Mobility Radeon HD 4300 Series supported 2 ATI Mobility Radeon HD 4300 +ATI Technologies Inc. ATI Mobility Radeon HD 4300/4500 Series supported 2 ATI Mobility Radeon HD 4300 +ATI Technologies Inc. ATI Mobility Radeon HD 4330 supported 2 ATI Mobility Radeon HD 4300 +ATI Technologies Inc. ATI Mobility Radeon HD 4330 Series supported 2 ATI Mobility Radeon HD 4300 +ATI Technologies Inc. ATI Mobility Radeon HD 4350 supported 2 ATI Mobility Radeon HD 4300 +ATI Technologies Inc. ATI Mobility Radeon HD 4350 Series supported 2 ATI Mobility Radeon HD 4300 +ATI Technologies Inc. ATI Mobility Radeon HD 4500 Series supported 3 ATI Mobility Radeon HD 4500 +ATI Technologies Inc. ATI Mobility Radeon HD 4500/5100 Series supported 3 ATI Mobility Radeon HD 4500 +ATI Technologies Inc. ATI Mobility Radeon HD 4530 supported 3 ATI Mobility Radeon HD 4500 +ATI Technologies Inc. ATI Mobility Radeon HD 4530 Series supported 3 ATI Mobility Radeon HD 4500 +ATI Technologies Inc. ATI Mobility Radeon HD 4550 supported 3 ATI Mobility Radeon HD 4500 +ATI Technologies Inc. ATI Mobility Radeon HD 4570 supported 3 ATI Mobility Radeon HD 4500 +ATI Technologies Inc. ATI Mobility Radeon HD 4600 Series supported 3 ATI Mobility Radeon HD 4600 +ATI Technologies Inc. ATI Mobility Radeon HD 4650 supported 3 ATI Mobility Radeon HD 4600 +ATI Technologies Inc. ATI Mobility Radeon HD 4650 Series supported 3 ATI Mobility Radeon HD 4600 +ATI Technologies Inc. ATI Mobility Radeon HD 4670 supported 3 ATI Mobility Radeon HD 4600 +ATI Technologies Inc. ATI Mobility Radeon HD 4830 Series supported 3 ATI Mobility Radeon HD 4800 +ATI Technologies Inc. ATI Mobility Radeon HD 4850 supported 3 ATI Mobility Radeon HD 4800 +ATI Technologies Inc. ATI Mobility Radeon HD 4870 supported 3 ATI Mobility Radeon HD 4800 +ATI Technologies Inc. ATI Mobility Radeon HD 5000 supported 0 ATI Mobility Radeon +ATI Technologies Inc. ATI Mobility Radeon HD 5000 Series supported 0 ATI Mobility Radeon +ATI Technologies Inc. ATI Mobility Radeon HD 5145 supported 2 ATI Mobility Radeon HD 5100 +ATI Technologies Inc. ATI Mobility Radeon HD 5165 supported 2 ATI Mobility Radeon HD 5100 +ATI Technologies Inc. ATI Mobility Radeon HD 530v supported 1 ATI Mobility Radeon HD 530v +ATI Technologies Inc. ATI Mobility Radeon HD 5400 Series supported 2 ATI Mobility Radeon HD 5400 +ATI Technologies Inc. ATI Mobility Radeon HD 540v supported 2 ATI Mobility Radeon HD 540v +ATI Technologies Inc. ATI Mobility Radeon HD 5430 supported 2 ATI Mobility Radeon HD 5400 +ATI Technologies Inc. ATI Mobility Radeon HD 5450 supported 2 ATI Mobility Radeon HD 5400 +ATI Technologies Inc. ATI Mobility Radeon HD 5450 Series supported 2 ATI Mobility Radeon HD 5400 +ATI Technologies Inc. ATI Mobility Radeon HD 545v supported 2 ATI Mobility Radeon HD 545v +ATI Technologies Inc. ATI Mobility Radeon HD 5470 supported 2 ATI Mobility Radeon HD 5400 +ATI Technologies Inc. ATI Mobility Radeon HD 550v supported 2 ATI Mobility Radeon HD 550v +ATI Technologies Inc. ATI Mobility Radeon HD 5600/5700 Series supported 2 ATI Mobility Radeon HD 5600 +ATI Technologies Inc. ATI Mobility Radeon HD 560v supported 2 ATI Mobility Radeon HD 560v +ATI Technologies Inc. ATI Mobility Radeon HD 5650 supported 2 ATI Mobility Radeon HD 5600 +ATI Technologies Inc. ATI Mobility Radeon HD 5700 Series supported 3 ATI Mobility Radeon HD 5700 +ATI Technologies Inc. ATI Mobility Radeon HD 5730 supported 3 ATI Mobility Radeon HD 5700 +ATI Technologies Inc. ATI Mobility Radeon HD 5800 Series supported 0 ATI Mobility Radeon +ATI Technologies Inc. ATI Mobility Radeon HD 5850 supported 0 ATI Mobility Radeon +ATI Technologies Inc. ATI Mobility Radeon HD 5870 supported 0 ATI Mobility Radeon +ATI Technologies Inc. ATI Mobility Radeon HD 6300 series supported 2 ATI Mobility Radeon HD 6300 +ATI Technologies Inc. ATI Mobility Radeon HD 6370 supported 2 ATI Mobility Radeon HD 6300 +ATI Technologies Inc. ATI Mobility Radeon HD 6470M supported 3 ATI Mobility Radeon HD 6400M +ATI Technologies Inc. ATI Mobility Radeon HD 6550 supported 3 ATI Mobility Radeon HD 6500M +ATI Technologies Inc. ATI Mobility Radeon HD 6570 supported 3 ATI Mobility Radeon HD 6500M +ATI Technologies Inc. ATI Mobility Radeon X1300 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Mobility Radeon X1300 x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Mobility Radeon X1300 x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Mobility Radeon X1350 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Mobility Radeon X1350 x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Mobility Radeon X1400 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Mobility Radeon X1400 x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Mobility Radeon X1600 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Mobility Radeon X1600 x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Mobility Radeon X1700 x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Mobility Radeon X2300 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI Mobility Radeon X2300 (Omega 3.8.442) supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI Mobility Radeon X2300 x86 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI Mobility Radeon X2300 x86/MMX/3DNow!/SSE2 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI Mobility Radeon X2300 x86/SSE2 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI Mobility Radeon X2500 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI Mobility Radeon X2500 x86/SSE2 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. ATI Mobility Radeon. HD 530v supported 1 ATI Mobility Radeon HD 530v +ATI Technologies Inc. ATI Mobility Radeon. HD 5470 supported 2 ATI Mobility Radeon HD 5400 +ATI Technologies Inc. ATI RADEON HD 3200 T25XX by CAMILO supported 0 ATI Radeon HD 3200 +ATI Technologies Inc. ATI RADEON XPRESS 1100 supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI RADEON XPRESS 200 Series supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI RADEON XPRESS 200 Series x86/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI RADEON XPRESS 200M SERIES supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Radeon supported 0 ATI Technologies +ATI Technologies Inc. ATI Radeon 2100 supported 0 ATI Radeon 2100 +ATI Technologies Inc. ATI Radeon 2100 (Microsoft - WDDM) supported 0 ATI Radeon 2100 +ATI Technologies Inc. ATI Radeon 2100 Graphics supported 0 ATI Radeon 2100 +ATI Technologies Inc. ATI Radeon 3000 supported 0 ATI Radeon 3000 +ATI Technologies Inc. ATI Radeon 3000 Graphics supported 0 ATI Radeon 3000 +ATI Technologies Inc. ATI Radeon 3100 Graphics supported 1 ATI Radeon 3100 +ATI Technologies Inc. ATI Radeon 5xxx series supported 3 ATI Radeon 5xxx +ATI Technologies Inc. ATI Radeon 9550 / X1050 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon 9550 / X1050 Series x86/MMX/3DNow!/SSE supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon 9550 / X1050 Series x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon 9550 / X1050 Series(Microsoft - WDDM) supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon 9600 / X1050 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon 9600/9550/X1050 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon BA Prototype OpenGL Engine supported 0 ATI Technologies +ATI Technologies Inc. ATI Radeon BB Prototype OpenGL Engine supported 0 ATI Technologies +ATI Technologies Inc. ATI Radeon Cedar PRO Prototype OpenGL Engine supported 2 AMD CEDAR (HD 5450) +ATI Technologies Inc. ATI Radeon Cypress PRO Prototype OpenGL Engine supported 3 AMD CYPRESS (HD 5800) +ATI Technologies Inc. ATI Radeon Graphics Processor supported 0 ATI Technologies +ATI Technologies Inc. ATI Radeon HD 2200 Graphics supported 0 ATI Technologies +ATI Technologies Inc. ATI Radeon HD 2350 supported 0 ATI Radeon HD 2300 +ATI Technologies Inc. ATI Radeon HD 2400 supported 1 ATI Radeon HD 2400 +ATI Technologies Inc. ATI Radeon HD 2400 OpenGL Engine supported 1 ATI Radeon HD 2400 +ATI Technologies Inc. ATI Radeon HD 2400 PRO supported 1 ATI Radeon HD 2400 +ATI Technologies Inc. ATI Radeon HD 2400 PRO AGP supported 1 ATI Radeon HD 2400 +ATI Technologies Inc. ATI Radeon HD 2400 Pro supported 1 ATI Radeon HD 2400 +ATI Technologies Inc. ATI Radeon HD 2400 Series supported 1 ATI Radeon HD 2400 +ATI Technologies Inc. ATI Radeon HD 2400 XT supported 1 ATI Radeon HD 2400 +ATI Technologies Inc. ATI Radeon HD 2400 XT OpenGL Engine supported 1 ATI Radeon HD 2400 +ATI Technologies Inc. ATI Radeon HD 2600 OpenGL Engine supported 2 ATI Radeon HD 2600 +ATI Technologies Inc. ATI Radeon HD 2600 PRO supported 2 ATI Radeon HD 2600 +ATI Technologies Inc. ATI Radeon HD 2600 PRO OpenGL Engine supported 2 ATI Radeon HD 2600 +ATI Technologies Inc. ATI Radeon HD 2600 Pro supported 2 ATI Radeon HD 2600 +ATI Technologies Inc. ATI Radeon HD 2600 Series supported 2 ATI Radeon HD 2600 +ATI Technologies Inc. ATI Radeon HD 2600 XT supported 2 ATI Radeon HD 2600 +ATI Technologies Inc. ATI Radeon HD 2900 GT supported 3 ATI Radeon HD 2900 +ATI Technologies Inc. ATI Radeon HD 2900 XT supported 3 ATI Radeon HD 2900 +ATI Technologies Inc. ATI Radeon HD 3200 Graphics supported 0 ATI Radeon HD 3200 +ATI Technologies Inc. ATI Radeon HD 3300 Graphics supported 1 ATI Radeon HD 3300 +ATI Technologies Inc. ATI Radeon HD 3400 Series supported 1 ATI Radeon HD 3400 +ATI Technologies Inc. ATI Radeon HD 3450 supported 1 ATI Radeon HD 3400 +ATI Technologies Inc. ATI Radeon HD 3450 - Dell Optiplex supported 1 ATI Radeon HD 3400 +ATI Technologies Inc. ATI Radeon HD 3470 supported 1 ATI Radeon HD 3400 +ATI Technologies Inc. ATI Radeon HD 3470 - Dell Optiplex supported 1 ATI Radeon HD 3400 +ATI Technologies Inc. ATI Radeon HD 3550 supported 1 ATI Radeon HD 3500 +ATI Technologies Inc. ATI Radeon HD 3600 Series supported 3 ATI Radeon HD 3600 +ATI Technologies Inc. ATI Radeon HD 3650 supported 3 ATI Radeon HD 3600 +ATI Technologies Inc. ATI Radeon HD 3650 AGP supported 3 ATI Radeon HD 3600 +ATI Technologies Inc. ATI Radeon HD 3730 supported 3 ATI Radeon HD 3700 +ATI Technologies Inc. ATI Radeon HD 3800 Series supported 3 ATI Radeon HD 3800 +ATI Technologies Inc. ATI Radeon HD 3850 supported 3 ATI Radeon HD 3800 +ATI Technologies Inc. ATI Radeon HD 3850 AGP supported 3 ATI Radeon HD 3800 +ATI Technologies Inc. ATI Radeon HD 3870 supported 3 ATI Radeon HD 3800 +ATI Technologies Inc. ATI Radeon HD 3870 X2 supported 3 ATI Radeon HD 3800 +ATI Technologies Inc. ATI Radeon HD 4200 supported 1 ATI Radeon HD 4200 +ATI Technologies Inc. ATI Radeon HD 4250 supported 1 ATI Radeon HD 4200 +ATI Technologies Inc. ATI Radeon HD 4250 Graphics supported 1 ATI Radeon HD 4200 +ATI Technologies Inc. ATI Radeon HD 4270 supported 1 ATI Radeon HD 4200 +ATI Technologies Inc. ATI Radeon HD 4290 supported 1 ATI Radeon HD 4200 +ATI Technologies Inc. ATI Radeon HD 4300 Series supported 1 ATI Radeon HD 4300 +ATI Technologies Inc. ATI Radeon HD 4300/4500 Series supported 1 ATI Radeon HD 4300 +ATI Technologies Inc. ATI Radeon HD 4350 supported 1 ATI Radeon HD 4300 +ATI Technologies Inc. ATI Radeon HD 4350 (Microsoft WDDM 1.1) supported 1 ATI Radeon HD 4300 +ATI Technologies Inc. ATI Radeon HD 4450 supported 1 ATI Radeon HD 4400 +ATI Technologies Inc. ATI Radeon HD 4500 Series supported 3 ATI Radeon HD 4500 +ATI Technologies Inc. ATI Radeon HD 4550 supported 3 ATI Radeon HD 4500 +ATI Technologies Inc. ATI Radeon HD 4600 Series supported 3 ATI Radeon HD 4600 +ATI Technologies Inc. ATI Radeon HD 4650 supported 3 ATI Radeon HD 4600 +ATI Technologies Inc. ATI Radeon HD 4670 supported 3 ATI Radeon HD 4600 +ATI Technologies Inc. ATI Radeon HD 4670 OpenGL Engine supported 3 ATI Radeon HD 4600 +ATI Technologies Inc. ATI Radeon HD 4700 Series supported 3 ATI Radeon HD 4700 +ATI Technologies Inc. ATI Radeon HD 4720 supported 3 ATI Radeon HD 4700 +ATI Technologies Inc. ATI Radeon HD 4730 supported 3 ATI Radeon HD 4700 +ATI Technologies Inc. ATI Radeon HD 4730 Series supported 3 ATI Radeon HD 4700 +ATI Technologies Inc. ATI Radeon HD 4750 supported 3 ATI Radeon HD 4700 +ATI Technologies Inc. ATI Radeon HD 4770 supported 3 ATI Radeon HD 4700 +ATI Technologies Inc. ATI Radeon HD 4800 Series supported 3 ATI Radeon HD 4800 +ATI Technologies Inc. ATI Radeon HD 4850 supported 3 ATI Radeon HD 4800 +ATI Technologies Inc. ATI Radeon HD 4850 OpenGL Engine supported 3 ATI Radeon HD 4800 +ATI Technologies Inc. ATI Radeon HD 4850 Series supported 3 ATI Radeon HD 4800 +ATI Technologies Inc. ATI Radeon HD 4870 supported 3 ATI Radeon HD 4800 +ATI Technologies Inc. ATI Radeon HD 4870 OpenGL Engine supported 3 ATI Radeon HD 4800 +ATI Technologies Inc. ATI Radeon HD 4870 X2 supported 3 ATI Radeon HD 4800 +ATI Technologies Inc. ATI Radeon HD 5400 Series supported 3 ATI Radeon HD 5400 +ATI Technologies Inc. ATI Radeon HD 5450 supported 3 ATI Radeon HD 5400 +ATI Technologies Inc. ATI Radeon HD 5500 Series supported 3 ATI Radeon HD 5500 +ATI Technologies Inc. ATI Radeon HD 5570 supported 3 ATI Radeon HD 5500 +ATI Technologies Inc. ATI Radeon HD 5600 Series supported 3 ATI Radeon HD 5600 +ATI Technologies Inc. ATI Radeon HD 5630 supported 3 ATI Radeon HD 5600 +ATI Technologies Inc. ATI Radeon HD 5670 supported 3 ATI Radeon HD 5600 +ATI Technologies Inc. ATI Radeon HD 5670 OpenGL Engine supported 3 ATI Radeon HD 5600 +ATI Technologies Inc. ATI Radeon HD 5700 Series supported 3 ATI Radeon HD 5700 +ATI Technologies Inc. ATI Radeon HD 5750 supported 3 ATI Radeon HD 5700 +ATI Technologies Inc. ATI Radeon HD 5750 OpenGL Engine supported 3 ATI Radeon HD 5700 +ATI Technologies Inc. ATI Radeon HD 5770 supported 3 ATI Radeon HD 5700 +ATI Technologies Inc. ATI Radeon HD 5770 OpenGL Engine supported 3 ATI Radeon HD 5700 +ATI Technologies Inc. ATI Radeon HD 5800 Series supported 3 ATI Radeon HD 5800 +ATI Technologies Inc. ATI Radeon HD 5850 supported 3 ATI Radeon HD 5800 +ATI Technologies Inc. ATI Radeon HD 5870 supported 3 ATI Radeon HD 5800 +ATI Technologies Inc. ATI Radeon HD 5870 OpenGL Engine supported 3 ATI Radeon HD 5800 +ATI Technologies Inc. ATI Radeon HD 5900 Series supported 3 ATI Radeon HD 5900 +ATI Technologies Inc. ATI Radeon HD 5970 supported 3 ATI Radeon HD 5900 +ATI Technologies Inc. ATI Radeon HD 6230 supported 2 ATI Radeon HD 6200 +ATI Technologies Inc. ATI Radeon HD 6250 supported 2 ATI Radeon HD 6200 +ATI Technologies Inc. ATI Radeon HD 6350 supported 2 ATI Radeon HD 6300 +ATI Technologies Inc. ATI Radeon HD 6390 supported 2 ATI Radeon HD 6300 +ATI Technologies Inc. ATI Radeon HD 6490M OpenGL Engine supported 3 ATI Radeon HD 6400 +ATI Technologies Inc. ATI Radeon HD 6510 supported 3 ATI Radeon HD 6500 +ATI Technologies Inc. ATI Radeon HD 6570M supported 3 ATI Radeon HD 6500 +ATI Technologies Inc. ATI Radeon HD 6750 supported 3 ATI Radeon HD 6700 +ATI Technologies Inc. ATI Radeon HD 6750M OpenGL Engine supported 3 ATI Radeon HD 6700 +ATI Technologies Inc. ATI Radeon HD 6770 supported 3 ATI Radeon HD 6700 +ATI Technologies Inc. ATI Radeon HD 6770M OpenGL Engine supported 3 ATI Radeon HD 6700 +ATI Technologies Inc. ATI Radeon HD 6800 Series supported 3 ATI Radeon HD 6800 +ATI Technologies Inc. ATI Radeon HD 6970M OpenGL Engine supported 3 ATI Radeon HD 6900 +ATI Technologies Inc. ATI Radeon HD3750 supported 3 ATI Radeon HD 3700 +ATI Technologies Inc. ATI Radeon HD4300/HD4500 series supported 1 ATI Radeon HD 4300 +ATI Technologies Inc. ATI Radeon HD4670 supported 3 ATI Radeon HD 4600 +ATI Technologies Inc. ATI Radeon Juniper LE Prototype OpenGL Engine supported 3 AMD JUNIPER (HD 5700) +ATI Technologies Inc. ATI Radeon RV710 Prototype OpenGL Engine supported 1 AMD RV710 (HD 4300) +ATI Technologies Inc. ATI Radeon RV730 Prototype OpenGL Engine supported 3 AMD RV730 (HD 4600) +ATI Technologies Inc. ATI Radeon RV770 Prototype OpenGL Engine supported 3 AMD RV770 (HD 4800) +ATI Technologies Inc. ATI Radeon RV790 Prototype OpenGL Engine supported 3 AMD RV790 (HD 4800) +ATI Technologies Inc. ATI Radeon Redwood PRO Prototype OpenGL Engine supported 3 AMD REDWOOD (HD 5500/5600) +ATI Technologies Inc. ATI Radeon Redwood XT Prototype OpenGL Engine supported 3 AMD REDWOOD (HD 5500/5600) +ATI Technologies Inc. ATI Radeon Whistler PRO/LP Prototype OpenGL Engine supported 0 ATI Technologies +ATI Technologies Inc. ATI Radeon X1050 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1050 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1200 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1200 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1200 Series x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1250 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1250 x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1270 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1270 x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1300/X1550 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1550 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1600 OpenGL Engine supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1900 OpenGL Engine supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X1950 GT supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon X300/X550/X1050 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. ATI Radeon Xpress 1100 supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Radeon Xpress 1150 supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Radeon Xpress 1150 x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Radeon Xpress 1200 supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Radeon Xpress 1200 Series supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Radeon Xpress 1200 Series x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Radeon Xpress 1200 x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Radeon Xpress 1250 supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Radeon Xpress 1250 x86/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Radeon Xpress Series supported 0 ATI Radeon Xpress +ATI Technologies Inc. ATI Yamaha HD 9000 supported 0 ATI Technologies +ATI Technologies Inc. ATi RS880M supported 1 ATI RS880M +ATI Technologies Inc. Carte graphique VGA standard supported 0 ATI Technologies +ATI Technologies Inc. Diamond Radeon X1550 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. EG JUNIPER supported 3 AMD JUNIPER (HD 5700) +ATI Technologies Inc. EG PARK supported 3 AMD PARK +ATI Technologies Inc. FireGL V3100 Pentium 4 (SSE2) supported 0 ATI FireGL +ATI Technologies Inc. FireMV 2400 PCI DDR x86 supported 0 ATI FireMV +ATI Technologies Inc. FireMV 2400 PCI DDR x86/SSE2 supported 0 ATI FireMV +ATI Technologies Inc. GeCube Radeon X1550 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Geforce 9500 GT supported 2 ATI Geforce 9500 GT +ATI Technologies Inc. Geforce 9500GT supported 2 ATI Geforce 9500 GT +ATI Technologies Inc. Geforce 9800 GT supported 2 ATI Geforce 9800 GT +ATI Technologies Inc. HD3730 supported 0 ATI Technologies +ATI Technologies Inc. HIGHTECH EXCALIBUR RADEON 9550SE Series supported 0 ATI Radeon 9500 +ATI Technologies Inc. HIGHTECH EXCALIBUR X700 PRO supported 0 ATI Technologies +ATI Technologies Inc. M21 x86/MMX/3DNow!/SSE2 supported 0 ATI Technologies +ATI Technologies Inc. M76M supported 3 ATI M76 +ATI Technologies Inc. MOBILITY RADEON 7500 DDR x86/SSE2 supported 0 ATI Mobility Radeon +ATI Technologies Inc. MOBILITY RADEON 9000 DDR x86/SSE2 supported 0 ATI Mobility Radeon +ATI Technologies Inc. MOBILITY RADEON 9000 IGPRADEON 9100 IGP DDR x86/SSE2 supported 0 ATI Mobility Radeon +ATI Technologies Inc. MOBILITY RADEON 9600 x86/SSE2 supported 0 ATI Mobility Radeon 9600 +ATI Technologies Inc. MOBILITY RADEON 9700 x86/SSE2 supported 1 ATI Mobility Radeon 9700 +ATI Technologies Inc. MOBILITY RADEON X300 x86/SSE2 supported 1 ATI Mobility Radeon X3xx +ATI Technologies Inc. MOBILITY RADEON X600 x86/SSE2 supported 1 ATI Mobility Radeon X6xx +ATI Technologies Inc. MOBILITY RADEON X700 SE x86 supported 1 ATI Mobility Radeon X7xx +ATI Technologies Inc. MOBILITY RADEON X700 x86/SSE2 supported 1 ATI Mobility Radeon X7xx +ATI Technologies Inc. MSI RX9550SE supported 1 ATI Radeon RX9550 +ATI Technologies Inc. Mobility Radeon X2300 HD supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. Mobility Radeon X2300 HD x86/SSE2 supported 0 ATI Mobility Radeon X2xxx +ATI Technologies Inc. RADEON 7000 DDR x86/MMX/3DNow!/SSE supported 0 ATI Radeon 7xxx +ATI Technologies Inc. RADEON 7000 DDR x86/SSE2 supported 0 ATI Radeon 7xxx +ATI Technologies Inc. RADEON 7500 DDR x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon 7xxx +ATI Technologies Inc. RADEON 7500 DDR x86/SSE2 supported 0 ATI Radeon 7xxx +ATI Technologies Inc. RADEON 9100 IGP DDR x86/SSE2 supported 0 ATI Radeon 9100 +ATI Technologies Inc. RADEON 9200 DDR x86/MMX/3DNow!/SSE supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9200 DDR x86/SSE2 supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9200 PRO DDR x86/MMX/3DNow!/SSE supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9200 Series DDR x86/MMX/3DNow!/SSE supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9200 Series DDR x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9200 Series DDR x86/SSE supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9200 Series DDR x86/SSE2 supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9200SE DDR x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9200SE DDR x86/SSE2 supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9250/9200 Series DDR x86/MMX/3DNow!/SSE supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9250/9200 Series DDR x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9250/9200 Series DDR x86/SSE2 supported 0 ATI Radeon 9200 +ATI Technologies Inc. RADEON 9500 supported 0 ATI Radeon 9500 +ATI Technologies Inc. RADEON 9550 x86/SSE2 supported 0 ATI Radeon 9500 +ATI Technologies Inc. RADEON 9600 SERIES supported 0 ATI Radeon 9600 +ATI Technologies Inc. RADEON 9600 SERIES x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon 9600 +ATI Technologies Inc. RADEON 9600 TX x86/SSE2 supported 0 ATI Radeon 9600 +ATI Technologies Inc. RADEON 9600 x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon 9600 +ATI Technologies Inc. RADEON 9600 x86/SSE2 supported 0 ATI Radeon 9600 +ATI Technologies Inc. RADEON 9700 PRO x86/MMX/3DNow!/SSE supported 1 ATI Radeon 9700 +ATI Technologies Inc. RADEON 9800 PRO supported 1 ATI Radeon 9800 +ATI Technologies Inc. RADEON 9800 x86/SSE2 supported 1 ATI Radeon 9800 +ATI Technologies Inc. RADEON IGP 340M DDR x86/SSE2 unsupported 0 ATI IGP 340M +ATI Technologies Inc. RADEON X300 Series x86/SSE2 supported 0 ATI Radeon X300 +ATI Technologies Inc. RADEON X300 x86/SSE2 supported 0 ATI Radeon X300 +ATI Technologies Inc. RADEON X300/X550 Series x86/SSE2 supported 0 ATI Radeon X300 +ATI Technologies Inc. RADEON X550 x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X500 +ATI Technologies Inc. RADEON X550 x86/SSE2 supported 0 ATI Radeon X500 +ATI Technologies Inc. RADEON X600 Series supported 1 ATI Radeon X600 +ATI Technologies Inc. RADEON X600 x86/SSE2 supported 1 ATI Radeon X600 +ATI Technologies Inc. RADEON X700 PRO x86/SSE2 supported 1 ATI Radeon X700 +ATI Technologies Inc. RADEON X800 SE x86/MMX/3DNow!/SSE2 supported 2 ATI Radeon X800 +ATI Technologies Inc. RADEON X800GT supported 2 ATI Radeon X800 +ATI Technologies Inc. RADEON XPRESS 200 Series SW TCL x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. RADEON XPRESS 200 Series SW TCL x86/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. RADEON XPRESS 200 Series x86/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. RADEON XPRESS 200M Series SW TCL x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. RADEON XPRESS 200M Series SW TCL x86/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. RADEON XPRESS 200M Series x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. RADEON XPRESS 200M Series x86/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. RADEON XPRESS Series x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. RADEON XPRESS Series x86/SSE2 supported 0 ATI Radeon Xpress +ATI Technologies Inc. RS740 supported 0 ATI Technologies +ATI Technologies Inc. RS780C supported 0 AMD RS780 (HD 3200) +ATI Technologies Inc. RS780M supported 0 AMD RS780 (HD 3200) +ATI Technologies Inc. RS880 supported 1 AMD RS880 (HD 4200) +ATI Technologies Inc. RV410 Pro x86/SSE2 supported 1 ATI RV410 (X700) +ATI Technologies Inc. RV790 supported 3 AMD RV790 (HD 4800) +ATI Technologies Inc. Radeon (TM) HD 6470M supported 0 ATI Technologies +ATI Technologies Inc. Radeon (TM) HD 6490M supported 0 ATI Technologies +ATI Technologies Inc. Radeon (TM) HD 6770M supported 0 ATI Technologies +ATI Technologies Inc. Radeon 7000 DDR x86/SSE2 supported 0 ATI Radeon 7xxx +ATI Technologies Inc. Radeon 7000 SDR x86/SSE2 supported 0 ATI Radeon 7xxx +ATI Technologies Inc. Radeon 7500 DDR x86/SSE2 supported 0 ATI Radeon 7xxx +ATI Technologies Inc. Radeon 9000 DDR x86/SSE2 supported 0 ATI Radeon 9000 +ATI Technologies Inc. Radeon DDR x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon DDR +ATI Technologies Inc. Radeon DDR x86/SSE supported 0 ATI Radeon DDR +ATI Technologies Inc. Radeon DDR x86/SSE2 supported 0 ATI Radeon DDR +ATI Technologies Inc. Radeon HD 6310 supported 2 ATI Radeon HD 6300 +ATI Technologies Inc. Radeon HD 6800 Series supported 3 ATI Radeon HD 6800 +ATI Technologies Inc. Radeon SDR x86/SSE2 supported 0 ATI Technologies +ATI Technologies Inc. Radeon X1300 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1300 Series x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1300 Series x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1300/X1550 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1300/X1550 Series x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1550 64-bit (Microsoft - WDDM) supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1550 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1550 Series x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1600 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1600 Pro / X1300XT x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1600 Series x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1600/X1650 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1650 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1650 Series x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1650 Series x86/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1900 Series x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1950 Pro supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1950 Pro x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1950 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X1950 Series (Microsoft - WDDM) supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X300/X550/X1050 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Radeon X550/X700 Series supported 0 ATI Radeon X500 +ATI Technologies Inc. Radeon X550XTX x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X500 +ATI Technologies Inc. SAPPHIRE RADEON X300SE supported 0 ATI Radeon X300 +ATI Technologies Inc. SAPPHIRE RADEON X300SE x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X300 +ATI Technologies Inc. SAPPHIRE RADEON X300SE x86/SSE2 supported 0 ATI Radeon X300 +ATI Technologies Inc. SAPPHIRE Radeon X1550 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. SAPPHIRE Radeon X1550 Series x86/MMX/3DNow!/SSE2 supported 0 ATI Radeon X1xxx +ATI Technologies Inc. Sapphire Radeon HD 3730 supported 3 ATI Radeon HD 3700 +ATI Technologies Inc. Sapphire Radeon HD 3750 supported 3 ATI Radeon HD 3700 +ATI Technologies Inc. Standard VGA Graphics Adapter supported 0 ATI Technologies +ATI Technologies Inc. Tul, RADEON X600 PRO supported 0 ATI Technologies +ATI Technologies Inc. Tul, RADEON X600 PRO x86/SSE2 supported 0 ATI Technologies +ATI Technologies Inc. Tul, RADEON X700 PRO supported 0 ATI Technologies +ATI Technologies Inc. Tul, RADEON X700 PRO x86/MMX/3DNow!/SSE2 supported 0 ATI Technologies +ATI Technologies Inc. VisionTek Radeon 4350 supported 0 ATI Technologies +ATI Technologies Inc. VisionTek Radeon X1550 Series supported 0 ATI Radeon X1xxx +ATI Technologies Inc. WRESTLER 9802 supported 0 ATI Technologies +ATI Technologies Inc. WRESTLER 9803 supported 0 ATI Technologies +ATI Technologies Inc. XFX Radeon HD 4570 supported 3 ATI Radeon HD 4500 +ATI Technologies Inc. Yamaha ATI HD 9000da/s supported 0 ATI Technologies +ATI Technologies Inc. Yamaha ATI HD 9000da/s 2048 supported 0 ATI Technologies +Advanced Micro Devices, Inc. Mesa DRI R600 (RS780 9612) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 supported 0 AMD RS780 (HD 3200) +Advanced Micro Devices, Inc. Mesa DRI R600 (RS880 9710) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 supported 1 AMD RS880 (HD 4200) +Advanced Micro Devices, Inc. Mesa DRI R600 (RS880 9712) 20090101 TCL supported 1 AMD RS880 (HD 4200) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV610 94C1) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 supported 1 AMD RV610 (HD 2400) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV610 94C9) 20090101 x86/MMX/SSE2 TCL DRI2 supported 1 AMD RV610 (HD 2400) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV620 95C4) 20090101 x86/MMX/SSE2 TCL DRI2 supported 1 AMD RV620 (HD 3400) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV620 95C5) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 supported 1 AMD RV620 (HD 3400) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV620 95C5) 20090101 x86/MMX/SSE2 TCL DRI2 supported 1 AMD RV620 (HD 3400) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV635 9596) 20090101 x86/MMX+/3DNow!+/SSE TCL DRI2 supported 3 AMD RV635 (HD 3600) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV670 9505) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 supported 3 AMD RV670 (HD 3800) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV710 9552) 20090101 x86/MMX/SSE2 TCL DRI2 supported 1 AMD RV710 (HD 4300) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV730 9490) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 supported 3 AMD RV730 (HD 4600) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV730 9490) 20090101 x86/MMX/SSE2 TCL DRI2 supported 3 AMD RV730 (HD 4600) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV730 9498) 20090101 TCL DRI2 supported 3 AMD RV730 (HD 4600) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV770 9440) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 supported 3 AMD RV770 (HD 4800) +Advanced Micro Devices, Inc. Mesa DRI R600 (RV770 9442) 20090101 x86/MMX/SSE2 TCL DRI2 supported 3 AMD RV770 (HD 4800) +Alex Mohr GL Hijacker! UNRECOGNIZED +Apple Software Renderer unsupported 0 Apple Software Renderer +DRI R300 Project Mesa DRI R300 (RS400 5954) 20090101 x86/MMX+/3DNow!+/SSE2 NO-TCL DRI2 supported 1 ATI R300 (9700) +DRI R300 Project Mesa DRI R300 (RS400 5975) 20090101 x86/MMX+/3DNow!+/SSE2 NO-TCL DRI2 supported 1 ATI R300 (9700) +DRI R300 Project Mesa DRI R300 (RS400 5A62) 20090101 x86/MMX/SSE2 NO-TCL DRI2 supported 1 ATI R300 (9700) +DRI R300 Project Mesa DRI R300 (RS600 7941) 20090101 x86/MMX/SSE2 NO-TCL unsupported 0 ATI RS600 (Xpress 3200) +DRI R300 Project Mesa DRI R300 (RS690 791F) 20090101 x86/MMX+/3DNow!+/SSE2 NO-TCL DRI2 supported 1 ATI R300 (9700) +DRI R300 Project Mesa DRI R300 (RV350 4151) 20090101 AGP 4x x86/MMX+/3DNow!+/SSE TCL supported 0 ATI RV350 (9600) +DRI R300 Project Mesa DRI R300 (RV350 4153) 20090101 AGP 8x x86/MMX+/3DNow!+/SSE TCL supported 0 ATI RV350 (9600) +DRI R300 Project Mesa DRI R300 (RV380 3150) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 supported 0 ATI RV380 +DRI R300 Project Mesa DRI R300 (RV380 3150) 20090101 x86/MMX/SSE2 TCL DRI2 supported 0 ATI RV380 +DRI R300 Project Mesa DRI R300 (RV380 5B60) 20090101 x86/MMX/SSE2 TCL DRI2 supported 0 ATI RV380 +DRI R300 Project Mesa DRI R300 (RV380 5B62) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 supported 0 ATI RV380 +DRI R300 Project Mesa DRI R300 (RV515 7145) 20090101 x86/MMX/SSE2 TCL DRI2 supported 1 ATI RV515 +DRI R300 Project Mesa DRI R300 (RV515 7146) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 supported 1 ATI RV515 +DRI R300 Project Mesa DRI R300 (RV515 7146) 20090101 x86/MMX/SSE2 TCL DRI2 supported 1 ATI RV515 +DRI R300 Project Mesa DRI R300 (RV515 7149) 20090101 x86/MMX/SSE2 TCL DRI2 supported 1 ATI RV515 +DRI R300 Project Mesa DRI R300 (RV515 714A) 20090101 x86/MMX/SSE2 TCL supported 1 ATI RV515 +DRI R300 Project Mesa DRI R300 (RV515 714A) 20090101 x86/MMX/SSE2 TCL DRI2 supported 1 ATI RV515 +DRI R300 Project Mesa DRI R300 (RV530 71C4) 20090101 x86/MMX/SSE2 TCL DRI2 supported 1 ATI RV530 +GPU_CLASS_UNKNOWN UNRECOGNIZED +Humper Chromium UNRECOGNIZED +Intel UNRECOGNIZED +Intel HD Graphics Family supported 2 Intel HD Graphics +Intel 3D-Analyze v2.2 - http://www.tommti-systems.com UNRECOGNIZED +Intel 3D-Analyze v2.3 - http://www.tommti-systems.com UNRECOGNIZED +Intel 4 Series Internal Chipset UNRECOGNIZED +Intel 830M unsupported 0 Intel 830M +Intel 845G unsupported 0 Intel 845G +Intel 855GM unsupported 0 Intel 855GM +Intel 865G unsupported 0 Intel 865G +Intel 915G unsupported 0 Intel 915G +Intel 915GM unsupported 0 Intel 915GM +Intel 945G supported 0 Intel 945G +Intel 945GM supported 0 Intel 945GM +Intel 950 supported 0 Intel 950 +Intel 965 supported 0 Intel 965 +Intel B43 Express Chipset UNRECOGNIZED +Intel Bear Lake unsupported 0 Intel Bear Lake +Intel Broadwater unsupported 0 Intel Broadwater +Intel Brookdale unsupported 0 Intel Brookdale +Intel Cantiga unsupported 0 Intel Cantiga +Intel Eaglelake supported 0 Intel Eaglelake +Intel Familia Mobile 45 Express Chipset (Microsoft Corporation - WDDM 1.1) UNRECOGNIZED +Intel G33 unsupported 0 Intel G33 +Intel G41 supported 0 Intel G41 +Intel G41 Express Chipset supported 0 Intel G41 +Intel G45 supported 0 Intel G45 +Intel G45/G43 Express Chipset supported 0 Intel G45 +Intel Graphics Media Accelerator HD supported 0 Intel Graphics Media HD +Intel HD Graphics supported 2 Intel HD Graphics +Intel HD Graphics 100 supported 2 Intel HD Graphics +Intel HD Graphics 200 supported 2 Intel HD Graphics +Intel HD Graphics 200 BR-1101-00SH supported 2 Intel HD Graphics +Intel HD Graphics 200 BR-1101-00SJ supported 2 Intel HD Graphics +Intel HD Graphics 200 BR-1101-00SK supported 2 Intel HD Graphics +Intel HD Graphics 200 BR-1101-01M5 supported 2 Intel HD Graphics +Intel HD Graphics 200 BR-1101-01M6 supported 2 Intel HD Graphics +Intel HD Graphics BR-1004-01Y1 supported 2 Intel HD Graphics +Intel HD Graphics BR-1006-0364 supported 2 Intel HD Graphics +Intel HD Graphics BR-1006-0365 supported 2 Intel HD Graphics +Intel HD Graphics BR-1006-0366 supported 2 Intel HD Graphics +Intel HD Graphics BR-1007-02G4 supported 2 Intel HD Graphics +Intel HD Graphics BR-1101-04SY supported 2 Intel HD Graphics +Intel HD Graphics BR-1101-04SZ supported 2 Intel HD Graphics +Intel HD Graphics BR-1101-04T0 supported 2 Intel HD Graphics +Intel HD Graphics BR-1101-04T9 supported 2 Intel HD Graphics +Intel HD Graphics Family supported 2 Intel HD Graphics +Intel HD Graphics Family BR-1012-00Y8 supported 2 Intel HD Graphics +Intel HD Graphics Family BR-1012-00YF supported 2 Intel HD Graphics +Intel HD Graphics Family BR-1012-00ZD supported 2 Intel HD Graphics +Intel HD Graphics Family BR-1102-00ML supported 2 Intel HD Graphics +Intel Inc. Intel GMA 900 OpenGL Engine UNRECOGNIZED +Intel Inc. Intel GMA 950 OpenGL Engine supported 0 Intel 950 +Intel Inc. Intel GMA X3100 OpenGL Engine supported 0 Intel X3100 +Intel Inc. Intel HD Graphics 3000 OpenGL Engine supported 2 Intel HD Graphics +Intel Inc. Intel HD Graphics OpenGL Engine supported 2 Intel HD Graphics +Intel Inc. Intel HD xxxx OpenGL Engine UNRECOGNIZED +Intel Intel 845G unsupported 0 Intel 845G +Intel Intel 855GM unsupported 0 Intel 855GM +Intel Intel 865G unsupported 0 Intel 865G +Intel Intel 915G unsupported 0 Intel 915G +Intel Intel 915GM unsupported 0 Intel 915GM +Intel Intel 945G supported 0 Intel 945G +Intel Intel 945GM supported 0 Intel 945GM +Intel Intel 965/963 Graphics Media Accelerator supported 0 Intel 965 +Intel Intel Bear Lake B unsupported 0 Intel Bear Lake +Intel Intel Broadwater G unsupported 0 Intel Broadwater +Intel Intel Brookdale-G unsupported 0 Intel Brookdale +Intel Intel Calistoga UNRECOGNIZED +Intel Intel Cantiga unsupported 0 Intel Cantiga +Intel Intel Eaglelake supported 0 Intel Eaglelake +Intel Intel Grantsdale-G UNRECOGNIZED +Intel Intel HD Graphics 3000 supported 2 Intel HD Graphics +Intel Intel Lakeport UNRECOGNIZED +Intel Intel Montara-GM unsupported 0 Intel Montara +Intel Intel Pineview Platform supported 0 Intel Pineview +Intel Intel Springdale-G unsupported 0 Intel Springdale +Intel Mobile - famiglia Express Chipset 45 (Microsoft Corporation - WDDM 1.1) UNRECOGNIZED +Intel Mobile 4 Series supported 0 Intel Mobile 4 Series +Intel Mobile 4 Series Express Chipset Family supported 0 Intel Mobile 4 Series +Intel Mobile 45 Express Chipset Family (Microsoft Corporation - WDDM 1.1) UNRECOGNIZED +Intel Mobile HD Graphics supported 2 Intel HD Graphics +Intel Mobile SandyBridge HD Graphics supported 2 Intel HD Graphics +Intel Montara unsupported 0 Intel Montara +Intel Pineview supported 0 Intel Pineview +Intel Q45/Q43 Express Chipset UNRECOGNIZED +Intel Royal BNA Driver UNRECOGNIZED +Intel SandyBridge HD Graphics supported 2 Intel HD Graphics +Intel SandyBridge HD Graphics BR-1006-00V8 supported 2 Intel HD Graphics +Intel Springdale unsupported 0 Intel Springdale +Intel X3100 supported 0 Intel X3100 +Intergraph wcgdrv 06.05.06.18 UNRECOGNIZED +Intergraph wcgdrv 06.06.00.35 UNRECOGNIZED +LegendgrafiX Mobile 945 Express C/TitaniumGL/GAC/D3D ACCELERATION/6x86/1 THREADs | http://Legendgra... UNRECOGNIZED +LegendgrafiX NVIDIA GeForce GT 430/TitaniumGL/GAC/D3D ACCELERATION/6x86/1 THREADs | http://Legendgr... supported 3 NVIDIA GT 430M +Linden Lab Headless UNRECOGNIZED +Matrox unsupported 0 Matrox +Mesa unsupported 0 Mesa +Mesa Project Software Rasterizer unsupported 0 Mesa +NVIDIA /PCI/SSE2 UNRECOGNIZED +NVIDIA /PCI/SSE2/3DNOW! UNRECOGNIZED +NVIDIA 205 supported 0 NVIDIA G 205M +NVIDIA 210 supported 1 NVIDIA G 210 +NVIDIA 310 supported 2 NVIDIA G 310M +NVIDIA 310M supported 2 NVIDIA G 310M +NVIDIA 315 supported 2 NVIDIA G 315 +NVIDIA 315M supported 2 NVIDIA G 315 +NVIDIA 320M supported 2 NVIDIA G 320M +NVIDIA C51 supported 0 NVIDIA C51 +NVIDIA D10M2-20/PCI/SSE2 UNRECOGNIZED +NVIDIA D10P1-25/PCI/SSE2 UNRECOGNIZED +NVIDIA D10P1-30/PCI/SSE2 UNRECOGNIZED +NVIDIA D10P2-50/PCI/SSE2 UNRECOGNIZED +NVIDIA D11M2-30/PCI/SSE2 UNRECOGNIZED +NVIDIA D12-P1-35/PCI/SSE2 UNRECOGNIZED +NVIDIA D12U-15/PCI/SSE2 UNRECOGNIZED +NVIDIA D13M1-40/PCI/SSE2 UNRECOGNIZED +NVIDIA D13P1-40/PCI/SSE2 UNRECOGNIZED +NVIDIA D13U-10/PCI/SSE2 UNRECOGNIZED +NVIDIA D13U/PCI/SSE2 UNRECOGNIZED +NVIDIA D9M supported 1 NVIDIA D9M +NVIDIA D9M-20/PCI/SSE2 supported 1 NVIDIA D9M +NVIDIA Entry Graphics/PCI/SSE2 UNRECOGNIZED +NVIDIA Entry Graphics/PCI/SSE2/3DNOW! UNRECOGNIZED +NVIDIA G 102M supported 0 NVIDIA G102M +NVIDIA G 103M supported 0 NVIDIA G103M +NVIDIA G 105M supported 0 NVIDIA G105M +NVIDIA G 110M supported 0 NVIDIA G 110M +NVIDIA G100 supported 0 NVIDIA G100 +NVIDIA G102M supported 0 NVIDIA G102M +NVIDIA G103M supported 0 NVIDIA G103M +NVIDIA G105M supported 0 NVIDIA G105M +NVIDIA G210 supported 1 NVIDIA G 210 +NVIDIA G210M supported 1 NVIDIA G 210 +NVIDIA G70/PCI/SSE2 UNRECOGNIZED +NVIDIA G72 supported 1 NVIDIA G72 +NVIDIA G73 supported 1 NVIDIA G73 +NVIDIA G84 supported 2 NVIDIA G84 +NVIDIA G86 supported 3 NVIDIA G86 +NVIDIA G92 supported 3 NVIDIA G92 +NVIDIA G92-200/PCI/SSE2 supported 3 NVIDIA G92 +NVIDIA G94 supported 3 NVIDIA G94 +NVIDIA G96/PCI/SSE2 UNRECOGNIZED +NVIDIA G98/PCI/SSE2 UNRECOGNIZED +NVIDIA GT 120 supported 2 NVIDIA GT 120M +NVIDIA GT 130 supported 2 NVIDIA GT 130M +NVIDIA GT 130M supported 2 NVIDIA GT 130M +NVIDIA GT 140 supported 2 NVIDIA GT 140M +NVIDIA GT 150 supported 2 NVIDIA GT 150M +NVIDIA GT 160M supported 2 NVIDIA GT 160M +NVIDIA GT 220 supported 2 NVIDIA GT 220M +NVIDIA GT 220/PCI/SSE2 supported 2 NVIDIA GT 220M +NVIDIA GT 220/PCI/SSE2/3DNOW! supported 2 NVIDIA GT 220M +NVIDIA GT 230 supported 2 NVIDIA GT 230M +NVIDIA GT 230M supported 2 NVIDIA GT 230M +NVIDIA GT 240 supported 2 NVIDIA GT 240M +NVIDIA GT 240M supported 2 NVIDIA GT 240M +NVIDIA GT 250M supported 2 NVIDIA GT 250M +NVIDIA GT 260M supported 2 NVIDIA GT 260M +NVIDIA GT 320 supported 2 NVIDIA GT 320M +NVIDIA GT 320M supported 2 NVIDIA GT 320M +NVIDIA GT 330 supported 3 NVIDIA GT 330M +NVIDIA GT 330M supported 3 NVIDIA GT 330M +NVIDIA GT 340 supported 2 NVIDIA GT 340M +NVIDIA GT 420 supported 2 NVIDIA GT 420M +NVIDIA GT 430 supported 3 NVIDIA GT 430M +NVIDIA GT 440 supported 3 NVIDIA GT 440M +NVIDIA GT 450 supported 3 NVIDIA GT 450M +NVIDIA GT 520 supported 3 NVIDIA GT 520M +NVIDIA GT 540 supported 3 NVIDIA GT 540M +NVIDIA GT 540M supported 3 NVIDIA GT 540M +NVIDIA GT-120 supported 2 NVIDIA GT 120 +NVIDIA GT200/PCI/SSE2 UNRECOGNIZED +NVIDIA GTS 150 supported 2 NVIDIA GT 150M +NVIDIA GTS 240 supported 3 NVIDIA GTS 240 +NVIDIA GTS 250 supported 3 NVIDIA GTS 250 +NVIDIA GTS 350M supported 3 NVIDIA GTS 350M +NVIDIA GTS 360 supported 3 NVIDIA GTS 360 +NVIDIA GTS 360M supported 3 NVIDIA GTS 360M +NVIDIA GTS 450 supported 3 NVIDIA GTS 450 +NVIDIA GTX 260 supported 3 NVIDIA GTX 260 +NVIDIA GTX 260M supported 3 NVIDIA GTX 260 +NVIDIA GTX 270 supported 3 NVIDIA GTX 270 +NVIDIA GTX 280 supported 3 NVIDIA GTX 280 +NVIDIA GTX 285 supported 3 NVIDIA GTX 285 +NVIDIA GTX 290 supported 3 NVIDIA GTX 290 +NVIDIA GTX 460 supported 3 NVIDIA GTX 460 +NVIDIA GTX 460M supported 3 NVIDIA GTX 460M +NVIDIA GTX 465 supported 3 NVIDIA GTX 465 +NVIDIA GTX 470 supported 3 NVIDIA GTX 470 +NVIDIA GTX 470M supported 3 NVIDIA GTX 470M +NVIDIA GTX 480 supported 3 NVIDIA GTX 480 +NVIDIA GTX 480M supported 3 NVIDIA GTX 480M +NVIDIA GTX 550 Ti supported 3 NVIDIA GTX 550 +NVIDIA GTX 560 supported 3 NVIDIA GTX 560 +NVIDIA GTX 560 Ti supported 3 NVIDIA GTX 560 +NVIDIA GTX 570 supported 3 NVIDIA GTX 570 +NVIDIA GTX 580 supported 3 NVIDIA GTX 580 +NVIDIA GTX 590 supported 3 NVIDIA GTX 590 +NVIDIA GeForce UNRECOGNIZED +NVIDIA GeForce 2 supported 0 NVIDIA GeForce 2 +NVIDIA GeForce 205/PCI/SSE2 supported 2 NVIDIA 205 +NVIDIA GeForce 210 supported 2 NVIDIA 210 +NVIDIA GeForce 210/PCI/SSE2 supported 2 NVIDIA 210 +NVIDIA GeForce 210/PCI/SSE2/3DNOW! supported 2 NVIDIA 210 +NVIDIA GeForce 3 supported 0 NVIDIA GeForce 3 +NVIDIA GeForce 305M/PCI/SSE2 supported 1 NVIDIA 305M +NVIDIA GeForce 310/PCI/SSE2 supported 3 NVIDIA 310 +NVIDIA GeForce 310/PCI/SSE2/3DNOW! supported 3 NVIDIA 310 +NVIDIA GeForce 310M/PCI/SSE2 supported 1 NVIDIA 310M +NVIDIA GeForce 315/PCI/SSE2 supported 3 NVIDIA 315 +NVIDIA GeForce 315/PCI/SSE2/3DNOW! supported 3 NVIDIA 315 +NVIDIA GeForce 315M/PCI/SSE2 supported 2 NVIDIA 315M +NVIDIA GeForce 320M/PCI/SSE2 supported 2 NVIDIA 320M +NVIDIA GeForce 4 Go supported 0 NVIDIA GeForce 4 +NVIDIA GeForce 4 MX supported 0 NVIDIA GeForce 4 +NVIDIA GeForce 4 Ti supported 0 NVIDIA GeForce 4 +NVIDIA GeForce 405/PCI/SSE2 supported 1 NVIDIA G 405 +NVIDIA GeForce 6100 supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6100 nForce 400/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6100 nForce 405/PCI/SSE2 supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6100 nForce 405/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6100 nForce 420/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6100 nForce 430/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6100/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6150 LE/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6150/PCI/SSE2 supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6150/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6150SE nForce 430/PCI/SSE2 supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6150SE nForce 430/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6150SE/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6100 +NVIDIA GeForce 6200 supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200 A-LE/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200 A-LE/AGP/SSE2 supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200 A-LE/AGP/SSE2/3DNOW! supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200 LE/PCI/SSE2 supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200 LE/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200 TurboCache(TM)/PCI/SSE2 supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200 TurboCache(TM)/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200/AGP/SSE2 supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200/AGP/SSE2/3DNOW! supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200/PCI/SSE/3DNOW! supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200/PCI/SSE2 supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6200SE TurboCache(TM)/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 6200 +NVIDIA GeForce 6500 supported 0 NVIDIA GeForce 6500 +NVIDIA GeForce 6500/PCI/SSE2 supported 0 NVIDIA GeForce 6500 +NVIDIA GeForce 6600 supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600 GT/AGP/SSE/3DNOW! supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600 GT/AGP/SSE2 supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600 GT/PCI/SSE/3DNOW! supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600 GT/PCI/SSE2 supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600 GT/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600 LE/PCI/SSE2 supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600/AGP/SSE/3DNOW! supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600/AGP/SSE2 supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600/AGP/SSE2/3DNOW! supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600/PCI/SSE2 supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6600/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 6600 +NVIDIA GeForce 6700 supported 2 NVIDIA GeForce 6700 +NVIDIA GeForce 6800 supported 2 NVIDIA GeForce 6800 +NVIDIA GeForce 6800 GS/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 6800 +NVIDIA GeForce 6800 GT/AGP/SSE2 supported 2 NVIDIA GeForce 6800 +NVIDIA GeForce 6800 GT/PCI/SSE2 supported 2 NVIDIA GeForce 6800 +NVIDIA GeForce 6800 XT/AGP/SSE2 supported 2 NVIDIA GeForce 6800 +NVIDIA GeForce 6800 XT/PCI/SSE2 supported 2 NVIDIA GeForce 6800 +NVIDIA GeForce 6800/PCI/SSE2 supported 2 NVIDIA GeForce 6800 +NVIDIA GeForce 6800/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 6800 +NVIDIA GeForce 7000 supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7000M supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7000M / nForce 610M/PCI/SSE2 supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7000M / nForce 610M/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7025 / NVIDIA nForce 630a/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7025 / nForce 630a/PCI/SSE2 supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7025 / nForce 630a/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7050 / NVIDIA nForce 610i/PCI/SSE2 supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7050 / NVIDIA nForce 620i/PCI/SSE2 supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7050 / nForce 610i/PCI/SSE2 supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7050 / nForce 620i/PCI/SSE2 supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7050 PV / NVIDIA nForce 630a/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7050 PV / nForce 630a/PCI/SSE2 supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7050 PV / nForce 630a/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7050 SE / NVIDIA nForce 630a/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 7000 +NVIDIA GeForce 7100 supported 0 NVIDIA GeForce 7100 +NVIDIA GeForce 7100 / NVIDIA nForce 620i/PCI/SSE2 supported 0 NVIDIA GeForce 7100 +NVIDIA GeForce 7100 / NVIDIA nForce 630i/PCI/SSE2 supported 0 NVIDIA GeForce 7100 +NVIDIA GeForce 7100 / nForce 630i/PCI/SSE2 supported 0 NVIDIA GeForce 7100 +NVIDIA GeForce 7100 GS/PCI/SSE2 supported 0 NVIDIA GeForce 7100 +NVIDIA GeForce 7100 GS/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 7100 +NVIDIA GeForce 7150M / nForce 630M/PCI/SSE2 supported 0 NVIDIA GeForce 7100 +NVIDIA GeForce 7150M / nForce 630M/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 7100 +NVIDIA GeForce 7300 supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 GS/PCI/SSE2 supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 GS/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 GT/AGP/SSE2 supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 GT/AGP/SSE2/3DNOW! supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 GT/PCI/SSE2 supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 GT/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 LE/PCI/SSE2 supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 LE/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 SE/7200 GS/PCI/SSE2 supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 SE/7200 GS/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 SE/PCI/SSE2 supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7300 SE/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7350 LE/PCI/SSE2 supported 1 NVIDIA GeForce 7300 +NVIDIA GeForce 7500 supported 1 NVIDIA GeForce 7500 +NVIDIA GeForce 7500 LE/PCI/SSE2 supported 1 NVIDIA GeForce 7500 +NVIDIA GeForce 7500 LE/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 7500 +NVIDIA GeForce 7600 supported 2 NVIDIA GeForce 7600 +NVIDIA GeForce 7600 GS/AGP/SSE2 supported 2 NVIDIA GeForce 7600 +NVIDIA GeForce 7600 GS/AGP/SSE2/3DNOW! supported 2 NVIDIA GeForce 7600 +NVIDIA GeForce 7600 GS/PCI/SSE2 supported 2 NVIDIA GeForce 7600 +NVIDIA GeForce 7600 GS/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 7600 +NVIDIA GeForce 7600 GT/AGP/SSE/3DNOW! supported 2 NVIDIA GeForce 7600 +NVIDIA GeForce 7600 GT/AGP/SSE2 supported 2 NVIDIA GeForce 7600 +NVIDIA GeForce 7600 GT/PCI/SSE2 supported 2 NVIDIA GeForce 7600 +NVIDIA GeForce 7600 GT/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 7600 +NVIDIA GeForce 7650 GS/PCI/SSE2 supported 2 NVIDIA GeForce 7600 +NVIDIA GeForce 7800 supported 2 NVIDIA GeForce 7800 +NVIDIA GeForce 7800 GS/AGP/SSE2 supported 2 NVIDIA GeForce 7800 +NVIDIA GeForce 7800 GS/AGP/SSE2/3DNOW! supported 2 NVIDIA GeForce 7800 +NVIDIA GeForce 7800 GT/PCI/SSE2 supported 2 NVIDIA GeForce 7800 +NVIDIA GeForce 7800 GTX/PCI/SSE2 supported 2 NVIDIA GeForce 7800 +NVIDIA GeForce 7800 GTX/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 7800 +NVIDIA GeForce 7900 supported 2 NVIDIA GeForce 7900 +NVIDIA GeForce 7900 GS/PCI/SSE2 supported 2 NVIDIA GeForce 7900 +NVIDIA GeForce 7900 GS/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 7900 +NVIDIA GeForce 7900 GT/GTO/PCI/SSE2 supported 2 NVIDIA GeForce 7900 +NVIDIA GeForce 7900 GT/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 7900 +NVIDIA GeForce 7900 GTX/PCI/SSE2 supported 2 NVIDIA GeForce 7900 +NVIDIA GeForce 7950 GT/PCI/SSE2 supported 2 NVIDIA GeForce 7900 +NVIDIA GeForce 7950 GT/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 7900 +NVIDIA GeForce 8100 supported 1 NVIDIA GeForce 8100 +NVIDIA GeForce 8100 / nForce 720a/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 8100 +NVIDIA GeForce 8200 supported 1 NVIDIA GeForce 8200 +NVIDIA GeForce 8200/PCI/SSE2 supported 1 NVIDIA GeForce 8200 +NVIDIA GeForce 8200/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 8200 +NVIDIA GeForce 8200M supported 1 NVIDIA GeForce 8200M +NVIDIA GeForce 8200M G/PCI/SSE2 supported 1 NVIDIA GeForce 8200M +NVIDIA GeForce 8200M G/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 8200M +NVIDIA GeForce 8300 supported 1 NVIDIA GeForce 8300 +NVIDIA GeForce 8300 GS/PCI/SSE2 supported 1 NVIDIA GeForce 8300 +NVIDIA GeForce 8400 supported 1 NVIDIA GeForce 8400 +NVIDIA GeForce 8400 GS/PCI/SSE/3DNOW! supported 1 NVIDIA GeForce 8400 +NVIDIA GeForce 8400 GS/PCI/SSE2 supported 1 NVIDIA GeForce 8400 +NVIDIA GeForce 8400 GS/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 8400 +NVIDIA GeForce 8400/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 8400 +NVIDIA GeForce 8400GS/PCI/SSE2 supported 1 NVIDIA GeForce 8400 +NVIDIA GeForce 8400GS/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 8400 +NVIDIA GeForce 8400M supported 1 NVIDIA GeForce 8400M +NVIDIA GeForce 8400M G/PCI/SSE2 supported 1 NVIDIA GeForce 8400M +NVIDIA GeForce 8400M G/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 8400M +NVIDIA GeForce 8400M GS/PCI/SSE2 supported 1 NVIDIA GeForce 8400M +NVIDIA GeForce 8400M GS/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 8400M +NVIDIA GeForce 8400M GT/PCI/SSE2 supported 1 NVIDIA GeForce 8400M +NVIDIA GeForce 8500 supported 3 NVIDIA GeForce 8500 +NVIDIA GeForce 8500 GT/PCI/SSE2 supported 3 NVIDIA GeForce 8500 +NVIDIA GeForce 8500 GT/PCI/SSE2/3DNOW! supported 3 NVIDIA GeForce 8500 +NVIDIA GeForce 8600 supported 3 NVIDIA GeForce 8600 +NVIDIA GeForce 8600 GS/PCI/SSE2 supported 3 NVIDIA GeForce 8600 +NVIDIA GeForce 8600 GS/PCI/SSE2/3DNOW! supported 3 NVIDIA GeForce 8600 +NVIDIA GeForce 8600 GT/PCI/SSE2 supported 3 NVIDIA GeForce 8600 +NVIDIA GeForce 8600 GT/PCI/SSE2/3DNOW! supported 3 NVIDIA GeForce 8600 +NVIDIA GeForce 8600 GTS/PCI/SSE2 supported 3 NVIDIA GeForce 8600 +NVIDIA GeForce 8600 GTS/PCI/SSE2/3DNOW! supported 3 NVIDIA GeForce 8600 +NVIDIA GeForce 8600GS/PCI/SSE2 supported 3 NVIDIA GeForce 8600 +NVIDIA GeForce 8600M supported 1 NVIDIA GeForce 8600M +NVIDIA GeForce 8600M GS/PCI/SSE2 supported 1 NVIDIA GeForce 8600M +NVIDIA GeForce 8600M GS/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 8600M +NVIDIA GeForce 8600M GT/PCI/SSE2 supported 1 NVIDIA GeForce 8600M +NVIDIA GeForce 8700 supported 3 NVIDIA GeForce 8700 +NVIDIA GeForce 8700M supported 3 NVIDIA GeForce 8700M +NVIDIA GeForce 8700M GT/PCI/SSE2 supported 3 NVIDIA GeForce 8700M +NVIDIA GeForce 8800 supported 3 NVIDIA GeForce 8800 +NVIDIA GeForce 8800 GS/PCI/SSE2 supported 3 NVIDIA GeForce 8800 +NVIDIA GeForce 8800 GT/PCI/SSE2 supported 3 NVIDIA GeForce 8800 +NVIDIA GeForce 8800 GT/PCI/SSE2/3DNOW! supported 3 NVIDIA GeForce 8800 +NVIDIA GeForce 8800 GTS 512/PCI/SSE2 supported 3 NVIDIA GeForce 8800 +NVIDIA GeForce 8800 GTS 512/PCI/SSE2/3DNOW! supported 3 NVIDIA GeForce 8800 +NVIDIA GeForce 8800 GTS/PCI/SSE2 supported 3 NVIDIA GeForce 8800 +NVIDIA GeForce 8800 GTS/PCI/SSE2/3DNOW! supported 3 NVIDIA GeForce 8800 +NVIDIA GeForce 8800 GTX/PCI/SSE2 supported 3 NVIDIA GeForce 8800 +NVIDIA GeForce 8800 Ultra/PCI/SSE2 supported 3 NVIDIA GeForce 8800 +NVIDIA GeForce 8800M GTS/PCI/SSE2 supported 3 NVIDIA GeForce 8800M +NVIDIA GeForce 8800M GTX/PCI/SSE2 supported 3 NVIDIA GeForce 8800M +NVIDIA GeForce 9100 supported 0 NVIDIA GeForce 9100 +NVIDIA GeForce 9100/PCI/SSE2 supported 0 NVIDIA GeForce 9100 +NVIDIA GeForce 9100/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 9100 +NVIDIA GeForce 9100M supported 0 NVIDIA GeForce 9100M +NVIDIA GeForce 9100M G/PCI/SSE2 supported 0 NVIDIA GeForce 9100M +NVIDIA GeForce 9100M G/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 9100M +NVIDIA GeForce 9200 supported 1 NVIDIA GeForce 9200 +NVIDIA GeForce 9200/PCI/SSE2 supported 1 NVIDIA GeForce 9200 +NVIDIA GeForce 9200/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 9200 +NVIDIA GeForce 9200M GE/PCI/SSE2 supported 1 NVIDIA GeForce 9200M +NVIDIA GeForce 9200M GS/PCI/SSE2 supported 1 NVIDIA GeForce 9200M +NVIDIA GeForce 9300 supported 1 NVIDIA GeForce 9300 +NVIDIA GeForce 9300 / nForce 730i/PCI/SSE2 supported 1 NVIDIA GeForce 9300 +NVIDIA GeForce 9300 GE/PCI/SSE2 supported 1 NVIDIA GeForce 9300 +NVIDIA GeForce 9300 GE/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 9300 +NVIDIA GeForce 9300 GS/PCI/SSE2 supported 1 NVIDIA GeForce 9300 +NVIDIA GeForce 9300 GS/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 9300 +NVIDIA GeForce 9300 SE/PCI/SSE2 supported 1 NVIDIA GeForce 9300 +NVIDIA GeForce 9300M supported 1 NVIDIA GeForce 9300M +NVIDIA GeForce 9300M G/PCI/SSE2 supported 1 NVIDIA GeForce 9300M +NVIDIA GeForce 9300M G/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 9300M +NVIDIA GeForce 9300M GS/PCI/SSE2 supported 1 NVIDIA GeForce 9300M +NVIDIA GeForce 9300M GS/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 9300M +NVIDIA GeForce 9400 supported 1 NVIDIA GeForce 9400 +NVIDIA GeForce 9400 GT/PCI/SSE2 supported 1 NVIDIA GeForce 9400 +NVIDIA GeForce 9400 GT/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce 9400 +NVIDIA GeForce 9400/PCI/SSE2 supported 1 NVIDIA GeForce 9400 +NVIDIA GeForce 9400M supported 1 NVIDIA GeForce 9400M +NVIDIA GeForce 9400M G/PCI/SSE2 supported 1 NVIDIA GeForce 9400M +NVIDIA GeForce 9400M/PCI/SSE2 supported 1 NVIDIA GeForce 9400M +NVIDIA GeForce 9500 supported 2 NVIDIA GeForce 9500 +NVIDIA GeForce 9500 GS/PCI/SSE2 supported 2 NVIDIA GeForce 9500 +NVIDIA GeForce 9500 GS/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 9500 +NVIDIA GeForce 9500 GT/PCI/SSE2 supported 2 NVIDIA GeForce 9500 +NVIDIA GeForce 9500 GT/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 9500 +NVIDIA GeForce 9500M supported 2 NVIDIA GeForce 9500M +NVIDIA GeForce 9500M GS/PCI/SSE2 supported 2 NVIDIA GeForce 9500M +NVIDIA GeForce 9600 supported 2 NVIDIA GeForce 9600 +NVIDIA GeForce 9600 GS/PCI/SSE2 supported 2 NVIDIA GeForce 9600 +NVIDIA GeForce 9600 GSO 512/PCI/SSE2 supported 2 NVIDIA GeForce 9600 +NVIDIA GeForce 9600 GSO/PCI/SSE2 supported 2 NVIDIA GeForce 9600 +NVIDIA GeForce 9600 GSO/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 9600 +NVIDIA GeForce 9600 GT/PCI/SSE2 supported 2 NVIDIA GeForce 9600 +NVIDIA GeForce 9600 GT/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce 9600 +NVIDIA GeForce 9600M supported 3 NVIDIA GeForce 9600M +NVIDIA GeForce 9600M GS/PCI/SSE2 supported 3 NVIDIA GeForce 9600M +NVIDIA GeForce 9600M GT/PCI/SSE2 supported 3 NVIDIA GeForce 9600M +NVIDIA GeForce 9650M GT/PCI/SSE2 supported 2 NVIDIA GeForce 9600 +NVIDIA GeForce 9700M supported 2 NVIDIA GeForce 9700M +NVIDIA GeForce 9700M GT/PCI/SSE2 supported 2 NVIDIA GeForce 9700M +NVIDIA GeForce 9700M GTS/PCI/SSE2 supported 2 NVIDIA GeForce 9700M +NVIDIA GeForce 9800 supported 3 NVIDIA GeForce 9800 +NVIDIA GeForce 9800 GT/PCI/SSE2 supported 3 NVIDIA GeForce 9800 +NVIDIA GeForce 9800 GT/PCI/SSE2/3DNOW! supported 3 NVIDIA GeForce 9800 +NVIDIA GeForce 9800 GTX+/PCI/SSE2 supported 3 NVIDIA GeForce 9800 +NVIDIA GeForce 9800 GTX+/PCI/SSE2/3DNOW! supported 3 NVIDIA GeForce 9800 +NVIDIA GeForce 9800 GTX/9800 GTX+/PCI/SSE2 supported 3 NVIDIA GeForce 9800 +NVIDIA GeForce 9800 GTX/PCI/SSE2 supported 3 NVIDIA GeForce 9800 +NVIDIA GeForce 9800 GX2/PCI/SSE2 supported 3 NVIDIA GeForce 9800 +NVIDIA GeForce 9800M supported 3 NVIDIA GeForce 9800M +NVIDIA GeForce 9800M GS/PCI/SSE2 supported 3 NVIDIA GeForce 9800M +NVIDIA GeForce 9800M GT/PCI/SSE2 supported 3 NVIDIA GeForce 9800M +NVIDIA GeForce 9800M GTS/PCI/SSE2 supported 3 NVIDIA GeForce 9800M +NVIDIA GeForce FX 5100 supported 0 NVIDIA GeForce FX 5100 +NVIDIA GeForce FX 5100/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce FX 5100 +NVIDIA GeForce FX 5200 supported 0 NVIDIA GeForce FX 5200 +NVIDIA GeForce FX 5200/AGP/SSE supported 0 NVIDIA GeForce FX 5200 +NVIDIA GeForce FX 5200/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce FX 5200 +NVIDIA GeForce FX 5200/AGP/SSE2 supported 0 NVIDIA GeForce FX 5200 +NVIDIA GeForce FX 5200/AGP/SSE2/3DNOW! supported 0 NVIDIA GeForce FX 5200 +NVIDIA GeForce FX 5200/PCI/SSE2 supported 0 NVIDIA GeForce FX 5200 +NVIDIA GeForce FX 5200/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce FX 5200 +NVIDIA GeForce FX 5200LE/AGP/SSE2 supported 0 NVIDIA GeForce FX 5200 +NVIDIA GeForce FX 5500 supported 0 NVIDIA GeForce FX 5500 +NVIDIA GeForce FX 5500/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce FX 5500 +NVIDIA GeForce FX 5500/AGP/SSE2 supported 0 NVIDIA GeForce FX 5500 +NVIDIA GeForce FX 5500/AGP/SSE2/3DNOW! supported 0 NVIDIA GeForce FX 5500 +NVIDIA GeForce FX 5500/PCI/SSE2 supported 0 NVIDIA GeForce FX 5500 +NVIDIA GeForce FX 5500/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce FX 5500 +NVIDIA GeForce FX 5600 supported 0 NVIDIA GeForce FX 5600 +NVIDIA GeForce FX 5600/AGP/SSE2 supported 0 NVIDIA GeForce FX 5600 +NVIDIA GeForce FX 5600/AGP/SSE2/3DNOW! supported 0 NVIDIA GeForce FX 5600 +NVIDIA GeForce FX 5600XT/AGP/SSE2/3DNOW! supported 0 NVIDIA GeForce FX 5600 +NVIDIA GeForce FX 5700 supported 1 NVIDIA GeForce FX 5700 +NVIDIA GeForce FX 5700/AGP/SSE/3DNOW! supported 1 NVIDIA GeForce FX 5700 +NVIDIA GeForce FX 5700LE/AGP/SSE supported 1 NVIDIA GeForce FX 5700 +NVIDIA GeForce FX 5700LE/AGP/SSE/3DNOW! supported 1 NVIDIA GeForce FX 5700 +NVIDIA GeForce FX 5800 supported 1 NVIDIA GeForce FX 5800 +NVIDIA GeForce FX 5900 supported 1 NVIDIA GeForce FX 5900 +NVIDIA GeForce FX 5900/AGP/SSE2 supported 1 NVIDIA GeForce FX 5900 +NVIDIA GeForce FX 5900XT/AGP/SSE2 supported 1 NVIDIA GeForce FX 5900 +NVIDIA GeForce FX Go5100 supported 0 NVIDIA GeForce FX Go5100 +NVIDIA GeForce FX Go5100/AGP/SSE2 supported 0 NVIDIA GeForce FX Go5100 +NVIDIA GeForce FX Go5200 supported 0 NVIDIA GeForce FX Go5200 +NVIDIA GeForce FX Go5200/AGP/SSE2 supported 0 NVIDIA GeForce FX Go5200 +NVIDIA GeForce FX Go5300 supported 0 NVIDIA GeForce FX Go5300 +NVIDIA GeForce FX Go5600 supported 0 NVIDIA GeForce FX Go5600 +NVIDIA GeForce FX Go5600/AGP/SSE2 supported 0 NVIDIA GeForce FX Go5600 +NVIDIA GeForce FX Go5650/AGP/SSE2 supported 0 NVIDIA GeForce FX Go5600 +NVIDIA GeForce FX Go5700 supported 1 NVIDIA GeForce FX Go5700 +NVIDIA GeForce FX Go5xxx/AGP/SSE2 supported 0 NVIDIA GeForce FX Go5xxx +NVIDIA GeForce G 103M/PCI/SSE2 supported 0 NVIDIA G103M +NVIDIA GeForce G 105M/PCI/SSE2 supported 0 NVIDIA G105M +NVIDIA GeForce G 110M/PCI/SSE2 supported 0 NVIDIA G 110M +NVIDIA GeForce G100/PCI/SSE2 supported 0 NVIDIA G100 +NVIDIA GeForce G100/PCI/SSE2/3DNOW! supported 0 NVIDIA G100 +NVIDIA GeForce G102M/PCI/SSE2 supported 0 NVIDIA G102M +NVIDIA GeForce G105M/PCI/SSE2 supported 0 NVIDIA G105M +NVIDIA GeForce G200/PCI/SSE2 supported 0 NVIDIA G 200 +NVIDIA GeForce G205M/PCI/SSE2 supported 0 NVIDIA G 205M +NVIDIA GeForce G210/PCI/SSE2 supported 1 NVIDIA G 210 +NVIDIA GeForce G210/PCI/SSE2/3DNOW! supported 1 NVIDIA G 210 +NVIDIA GeForce G210M/PCI/SSE2 supported 1 NVIDIA G 210 +NVIDIA GeForce G310M/PCI/SSE2 supported 2 NVIDIA G 310M +NVIDIA GeForce GT 120/PCI/SSE2 supported 2 NVIDIA GT 120M +NVIDIA GeForce GT 120/PCI/SSE2/3DNOW! supported 2 NVIDIA GT 120M +NVIDIA GeForce GT 120M/PCI/SSE2 supported 2 NVIDIA GT 120M +NVIDIA GeForce GT 130M/PCI/SSE2 supported 2 NVIDIA GT 130M +NVIDIA GeForce GT 140/PCI/SSE2 supported 2 NVIDIA GT 140M +NVIDIA GeForce GT 220/PCI/SSE2 supported 2 NVIDIA GT 220M +NVIDIA GeForce GT 220/PCI/SSE2/3DNOW! supported 2 NVIDIA GT 220M +NVIDIA GeForce GT 220M/PCI/SSE2 supported 2 NVIDIA GT 220M +NVIDIA GeForce GT 230/PCI/SSE2 supported 2 NVIDIA GT 230M +NVIDIA GeForce GT 230M/PCI/SSE2 supported 2 NVIDIA GT 230M +NVIDIA GeForce GT 240 supported 2 NVIDIA GT 240M +NVIDIA GeForce GT 240/PCI/SSE2 supported 2 NVIDIA GT 240M +NVIDIA GeForce GT 240/PCI/SSE2/3DNOW! supported 2 NVIDIA GT 240M +NVIDIA GeForce GT 240M/PCI/SSE2 supported 2 NVIDIA GT 240M +NVIDIA GeForce GT 320/PCI/SSE2 supported 2 NVIDIA GT 320M +NVIDIA GeForce GT 320M/PCI/SSE2 supported 2 NVIDIA GT 320M +NVIDIA GeForce GT 325M/PCI/SSE2 supported 0 NVIDIA GT 325M +NVIDIA GeForce GT 330/PCI/SSE2 supported 3 NVIDIA GT 330M +NVIDIA GeForce GT 330/PCI/SSE2/3DNOW! supported 3 NVIDIA GT 330M +NVIDIA GeForce GT 330M/PCI/SSE2 supported 3 NVIDIA GT 330M +NVIDIA GeForce GT 335M/PCI/SSE2 supported 1 NVIDIA GT 335M +NVIDIA GeForce GT 340/PCI/SSE2 supported 2 NVIDIA GT 340M +NVIDIA GeForce GT 340/PCI/SSE2/3DNOW! supported 2 NVIDIA GT 340M +NVIDIA GeForce GT 415M/PCI/SSE2 supported 2 NVIDIA GT 415M +NVIDIA GeForce GT 420/PCI/SSE2 supported 2 NVIDIA GT 420M +NVIDIA GeForce GT 420M/PCI/SSE2 supported 2 NVIDIA GT 420M +NVIDIA GeForce GT 425M/PCI/SSE2 supported 3 NVIDIA GT 425M +NVIDIA GeForce GT 430/PCI/SSE2 supported 3 NVIDIA GT 430M +NVIDIA GeForce GT 430/PCI/SSE2/3DNOW! supported 3 NVIDIA GT 430M +NVIDIA GeForce GT 435M/PCI/SSE2 supported 3 NVIDIA GT 435M +NVIDIA GeForce GT 440/PCI/SSE2 supported 3 NVIDIA GT 440M +NVIDIA GeForce GT 440/PCI/SSE2/3DNOW! supported 3 NVIDIA GT 440M +NVIDIA GeForce GT 445M/PCI/SSE2 supported 3 NVIDIA GT 445M +NVIDIA GeForce GT 520M/PCI/SSE2 supported 3 NVIDIA GT 520M +NVIDIA GeForce GT 525M/PCI/SSE2 supported 3 NVIDIA GT 525M +NVIDIA GeForce GT 540M/PCI/SSE2 supported 3 NVIDIA GT 540M +NVIDIA GeForce GT 550M/PCI/SSE2 supported 3 NVIDIA GT 550M +NVIDIA GeForce GT 555M/PCI/SSE2 supported 3 NVIDIA GT 555M +NVIDIA GeForce GTS 150/PCI/SSE2 supported 2 NVIDIA GT 150M +NVIDIA GeForce GTS 160M/PCI/SSE2 supported 2 NVIDIA GTS 160M +NVIDIA GeForce GTS 240/PCI/SSE2 supported 3 NVIDIA GTS 240 +NVIDIA GeForce GTS 250/PCI/SSE2 supported 3 NVIDIA GTS 250 +NVIDIA GeForce GTS 250/PCI/SSE2/3DNOW! supported 3 NVIDIA GTS 250 +NVIDIA GeForce GTS 250M/PCI/SSE2 supported 3 NVIDIA GTS 250 +NVIDIA GeForce GTS 350M/PCI/SSE2 supported 3 NVIDIA GTS 350M +NVIDIA GeForce GTS 360M/PCI/SSE2 supported 3 NVIDIA GTS 360M +NVIDIA GeForce GTS 450/PCI/SSE2 supported 3 NVIDIA GTS 450 +NVIDIA GeForce GTS 450/PCI/SSE2/3DNOW! supported 3 NVIDIA GTS 450 +NVIDIA GeForce GTS 455/PCI/SSE2 supported 3 NVIDIA GTS 450 +NVIDIA GeForce GTX 260/PCI/SSE2 supported 3 NVIDIA GTX 260 +NVIDIA GeForce GTX 260/PCI/SSE2/3DNOW! supported 3 NVIDIA GTX 260 +NVIDIA GeForce GTX 260M/PCI/SSE2 supported 3 NVIDIA GTX 260 +NVIDIA GeForce GTX 275/PCI/SSE2 supported 3 NVIDIA GTX 275 +NVIDIA GeForce GTX 280 supported 3 NVIDIA GTX 280 +NVIDIA GeForce GTX 280/PCI/SSE2 supported 3 NVIDIA GTX 280 +NVIDIA GeForce GTX 280M/PCI/SSE2 supported 3 NVIDIA GTX 280 +NVIDIA GeForce GTX 285/PCI/SSE2 supported 3 NVIDIA GTX 285 +NVIDIA GeForce GTX 295/PCI/SSE2 supported 3 NVIDIA GTX 295 +NVIDIA GeForce GTX 460 SE/PCI/SSE2 supported 3 NVIDIA GTX 460 +NVIDIA GeForce GTX 460 SE/PCI/SSE2/3DNOW! supported 3 NVIDIA GTX 460 +NVIDIA GeForce GTX 460/PCI/SSE2 supported 3 NVIDIA GTX 460 +NVIDIA GeForce GTX 460/PCI/SSE2/3DNOW! supported 3 NVIDIA GTX 460 +NVIDIA GeForce GTX 460M/PCI/SSE2 supported 3 NVIDIA GTX 460M +NVIDIA GeForce GTX 465/PCI/SSE2 supported 3 NVIDIA GTX 465 +NVIDIA GeForce GTX 465/PCI/SSE2/3DNOW! supported 3 NVIDIA GTX 465 +NVIDIA GeForce GTX 470/PCI/SSE2 supported 3 NVIDIA GTX 470 +NVIDIA GeForce GTX 470/PCI/SSE2/3DNOW! supported 3 NVIDIA GTX 470 +NVIDIA GeForce GTX 480/PCI/SSE2 supported 3 NVIDIA GTX 480 +NVIDIA GeForce GTX 550 Ti/PCI/SSE2 supported 3 NVIDIA GTX 550 +NVIDIA GeForce GTX 550 Ti/PCI/SSE2/3DNOW! supported 3 NVIDIA GTX 550 +NVIDIA GeForce GTX 560 Ti/PCI/SSE2 supported 3 NVIDIA GTX 560 +NVIDIA GeForce GTX 560 Ti/PCI/SSE2/3DNOW! supported 3 NVIDIA GTX 560 +NVIDIA GeForce GTX 560/PCI/SSE2 supported 3 NVIDIA GTX 560 +NVIDIA GeForce GTX 570/PCI/SSE2 supported 3 NVIDIA GTX 570 +NVIDIA GeForce GTX 570/PCI/SSE2/3DNOW! supported 3 NVIDIA GTX 570 +NVIDIA GeForce GTX 580/PCI/SSE2 supported 3 NVIDIA GTX 580 +NVIDIA GeForce GTX 580/PCI/SSE2/3DNOW! supported 3 NVIDIA GTX 580 +NVIDIA GeForce GTX 580M/PCI/SSE2 supported 3 NVIDIA GTX 580M +NVIDIA GeForce GTX 590/PCI/SSE2 supported 3 NVIDIA GTX 590 +NVIDIA GeForce Go 6 supported 1 NVIDIA GeForce Go 6 +NVIDIA GeForce Go 6100 supported 0 NVIDIA GeForce Go 6100 +NVIDIA GeForce Go 6100/PCI/SSE2 supported 0 NVIDIA GeForce Go 6100 +NVIDIA GeForce Go 6100/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce Go 6100 +NVIDIA GeForce Go 6150/PCI/SSE2 supported 0 NVIDIA GeForce Go 6100 +NVIDIA GeForce Go 6150/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce Go 6100 +NVIDIA GeForce Go 6200 supported 0 NVIDIA GeForce Go 6200 +NVIDIA GeForce Go 6200/PCI/SSE2 supported 0 NVIDIA GeForce Go 6200 +NVIDIA GeForce Go 6400 supported 1 NVIDIA GeForce Go 6400 +NVIDIA GeForce Go 6400/PCI/SSE2 supported 1 NVIDIA GeForce Go 6400 +NVIDIA GeForce Go 6600 supported 1 NVIDIA GeForce Go 6600 +NVIDIA GeForce Go 6600/PCI/SSE2 supported 1 NVIDIA GeForce Go 6600 +NVIDIA GeForce Go 6800 supported 1 NVIDIA GeForce Go 6800 +NVIDIA GeForce Go 6800 Ultra/PCI/SSE2 supported 1 NVIDIA GeForce Go 6800 +NVIDIA GeForce Go 6800/PCI/SSE2 supported 1 NVIDIA GeForce Go 6800 +NVIDIA GeForce Go 7200 supported 1 NVIDIA GeForce Go 7200 +NVIDIA GeForce Go 7200/PCI/SSE2 supported 1 NVIDIA GeForce Go 7200 +NVIDIA GeForce Go 7200/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce Go 7200 +NVIDIA GeForce Go 7300 supported 1 NVIDIA GeForce Go 7300 +NVIDIA GeForce Go 7300/PCI/SSE2 supported 1 NVIDIA GeForce Go 7300 +NVIDIA GeForce Go 7300/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce Go 7300 +NVIDIA GeForce Go 7400 supported 1 NVIDIA GeForce Go 7400 +NVIDIA GeForce Go 7400/PCI/SSE2 supported 1 NVIDIA GeForce Go 7400 +NVIDIA GeForce Go 7400/PCI/SSE2/3DNOW! supported 1 NVIDIA GeForce Go 7400 +NVIDIA GeForce Go 7600 supported 2 NVIDIA GeForce Go 7600 +NVIDIA GeForce Go 7600/PCI/SSE2 supported 2 NVIDIA GeForce Go 7600 +NVIDIA GeForce Go 7600/PCI/SSE2/3DNOW! supported 2 NVIDIA GeForce Go 7600 +NVIDIA GeForce Go 7700 supported 2 NVIDIA GeForce Go 7700 +NVIDIA GeForce Go 7800 supported 2 NVIDIA GeForce Go 7800 +NVIDIA GeForce Go 7800 GTX/PCI/SSE2 supported 2 NVIDIA GeForce Go 7800 +NVIDIA GeForce Go 7900 supported 2 NVIDIA GeForce Go 7900 +NVIDIA GeForce Go 7900 GS/PCI/SSE2 supported 2 NVIDIA GeForce Go 7900 +NVIDIA GeForce Go 7900 GTX/PCI/SSE2 supported 2 NVIDIA GeForce Go 7900 +NVIDIA GeForce Go 7950 GTX/PCI/SSE2 supported 2 NVIDIA GeForce Go 7900 +NVIDIA GeForce PCX supported 0 NVIDIA GeForce PCX +NVIDIA GeForce2 GTS/AGP/SSE supported 0 NVIDIA GeForce 2 +NVIDIA GeForce2 MX/AGP/3DNOW! supported 0 NVIDIA GeForce 2 +NVIDIA GeForce2 MX/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce 2 +NVIDIA GeForce2 MX/AGP/SSE2 supported 0 NVIDIA GeForce 2 +NVIDIA GeForce2 MX/PCI/SSE2 supported 0 NVIDIA GeForce 2 +NVIDIA GeForce3/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce 3 +NVIDIA GeForce3/AGP/SSE2 supported 0 NVIDIA GeForce 3 +NVIDIA GeForce4 420 Go 32M/AGP/SSE2 supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 420 Go 32M/AGP/SSE2/3DNOW! supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 420 Go 32M/PCI/SSE2/3DNOW! supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 440 Go 64M/AGP/SSE2/3DNOW! supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 460 Go/AGP/SSE2 supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 4000/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 4000/AGP/SSE2 supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 4000/PCI/3DNOW! supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 4000/PCI/SSE/3DNOW! supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 4000/PCI/SSE2 supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 420/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 420/AGP/SSE2 supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 440 with AGP8X/AGP/SSE2 supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 440/AGP/SSE2 supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 440/AGP/SSE2/3DNOW! supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX 440SE with AGP8X/AGP/SSE2 supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 MX Integrated GPU/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 Ti 4200 with AGP8X/AGP/SSE supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 Ti 4200/AGP/SSE/3DNOW! supported 0 NVIDIA GeForce 4 +NVIDIA GeForce4 Ti 4400/AGP/SSE2 supported 0 NVIDIA GeForce 4 +NVIDIA Generic UNRECOGNIZED +NVIDIA ION LE/PCI/SSE2 supported 2 NVIDIA ION +NVIDIA ION/PCI/SSE2 supported 2 NVIDIA ION +NVIDIA ION/PCI/SSE2/3DNOW! supported 2 NVIDIA ION +NVIDIA MCP61/PCI/SSE2 UNRECOGNIZED +NVIDIA MCP61/PCI/SSE2/3DNOW! UNRECOGNIZED +NVIDIA MCP73/PCI/SSE2 UNRECOGNIZED +NVIDIA MCP79MH/PCI/SSE2 UNRECOGNIZED +NVIDIA MCP79MX/PCI/SSE2 UNRECOGNIZED +NVIDIA MCP7A-O/PCI/SSE2 UNRECOGNIZED +NVIDIA MCP7A-S/PCI/SSE2 UNRECOGNIZED +NVIDIA MCP89-EPT/PCI/SSE2 UNRECOGNIZED +NVIDIA N10M-GE1/PCI/SSE2 UNRECOGNIZED +NVIDIA N10P-GE1/PCI/SSE2 UNRECOGNIZED +NVIDIA N10P-GV2/PCI/SSE2 UNRECOGNIZED +NVIDIA N11M-GE1/PCI/SSE2 UNRECOGNIZED +NVIDIA N11M-GE2/PCI/SSE2 UNRECOGNIZED +NVIDIA N12E-GS-A1/PCI/SSE2 UNRECOGNIZED +NVIDIA NB9M-GE/PCI/SSE2 UNRECOGNIZED +NVIDIA NB9M-GE1/PCI/SSE2 UNRECOGNIZED +NVIDIA NB9M-GS/PCI/SSE2 UNRECOGNIZED +NVIDIA NB9M-NS/PCI/SSE2 UNRECOGNIZED +NVIDIA NB9P-GE1/PCI/SSE2 UNRECOGNIZED +NVIDIA NB9P-GS/PCI/SSE2 UNRECOGNIZED +NVIDIA NV17/AGP/3DNOW! UNRECOGNIZED +NVIDIA NV17/AGP/SSE2 UNRECOGNIZED +NVIDIA NV34 supported 0 NVIDIA NV34 +NVIDIA NV35 supported 0 NVIDIA NV35 +NVIDIA NV36/AGP/SSE/3DNOW! UNRECOGNIZED +NVIDIA NV36/AGP/SSE2 UNRECOGNIZED +NVIDIA NV41/PCI/SSE2 UNRECOGNIZED +NVIDIA NV43 supported 1 NVIDIA NV43 +NVIDIA NV44 supported 1 NVIDIA NV44 +NVIDIA NVIDIA GeForce 210 OpenGL Engine supported 2 NVIDIA 210 +NVIDIA NVIDIA GeForce 320M OpenGL Engine supported 2 NVIDIA 320M +NVIDIA NVIDIA GeForce 7300 GT OpenGL Engine supported 1 NVIDIA GeForce 7300 +NVIDIA NVIDIA GeForce 7600 GT OpenGL Engine supported 2 NVIDIA GeForce 7600 +NVIDIA NVIDIA GeForce 8600M GT OpenGL Engine supported 1 NVIDIA GeForce 8600M +NVIDIA NVIDIA GeForce 8800 GS OpenGL Engine supported 3 NVIDIA GeForce 8800 +NVIDIA NVIDIA GeForce 8800 GT OpenGL Engine supported 3 NVIDIA GeForce 8800 +NVIDIA NVIDIA GeForce 9400 OpenGL Engine supported 1 NVIDIA GeForce 9400 +NVIDIA NVIDIA GeForce 9400M OpenGL Engine supported 1 NVIDIA GeForce 9400M +NVIDIA NVIDIA GeForce 9500 GT OpenGL Engine supported 2 NVIDIA GeForce 9500 +NVIDIA NVIDIA GeForce 9600M GT OpenGL Engine supported 3 NVIDIA GeForce 9600M +NVIDIA NVIDIA GeForce GT 120 OpenGL Engine supported 2 NVIDIA GT 120M +NVIDIA NVIDIA GeForce GT 130 OpenGL Engine supported 2 NVIDIA GT 130M +NVIDIA NVIDIA GeForce GT 220 OpenGL Engine supported 2 NVIDIA GT 220M +NVIDIA NVIDIA GeForce GT 230M OpenGL Engine supported 2 NVIDIA GT 230M +NVIDIA NVIDIA GeForce GT 240M OpenGL Engine supported 2 NVIDIA GT 240M +NVIDIA NVIDIA GeForce GT 330M OpenGL Engine supported 3 NVIDIA GT 330M +NVIDIA NVIDIA GeForce GT 420M OpenGL Engine supported 2 NVIDIA GT 420M +NVIDIA NVIDIA GeForce GT 425M OpenGL Engine supported 3 NVIDIA GT 425M +NVIDIA NVIDIA GeForce GT 430 OpenGL Engine supported 3 NVIDIA GT 430M +NVIDIA NVIDIA GeForce GT 440 OpenGL Engine supported 3 NVIDIA GT 440M +NVIDIA NVIDIA GeForce GT 540M OpenGL Engine supported 3 NVIDIA GT 540M +NVIDIA NVIDIA GeForce GTS 240 OpenGL Engine supported 3 NVIDIA GTS 240 +NVIDIA NVIDIA GeForce GTS 250 OpenGL Engine supported 3 NVIDIA GTS 250 +NVIDIA NVIDIA GeForce GTS 450 OpenGL Engine supported 3 NVIDIA GTS 450 +NVIDIA NVIDIA GeForce GTX 285 OpenGL Engine supported 3 NVIDIA GTX 285 +NVIDIA NVIDIA GeForce GTX 460 OpenGL Engine supported 3 NVIDIA GTX 460 +NVIDIA NVIDIA GeForce GTX 460M OpenGL Engine supported 3 NVIDIA GTX 460M +NVIDIA NVIDIA GeForce GTX 465 OpenGL Engine supported 3 NVIDIA GTX 465 +NVIDIA NVIDIA GeForce GTX 470 OpenGL Engine supported 3 NVIDIA GTX 470 +NVIDIA NVIDIA GeForce GTX 480 OpenGL Engine supported 3 NVIDIA GTX 480 +NVIDIA NVIDIA GeForce Pre-Release ION OpenGL Engine UNRECOGNIZED +NVIDIA NVIDIA GeForce4 OpenGL Engine supported 0 NVIDIA GeForce 4 +NVIDIA NVIDIA NV34MAP OpenGL Engine supported 0 NVIDIA NV34 +NVIDIA NVIDIA Quadro 4000 OpenGL Engine supported 3 NVIDIA Quadro 4000 +NVIDIA NVIDIA Quadro FX 4800 OpenGL Engine supported 3 NVIDIA Quadro FX 4800 +NVIDIA NVS 2100M/PCI/SSE2 supported 2 NVIDIA Quadro NVS 2100M +NVIDIA NVS 300/PCI/SSE2 supported 0 NVIDIA Quadro NVS +NVIDIA NVS 3100M/PCI/SSE2 supported 2 NVIDIA Quadro NVS 3100M +NVIDIA NVS 4100/PCI/SSE2/3DNOW! supported 0 NVIDIA Quadro NVS +NVIDIA NVS 4200M/PCI/SSE2 supported 2 NVIDIA Quadro NVS 4200M +NVIDIA NVS 5100M/PCI/SSE2 supported 2 NVIDIA Quadro NVS 5100M +NVIDIA PCI UNRECOGNIZED +NVIDIA Quadro 2000/PCI/SSE2 supported 3 NVIDIA Quadro 2000 M/D +NVIDIA Quadro 4000 supported 3 NVIDIA Quadro 4000 +NVIDIA Quadro 4000 OpenGL Engine supported 3 NVIDIA Quadro 4000 +NVIDIA Quadro 4000/PCI/SSE2 supported 3 NVIDIA Quadro 4000 +NVIDIA Quadro 5000/PCI/SSE2 supported 3 NVIDIA Quadro 50x0 M +NVIDIA Quadro 5000M/PCI/SSE2 supported 3 NVIDIA Quadro 50x0 M +NVIDIA Quadro 600 supported 2 NVIDIA Quadro 600 +NVIDIA Quadro 600/PCI/SSE2 supported 2 NVIDIA Quadro 600 +NVIDIA Quadro 600/PCI/SSE2/3DNOW! supported 2 NVIDIA Quadro 600 +NVIDIA Quadro 6000 supported 3 NVIDIA Quadro 6000 +NVIDIA Quadro 6000/PCI/SSE2 supported 3 NVIDIA Quadro 6000 +NVIDIA Quadro CX/PCI/SSE2 UNRECOGNIZED +NVIDIA Quadro DCC supported 0 NVIDIA Quadro DCC +NVIDIA Quadro FX supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 1100/AGP/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 1400/PCI/SSE2 supported 2 NVIDIA Quadro 400 +NVIDIA Quadro FX 1500 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 1500M/PCI/SSE2 supported 1 NVIDIA Quadro FX 1500M +NVIDIA Quadro FX 1600M/PCI/SSE2 supported 2 NVIDIA Quadro 600 +NVIDIA Quadro FX 1700 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 1700M/PCI/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 1800 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 1800/PCI/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 1800M/PCI/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 2500M/PCI/SSE2 supported 2 NVIDIA Quadro FX 2500M +NVIDIA Quadro FX 2700M/PCI/SSE2 supported 3 NVIDIA Quadro FX 2700M +NVIDIA Quadro FX 2800M/PCI/SSE2 supported 3 NVIDIA Quadro FX 2800M +NVIDIA Quadro FX 3400 supported 2 NVIDIA Quadro 400 +NVIDIA Quadro FX 3450 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 3450/4000 SDI/PCI/SSE2 supported 2 NVIDIA Quadro 400 +NVIDIA Quadro FX 3500 supported 2 NVIDIA Quadro FX 3500 +NVIDIA Quadro FX 3500M/PCI/SSE2 supported 2 NVIDIA Quadro FX 3500 +NVIDIA Quadro FX 360M/PCI/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 370 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 370/PCI/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 3700 supported 3 NVIDIA Quadro FX 3700 +NVIDIA Quadro FX 3700M/PCI/SSE2 supported 3 NVIDIA Quadro FX 3700 +NVIDIA Quadro FX 370M/PCI/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 3800 supported 3 NVIDIA Quadro FX 3800 +NVIDIA Quadro FX 3800M/PCI/SSE2 supported 3 NVIDIA Quadro FX 3800 +NVIDIA Quadro FX 4500 supported 3 NVIDIA Quadro FX 4500 +NVIDIA Quadro FX 4600 supported 2 NVIDIA Quadro 600 +NVIDIA Quadro FX 4800 supported 3 NVIDIA Quadro FX 4800 +NVIDIA Quadro FX 4800/PCI/SSE2 supported 3 NVIDIA Quadro FX 4800 +NVIDIA Quadro FX 560 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 5600 supported 2 NVIDIA Quadro 600 +NVIDIA Quadro FX 570 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 570/PCI/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 570M/PCI/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 580/PCI/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro FX 770M/PCI/SSE2 supported 2 NVIDIA Quadro FX 770M +NVIDIA Quadro FX 880M supported 3 NVIDIA Quadro FX 880M +NVIDIA Quadro FX 880M/PCI/SSE2 supported 3 NVIDIA Quadro FX 880M +NVIDIA Quadro FX Go700/AGP/SSE2 supported 1 NVIDIA Quadro FX +NVIDIA Quadro NVS supported 0 NVIDIA Quadro NVS +NVIDIA Quadro NVS 110M/PCI/SSE2 supported 0 NVIDIA Quadro NVS 1xxM +NVIDIA Quadro NVS 130M/PCI/SSE2 supported 0 NVIDIA Quadro NVS 1xxM +NVIDIA Quadro NVS 135M/PCI/SSE2 supported 0 NVIDIA Quadro NVS 1xxM +NVIDIA Quadro NVS 140M/PCI/SSE2 supported 0 NVIDIA Quadro NVS 1xxM +NVIDIA Quadro NVS 150M/PCI/SSE2 supported 0 NVIDIA Quadro NVS 1xxM +NVIDIA Quadro NVS 160M/PCI/SSE2 supported 0 NVIDIA Quadro NVS 1xxM +NVIDIA Quadro NVS 210S/PCI/SSE2/3DNOW! supported 0 NVIDIA Quadro NVS +NVIDIA Quadro NVS 285/PCI/SSE2 supported 0 NVIDIA Quadro NVS +NVIDIA Quadro NVS 290/PCI/SSE2 supported 0 NVIDIA Quadro NVS +NVIDIA Quadro NVS 295/PCI/SSE2 supported 0 NVIDIA Quadro NVS +NVIDIA Quadro NVS 320M/PCI/SSE2 supported 2 NVIDIA Quadro NVS 320M +NVIDIA Quadro NVS 55/280 PCI/PCI/SSE2 supported 0 NVIDIA Quadro NVS +NVIDIA Quadro NVS/PCI/SSE2 supported 0 NVIDIA Quadro NVS +NVIDIA Quadro PCI-E Series/PCI/SSE2/3DNOW! UNRECOGNIZED +NVIDIA Quadro VX 200/PCI/SSE2 UNRECOGNIZED +NVIDIA Quadro/AGP/SSE2 UNRECOGNIZED +NVIDIA Quadro2 supported 0 NVIDIA Quadro2 +NVIDIA Quadro4 supported 0 NVIDIA Quadro4 +NVIDIA RIVA TNT unsupported 0 NVIDIA RIVA TNT +NVIDIA RIVA TNT2/AGP/SSE2 unsupported 0 NVIDIA RIVA TNT +NVIDIA RIVA TNT2/PCI/3DNOW! unsupported 0 NVIDIA RIVA TNT +NVIDIA nForce unsupported 0 NVIDIA nForce +NVIDIA unknown board/AGP/SSE2 UNRECOGNIZED +NVIDIA unknown board/PCI/SSE2 UNRECOGNIZED +NVIDIA unknown board/PCI/SSE2/3DNOW! UNRECOGNIZED +Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 5670 OpenGL Engine supported 3 ATI Radeon HD 5600 +Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 5750 OpenGL Engine supported 3 ATI Radeon HD 5700 +Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 5770 OpenGL Engine supported 3 ATI Radeon HD 5700 +Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 6490M OpenGL Engine supported 3 ATI Radeon HD 6400 +Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 6750M OpenGL Engine supported 3 ATI Radeon HD 6700 +Parallels and Intel Inc. 3D-Analyze v2.3 - http://www.tommti-systems.com UNRECOGNIZED +Parallels and Intel Inc. Parallels using Intel HD Graphics 3000 OpenGL Engine supported 2 Intel HD Graphics +Parallels and NVIDIA Parallels using NVIDIA GeForce 320M OpenGL Engine supported 2 NVIDIA 320M +Parallels and NVIDIA Parallels using NVIDIA GeForce 9400 OpenGL Engine supported 1 NVIDIA GeForce 9400 +Parallels and NVIDIA Parallels using NVIDIA GeForce GT 120 OpenGL Engine supported 2 NVIDIA GT 120M +Parallels and NVIDIA Parallels using NVIDIA GeForce GT 330M OpenGL Engine supported 3 NVIDIA GT 330M +Radeon RV350 on Gallium supported 0 ATI RV350 (9600) +S3 UNRECOGNIZED +S3 Graphics VIA/S3G UniChrome IGP/MMX/K3D unsupported 0 S3 +S3 Graphics VIA/S3G UniChrome Pro IGP/MMX/SSE unsupported 0 S3 +S3 Graphics, Incorporated ProSavage/Twister unsupported 0 S3 +S3 Graphics, Incorporated S3 Graphics Chrome9 HC unsupported 0 S3 +S3 Graphics, Incorporated S3 Graphics DeltaChrome unsupported 0 S3 +S3 Graphics, Incorporated VIA Chrome9 HC IGP unsupported 0 S3 +SiS unsupported 0 SiS +SiS 661 VGA unsupported 0 SiS +SiS 662 VGA unsupported 0 SiS +SiS 741 VGA unsupported 0 SiS +SiS 760 VGA unsupported 0 SiS +SiS 761GX VGA unsupported 0 SiS +SiS Mirage Graphics3 unsupported 0 SiS +Trident unsupported 0 Trident +Tungsten Graphics unsupported 0 Tungsten Graphics +Tungsten Graphics, Inc Mesa DRI 865G GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 865G GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 915G GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 915G GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 915GM GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 915GM GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 915GM GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945G unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945G GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945G GEM 20100330 DEVELOPMENT unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945G GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945GM GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945GM GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945GM GEM 20100328 2010Q1 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945GM GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945GME x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945GME 20061017 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945GME GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945GME GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 945GME GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 965GM GEM 20090326 2009Q1 RC2 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 965GM GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 965GM GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI 965GM GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI G33 20061017 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI G33 GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI G33 GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI G41 GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI G41 GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI GMA500 20081116 - 5.0.1.0046 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI IGD GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI IGD GEM 20100330 DEVELOPMENT unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI IGD GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI IGDNG_D GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI Ironlake Desktop GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI Ironlake Mobile GEM 20100330 DEVELOPMENT x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset 20080716 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset GEM 20090712 2009Q2 RC3 x86/MMX... unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset GEM 20091221 2009Q4 x86/MMX/SSE2 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset GEM 20100328 2010Q1 unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset GEM 20100330 DEVELOPMENT unsupported 0 Mesa +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset GEM 20100330 DEVELOPMENT x86/MM... unsupported 0 Mesa +Tungsten Graphics, Inc. Mesa DRI R200 (RV280 5964) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 unsupported 0 Mesa +VIA unsupported 0 VIA +VMware, Inc. Gallium 0.3 on SVGA3D; build: RELEASE; UNRECOGNIZED +VMware, Inc. Gallium 0.4 on i915 (chipset: 945GM) UNRECOGNIZED +VMware, Inc. Gallium 0.4 on llvmpipe UNRECOGNIZED +VMware, Inc. Gallium 0.4 on softpipe UNRECOGNIZED +X.Org Gallium 0.4 on AMD BARTS supported 3 AMD BARTS (HD 6800) +X.Org Gallium 0.4 on AMD CEDAR supported 2 AMD CEDAR (HD 5450) +X.Org Gallium 0.4 on AMD HEMLOCK supported 3 AMD HEMLOCK (HD 5970) +X.Org Gallium 0.4 on AMD JUNIPER supported 3 AMD JUNIPER (HD 5700) +X.Org Gallium 0.4 on AMD REDWOOD supported 3 AMD REDWOOD (HD 5500/5600) +X.Org Gallium 0.4 on AMD RS780 supported 0 AMD RS780 (HD 3200) +X.Org Gallium 0.4 on AMD RS880 supported 1 AMD RS880 (HD 4200) +X.Org Gallium 0.4 on AMD RV610 supported 1 AMD RV610 (HD 2400) +X.Org Gallium 0.4 on AMD RV620 supported 1 AMD RV620 (HD 3400) +X.Org Gallium 0.4 on AMD RV630 supported 2 AMD RV630 (HD 2600) +X.Org Gallium 0.4 on AMD RV635 supported 3 AMD RV635 (HD 3600) +X.Org Gallium 0.4 on AMD RV710 supported 1 AMD RV710 (HD 4300) +X.Org Gallium 0.4 on AMD RV730 supported 3 AMD RV730 (HD 4600) +X.Org Gallium 0.4 on AMD RV740 supported 3 AMD RV740 (HD 4700) +X.Org Gallium 0.4 on AMD RV770 supported 3 AMD RV770 (HD 4800) +X.Org R300 Project Gallium 0.4 on ATI R300 supported 1 ATI R300 (9700) +X.Org R300 Project Gallium 0.4 on ATI R580 supported 3 ATI R580 (X1900) +X.Org R300 Project Gallium 0.4 on ATI RC410 unsupported 0 ATI RC410 (Xpress 200) +X.Org R300 Project Gallium 0.4 on ATI RS482 unsupported 0 ATI RS48x (Xpress 200x) +X.Org R300 Project Gallium 0.4 on ATI RS600 unsupported 0 ATI RS600 (Xpress 3200) +X.Org R300 Project Gallium 0.4 on ATI RS690 supported 1 ATI R300 (9700) +X.Org R300 Project Gallium 0.4 on ATI RV350 supported 0 ATI RV350 (9600) +X.Org R300 Project Gallium 0.4 on ATI RV370 supported 0 ATI RV370 (X300) +X.Org R300 Project Gallium 0.4 on ATI RV410 supported 1 ATI RV410 (X700) +X.Org R300 Project Gallium 0.4 on ATI RV515 supported 1 ATI RV515 +X.Org R300 Project Gallium 0.4 on ATI RV530 supported 1 ATI RV530 +X.Org R300 Project Gallium 0.4 on ATI RV570 supported 3 ATI RV570 (X1900 GT/PRO) +X.Org R300 Project Gallium 0.4 on R420 supported 1 ATI R300 (9700) +X.Org R300 Project Gallium 0.4 on R580 supported 3 ATI R580 (X1900) +X.Org R300 Project Gallium 0.4 on RC410 unsupported 0 ATI RC410 (Xpress 200) +X.Org R300 Project Gallium 0.4 on RS480 unsupported 0 ATI RS48x (Xpress 200x) +X.Org R300 Project Gallium 0.4 on RS482 unsupported 0 ATI RS48x (Xpress 200x) +X.Org R300 Project Gallium 0.4 on RS600 unsupported 0 ATI RS600 (Xpress 3200) +X.Org R300 Project Gallium 0.4 on RS690 supported 1 ATI R300 (9700) +X.Org R300 Project Gallium 0.4 on RS740 supported 1 ATI R300 (9700) +X.Org R300 Project Gallium 0.4 on RV350 supported 0 ATI RV350 (9600) +X.Org R300 Project Gallium 0.4 on RV370 supported 0 ATI RV370 (X300) +X.Org R300 Project Gallium 0.4 on RV410 supported 1 ATI RV410 (X700) +X.Org R300 Project Gallium 0.4 on RV515 supported 1 ATI RV515 +X.Org R300 Project Gallium 0.4 on RV530 supported 1 ATI RV530 +XGI unsupported 0 XGI +nouveau Gallium 0.4 on NV34 UNRECOGNIZED +nouveau Gallium 0.4 on NV36 UNRECOGNIZED +nouveau Gallium 0.4 on NV46 UNRECOGNIZED +nouveau Gallium 0.4 on NV49 UNRECOGNIZED +nouveau Gallium 0.4 on NV4A UNRECOGNIZED +nouveau Gallium 0.4 on NV4B UNRECOGNIZED +nouveau Gallium 0.4 on NV4E UNRECOGNIZED +nouveau Gallium 0.4 on NV50 UNRECOGNIZED +nouveau Gallium 0.4 on NV84 UNRECOGNIZED +nouveau Gallium 0.4 on NV86 UNRECOGNIZED +nouveau Gallium 0.4 on NV92 UNRECOGNIZED +nouveau Gallium 0.4 on NV94 UNRECOGNIZED +nouveau Gallium 0.4 on NV96 UNRECOGNIZED +nouveau Gallium 0.4 on NV98 UNRECOGNIZED +nouveau Gallium 0.4 on NVA0 UNRECOGNIZED +nouveau Gallium 0.4 on NVA3 UNRECOGNIZED +nouveau Gallium 0.4 on NVA5 UNRECOGNIZED +nouveau Gallium 0.4 on NVA8 UNRECOGNIZED +nouveau Gallium 0.4 on NVAA UNRECOGNIZED +nouveau Gallium 0.4 on NVAC UNRECOGNIZED diff --git a/indra/newview/tests/gpus_seen.txt b/indra/newview/tests/gpus_seen.txt new file mode 100644 index 0000000000..c807f22b58 --- /dev/null +++ b/indra/newview/tests/gpus_seen.txt @@ -0,0 +1,1593 @@ +ATI +ATI 3D-Analyze +ATI ASUS A9xxx +ATI ASUS AH24xx +ATI ASUS AH26xx +ATI ASUS AH34xx +ATI ASUS AH36xx +ATI ASUS AH46xx +ATI ASUS AX3xx +ATI ASUS AX5xx +ATI ASUS AX8xx +ATI ASUS EAH38xx +ATI ASUS EAH43xx +ATI ASUS EAH45xx +ATI ASUS EAH48xx +ATI ASUS EAH57xx +ATI ASUS EAH58xx +ATI ASUS X1xxx +ATI All-in-Wonder 9xxx +ATI All-in-Wonder HD +ATI All-in-Wonder PCI-E +ATI All-in-Wonder X1800 +ATI All-in-Wonder X1900 +ATI All-in-Wonder X600 +ATI All-in-Wonder X800 +ATI Diamond X1xxx +ATI Display Adapter +ATI FireGL +ATI FireGL 5200 +ATI FireGL 5xxx +ATI FireMV +ATI Generic +ATI Hercules 9800 +ATI IGP 340M +ATI M52 +ATI M54 +ATI M56 +ATI M71 +ATI M72 +ATI M76 +ATI Mobility Radeon +ATI Mobility Radeon 7xxx +ATI Mobility Radeon 9600 +ATI Mobility Radeon 9700 +ATI Mobility Radeon 9800 +ATI Mobility Radeon HD 2300 +ATI Mobility Radeon HD 2400 +ATI Mobility Radeon HD 2600 +ATI Mobility Radeon HD 2700 +ATI Mobility Radeon HD 3400 +ATI Mobility Radeon HD 3600 +ATI Mobility Radeon HD 3800 +ATI Mobility Radeon HD 4200 +ATI Mobility Radeon HD 4300 +ATI Mobility Radeon HD 4500 +ATI Mobility Radeon HD 4600 +ATI Mobility Radeon HD 4800 +ATI Mobility Radeon HD 5400 +ATI Mobility Radeon HD 5600 +ATI Mobility Radeon X1xxx +ATI Mobility Radeon X2xxx +ATI Mobility Radeon X3xx +ATI Mobility Radeon X6xx +ATI Mobility Radeon X7xx +ATI Mobility Radeon Xxxx +ATI RV380 +ATI RV530 +ATI Radeon 2100 +ATI Radeon 3000 +ATI Radeon 3100 +ATI Radeon 7000 +ATI Radeon 7xxx +ATI Radeon 8xxx +ATI Radeon 9000 +ATI Radeon 9100 +ATI Radeon 9200 +ATI Radeon 9500 +ATI Radeon 9600 +ATI Radeon 9700 +ATI Radeon 9800 +ATI Radeon HD 2300 +ATI Radeon HD 2400 +ATI Radeon HD 2600 +ATI Radeon HD 2900 +ATI Radeon HD 3000 +ATI Radeon HD 3100 +ATI Radeon HD 3200 +ATI Radeon HD 3300 +ATI Radeon HD 3400 +ATI Radeon HD 3600 +ATI Radeon HD 3800 +ATI Radeon HD 4200 +ATI Radeon HD 4300 +ATI Radeon HD 4500 +ATI Radeon HD 4600 +ATI Radeon HD 4700 +ATI Radeon HD 4800 +ATI Radeon HD 5400 +ATI Radeon HD 5500 +ATI Radeon HD 5600 +ATI Radeon HD 5700 +ATI Radeon HD 5800 +ATI Radeon HD 5900 +ATI Radeon HD 6200 +ATI Radeon HD 6300 +ATI Radeon HD 6500 +ATI Radeon HD 6800 +ATI Radeon HD 6900 +ATI Radeon OpenGL +ATI Radeon RV250 +ATI Radeon RV600 +ATI Radeon RX9550 +ATI Radeon VE +ATI Radeon X1000 +ATI Radeon X1200 +ATI Radeon X1300 +ATI Radeon X13xx +ATI Radeon X1400 +ATI Radeon X1500 +ATI Radeon X1600 +ATI Radeon X16xx +ATI Radeon X1700 +ATI Radeon X1800 +ATI Radeon X1900 +ATI Radeon X19xx +ATI Radeon X1xxx +ATI Radeon X300 +ATI Radeon X500 +ATI Radeon X600 +ATI Radeon X700 +ATI Radeon X7xx +ATI Radeon X800 +ATI Radeon Xpress +ATI Rage 128 +ATI Technologies Inc. +ATI Technologies Inc. x86 +ATI Technologies Inc. x86/SSE2 +ATI Technologies Inc. (Vista) ATI Mobility Radeon HD 5730 +ATI Technologies Inc. 256MB ATI Radeon X1300PRO x86/SSE2 +ATI Technologies Inc. AMD 760G +ATI Technologies Inc. AMD 760G (Microsoft WDDM 1.1) +ATI Technologies Inc. AMD 780L +ATI Technologies Inc. AMD FirePro 2270 +ATI Technologies Inc. AMD M860G with ATI Mobility Radeon 4100 +ATI Technologies Inc. AMD M880G with ATI Mobility Radeon HD 4200 +ATI Technologies Inc. AMD M880G with ATI Mobility Radeon HD 4250 +ATI Technologies Inc. AMD RADEON HD 6450 +ATI Technologies Inc. AMD Radeon HD 6200 series Graphics +ATI Technologies Inc. AMD Radeon HD 6250 Graphics +ATI Technologies Inc. AMD Radeon HD 6300 series Graphics +ATI Technologies Inc. AMD Radeon HD 6300M Series +ATI Technologies Inc. AMD Radeon HD 6310 Graphics +ATI Technologies Inc. AMD Radeon HD 6310M +ATI Technologies Inc. AMD Radeon HD 6330M +ATI Technologies Inc. AMD Radeon HD 6350 +ATI Technologies Inc. AMD Radeon HD 6370M +ATI Technologies Inc. AMD Radeon HD 6400M Series +ATI Technologies Inc. AMD Radeon HD 6450 +ATI Technologies Inc. AMD Radeon HD 6470M +ATI Technologies Inc. AMD Radeon HD 6490M +ATI Technologies Inc. AMD Radeon HD 6500M/5600/5700 Series +ATI Technologies Inc. AMD Radeon HD 6530M +ATI Technologies Inc. AMD Radeon HD 6550M +ATI Technologies Inc. AMD Radeon HD 6570 +ATI Technologies Inc. AMD Radeon HD 6570M +ATI Technologies Inc. AMD Radeon HD 6570M/5700 Series +ATI Technologies Inc. AMD Radeon HD 6600M Series +ATI Technologies Inc. AMD Radeon HD 6650M +ATI Technologies Inc. AMD Radeon HD 6670 +ATI Technologies Inc. AMD Radeon HD 6700 Series +ATI Technologies Inc. AMD Radeon HD 6750 +ATI Technologies Inc. AMD Radeon HD 6750M +ATI Technologies Inc. AMD Radeon HD 6770 +ATI Technologies Inc. AMD Radeon HD 6800 Series +ATI Technologies Inc. AMD Radeon HD 6850M +ATI Technologies Inc. AMD Radeon HD 6870 +ATI Technologies Inc. AMD Radeon HD 6870M +ATI Technologies Inc. AMD Radeon HD 6900 Series +ATI Technologies Inc. AMD Radeon HD 6970M +ATI Technologies Inc. AMD Radeon HD 6990 +ATI Technologies Inc. AMD Radeon(TM) HD 6470M +ATI Technologies Inc. ASUS 5870 Eyefinity 6 +ATI Technologies Inc. ASUS AH2600 Series +ATI Technologies Inc. ASUS AH3450 Series +ATI Technologies Inc. ASUS AH3650 Series +ATI Technologies Inc. ASUS AH4650 Series +ATI Technologies Inc. ASUS ARES +ATI Technologies Inc. ASUS EAH2900 Series +ATI Technologies Inc. ASUS EAH3450 Series +ATI Technologies Inc. ASUS EAH3650 Series +ATI Technologies Inc. ASUS EAH4350 series +ATI Technologies Inc. ASUS EAH4550 series +ATI Technologies Inc. ASUS EAH4650 series +ATI Technologies Inc. ASUS EAH4670 series +ATI Technologies Inc. ASUS EAH4750 Series +ATI Technologies Inc. ASUS EAH4770 Series +ATI Technologies Inc. ASUS EAH4770 series +ATI Technologies Inc. ASUS EAH4850 series +ATI Technologies Inc. ASUS EAH5450 Series +ATI Technologies Inc. ASUS EAH5550 Series +ATI Technologies Inc. ASUS EAH5570 series +ATI Technologies Inc. ASUS EAH5670 Series +ATI Technologies Inc. ASUS EAH5750 Series +ATI Technologies Inc. ASUS EAH5770 Series +ATI Technologies Inc. ASUS EAH5830 Series +ATI Technologies Inc. ASUS EAH5850 Series +ATI Technologies Inc. ASUS EAH5870 Series +ATI Technologies Inc. ASUS EAH5970 Series +ATI Technologies Inc. ASUS EAH6850 Series +ATI Technologies Inc. ASUS EAH6870 Series +ATI Technologies Inc. ASUS EAH6950 Series +ATI Technologies Inc. ASUS EAH6970 Series +ATI Technologies Inc. ASUS EAHG4670 series +ATI Technologies Inc. ASUS Extreme AX600 Series +ATI Technologies Inc. ASUS Extreme AX600XT-TD +ATI Technologies Inc. ASUS X1300 Series x86/SSE2 +ATI Technologies Inc. ASUS X1550 Series +ATI Technologies Inc. ASUS X1950 Series x86/SSE2 +ATI Technologies Inc. ASUS X800 Series +ATI Technologies Inc. ASUS X850 Series +ATI Technologies Inc. ATI All-in-Wonder HD +ATI Technologies Inc. ATI FirePro 2260 +ATI Technologies Inc. ATI FirePro 2450 +ATI Technologies Inc. ATI FirePro M5800 +ATI Technologies Inc. ATI FirePro M7740 +ATI Technologies Inc. ATI FirePro M7820 +ATI Technologies Inc. ATI FirePro V3700 (FireGL) +ATI Technologies Inc. ATI FirePro V3800 +ATI Technologies Inc. ATI FirePro V4800 +ATI Technologies Inc. ATI FirePro V4800 (FireGL) +ATI Technologies Inc. ATI FirePro V5800 +ATI Technologies Inc. ATI FirePro V7800 +ATI Technologies Inc. ATI MOBILITY RADEON 9XXX x86/SSE2 +ATI Technologies Inc. ATI MOBILITY RADEON HD 3450 +ATI Technologies Inc. ATI MOBILITY RADEON X1600 +ATI Technologies Inc. ATI MOBILITY RADEON X2300 +ATI Technologies Inc. ATI MOBILITY RADEON X2300 HD x86/SSE2 +ATI Technologies Inc. ATI MOBILITY RADEON X2300 x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. ATI MOBILITY RADEON X2300 x86/SSE2 +ATI Technologies Inc. ATI MOBILITY RADEON X300 +ATI Technologies Inc. ATI MOBILITY RADEON X600 +ATI Technologies Inc. ATI MOBILITY RADEON XPRESS 200 +ATI Technologies Inc. ATI Mobility FireGL V5700 +ATI Technologies Inc. ATI Mobility Radeon 4100 +ATI Technologies Inc. ATI Mobility Radeon Graphics +ATI Technologies Inc. ATI Mobility Radeon HD 2300 +ATI Technologies Inc. ATI Mobility Radeon HD 2400 +ATI Technologies Inc. ATI Mobility Radeon HD 2400 XT +ATI Technologies Inc. ATI Mobility Radeon HD 2600 +ATI Technologies Inc. ATI Mobility Radeon HD 2600 XT +ATI Technologies Inc. ATI Mobility Radeon HD 2700 +ATI Technologies Inc. ATI Mobility Radeon HD 3400 Series +ATI Technologies Inc. ATI Mobility Radeon HD 3430 +ATI Technologies Inc. ATI Mobility Radeon HD 3450 +ATI Technologies Inc. ATI Mobility Radeon HD 3470 +ATI Technologies Inc. ATI Mobility Radeon HD 3470 Hybrid X2 +ATI Technologies Inc. ATI Mobility Radeon HD 3650 +ATI Technologies Inc. ATI Mobility Radeon HD 4200 +ATI Technologies Inc. ATI Mobility Radeon HD 4200 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4225 +ATI Technologies Inc. ATI Mobility Radeon HD 4225 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4250 +ATI Technologies Inc. ATI Mobility Radeon HD 4250 Graphics +ATI Technologies Inc. ATI Mobility Radeon HD 4270 +ATI Technologies Inc. ATI Mobility Radeon HD 4300 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4300/4500 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4330 +ATI Technologies Inc. ATI Mobility Radeon HD 4330 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4350 +ATI Technologies Inc. ATI Mobility Radeon HD 4350 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4500 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4500/5100 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4530 +ATI Technologies Inc. ATI Mobility Radeon HD 4530 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4550 +ATI Technologies Inc. ATI Mobility Radeon HD 4570 +ATI Technologies Inc. ATI Mobility Radeon HD 4600 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4650 +ATI Technologies Inc. ATI Mobility Radeon HD 4650 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4670 +ATI Technologies Inc. ATI Mobility Radeon HD 4830 Series +ATI Technologies Inc. ATI Mobility Radeon HD 4850 +ATI Technologies Inc. ATI Mobility Radeon HD 4870 +ATI Technologies Inc. ATI Mobility Radeon HD 5000 +ATI Technologies Inc. ATI Mobility Radeon HD 5000 Series +ATI Technologies Inc. ATI Mobility Radeon HD 5145 +ATI Technologies Inc. ATI Mobility Radeon HD 5165 +ATI Technologies Inc. ATI Mobility Radeon HD 530v +ATI Technologies Inc. ATI Mobility Radeon HD 5400 Series +ATI Technologies Inc. ATI Mobility Radeon HD 540v +ATI Technologies Inc. ATI Mobility Radeon HD 5430 +ATI Technologies Inc. ATI Mobility Radeon HD 5450 +ATI Technologies Inc. ATI Mobility Radeon HD 5450 Series +ATI Technologies Inc. ATI Mobility Radeon HD 545v +ATI Technologies Inc. ATI Mobility Radeon HD 5470 +ATI Technologies Inc. ATI Mobility Radeon HD 550v +ATI Technologies Inc. ATI Mobility Radeon HD 5600/5700 Series +ATI Technologies Inc. ATI Mobility Radeon HD 560v +ATI Technologies Inc. ATI Mobility Radeon HD 5650 +ATI Technologies Inc. ATI Mobility Radeon HD 5700 Series +ATI Technologies Inc. ATI Mobility Radeon HD 5730 +ATI Technologies Inc. ATI Mobility Radeon HD 5800 Series +ATI Technologies Inc. ATI Mobility Radeon HD 5850 +ATI Technologies Inc. ATI Mobility Radeon HD 5870 +ATI Technologies Inc. ATI Mobility Radeon HD 6300 series +ATI Technologies Inc. ATI Mobility Radeon HD 6370 +ATI Technologies Inc. ATI Mobility Radeon HD 6470M +ATI Technologies Inc. ATI Mobility Radeon HD 6550 +ATI Technologies Inc. ATI Mobility Radeon HD 6570 +ATI Technologies Inc. ATI Mobility Radeon X1300 +ATI Technologies Inc. ATI Mobility Radeon X1300 x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. ATI Mobility Radeon X1300 x86/SSE2 +ATI Technologies Inc. ATI Mobility Radeon X1350 +ATI Technologies Inc. ATI Mobility Radeon X1350 x86/SSE2 +ATI Technologies Inc. ATI Mobility Radeon X1400 +ATI Technologies Inc. ATI Mobility Radeon X1400 x86/SSE2 +ATI Technologies Inc. ATI Mobility Radeon X1600 +ATI Technologies Inc. ATI Mobility Radeon X1600 x86/SSE2 +ATI Technologies Inc. ATI Mobility Radeon X1700 x86/SSE2 +ATI Technologies Inc. ATI Mobility Radeon X2300 +ATI Technologies Inc. ATI Mobility Radeon X2300 (Omega 3.8.442) +ATI Technologies Inc. ATI Mobility Radeon X2300 x86 +ATI Technologies Inc. ATI Mobility Radeon X2300 x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. ATI Mobility Radeon X2300 x86/SSE2 +ATI Technologies Inc. ATI Mobility Radeon X2500 +ATI Technologies Inc. ATI Mobility Radeon X2500 x86/SSE2 +ATI Technologies Inc. ATI Mobility Radeon. HD 530v +ATI Technologies Inc. ATI Mobility Radeon. HD 5470 +ATI Technologies Inc. ATI RADEON HD 3200 T25XX by CAMILO +ATI Technologies Inc. ATI RADEON XPRESS 1100 +ATI Technologies Inc. ATI RADEON XPRESS 200 Series +ATI Technologies Inc. ATI RADEON XPRESS 200 Series x86/SSE2 +ATI Technologies Inc. ATI RADEON XPRESS 200M SERIES +ATI Technologies Inc. ATI Radeon +ATI Technologies Inc. ATI Radeon 2100 +ATI Technologies Inc. ATI Radeon 2100 (Microsoft - WDDM) +ATI Technologies Inc. ATI Radeon 2100 Graphics +ATI Technologies Inc. ATI Radeon 3000 +ATI Technologies Inc. ATI Radeon 3000 Graphics +ATI Technologies Inc. ATI Radeon 3100 Graphics +ATI Technologies Inc. ATI Radeon 5xxx series +ATI Technologies Inc. ATI Radeon 9550 / X1050 Series +ATI Technologies Inc. ATI Radeon 9550 / X1050 Series x86/MMX/3DNow!/SSE +ATI Technologies Inc. ATI Radeon 9550 / X1050 Series x86/SSE2 +ATI Technologies Inc. ATI Radeon 9550 / X1050 Series(Microsoft - WDDM) +ATI Technologies Inc. ATI Radeon 9600 / X1050 Series +ATI Technologies Inc. ATI Radeon 9600/9550/X1050 Series +ATI Technologies Inc. ATI Radeon BA Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon BB Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon Cedar PRO Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon Cypress PRO Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon Graphics Processor +ATI Technologies Inc. ATI Radeon HD 2200 Graphics +ATI Technologies Inc. ATI Radeon HD 2350 +ATI Technologies Inc. ATI Radeon HD 2400 +ATI Technologies Inc. ATI Radeon HD 2400 OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 2400 PRO +ATI Technologies Inc. ATI Radeon HD 2400 PRO AGP +ATI Technologies Inc. ATI Radeon HD 2400 Pro +ATI Technologies Inc. ATI Radeon HD 2400 Series +ATI Technologies Inc. ATI Radeon HD 2400 XT +ATI Technologies Inc. ATI Radeon HD 2400 XT OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 2600 OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 2600 PRO +ATI Technologies Inc. ATI Radeon HD 2600 PRO OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 2600 Pro +ATI Technologies Inc. ATI Radeon HD 2600 Series +ATI Technologies Inc. ATI Radeon HD 2600 XT +ATI Technologies Inc. ATI Radeon HD 2900 GT +ATI Technologies Inc. ATI Radeon HD 2900 XT +ATI Technologies Inc. ATI Radeon HD 3200 Graphics +ATI Technologies Inc. ATI Radeon HD 3300 Graphics +ATI Technologies Inc. ATI Radeon HD 3400 Series +ATI Technologies Inc. ATI Radeon HD 3450 +ATI Technologies Inc. ATI Radeon HD 3450 - Dell Optiplex +ATI Technologies Inc. ATI Radeon HD 3470 +ATI Technologies Inc. ATI Radeon HD 3470 - Dell Optiplex +ATI Technologies Inc. ATI Radeon HD 3550 +ATI Technologies Inc. ATI Radeon HD 3600 Series +ATI Technologies Inc. ATI Radeon HD 3650 +ATI Technologies Inc. ATI Radeon HD 3650 AGP +ATI Technologies Inc. ATI Radeon HD 3730 +ATI Technologies Inc. ATI Radeon HD 3800 Series +ATI Technologies Inc. ATI Radeon HD 3850 +ATI Technologies Inc. ATI Radeon HD 3850 AGP +ATI Technologies Inc. ATI Radeon HD 3870 +ATI Technologies Inc. ATI Radeon HD 3870 X2 +ATI Technologies Inc. ATI Radeon HD 4200 +ATI Technologies Inc. ATI Radeon HD 4250 +ATI Technologies Inc. ATI Radeon HD 4250 Graphics +ATI Technologies Inc. ATI Radeon HD 4270 +ATI Technologies Inc. ATI Radeon HD 4290 +ATI Technologies Inc. ATI Radeon HD 4300 Series +ATI Technologies Inc. ATI Radeon HD 4300/4500 Series +ATI Technologies Inc. ATI Radeon HD 4350 +ATI Technologies Inc. ATI Radeon HD 4350 (Microsoft WDDM 1.1) +ATI Technologies Inc. ATI Radeon HD 4450 +ATI Technologies Inc. ATI Radeon HD 4500 Series +ATI Technologies Inc. ATI Radeon HD 4550 +ATI Technologies Inc. ATI Radeon HD 4600 Series +ATI Technologies Inc. ATI Radeon HD 4650 +ATI Technologies Inc. ATI Radeon HD 4670 +ATI Technologies Inc. ATI Radeon HD 4670 OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 4700 Series +ATI Technologies Inc. ATI Radeon HD 4720 +ATI Technologies Inc. ATI Radeon HD 4730 +ATI Technologies Inc. ATI Radeon HD 4730 Series +ATI Technologies Inc. ATI Radeon HD 4750 +ATI Technologies Inc. ATI Radeon HD 4770 +ATI Technologies Inc. ATI Radeon HD 4800 Series +ATI Technologies Inc. ATI Radeon HD 4850 +ATI Technologies Inc. ATI Radeon HD 4850 OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 4850 Series +ATI Technologies Inc. ATI Radeon HD 4870 +ATI Technologies Inc. ATI Radeon HD 4870 OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 4870 X2 +ATI Technologies Inc. ATI Radeon HD 5400 Series +ATI Technologies Inc. ATI Radeon HD 5450 +ATI Technologies Inc. ATI Radeon HD 5500 Series +ATI Technologies Inc. ATI Radeon HD 5570 +ATI Technologies Inc. ATI Radeon HD 5600 Series +ATI Technologies Inc. ATI Radeon HD 5630 +ATI Technologies Inc. ATI Radeon HD 5670 +ATI Technologies Inc. ATI Radeon HD 5670 OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 5700 Series +ATI Technologies Inc. ATI Radeon HD 5750 +ATI Technologies Inc. ATI Radeon HD 5750 OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 5770 +ATI Technologies Inc. ATI Radeon HD 5770 OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 5800 Series +ATI Technologies Inc. ATI Radeon HD 5850 +ATI Technologies Inc. ATI Radeon HD 5870 +ATI Technologies Inc. ATI Radeon HD 5870 OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 5900 Series +ATI Technologies Inc. ATI Radeon HD 5970 +ATI Technologies Inc. ATI Radeon HD 6230 +ATI Technologies Inc. ATI Radeon HD 6250 +ATI Technologies Inc. ATI Radeon HD 6350 +ATI Technologies Inc. ATI Radeon HD 6390 +ATI Technologies Inc. ATI Radeon HD 6490M OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 6510 +ATI Technologies Inc. ATI Radeon HD 6570M +ATI Technologies Inc. ATI Radeon HD 6750 +ATI Technologies Inc. ATI Radeon HD 6750M OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 6770 +ATI Technologies Inc. ATI Radeon HD 6770M OpenGL Engine +ATI Technologies Inc. ATI Radeon HD 6800 Series +ATI Technologies Inc. ATI Radeon HD 6970M OpenGL Engine +ATI Technologies Inc. ATI Radeon HD3750 +ATI Technologies Inc. ATI Radeon HD4300/HD4500 series +ATI Technologies Inc. ATI Radeon HD4670 +ATI Technologies Inc. ATI Radeon Juniper LE Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon RV710 Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon RV730 Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon RV770 Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon RV790 Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon Redwood PRO Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon Redwood XT Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon Whistler PRO/LP Prototype OpenGL Engine +ATI Technologies Inc. ATI Radeon X1050 +ATI Technologies Inc. ATI Radeon X1050 Series +ATI Technologies Inc. ATI Radeon X1200 +ATI Technologies Inc. ATI Radeon X1200 Series +ATI Technologies Inc. ATI Radeon X1200 Series x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. ATI Radeon X1250 +ATI Technologies Inc. ATI Radeon X1250 x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. ATI Radeon X1270 +ATI Technologies Inc. ATI Radeon X1270 x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. ATI Radeon X1300/X1550 Series +ATI Technologies Inc. ATI Radeon X1550 Series +ATI Technologies Inc. ATI Radeon X1600 OpenGL Engine +ATI Technologies Inc. ATI Radeon X1900 OpenGL Engine +ATI Technologies Inc. ATI Radeon X1950 GT +ATI Technologies Inc. ATI Radeon X300/X550/X1050 Series +ATI Technologies Inc. ATI Radeon Xpress 1100 +ATI Technologies Inc. ATI Radeon Xpress 1150 +ATI Technologies Inc. ATI Radeon Xpress 1150 x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. ATI Radeon Xpress 1200 +ATI Technologies Inc. ATI Radeon Xpress 1200 Series +ATI Technologies Inc. ATI Radeon Xpress 1200 Series x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. ATI Radeon Xpress 1200 x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. ATI Radeon Xpress 1250 +ATI Technologies Inc. ATI Radeon Xpress 1250 x86/SSE2 +ATI Technologies Inc. ATI Radeon Xpress Series +ATI Technologies Inc. ATI Yamaha HD 9000 +ATI Technologies Inc. ATi RS880M +ATI Technologies Inc. Carte graphique VGA standard +ATI Technologies Inc. Diamond Radeon X1550 Series +ATI Technologies Inc. EG JUNIPER +ATI Technologies Inc. EG PARK +ATI Technologies Inc. FireGL V3100 Pentium 4 (SSE2) +ATI Technologies Inc. FireMV 2400 PCI DDR x86 +ATI Technologies Inc. FireMV 2400 PCI DDR x86/SSE2 +ATI Technologies Inc. GeCube Radeon X1550 +ATI Technologies Inc. Geforce 9500 GT +ATI Technologies Inc. Geforce 9500GT +ATI Technologies Inc. Geforce 9800 GT +ATI Technologies Inc. HD3730 +ATI Technologies Inc. HIGHTECH EXCALIBUR RADEON 9550SE Series +ATI Technologies Inc. HIGHTECH EXCALIBUR X700 PRO +ATI Technologies Inc. M21 x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. M76M +ATI Technologies Inc. MOBILITY RADEON 7500 DDR x86/SSE2 +ATI Technologies Inc. MOBILITY RADEON 9000 DDR x86/SSE2 +ATI Technologies Inc. MOBILITY RADEON 9000 IGPRADEON 9100 IGP DDR x86/SSE2 +ATI Technologies Inc. MOBILITY RADEON 9600 x86/SSE2 +ATI Technologies Inc. MOBILITY RADEON 9700 x86/SSE2 +ATI Technologies Inc. MOBILITY RADEON X300 x86/SSE2 +ATI Technologies Inc. MOBILITY RADEON X600 x86/SSE2 +ATI Technologies Inc. MOBILITY RADEON X700 SE x86 +ATI Technologies Inc. MOBILITY RADEON X700 x86/SSE2 +ATI Technologies Inc. MSI RX9550SE +ATI Technologies Inc. Mobility Radeon X2300 HD +ATI Technologies Inc. Mobility Radeon X2300 HD x86/SSE2 +ATI Technologies Inc. RADEON 7000 DDR x86/MMX/3DNow!/SSE +ATI Technologies Inc. RADEON 7000 DDR x86/SSE2 +ATI Technologies Inc. RADEON 7500 DDR x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON 7500 DDR x86/SSE2 +ATI Technologies Inc. RADEON 9100 IGP DDR x86/SSE2 +ATI Technologies Inc. RADEON 9200 DDR x86/MMX/3DNow!/SSE +ATI Technologies Inc. RADEON 9200 DDR x86/SSE2 +ATI Technologies Inc. RADEON 9200 PRO DDR x86/MMX/3DNow!/SSE +ATI Technologies Inc. RADEON 9200 Series DDR x86/MMX/3DNow!/SSE +ATI Technologies Inc. RADEON 9200 Series DDR x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON 9200 Series DDR x86/SSE +ATI Technologies Inc. RADEON 9200 Series DDR x86/SSE2 +ATI Technologies Inc. RADEON 9200SE DDR x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON 9200SE DDR x86/SSE2 +ATI Technologies Inc. RADEON 9250/9200 Series DDR x86/MMX/3DNow!/SSE +ATI Technologies Inc. RADEON 9250/9200 Series DDR x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON 9250/9200 Series DDR x86/SSE2 +ATI Technologies Inc. RADEON 9500 +ATI Technologies Inc. RADEON 9550 x86/SSE2 +ATI Technologies Inc. RADEON 9600 SERIES +ATI Technologies Inc. RADEON 9600 SERIES x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON 9600 TX x86/SSE2 +ATI Technologies Inc. RADEON 9600 x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON 9600 x86/SSE2 +ATI Technologies Inc. RADEON 9700 PRO x86/MMX/3DNow!/SSE +ATI Technologies Inc. RADEON 9800 PRO +ATI Technologies Inc. RADEON 9800 x86/SSE2 +ATI Technologies Inc. RADEON IGP 340M DDR x86/SSE2 +ATI Technologies Inc. RADEON X300 Series x86/SSE2 +ATI Technologies Inc. RADEON X300 x86/SSE2 +ATI Technologies Inc. RADEON X300/X550 Series x86/SSE2 +ATI Technologies Inc. RADEON X550 x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON X550 x86/SSE2 +ATI Technologies Inc. RADEON X600 Series +ATI Technologies Inc. RADEON X600 x86/SSE2 +ATI Technologies Inc. RADEON X700 PRO x86/SSE2 +ATI Technologies Inc. RADEON X800 SE x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON X800GT +ATI Technologies Inc. RADEON XPRESS 200 Series SW TCL x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON XPRESS 200 Series SW TCL x86/SSE2 +ATI Technologies Inc. RADEON XPRESS 200 Series x86/SSE2 +ATI Technologies Inc. RADEON XPRESS 200M Series SW TCL x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON XPRESS 200M Series SW TCL x86/SSE2 +ATI Technologies Inc. RADEON XPRESS 200M Series x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON XPRESS 200M Series x86/SSE2 +ATI Technologies Inc. RADEON XPRESS Series x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. RADEON XPRESS Series x86/SSE2 +ATI Technologies Inc. RS740 +ATI Technologies Inc. RS780C +ATI Technologies Inc. RS780M +ATI Technologies Inc. RS880 +ATI Technologies Inc. RV410 Pro x86/SSE2 +ATI Technologies Inc. RV790 +ATI Technologies Inc. Radeon (TM) HD 6470M +ATI Technologies Inc. Radeon (TM) HD 6490M +ATI Technologies Inc. Radeon (TM) HD 6770M +ATI Technologies Inc. Radeon 7000 DDR x86/SSE2 +ATI Technologies Inc. Radeon 7000 SDR x86/SSE2 +ATI Technologies Inc. Radeon 7500 DDR x86/SSE2 +ATI Technologies Inc. Radeon 9000 DDR x86/SSE2 +ATI Technologies Inc. Radeon DDR x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. Radeon DDR x86/SSE +ATI Technologies Inc. Radeon DDR x86/SSE2 +ATI Technologies Inc. Radeon HD 6310 +ATI Technologies Inc. Radeon HD 6800 Series +ATI Technologies Inc. Radeon SDR x86/SSE2 +ATI Technologies Inc. Radeon X1300 Series +ATI Technologies Inc. Radeon X1300 Series x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. Radeon X1300 Series x86/SSE2 +ATI Technologies Inc. Radeon X1300/X1550 Series +ATI Technologies Inc. Radeon X1300/X1550 Series x86/SSE2 +ATI Technologies Inc. Radeon X1550 64-bit (Microsoft - WDDM) +ATI Technologies Inc. Radeon X1550 Series +ATI Technologies Inc. Radeon X1550 Series x86/SSE2 +ATI Technologies Inc. Radeon X1600 +ATI Technologies Inc. Radeon X1600 Pro / X1300XT x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. Radeon X1600 Series x86/SSE2 +ATI Technologies Inc. Radeon X1600/X1650 Series +ATI Technologies Inc. Radeon X1650 Series +ATI Technologies Inc. Radeon X1650 Series x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. Radeon X1650 Series x86/SSE2 +ATI Technologies Inc. Radeon X1900 Series x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. Radeon X1950 Pro +ATI Technologies Inc. Radeon X1950 Pro x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. Radeon X1950 Series +ATI Technologies Inc. Radeon X1950 Series (Microsoft - WDDM) +ATI Technologies Inc. Radeon X300/X550/X1050 Series +ATI Technologies Inc. Radeon X550/X700 Series +ATI Technologies Inc. Radeon X550XTX x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. SAPPHIRE RADEON X300SE +ATI Technologies Inc. SAPPHIRE RADEON X300SE x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. SAPPHIRE RADEON X300SE x86/SSE2 +ATI Technologies Inc. SAPPHIRE Radeon X1550 Series +ATI Technologies Inc. SAPPHIRE Radeon X1550 Series x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. Sapphire Radeon HD 3730 +ATI Technologies Inc. Sapphire Radeon HD 3750 +ATI Technologies Inc. Standard VGA Graphics Adapter +ATI Technologies Inc. Tul, RADEON X600 PRO +ATI Technologies Inc. Tul, RADEON X600 PRO x86/SSE2 +ATI Technologies Inc. Tul, RADEON X700 PRO +ATI Technologies Inc. Tul, RADEON X700 PRO x86/MMX/3DNow!/SSE2 +ATI Technologies Inc. VisionTek Radeon 4350 +ATI Technologies Inc. VisionTek Radeon X1550 Series +ATI Technologies Inc. WRESTLER 9802 +ATI Technologies Inc. WRESTLER 9803 +ATI Technologies Inc. XFX Radeon HD 4570 +ATI Technologies Inc. Yamaha ATI HD 9000da/s +ATI Technologies Inc. Yamaha ATI HD 9000da/s 2048 +Advanced Micro Devices, Inc. Mesa DRI R600 (RS780 9612) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RS880 9710) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RS880 9712) 20090101 TCL +Advanced Micro Devices, Inc. Mesa DRI R600 (RV610 94C1) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV610 94C9) 20090101 x86/MMX/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV620 95C4) 20090101 x86/MMX/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV620 95C5) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV620 95C5) 20090101 x86/MMX/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV635 9596) 20090101 x86/MMX+/3DNow!+/SSE TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV670 9505) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV710 9552) 20090101 x86/MMX/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV730 9490) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV730 9490) 20090101 x86/MMX/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV730 9498) 20090101 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV770 9440) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +Advanced Micro Devices, Inc. Mesa DRI R600 (RV770 9442) 20090101 x86/MMX/SSE2 TCL DRI2 +Alex Mohr GL Hijacker! +Apple Software Renderer +DRI R300 Project Mesa DRI R300 (RS400 5954) 20090101 x86/MMX+/3DNow!+/SSE2 NO-TCL DRI2 +DRI R300 Project Mesa DRI R300 (RS400 5975) 20090101 x86/MMX+/3DNow!+/SSE2 NO-TCL DRI2 +DRI R300 Project Mesa DRI R300 (RS400 5A62) 20090101 x86/MMX/SSE2 NO-TCL DRI2 +DRI R300 Project Mesa DRI R300 (RS600 7941) 20090101 x86/MMX/SSE2 NO-TCL +DRI R300 Project Mesa DRI R300 (RS690 791F) 20090101 x86/MMX+/3DNow!+/SSE2 NO-TCL DRI2 +DRI R300 Project Mesa DRI R300 (RV350 4151) 20090101 AGP 4x x86/MMX+/3DNow!+/SSE TCL +DRI R300 Project Mesa DRI R300 (RV350 4153) 20090101 AGP 8x x86/MMX+/3DNow!+/SSE TCL +DRI R300 Project Mesa DRI R300 (RV380 3150) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +DRI R300 Project Mesa DRI R300 (RV380 3150) 20090101 x86/MMX/SSE2 TCL DRI2 +DRI R300 Project Mesa DRI R300 (RV380 5B60) 20090101 x86/MMX/SSE2 TCL DRI2 +DRI R300 Project Mesa DRI R300 (RV380 5B62) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +DRI R300 Project Mesa DRI R300 (RV515 7145) 20090101 x86/MMX/SSE2 TCL DRI2 +DRI R300 Project Mesa DRI R300 (RV515 7146) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +DRI R300 Project Mesa DRI R300 (RV515 7146) 20090101 x86/MMX/SSE2 TCL DRI2 +DRI R300 Project Mesa DRI R300 (RV515 7149) 20090101 x86/MMX/SSE2 TCL DRI2 +DRI R300 Project Mesa DRI R300 (RV515 714A) 20090101 x86/MMX/SSE2 TCL +DRI R300 Project Mesa DRI R300 (RV515 714A) 20090101 x86/MMX/SSE2 TCL DRI2 +DRI R300 Project Mesa DRI R300 (RV530 71C4) 20090101 x86/MMX/SSE2 TCL DRI2 +GPU_CLASS_UNKNOWN +Humper Chromium +Intel +Intel HD Graphics Family +Intel 3D-Analyze v2.2 - http://www.tommti-systems.com +Intel 3D-Analyze v2.3 - http://www.tommti-systems.com +Intel 4 Series Internal Chipset +Intel 830M +Intel 845G +Intel 855GM +Intel 865G +Intel 915G +Intel 915GM +Intel 945G +Intel 945GM +Intel 950 +Intel 965 +Intel B43 Express Chipset +Intel Bear Lake +Intel Broadwater +Intel Brookdale +Intel Cantiga +Intel Eaglelake +Intel Familia Mobile 45 Express Chipset (Microsoft Corporation - WDDM 1.1) +Intel G33 +Intel G41 +Intel G41 Express Chipset +Intel G45 +Intel G45/G43 Express Chipset +Intel Graphics Media Accelerator HD +Intel HD Graphics +Intel HD Graphics 100 +Intel HD Graphics 200 +Intel HD Graphics 200 BR-1101-00SH +Intel HD Graphics 200 BR-1101-00SJ +Intel HD Graphics 200 BR-1101-00SK +Intel HD Graphics 200 BR-1101-01M5 +Intel HD Graphics 200 BR-1101-01M6 +Intel HD Graphics BR-1004-01Y1 +Intel HD Graphics BR-1006-0364 +Intel HD Graphics BR-1006-0365 +Intel HD Graphics BR-1006-0366 +Intel HD Graphics BR-1007-02G4 +Intel HD Graphics BR-1101-04SY +Intel HD Graphics BR-1101-04SZ +Intel HD Graphics BR-1101-04T0 +Intel HD Graphics BR-1101-04T9 +Intel HD Graphics Family +Intel HD Graphics Family BR-1012-00Y8 +Intel HD Graphics Family BR-1012-00YF +Intel HD Graphics Family BR-1012-00ZD +Intel HD Graphics Family BR-1102-00ML +Intel Inc. Intel GMA 900 OpenGL Engine +Intel Inc. Intel GMA 950 OpenGL Engine +Intel Inc. Intel GMA X3100 OpenGL Engine +Intel Inc. Intel HD Graphics 3000 OpenGL Engine +Intel Inc. Intel HD Graphics OpenGL Engine +Intel Inc. Intel HD xxxx OpenGL Engine +Intel Intel 845G +Intel Intel 855GM +Intel Intel 865G +Intel Intel 915G +Intel Intel 915GM +Intel Intel 945G +Intel Intel 945GM +Intel Intel 965/963 Graphics Media Accelerator +Intel Intel Bear Lake B +Intel Intel Broadwater G +Intel Intel Brookdale-G +Intel Intel Calistoga +Intel Intel Cantiga +Intel Intel Eaglelake +Intel Intel Grantsdale-G +Intel Intel HD Graphics 3000 +Intel Intel Lakeport +Intel Intel Montara-GM +Intel Intel Pineview Platform +Intel Intel Springdale-G +Intel Mobile - famiglia Express Chipset 45 (Microsoft Corporation - WDDM 1.1) +Intel Mobile 4 Series +Intel Mobile 4 Series Express Chipset Family +Intel Mobile 45 Express Chipset Family (Microsoft Corporation - WDDM 1.1) +Intel Mobile HD Graphics +Intel Mobile SandyBridge HD Graphics +Intel Montara +Intel Pineview +Intel Q45/Q43 Express Chipset +Intel Royal BNA Driver +Intel SandyBridge HD Graphics +Intel SandyBridge HD Graphics BR-1006-00V8 +Intel Springdale +Intel X3100 +Intergraph wcgdrv 06.05.06.18 +Intergraph wcgdrv 06.06.00.35 +LegendgrafiX Mobile 945 Express C/TitaniumGL/GAC/D3D ACCELERATION/6x86/1 THREADs | http://LegendgrafiX.tk +LegendgrafiX NVIDIA GeForce GT 430/TitaniumGL/GAC/D3D ACCELERATION/6x86/1 THREADs | http://LegendgrafiX.tk +Linden Lab Headless +Matrox +Mesa +Mesa Project Software Rasterizer +NVIDIA /PCI/SSE2 +NVIDIA /PCI/SSE2/3DNOW! +NVIDIA 205 +NVIDIA 210 +NVIDIA 310 +NVIDIA 310M +NVIDIA 315 +NVIDIA 315M +NVIDIA 320M +NVIDIA C51 +NVIDIA D10M2-20/PCI/SSE2 +NVIDIA D10P1-25/PCI/SSE2 +NVIDIA D10P1-30/PCI/SSE2 +NVIDIA D10P2-50/PCI/SSE2 +NVIDIA D11M2-30/PCI/SSE2 +NVIDIA D12-P1-35/PCI/SSE2 +NVIDIA D12U-15/PCI/SSE2 +NVIDIA D13M1-40/PCI/SSE2 +NVIDIA D13P1-40/PCI/SSE2 +NVIDIA D13U-10/PCI/SSE2 +NVIDIA D13U/PCI/SSE2 +NVIDIA D9M +NVIDIA D9M-20/PCI/SSE2 +NVIDIA Entry Graphics/PCI/SSE2 +NVIDIA Entry Graphics/PCI/SSE2/3DNOW! +NVIDIA G 102M +NVIDIA G 103M +NVIDIA G 105M +NVIDIA G 110M +NVIDIA G100 +NVIDIA G102M +NVIDIA G103M +NVIDIA G105M +NVIDIA G210 +NVIDIA G210M +NVIDIA G70/PCI/SSE2 +NVIDIA G72 +NVIDIA G73 +NVIDIA G84 +NVIDIA G86 +NVIDIA G92 +NVIDIA G92-200/PCI/SSE2 +NVIDIA G94 +NVIDIA G96/PCI/SSE2 +NVIDIA G98/PCI/SSE2 +NVIDIA GT 120 +NVIDIA GT 130 +NVIDIA GT 130M +NVIDIA GT 140 +NVIDIA GT 150 +NVIDIA GT 160M +NVIDIA GT 220 +NVIDIA GT 220/PCI/SSE2 +NVIDIA GT 220/PCI/SSE2/3DNOW! +NVIDIA GT 230 +NVIDIA GT 230M +NVIDIA GT 240 +NVIDIA GT 240M +NVIDIA GT 250M +NVIDIA GT 260M +NVIDIA GT 320 +NVIDIA GT 320M +NVIDIA GT 330 +NVIDIA GT 330M +NVIDIA GT 340 +NVIDIA GT 420 +NVIDIA GT 430 +NVIDIA GT 440 +NVIDIA GT 450 +NVIDIA GT 520 +NVIDIA GT 540 +NVIDIA GT 540M +NVIDIA GT-120 +NVIDIA GT200/PCI/SSE2 +NVIDIA GTS 150 +NVIDIA GTS 240 +NVIDIA GTS 250 +NVIDIA GTS 350M +NVIDIA GTS 360 +NVIDIA GTS 360M +NVIDIA GTS 450 +NVIDIA GTX 260 +NVIDIA GTX 260M +NVIDIA GTX 270 +NVIDIA GTX 280 +NVIDIA GTX 285 +NVIDIA GTX 290 +NVIDIA GTX 460 +NVIDIA GTX 460M +NVIDIA GTX 465 +NVIDIA GTX 470 +NVIDIA GTX 470M +NVIDIA GTX 480 +NVIDIA GTX 480M +NVIDIA GTX 550 Ti +NVIDIA GTX 560 +NVIDIA GTX 560 Ti +NVIDIA GTX 570 +NVIDIA GTX 580 +NVIDIA GTX 590 +NVIDIA GeForce +NVIDIA GeForce 2 +NVIDIA GeForce 205/PCI/SSE2 +NVIDIA GeForce 210 +NVIDIA GeForce 210/PCI/SSE2 +NVIDIA GeForce 210/PCI/SSE2/3DNOW! +NVIDIA GeForce 3 +NVIDIA GeForce 305M/PCI/SSE2 +NVIDIA GeForce 310/PCI/SSE2 +NVIDIA GeForce 310/PCI/SSE2/3DNOW! +NVIDIA GeForce 310M/PCI/SSE2 +NVIDIA GeForce 315/PCI/SSE2 +NVIDIA GeForce 315/PCI/SSE2/3DNOW! +NVIDIA GeForce 315M/PCI/SSE2 +NVIDIA GeForce 320M/PCI/SSE2 +NVIDIA GeForce 4 Go +NVIDIA GeForce 4 MX +NVIDIA GeForce 4 Ti +NVIDIA GeForce 405/PCI/SSE2 +NVIDIA GeForce 6100 +NVIDIA GeForce 6100 nForce 400/PCI/SSE2/3DNOW! +NVIDIA GeForce 6100 nForce 405/PCI/SSE2 +NVIDIA GeForce 6100 nForce 405/PCI/SSE2/3DNOW! +NVIDIA GeForce 6100 nForce 420/PCI/SSE2/3DNOW! +NVIDIA GeForce 6100 nForce 430/PCI/SSE2/3DNOW! +NVIDIA GeForce 6100/PCI/SSE2/3DNOW! +NVIDIA GeForce 6150 LE/PCI/SSE2/3DNOW! +NVIDIA GeForce 6150/PCI/SSE2 +NVIDIA GeForce 6150/PCI/SSE2/3DNOW! +NVIDIA GeForce 6150SE nForce 430/PCI/SSE2 +NVIDIA GeForce 6150SE nForce 430/PCI/SSE2/3DNOW! +NVIDIA GeForce 6150SE/PCI/SSE2/3DNOW! +NVIDIA GeForce 6200 +NVIDIA GeForce 6200 A-LE/AGP/SSE/3DNOW! +NVIDIA GeForce 6200 A-LE/AGP/SSE2 +NVIDIA GeForce 6200 A-LE/AGP/SSE2/3DNOW! +NVIDIA GeForce 6200 LE/PCI/SSE2 +NVIDIA GeForce 6200 LE/PCI/SSE2/3DNOW! +NVIDIA GeForce 6200 TurboCache(TM)/PCI/SSE2 +NVIDIA GeForce 6200 TurboCache(TM)/PCI/SSE2/3DNOW! +NVIDIA GeForce 6200/AGP/SSE/3DNOW! +NVIDIA GeForce 6200/AGP/SSE2 +NVIDIA GeForce 6200/AGP/SSE2/3DNOW! +NVIDIA GeForce 6200/PCI/SSE/3DNOW! +NVIDIA GeForce 6200/PCI/SSE2 +NVIDIA GeForce 6200/PCI/SSE2/3DNOW! +NVIDIA GeForce 6200SE TurboCache(TM)/PCI/SSE2/3DNOW! +NVIDIA GeForce 6500 +NVIDIA GeForce 6500/PCI/SSE2 +NVIDIA GeForce 6600 +NVIDIA GeForce 6600 GT/AGP/SSE/3DNOW! +NVIDIA GeForce 6600 GT/AGP/SSE2 +NVIDIA GeForce 6600 GT/PCI/SSE/3DNOW! +NVIDIA GeForce 6600 GT/PCI/SSE2 +NVIDIA GeForce 6600 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 6600 LE/PCI/SSE2 +NVIDIA GeForce 6600/AGP/SSE/3DNOW! +NVIDIA GeForce 6600/AGP/SSE2 +NVIDIA GeForce 6600/AGP/SSE2/3DNOW! +NVIDIA GeForce 6600/PCI/SSE2 +NVIDIA GeForce 6600/PCI/SSE2/3DNOW! +NVIDIA GeForce 6700 +NVIDIA GeForce 6800 +NVIDIA GeForce 6800 GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 6800 GT/AGP/SSE2 +NVIDIA GeForce 6800 GT/PCI/SSE2 +NVIDIA GeForce 6800 XT/AGP/SSE2 +NVIDIA GeForce 6800 XT/PCI/SSE2 +NVIDIA GeForce 6800/PCI/SSE2 +NVIDIA GeForce 6800/PCI/SSE2/3DNOW! +NVIDIA GeForce 7000 +NVIDIA GeForce 7000M +NVIDIA GeForce 7000M / nForce 610M/PCI/SSE2 +NVIDIA GeForce 7000M / nForce 610M/PCI/SSE2/3DNOW! +NVIDIA GeForce 7025 / NVIDIA nForce 630a/PCI/SSE2/3DNOW! +NVIDIA GeForce 7025 / nForce 630a/PCI/SSE2 +NVIDIA GeForce 7025 / nForce 630a/PCI/SSE2/3DNOW! +NVIDIA GeForce 7050 / NVIDIA nForce 610i/PCI/SSE2 +NVIDIA GeForce 7050 / NVIDIA nForce 620i/PCI/SSE2 +NVIDIA GeForce 7050 / nForce 610i/PCI/SSE2 +NVIDIA GeForce 7050 / nForce 620i/PCI/SSE2 +NVIDIA GeForce 7050 PV / NVIDIA nForce 630a/PCI/SSE2/3DNOW! +NVIDIA GeForce 7050 PV / nForce 630a/PCI/SSE2 +NVIDIA GeForce 7050 PV / nForce 630a/PCI/SSE2/3DNOW! +NVIDIA GeForce 7050 SE / NVIDIA nForce 630a/PCI/SSE2/3DNOW! +NVIDIA GeForce 7100 +NVIDIA GeForce 7100 / NVIDIA nForce 620i/PCI/SSE2 +NVIDIA GeForce 7100 / NVIDIA nForce 630i/PCI/SSE2 +NVIDIA GeForce 7100 / nForce 630i/PCI/SSE2 +NVIDIA GeForce 7100 GS/PCI/SSE2 +NVIDIA GeForce 7100 GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 7150M / nForce 630M/PCI/SSE2 +NVIDIA GeForce 7150M / nForce 630M/PCI/SSE2/3DNOW! +NVIDIA GeForce 7300 +NVIDIA GeForce 7300 GS/PCI/SSE2 +NVIDIA GeForce 7300 GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 7300 GT/AGP/SSE2 +NVIDIA GeForce 7300 GT/AGP/SSE2/3DNOW! +NVIDIA GeForce 7300 GT/PCI/SSE2 +NVIDIA GeForce 7300 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 7300 LE/PCI/SSE2 +NVIDIA GeForce 7300 LE/PCI/SSE2/3DNOW! +NVIDIA GeForce 7300 SE/7200 GS/PCI/SSE2 +NVIDIA GeForce 7300 SE/7200 GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 7300 SE/PCI/SSE2 +NVIDIA GeForce 7300 SE/PCI/SSE2/3DNOW! +NVIDIA GeForce 7350 LE/PCI/SSE2 +NVIDIA GeForce 7500 +NVIDIA GeForce 7500 LE/PCI/SSE2 +NVIDIA GeForce 7500 LE/PCI/SSE2/3DNOW! +NVIDIA GeForce 7600 +NVIDIA GeForce 7600 GS/AGP/SSE2 +NVIDIA GeForce 7600 GS/AGP/SSE2/3DNOW! +NVIDIA GeForce 7600 GS/PCI/SSE2 +NVIDIA GeForce 7600 GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 7600 GT/AGP/SSE/3DNOW! +NVIDIA GeForce 7600 GT/AGP/SSE2 +NVIDIA GeForce 7600 GT/PCI/SSE2 +NVIDIA GeForce 7600 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 7650 GS/PCI/SSE2 +NVIDIA GeForce 7800 +NVIDIA GeForce 7800 GS/AGP/SSE2 +NVIDIA GeForce 7800 GS/AGP/SSE2/3DNOW! +NVIDIA GeForce 7800 GT/PCI/SSE2 +NVIDIA GeForce 7800 GTX/PCI/SSE2 +NVIDIA GeForce 7800 GTX/PCI/SSE2/3DNOW! +NVIDIA GeForce 7900 +NVIDIA GeForce 7900 GS/PCI/SSE2 +NVIDIA GeForce 7900 GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 7900 GT/GTO/PCI/SSE2 +NVIDIA GeForce 7900 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 7900 GTX/PCI/SSE2 +NVIDIA GeForce 7950 GT/PCI/SSE2 +NVIDIA GeForce 7950 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 8100 +NVIDIA GeForce 8100 / nForce 720a/PCI/SSE2/3DNOW! +NVIDIA GeForce 8200 +NVIDIA GeForce 8200/PCI/SSE2 +NVIDIA GeForce 8200/PCI/SSE2/3DNOW! +NVIDIA GeForce 8200M +NVIDIA GeForce 8200M G/PCI/SSE2 +NVIDIA GeForce 8200M G/PCI/SSE2/3DNOW! +NVIDIA GeForce 8300 +NVIDIA GeForce 8300 GS/PCI/SSE2 +NVIDIA GeForce 8400 +NVIDIA GeForce 8400 GS/PCI/SSE/3DNOW! +NVIDIA GeForce 8400 GS/PCI/SSE2 +NVIDIA GeForce 8400 GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 8400/PCI/SSE2/3DNOW! +NVIDIA GeForce 8400GS/PCI/SSE2 +NVIDIA GeForce 8400GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 8400M +NVIDIA GeForce 8400M G/PCI/SSE2 +NVIDIA GeForce 8400M G/PCI/SSE2/3DNOW! +NVIDIA GeForce 8400M GS/PCI/SSE2 +NVIDIA GeForce 8400M GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 8400M GT/PCI/SSE2 +NVIDIA GeForce 8500 +NVIDIA GeForce 8500 GT/PCI/SSE2 +NVIDIA GeForce 8500 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 8600 +NVIDIA GeForce 8600 GS/PCI/SSE2 +NVIDIA GeForce 8600 GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 8600 GT/PCI/SSE2 +NVIDIA GeForce 8600 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 8600 GTS/PCI/SSE2 +NVIDIA GeForce 8600 GTS/PCI/SSE2/3DNOW! +NVIDIA GeForce 8600GS/PCI/SSE2 +NVIDIA GeForce 8600M +NVIDIA GeForce 8600M GS/PCI/SSE2 +NVIDIA GeForce 8600M GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 8600M GT/PCI/SSE2 +NVIDIA GeForce 8700 +NVIDIA GeForce 8700M +NVIDIA GeForce 8700M GT/PCI/SSE2 +NVIDIA GeForce 8800 +NVIDIA GeForce 8800 GS/PCI/SSE2 +NVIDIA GeForce 8800 GT/PCI/SSE2 +NVIDIA GeForce 8800 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 8800 GTS 512/PCI/SSE2 +NVIDIA GeForce 8800 GTS 512/PCI/SSE2/3DNOW! +NVIDIA GeForce 8800 GTS/PCI/SSE2 +NVIDIA GeForce 8800 GTS/PCI/SSE2/3DNOW! +NVIDIA GeForce 8800 GTX/PCI/SSE2 +NVIDIA GeForce 8800 Ultra/PCI/SSE2 +NVIDIA GeForce 8800M GTS/PCI/SSE2 +NVIDIA GeForce 8800M GTX/PCI/SSE2 +NVIDIA GeForce 9100 +NVIDIA GeForce 9100/PCI/SSE2 +NVIDIA GeForce 9100/PCI/SSE2/3DNOW! +NVIDIA GeForce 9100M +NVIDIA GeForce 9100M G/PCI/SSE2 +NVIDIA GeForce 9100M G/PCI/SSE2/3DNOW! +NVIDIA GeForce 9200 +NVIDIA GeForce 9200/PCI/SSE2 +NVIDIA GeForce 9200/PCI/SSE2/3DNOW! +NVIDIA GeForce 9200M GE/PCI/SSE2 +NVIDIA GeForce 9200M GS/PCI/SSE2 +NVIDIA GeForce 9300 +NVIDIA GeForce 9300 / nForce 730i/PCI/SSE2 +NVIDIA GeForce 9300 GE/PCI/SSE2 +NVIDIA GeForce 9300 GE/PCI/SSE2/3DNOW! +NVIDIA GeForce 9300 GS/PCI/SSE2 +NVIDIA GeForce 9300 GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 9300 SE/PCI/SSE2 +NVIDIA GeForce 9300M +NVIDIA GeForce 9300M G/PCI/SSE2 +NVIDIA GeForce 9300M G/PCI/SSE2/3DNOW! +NVIDIA GeForce 9300M GS/PCI/SSE2 +NVIDIA GeForce 9300M GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 9400 +NVIDIA GeForce 9400 GT/PCI/SSE2 +NVIDIA GeForce 9400 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 9400/PCI/SSE2 +NVIDIA GeForce 9400M +NVIDIA GeForce 9400M G/PCI/SSE2 +NVIDIA GeForce 9400M/PCI/SSE2 +NVIDIA GeForce 9500 +NVIDIA GeForce 9500 GS/PCI/SSE2 +NVIDIA GeForce 9500 GS/PCI/SSE2/3DNOW! +NVIDIA GeForce 9500 GT/PCI/SSE2 +NVIDIA GeForce 9500 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 9500M +NVIDIA GeForce 9500M GS/PCI/SSE2 +NVIDIA GeForce 9600 +NVIDIA GeForce 9600 GS/PCI/SSE2 +NVIDIA GeForce 9600 GSO 512/PCI/SSE2 +NVIDIA GeForce 9600 GSO/PCI/SSE2 +NVIDIA GeForce 9600 GSO/PCI/SSE2/3DNOW! +NVIDIA GeForce 9600 GT/PCI/SSE2 +NVIDIA GeForce 9600 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 9600M +NVIDIA GeForce 9600M GS/PCI/SSE2 +NVIDIA GeForce 9600M GT/PCI/SSE2 +NVIDIA GeForce 9650M GT/PCI/SSE2 +NVIDIA GeForce 9700M +NVIDIA GeForce 9700M GT/PCI/SSE2 +NVIDIA GeForce 9700M GTS/PCI/SSE2 +NVIDIA GeForce 9800 +NVIDIA GeForce 9800 GT/PCI/SSE2 +NVIDIA GeForce 9800 GT/PCI/SSE2/3DNOW! +NVIDIA GeForce 9800 GTX+/PCI/SSE2 +NVIDIA GeForce 9800 GTX+/PCI/SSE2/3DNOW! +NVIDIA GeForce 9800 GTX/9800 GTX+/PCI/SSE2 +NVIDIA GeForce 9800 GTX/PCI/SSE2 +NVIDIA GeForce 9800 GX2/PCI/SSE2 +NVIDIA GeForce 9800M +NVIDIA GeForce 9800M GS/PCI/SSE2 +NVIDIA GeForce 9800M GT/PCI/SSE2 +NVIDIA GeForce 9800M GTS/PCI/SSE2 +NVIDIA GeForce FX 5100 +NVIDIA GeForce FX 5100/AGP/SSE/3DNOW! +NVIDIA GeForce FX 5200 +NVIDIA GeForce FX 5200/AGP/SSE +NVIDIA GeForce FX 5200/AGP/SSE/3DNOW! +NVIDIA GeForce FX 5200/AGP/SSE2 +NVIDIA GeForce FX 5200/AGP/SSE2/3DNOW! +NVIDIA GeForce FX 5200/PCI/SSE2 +NVIDIA GeForce FX 5200/PCI/SSE2/3DNOW! +NVIDIA GeForce FX 5200LE/AGP/SSE2 +NVIDIA GeForce FX 5500 +NVIDIA GeForce FX 5500/AGP/SSE/3DNOW! +NVIDIA GeForce FX 5500/AGP/SSE2 +NVIDIA GeForce FX 5500/AGP/SSE2/3DNOW! +NVIDIA GeForce FX 5500/PCI/SSE2 +NVIDIA GeForce FX 5500/PCI/SSE2/3DNOW! +NVIDIA GeForce FX 5600 +NVIDIA GeForce FX 5600/AGP/SSE2 +NVIDIA GeForce FX 5600/AGP/SSE2/3DNOW! +NVIDIA GeForce FX 5600XT/AGP/SSE2/3DNOW! +NVIDIA GeForce FX 5700 +NVIDIA GeForce FX 5700/AGP/SSE/3DNOW! +NVIDIA GeForce FX 5700LE/AGP/SSE +NVIDIA GeForce FX 5700LE/AGP/SSE/3DNOW! +NVIDIA GeForce FX 5800 +NVIDIA GeForce FX 5900 +NVIDIA GeForce FX 5900/AGP/SSE2 +NVIDIA GeForce FX 5900XT/AGP/SSE2 +NVIDIA GeForce FX Go5100 +NVIDIA GeForce FX Go5100/AGP/SSE2 +NVIDIA GeForce FX Go5200 +NVIDIA GeForce FX Go5200/AGP/SSE2 +NVIDIA GeForce FX Go5300 +NVIDIA GeForce FX Go5600 +NVIDIA GeForce FX Go5600/AGP/SSE2 +NVIDIA GeForce FX Go5650/AGP/SSE2 +NVIDIA GeForce FX Go5700 +NVIDIA GeForce FX Go5xxx/AGP/SSE2 +NVIDIA GeForce G 103M/PCI/SSE2 +NVIDIA GeForce G 105M/PCI/SSE2 +NVIDIA GeForce G 110M/PCI/SSE2 +NVIDIA GeForce G100/PCI/SSE2 +NVIDIA GeForce G100/PCI/SSE2/3DNOW! +NVIDIA GeForce G102M/PCI/SSE2 +NVIDIA GeForce G105M/PCI/SSE2 +NVIDIA GeForce G200/PCI/SSE2 +NVIDIA GeForce G205M/PCI/SSE2 +NVIDIA GeForce G210/PCI/SSE2 +NVIDIA GeForce G210/PCI/SSE2/3DNOW! +NVIDIA GeForce G210M/PCI/SSE2 +NVIDIA GeForce G310M/PCI/SSE2 +NVIDIA GeForce GT 120/PCI/SSE2 +NVIDIA GeForce GT 120/PCI/SSE2/3DNOW! +NVIDIA GeForce GT 120M/PCI/SSE2 +NVIDIA GeForce GT 130M/PCI/SSE2 +NVIDIA GeForce GT 140/PCI/SSE2 +NVIDIA GeForce GT 220/PCI/SSE2 +NVIDIA GeForce GT 220/PCI/SSE2/3DNOW! +NVIDIA GeForce GT 220M/PCI/SSE2 +NVIDIA GeForce GT 230/PCI/SSE2 +NVIDIA GeForce GT 230M/PCI/SSE2 +NVIDIA GeForce GT 240 +NVIDIA GeForce GT 240/PCI/SSE2 +NVIDIA GeForce GT 240/PCI/SSE2/3DNOW! +NVIDIA GeForce GT 240M/PCI/SSE2 +NVIDIA GeForce GT 320/PCI/SSE2 +NVIDIA GeForce GT 320M/PCI/SSE2 +NVIDIA GeForce GT 325M/PCI/SSE2 +NVIDIA GeForce GT 330/PCI/SSE2 +NVIDIA GeForce GT 330/PCI/SSE2/3DNOW! +NVIDIA GeForce GT 330M/PCI/SSE2 +NVIDIA GeForce GT 335M/PCI/SSE2 +NVIDIA GeForce GT 340/PCI/SSE2 +NVIDIA GeForce GT 340/PCI/SSE2/3DNOW! +NVIDIA GeForce GT 415M/PCI/SSE2 +NVIDIA GeForce GT 420/PCI/SSE2 +NVIDIA GeForce GT 420M/PCI/SSE2 +NVIDIA GeForce GT 425M/PCI/SSE2 +NVIDIA GeForce GT 430/PCI/SSE2 +NVIDIA GeForce GT 430/PCI/SSE2/3DNOW! +NVIDIA GeForce GT 435M/PCI/SSE2 +NVIDIA GeForce GT 440/PCI/SSE2 +NVIDIA GeForce GT 440/PCI/SSE2/3DNOW! +NVIDIA GeForce GT 445M/PCI/SSE2 +NVIDIA GeForce GT 520M/PCI/SSE2 +NVIDIA GeForce GT 525M/PCI/SSE2 +NVIDIA GeForce GT 540M/PCI/SSE2 +NVIDIA GeForce GT 550M/PCI/SSE2 +NVIDIA GeForce GT 555M/PCI/SSE2 +NVIDIA GeForce GTS 150/PCI/SSE2 +NVIDIA GeForce GTS 160M/PCI/SSE2 +NVIDIA GeForce GTS 240/PCI/SSE2 +NVIDIA GeForce GTS 250/PCI/SSE2 +NVIDIA GeForce GTS 250/PCI/SSE2/3DNOW! +NVIDIA GeForce GTS 250M/PCI/SSE2 +NVIDIA GeForce GTS 350M/PCI/SSE2 +NVIDIA GeForce GTS 360M/PCI/SSE2 +NVIDIA GeForce GTS 450/PCI/SSE2 +NVIDIA GeForce GTS 450/PCI/SSE2/3DNOW! +NVIDIA GeForce GTS 455/PCI/SSE2 +NVIDIA GeForce GTX 260/PCI/SSE2 +NVIDIA GeForce GTX 260/PCI/SSE2/3DNOW! +NVIDIA GeForce GTX 260M/PCI/SSE2 +NVIDIA GeForce GTX 275/PCI/SSE2 +NVIDIA GeForce GTX 280 +NVIDIA GeForce GTX 280/PCI/SSE2 +NVIDIA GeForce GTX 280M/PCI/SSE2 +NVIDIA GeForce GTX 285/PCI/SSE2 +NVIDIA GeForce GTX 295/PCI/SSE2 +NVIDIA GeForce GTX 460 SE/PCI/SSE2 +NVIDIA GeForce GTX 460 SE/PCI/SSE2/3DNOW! +NVIDIA GeForce GTX 460/PCI/SSE2 +NVIDIA GeForce GTX 460/PCI/SSE2/3DNOW! +NVIDIA GeForce GTX 460M/PCI/SSE2 +NVIDIA GeForce GTX 465/PCI/SSE2 +NVIDIA GeForce GTX 465/PCI/SSE2/3DNOW! +NVIDIA GeForce GTX 470/PCI/SSE2 +NVIDIA GeForce GTX 470/PCI/SSE2/3DNOW! +NVIDIA GeForce GTX 480/PCI/SSE2 +NVIDIA GeForce GTX 550 Ti/PCI/SSE2 +NVIDIA GeForce GTX 550 Ti/PCI/SSE2/3DNOW! +NVIDIA GeForce GTX 560 Ti/PCI/SSE2 +NVIDIA GeForce GTX 560 Ti/PCI/SSE2/3DNOW! +NVIDIA GeForce GTX 560/PCI/SSE2 +NVIDIA GeForce GTX 570/PCI/SSE2 +NVIDIA GeForce GTX 570/PCI/SSE2/3DNOW! +NVIDIA GeForce GTX 580/PCI/SSE2 +NVIDIA GeForce GTX 580/PCI/SSE2/3DNOW! +NVIDIA GeForce GTX 580M/PCI/SSE2 +NVIDIA GeForce GTX 590/PCI/SSE2 +NVIDIA GeForce Go 6 +NVIDIA GeForce Go 6100 +NVIDIA GeForce Go 6100/PCI/SSE2 +NVIDIA GeForce Go 6100/PCI/SSE2/3DNOW! +NVIDIA GeForce Go 6150/PCI/SSE2 +NVIDIA GeForce Go 6150/PCI/SSE2/3DNOW! +NVIDIA GeForce Go 6200 +NVIDIA GeForce Go 6200/PCI/SSE2 +NVIDIA GeForce Go 6400 +NVIDIA GeForce Go 6400/PCI/SSE2 +NVIDIA GeForce Go 6600 +NVIDIA GeForce Go 6600/PCI/SSE2 +NVIDIA GeForce Go 6800 +NVIDIA GeForce Go 6800 Ultra/PCI/SSE2 +NVIDIA GeForce Go 6800/PCI/SSE2 +NVIDIA GeForce Go 7200 +NVIDIA GeForce Go 7200/PCI/SSE2 +NVIDIA GeForce Go 7200/PCI/SSE2/3DNOW! +NVIDIA GeForce Go 7300 +NVIDIA GeForce Go 7300/PCI/SSE2 +NVIDIA GeForce Go 7300/PCI/SSE2/3DNOW! +NVIDIA GeForce Go 7400 +NVIDIA GeForce Go 7400/PCI/SSE2 +NVIDIA GeForce Go 7400/PCI/SSE2/3DNOW! +NVIDIA GeForce Go 7600 +NVIDIA GeForce Go 7600/PCI/SSE2 +NVIDIA GeForce Go 7600/PCI/SSE2/3DNOW! +NVIDIA GeForce Go 7700 +NVIDIA GeForce Go 7800 +NVIDIA GeForce Go 7800 GTX/PCI/SSE2 +NVIDIA GeForce Go 7900 +NVIDIA GeForce Go 7900 GS/PCI/SSE2 +NVIDIA GeForce Go 7900 GTX/PCI/SSE2 +NVIDIA GeForce Go 7950 GTX/PCI/SSE2 +NVIDIA GeForce PCX +NVIDIA GeForce2 GTS/AGP/SSE +NVIDIA GeForce2 MX/AGP/3DNOW! +NVIDIA GeForce2 MX/AGP/SSE/3DNOW! +NVIDIA GeForce2 MX/AGP/SSE2 +NVIDIA GeForce2 MX/PCI/SSE2 +NVIDIA GeForce3/AGP/SSE/3DNOW! +NVIDIA GeForce3/AGP/SSE2 +NVIDIA GeForce4 420 Go 32M/AGP/SSE2 +NVIDIA GeForce4 420 Go 32M/AGP/SSE2/3DNOW! +NVIDIA GeForce4 420 Go 32M/PCI/SSE2/3DNOW! +NVIDIA GeForce4 440 Go 64M/AGP/SSE2/3DNOW! +NVIDIA GeForce4 460 Go/AGP/SSE2 +NVIDIA GeForce4 MX 4000/AGP/SSE/3DNOW! +NVIDIA GeForce4 MX 4000/AGP/SSE2 +NVIDIA GeForce4 MX 4000/PCI/3DNOW! +NVIDIA GeForce4 MX 4000/PCI/SSE/3DNOW! +NVIDIA GeForce4 MX 4000/PCI/SSE2 +NVIDIA GeForce4 MX 420/AGP/SSE/3DNOW! +NVIDIA GeForce4 MX 420/AGP/SSE2 +NVIDIA GeForce4 MX 440 with AGP8X/AGP/SSE2 +NVIDIA GeForce4 MX 440/AGP/SSE2 +NVIDIA GeForce4 MX 440/AGP/SSE2/3DNOW! +NVIDIA GeForce4 MX 440SE with AGP8X/AGP/SSE2 +NVIDIA GeForce4 MX Integrated GPU/AGP/SSE/3DNOW! +NVIDIA GeForce4 Ti 4200 with AGP8X/AGP/SSE +NVIDIA GeForce4 Ti 4200/AGP/SSE/3DNOW! +NVIDIA GeForce4 Ti 4400/AGP/SSE2 +NVIDIA Generic +NVIDIA ION LE/PCI/SSE2 +NVIDIA ION/PCI/SSE2 +NVIDIA ION/PCI/SSE2/3DNOW! +NVIDIA MCP61/PCI/SSE2 +NVIDIA MCP61/PCI/SSE2/3DNOW! +NVIDIA MCP73/PCI/SSE2 +NVIDIA MCP79MH/PCI/SSE2 +NVIDIA MCP79MX/PCI/SSE2 +NVIDIA MCP7A-O/PCI/SSE2 +NVIDIA MCP7A-S/PCI/SSE2 +NVIDIA MCP89-EPT/PCI/SSE2 +NVIDIA N10M-GE1/PCI/SSE2 +NVIDIA N10P-GE1/PCI/SSE2 +NVIDIA N10P-GV2/PCI/SSE2 +NVIDIA N11M-GE1/PCI/SSE2 +NVIDIA N11M-GE2/PCI/SSE2 +NVIDIA N12E-GS-A1/PCI/SSE2 +NVIDIA NB9M-GE/PCI/SSE2 +NVIDIA NB9M-GE1/PCI/SSE2 +NVIDIA NB9M-GS/PCI/SSE2 +NVIDIA NB9M-NS/PCI/SSE2 +NVIDIA NB9P-GE1/PCI/SSE2 +NVIDIA NB9P-GS/PCI/SSE2 +NVIDIA NV17/AGP/3DNOW! +NVIDIA NV17/AGP/SSE2 +NVIDIA NV34 +NVIDIA NV35 +NVIDIA NV36/AGP/SSE/3DNOW! +NVIDIA NV36/AGP/SSE2 +NVIDIA NV41/PCI/SSE2 +NVIDIA NV43 +NVIDIA NV44 +NVIDIA NVIDIA GeForce 210 OpenGL Engine +NVIDIA NVIDIA GeForce 320M OpenGL Engine +NVIDIA NVIDIA GeForce 7300 GT OpenGL Engine +NVIDIA NVIDIA GeForce 7600 GT OpenGL Engine +NVIDIA NVIDIA GeForce 8600M GT OpenGL Engine +NVIDIA NVIDIA GeForce 8800 GS OpenGL Engine +NVIDIA NVIDIA GeForce 8800 GT OpenGL Engine +NVIDIA NVIDIA GeForce 9400 OpenGL Engine +NVIDIA NVIDIA GeForce 9400M OpenGL Engine +NVIDIA NVIDIA GeForce 9500 GT OpenGL Engine +NVIDIA NVIDIA GeForce 9600M GT OpenGL Engine +NVIDIA NVIDIA GeForce GT 120 OpenGL Engine +NVIDIA NVIDIA GeForce GT 130 OpenGL Engine +NVIDIA NVIDIA GeForce GT 220 OpenGL Engine +NVIDIA NVIDIA GeForce GT 230M OpenGL Engine +NVIDIA NVIDIA GeForce GT 240M OpenGL Engine +NVIDIA NVIDIA GeForce GT 330M OpenGL Engine +NVIDIA NVIDIA GeForce GT 420M OpenGL Engine +NVIDIA NVIDIA GeForce GT 425M OpenGL Engine +NVIDIA NVIDIA GeForce GT 430 OpenGL Engine +NVIDIA NVIDIA GeForce GT 440 OpenGL Engine +NVIDIA NVIDIA GeForce GT 540M OpenGL Engine +NVIDIA NVIDIA GeForce GTS 240 OpenGL Engine +NVIDIA NVIDIA GeForce GTS 250 OpenGL Engine +NVIDIA NVIDIA GeForce GTS 450 OpenGL Engine +NVIDIA NVIDIA GeForce GTX 285 OpenGL Engine +NVIDIA NVIDIA GeForce GTX 460 OpenGL Engine +NVIDIA NVIDIA GeForce GTX 460M OpenGL Engine +NVIDIA NVIDIA GeForce GTX 465 OpenGL Engine +NVIDIA NVIDIA GeForce GTX 470 OpenGL Engine +NVIDIA NVIDIA GeForce GTX 480 OpenGL Engine +NVIDIA NVIDIA GeForce Pre-Release ION OpenGL Engine +NVIDIA NVIDIA GeForce4 OpenGL Engine +NVIDIA NVIDIA NV34MAP OpenGL Engine +NVIDIA NVIDIA Quadro 4000 OpenGL Engine +NVIDIA NVIDIA Quadro FX 4800 OpenGL Engine +NVIDIA NVS 2100M/PCI/SSE2 +NVIDIA NVS 300/PCI/SSE2 +NVIDIA NVS 3100M/PCI/SSE2 +NVIDIA NVS 4100/PCI/SSE2/3DNOW! +NVIDIA NVS 4200M/PCI/SSE2 +NVIDIA NVS 5100M/PCI/SSE2 +NVIDIA PCI +NVIDIA Quadro 2000/PCI/SSE2 +NVIDIA Quadro 4000 +NVIDIA Quadro 4000 OpenGL Engine +NVIDIA Quadro 4000/PCI/SSE2 +NVIDIA Quadro 5000/PCI/SSE2 +NVIDIA Quadro 5000M/PCI/SSE2 +NVIDIA Quadro 600 +NVIDIA Quadro 600/PCI/SSE2 +NVIDIA Quadro 600/PCI/SSE2/3DNOW! +NVIDIA Quadro 6000 +NVIDIA Quadro 6000/PCI/SSE2 +NVIDIA Quadro CX/PCI/SSE2 +NVIDIA Quadro DCC +NVIDIA Quadro FX +NVIDIA Quadro FX 1100/AGP/SSE2 +NVIDIA Quadro FX 1400/PCI/SSE2 +NVIDIA Quadro FX 1500 +NVIDIA Quadro FX 1500M/PCI/SSE2 +NVIDIA Quadro FX 1600M/PCI/SSE2 +NVIDIA Quadro FX 1700 +NVIDIA Quadro FX 1700M/PCI/SSE2 +NVIDIA Quadro FX 1800 +NVIDIA Quadro FX 1800/PCI/SSE2 +NVIDIA Quadro FX 1800M/PCI/SSE2 +NVIDIA Quadro FX 2500M/PCI/SSE2 +NVIDIA Quadro FX 2700M/PCI/SSE2 +NVIDIA Quadro FX 2800M/PCI/SSE2 +NVIDIA Quadro FX 3400 +NVIDIA Quadro FX 3450 +NVIDIA Quadro FX 3450/4000 SDI/PCI/SSE2 +NVIDIA Quadro FX 3500 +NVIDIA Quadro FX 3500M/PCI/SSE2 +NVIDIA Quadro FX 360M/PCI/SSE2 +NVIDIA Quadro FX 370 +NVIDIA Quadro FX 370/PCI/SSE2 +NVIDIA Quadro FX 3700 +NVIDIA Quadro FX 3700M/PCI/SSE2 +NVIDIA Quadro FX 370M/PCI/SSE2 +NVIDIA Quadro FX 3800 +NVIDIA Quadro FX 3800M/PCI/SSE2 +NVIDIA Quadro FX 4500 +NVIDIA Quadro FX 4600 +NVIDIA Quadro FX 4800 +NVIDIA Quadro FX 4800/PCI/SSE2 +NVIDIA Quadro FX 560 +NVIDIA Quadro FX 5600 +NVIDIA Quadro FX 570 +NVIDIA Quadro FX 570/PCI/SSE2 +NVIDIA Quadro FX 570M/PCI/SSE2 +NVIDIA Quadro FX 580/PCI/SSE2 +NVIDIA Quadro FX 770M/PCI/SSE2 +NVIDIA Quadro FX 880M +NVIDIA Quadro FX 880M/PCI/SSE2 +NVIDIA Quadro FX Go700/AGP/SSE2 +NVIDIA Quadro NVS +NVIDIA Quadro NVS 110M/PCI/SSE2 +NVIDIA Quadro NVS 130M/PCI/SSE2 +NVIDIA Quadro NVS 135M/PCI/SSE2 +NVIDIA Quadro NVS 140M/PCI/SSE2 +NVIDIA Quadro NVS 150M/PCI/SSE2 +NVIDIA Quadro NVS 160M/PCI/SSE2 +NVIDIA Quadro NVS 210S/PCI/SSE2/3DNOW! +NVIDIA Quadro NVS 285/PCI/SSE2 +NVIDIA Quadro NVS 290/PCI/SSE2 +NVIDIA Quadro NVS 295/PCI/SSE2 +NVIDIA Quadro NVS 320M/PCI/SSE2 +NVIDIA Quadro NVS 55/280 PCI/PCI/SSE2 +NVIDIA Quadro NVS/PCI/SSE2 +NVIDIA Quadro PCI-E Series/PCI/SSE2/3DNOW! +NVIDIA Quadro VX 200/PCI/SSE2 +NVIDIA Quadro/AGP/SSE2 +NVIDIA Quadro2 +NVIDIA Quadro4 +NVIDIA RIVA TNT +NVIDIA RIVA TNT2/AGP/SSE2 +NVIDIA RIVA TNT2/PCI/3DNOW! +NVIDIA nForce +NVIDIA unknown board/AGP/SSE2 +NVIDIA unknown board/PCI/SSE2 +NVIDIA unknown board/PCI/SSE2/3DNOW! +Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 5670 OpenGL Engine +Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 5750 OpenGL Engine +Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 5770 OpenGL Engine +Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 6490M OpenGL Engine +Parallels and ATI Technologies Inc. Parallels using ATI Radeon HD 6750M OpenGL Engine +Parallels and Intel Inc. 3D-Analyze v2.3 - http://www.tommti-systems.com +Parallels and Intel Inc. Parallels using Intel HD Graphics 3000 OpenGL Engine +Parallels and NVIDIA Parallels using NVIDIA GeForce 320M OpenGL Engine +Parallels and NVIDIA Parallels using NVIDIA GeForce 9400 OpenGL Engine +Parallels and NVIDIA Parallels using NVIDIA GeForce GT 120 OpenGL Engine +Parallels and NVIDIA Parallels using NVIDIA GeForce GT 330M OpenGL Engine +Radeon RV350 on Gallium +S3 +S3 Graphics VIA/S3G UniChrome IGP/MMX/K3D +S3 Graphics VIA/S3G UniChrome Pro IGP/MMX/SSE +S3 Graphics, Incorporated ProSavage/Twister +S3 Graphics, Incorporated S3 Graphics Chrome9 HC +S3 Graphics, Incorporated S3 Graphics DeltaChrome +S3 Graphics, Incorporated VIA Chrome9 HC IGP +SiS +SiS 661 VGA +SiS 662 VGA +SiS 741 VGA +SiS 760 VGA +SiS 761GX VGA +SiS Mirage Graphics3 +Trident +Tungsten Graphics +Tungsten Graphics, Inc Mesa DRI 865G GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 865G GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 915G GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 915G GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 915GM GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 915GM GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 915GM GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 945G +Tungsten Graphics, Inc Mesa DRI 945G GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 945G GEM 20100330 DEVELOPMENT +Tungsten Graphics, Inc Mesa DRI 945G GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 945GM GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 945GM GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 945GM GEM 20100328 2010Q1 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 945GM GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 945GME x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 945GME 20061017 +Tungsten Graphics, Inc Mesa DRI 945GME GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 945GME GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 945GME GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 965GM GEM 20090326 2009Q1 RC2 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 965GM GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 965GM GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI 965GM GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI G33 20061017 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI G33 GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI G33 GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI G41 GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI G41 GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI GMA500 20081116 - 5.0.1.0046 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI IGD GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI IGD GEM 20100330 DEVELOPMENT +Tungsten Graphics, Inc Mesa DRI IGD GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI IGDNG_D GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI Ironlake Desktop GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI Ironlake Mobile GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset 20080716 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset GEM 20090712 2009Q2 RC3 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset GEM 20091221 2009Q4 x86/MMX/SSE2 +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset GEM 20100328 2010Q1 +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset GEM 20100330 DEVELOPMENT +Tungsten Graphics, Inc Mesa DRI Mobile Intelå¨ GM45 Express Chipset GEM 20100330 DEVELOPMENT x86/MMX/SSE2 +Tungsten Graphics, Inc. Mesa DRI R200 (RV280 5964) 20090101 x86/MMX+/3DNow!+/SSE2 TCL DRI2 +VIA +VMware, Inc. Gallium 0.3 on SVGA3D; build: RELEASE; +VMware, Inc. Gallium 0.4 on i915 (chipset: 945GM) +VMware, Inc. Gallium 0.4 on llvmpipe +VMware, Inc. Gallium 0.4 on softpipe +X.Org Gallium 0.4 on AMD BARTS +X.Org Gallium 0.4 on AMD CEDAR +X.Org Gallium 0.4 on AMD HEMLOCK +X.Org Gallium 0.4 on AMD JUNIPER +X.Org Gallium 0.4 on AMD REDWOOD +X.Org Gallium 0.4 on AMD RS780 +X.Org Gallium 0.4 on AMD RS880 +X.Org Gallium 0.4 on AMD RV610 +X.Org Gallium 0.4 on AMD RV620 +X.Org Gallium 0.4 on AMD RV630 +X.Org Gallium 0.4 on AMD RV635 +X.Org Gallium 0.4 on AMD RV710 +X.Org Gallium 0.4 on AMD RV730 +X.Org Gallium 0.4 on AMD RV740 +X.Org Gallium 0.4 on AMD RV770 +X.Org R300 Project Gallium 0.4 on ATI R300 +X.Org R300 Project Gallium 0.4 on ATI R580 +X.Org R300 Project Gallium 0.4 on ATI RC410 +X.Org R300 Project Gallium 0.4 on ATI RS482 +X.Org R300 Project Gallium 0.4 on ATI RS600 +X.Org R300 Project Gallium 0.4 on ATI RS690 +X.Org R300 Project Gallium 0.4 on ATI RV350 +X.Org R300 Project Gallium 0.4 on ATI RV370 +X.Org R300 Project Gallium 0.4 on ATI RV410 +X.Org R300 Project Gallium 0.4 on ATI RV515 +X.Org R300 Project Gallium 0.4 on ATI RV530 +X.Org R300 Project Gallium 0.4 on ATI RV570 +X.Org R300 Project Gallium 0.4 on R420 +X.Org R300 Project Gallium 0.4 on R580 +X.Org R300 Project Gallium 0.4 on RC410 +X.Org R300 Project Gallium 0.4 on RS480 +X.Org R300 Project Gallium 0.4 on RS482 +X.Org R300 Project Gallium 0.4 on RS600 +X.Org R300 Project Gallium 0.4 on RS690 +X.Org R300 Project Gallium 0.4 on RS740 +X.Org R300 Project Gallium 0.4 on RV350 +X.Org R300 Project Gallium 0.4 on RV370 +X.Org R300 Project Gallium 0.4 on RV410 +X.Org R300 Project Gallium 0.4 on RV515 +X.Org R300 Project Gallium 0.4 on RV530 +XGI +nouveau Gallium 0.4 on NV34 +nouveau Gallium 0.4 on NV36 +nouveau Gallium 0.4 on NV46 +nouveau Gallium 0.4 on NV49 +nouveau Gallium 0.4 on NV4A +nouveau Gallium 0.4 on NV4B +nouveau Gallium 0.4 on NV4E +nouveau Gallium 0.4 on NV50 +nouveau Gallium 0.4 on NV84 +nouveau Gallium 0.4 on NV86 +nouveau Gallium 0.4 on NV92 +nouveau Gallium 0.4 on NV94 +nouveau Gallium 0.4 on NV96 +nouveau Gallium 0.4 on NV98 +nouveau Gallium 0.4 on NVA0 +nouveau Gallium 0.4 on NVA3 +nouveau Gallium 0.4 on NVA5 +nouveau Gallium 0.4 on NVA8 +nouveau Gallium 0.4 on NVAA +nouveau Gallium 0.4 on NVAC diff --git a/indra/newview/tests/llcapabilitylistener_test.cpp b/indra/newview/tests/llcapabilitylistener_test.cpp index d691bb6c44..2ad08dc1f3 100644 --- a/indra/newview/tests/llcapabilitylistener_test.cpp +++ b/indra/newview/tests/llcapabilitylistener_test.cpp @@ -114,6 +114,7 @@ namespace tut regionListener("testCapabilityListener", NULL, provider, LLUUID(), LLUUID()), regionPump(regionListener.getCapAPI()) { + LLCurl::initClass(); provider.setCapability("good", server + "capability-test"); provider.setCapability("fail", server + "fail"); } diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 450d274fd7..8aa94616d6 100644 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -263,25 +263,38 @@ class WindowsManifest(ViewerManifest): #self.disable_manifest_check() self.path(src="../viewer_components/updater/scripts/windows/update_install.bat", dst="update_install.bat") - # Get shared libs from the shared libs staging directory if self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration']), dst=""): #self.enable_crt_manifest_check() - + # Get llcommon and deps. If missing assume static linkage and continue. try: self.path('llcommon.dll') self.path('libapr-1.dll') self.path('libaprutil-1.dll') self.path('libapriconv-1.dll') + except RuntimeError, err: print err.message print "Skipping llcommon.dll (assuming llcommon was linked statically)" #self.disable_manifest_check() + # Mesh 3rd party libs needed for auto LOD and collada reading + try: + if self.args['configuration'].lower() == 'debug': + self.path("libcollada14dom22-d.dll") + else: + self.path("libcollada14dom22.dll") + + self.path("glod.dll") + except RuntimeError, err: + print err.message + print "Skipping COLLADA and GLOD libraries (assumming linked statically)" + + # Get fmod dll, continue if missing try: self.path("fmod.dll") @@ -332,7 +345,7 @@ class WindowsManifest(ViewerManifest): self.path("featuretable_xp.txt") #self.enable_no_crt_manifest_check() - + # Media plugins - QuickTime if self.prefix(src='../media_plugins/quicktime/%s' % self.args['configuration'], dst="llplugin"): self.path("media_plugin_quicktime.dll") @@ -646,6 +659,8 @@ class DarwinManifest(ViewerManifest): "libaprutil-1.0.dylib", "libexpat.1.5.2.dylib", "libexception_handler.dylib", + "libGLOD.dylib", + "libcollada14dom.dylib" ): self.path(os.path.join(libdir, libfile), libfile) @@ -677,6 +692,8 @@ class DarwinManifest(ViewerManifest): "libaprutil-1.0.dylib", "libexpat.1.5.2.dylib", "libexception_handler.dylib", + "libGLOD.dylib", + "libcollada14dom.dylib" ): target_lib = os.path.join('../../..', libfile) self.run_command("ln -sf %(target)r %(link)r" % @@ -716,6 +733,7 @@ class DarwinManifest(ViewerManifest): self.run_command('strip -S %(viewer_binary)r' % { 'viewer_binary' : self.dst_path_of('Contents/MacOS/Second Life')}) + def copy_finish(self): # Force executable permissions to be set for scripts # see CHOP-223 and http://mercurial.selenic.com/bts/issue1802 @@ -946,12 +964,15 @@ class Linux_i686Manifest(LinuxManifest): self.path("libbreakpad_client.so.0.0.0") self.path("libbreakpad_client.so.0") self.path("libbreakpad_client.so") + self.path("libcollada14dom.so") self.path("libdb-5.1.so") self.path("libdb-5.so") self.path("libdb.so") self.path("libcrypto.so.1.0.0") self.path("libexpat.so.1.5.2") self.path("libssl.so.1.0.0") + self.path("libglod.so") + self.path("libminizip.so") self.path("libuuid.so") self.path("libuuid.so.16") self.path("libuuid.so.16.0.22") @@ -966,6 +987,9 @@ class Linux_i686Manifest(LinuxManifest): self.path("libopenal.so", "libopenal.so.1") self.path("libopenal.so", "libvivoxoal.so.1") # vivox's sdk expects this soname self.path("libfontconfig.so.1.4.4") + self.path("libtcmalloc.so", "libtcmalloc.so") #formerly called google perf tools + self.path("libtcmalloc.so.0", "libtcmalloc.so.0") #formerly called google perf tools + self.path("libtcmalloc.so.0.1.0", "libtcmalloc.so.0.1.0") #formerly called google perf tools try: self.path("libfmod-3.75.so") pass @@ -986,6 +1010,11 @@ class Linux_i686Manifest(LinuxManifest): self.path("libvivoxplatform.so") self.end_prefix("lib") + if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer(): + print "* Going strip-crazy on the packaged binaries, since this is a RELEASE build" + self.run_command("find %(d)r/bin %(d)r/lib -type f \\! -name update_install | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure + + class Linux_x86_64Manifest(LinuxManifest): def construct(self): super(Linux_x86_64Manifest, self).construct() |