Compare commits

..

540 Commits

Author SHA1 Message Date
Shyotl
43aa145c94 It's silly that this was necessary... but it was. AMD... :( 2015-02-25 21:11:06 -06:00
Shyotl
1608ed43c1 Release 1.8.6 2014-09-04 03:20:01 -05:00
Inusaito Sayori
fa103a69f9 I like jackals. 2014-09-03 21:49:08 -04:00
Inusaito Sayori
f8520f9dd3 Em Dash wants build tools to focus properly when the build button is clicked.
If the world is in focus and build button is pressed without the build floater open, don't bother focusing.
If a floater is in focus and build button is pressed without the build floater open, focus the build floater
If the build floater is in the background and the button is pressed, focus the build floater.
If the build floater is in focus and the button is pressed, close the build floater.
If the build floater is  not in focus but nothing else is, close the build floater.
2014-09-03 19:41:07 -04:00
Inusaito Sayori
3a372afc0e Add Render muted avatars check to System->Security & Privacy Preferences
Redefaulted LiruLegacyDisplayMuteds to false due to (at least) two alpha testers noticing it and wanting it back how it is in the current release (since 1.7.0).
True was to get back to the old ways of v1, but it's okay to be false by default, better now since it's exposed.

Also irrelevant tiny voice cleanup from Spatters.
2014-09-03 08:28:16 -04:00
Inusaito Sayori
95d6bec68f Maximum bandwidth is apparently 10000 on SL Viewer, match that. 2014-09-03 08:28:11 -04:00
Inusaito Sayori
56f2e20cb4 Feature Request: Add LiruResizeRootWithScreen to prevent ui getting messed up when the window is resized
This is not complete, and it should only be used if you know what you're getting into.
2014-09-03 08:28:06 -04:00
Shyotl
4cbcaba7f2 Merge branch 'master' of git@github.com:Shyotl/SingularityViewer.git 2014-09-03 01:47:43 -05:00
Shyotl
aeeca6e2c0 llcommon.dll doer faster. (set /LTCG and /GL) 2014-09-03 01:45:47 -05:00
Inusaito Sayori
74704d0d2a Fix crash signature 608
This was a crash in LLPanelDirClassified::postBuild(), on the line changed here, probably accessng null pointer.
There are probably a few other signatures for this in our database.
2014-09-02 10:53:36 -04:00
Shyotl
0b384bdd72 Merge branch 'master' of git@github.com:Shyotl/SingularityViewer.git 2014-09-02 02:57:28 -05:00
Shyotl
e9cf3a6806 Fix tiled snapshots. Also, LLRender::genRot takes degrees, not radians. 2014-09-02 02:53:10 -05:00
Shyotl
c5f9068664 Merge branch 'master' of git@github.com:Shyotl/SingularityViewer.git 2014-09-01 00:49:05 -05:00
Shyotl
992bbbba1c A bit of cleanup, and call subprocess.Popen with shell=True. 2014-09-01 00:47:39 -05:00
Shyotl
fe9dd63558 Merge branch 'master' of git@github.com:Shyotl/SingularityViewer.git 2014-08-31 04:58:29 -05:00
Shyotl
8e45003c27 Packaging bugs. I'm drowning in them. (use subprocess.Popen instead of os.popen) 2014-08-31 04:56:55 -05:00
Shyotl
f53d824e07 Merge branch 'master' of https://github.com/Lirusaito/SingularityViewer.git 2014-08-31 00:05:11 -05:00
Shyotl
259670af85 Merge branch 'master' of git@github.com:Shyotl/SingularityViewer.git 2014-08-31 00:04:59 -05:00
Shyotl
c7e9430f99 Avoid erroneously creating 'About Land' instance. Also avoid issuing 'ParcelPropertiesRequest' excessively. 2014-08-30 23:48:56 -05:00
Shyotl
afe573d2eb Spaces in path... and nsi script... issues. 2014-08-30 23:47:32 -05:00
Shyotl
547d9817db Replace \t with spaces in develop.py. 2014-08-30 18:57:12 -05:00
Shyotl
9c63243fe7 Fix issue with planar face alignment. 2014-08-30 18:56:27 -05:00
Shyotl
5535ba6b47 Fix issue with paths with spaces, in viewer_manifest.py 2014-08-30 16:25:46 -05:00
Inusaito Sayori
52a80f98ed Nomade's touches to french Object Weights Floater
Supposedly fixes a french crash.
2014-08-30 06:09:33 -04:00
Inusaito Sayori
9600319094 Add debug setting LiruHighlightNewInventory to prevent selection being changed on accepting new inventory. 2014-08-27 07:58:08 -04:00
Aleric Inglewood
9b930c8716 Don't set a SSL ctx callback when we don't use openSSL. 2014-08-26 19:19:06 +02:00
Aleric Inglewood
eb0d2e5b2c libcurl-gnutls.so (debian) links with libgnutls.so
In that case we DO reach the assert here.
I verified that curl_global_init() indeed calls gnutls_global_init().
2014-08-26 01:35:13 +02:00
Aleric Inglewood
5e2722475a This header uses LLMatrix4a, not LLMatrix4. 2014-08-26 00:29:59 +02:00
Aleric Inglewood
b1e406731d Merge remote-tracking branch 'singu/master' 2014-08-25 18:39:46 +02:00
Aleric Inglewood
8c6d51cb71 No longer support DEBUG_CURLIO when libcwd isn't installed. 2014-08-25 17:58:45 +02:00
Shyotl
4b205084f8 Fix develop.py 'build' command. 2014-08-23 20:52:01 -05:00
Shyotl
eb910b0bae Use /Zm140 for all windows builds. 2014-08-23 20:50:56 -05:00
Shyotl
09a6a1f259 Merge branch 'master' of git@github.com:Shyotl/SingularityViewer.git 2014-08-23 01:37:48 -05:00
Shyotl
315618a18b Fixed materials specularmap + glossiness=0 combination. 2014-08-23 01:34:25 -05:00
Inusaito Sayori
59af03695b Fix debug settings boolean to work with the radiogroup update. 2014-08-23 00:24:57 -04:00
Inusaito Sayori
e1851f7b5b Sync llwindowwin32 with Alchemy. 2014-08-22 21:47:52 -04:00
Inusaito Sayori
a126b4003f Fix the first double click of every session failing. 2014-08-22 21:43:48 -04:00
Inusaito Sayori
9067de26ac Seriously, what is logic? 2014-08-22 17:32:28 -04:00
Inusaito Sayori
260c5345fd Logic, what's that?! 2014-08-22 16:16:08 -04:00
Inusaito Sayori
e3dd05ef21 Fix the broken radio groups
Now can I go to sleep, Papa?
...
But I did my chores and fixed the bugs.
...
YAY! *runs off to bed*
2014-08-22 07:14:19 -04:00
Inusaito Sayori
9379bcedf9 A propos de [SHORT_APP_NAME] 2014-08-22 06:02:03 -04:00
Inusaito Sayori
2c91210d6e Is almost zero approximately zero? 2014-08-22 06:01:45 -04:00
Shyotl
f721d935e4 Merge branch 'master' of https://github.com/Lirusaito/SingularityViewer.git 2014-08-22 03:55:21 -05:00
Shyotl
66597cade3 Use [SHORT_APP_NAME] xui/de/floater_about.xml as per liru request. 2014-08-22 03:52:13 -05:00
Shyotl
3c5f39e26a Use a dynamic buffer for LLMeshHeaderResponder. 2014-08-22 03:41:00 -05:00
Shyotl
24e3176f1b Fixed some odd initialization oddness in develop.py. Also changed win64 build targetdir to build-vc###-Win64 2014-08-22 03:38:49 -05:00
Shyotl
e59757e3e8 Clean up a few harmless compiler warnings (signed/unsigned, double to float) 2014-08-20 19:43:32 -05:00
Shyotl
282de8c7f5 Only use LLAvatarJoint when necessary, else LLJoint 2014-08-20 19:40:31 -05:00
Shyotl
541021f29c Fix relwithdebug. 2014-08-20 17:42:48 -05:00
Inusaito Sayori
e01b9dcd39 If it's not a translation, don't change APP_NAME and related strings in strings.xml 2014-08-19 20:06:43 -04:00
Inusaito Sayori
8d4567b930 Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer 2014-08-19 19:55:34 -04:00
Inusaito Sayori
6f6988a487 Add "Move to Lost And Found" option for displaced inventory
Inspired by the work of Kitty Barnett
Fixes Issue 1337: Corrupted Inventory
Fixes Issue 1625: Unattainable inventory is Outside of My Inventoy and no options to move back to My Inventory
Fixes Issue 1580: Deleted folders showing outside of inventory folder.
2014-08-19 19:52:24 -04:00
Inusaito Sayori
435ab2ce77 Modernize llradiogroup, allows v3-style attributes: value, label for radio_item; allow_deselect for radio_group.
LLRadioCtrl moves into llradiogroup.cpp
2014-08-19 19:42:42 -04:00
Shyotl
1afd723c4e Post-merge fixup. 2014-08-19 01:36:24 -05:00
Shyotl
b09f7f5ac7 Merge branch 'master' of https://github.com/Lirusaito/SingularityViewer.git
Conflicts:
	indra/newview/llviewerobjectlist.cpp
	indra/newview/llviewerpartsim.cpp
2014-08-18 23:55:03 -05:00
Shyotl
1b3f0f9ec0 Manual texture reloading now re-fetches materials-related textures. 2014-08-18 23:47:37 -05:00
Shyotl
d1d68721ac Pulled mesh header info parsing and VFS fetching into their own procedures to remove duplicate code. 2014-08-18 17:16:45 -05:00
Inusaito Sayori
2f4afe5b68 Fix About [APP_NAME] to read About [SHORT_APP_NAME] 2014-08-18 17:58:45 -04:00
Shyotl
47fcc70756 Write initial mesh data to file in larger chunks. Reduces file i/o stalls. 2014-08-18 00:54:46 -05:00
Shyotl
0e86b696c5 Added more verbose statemachine debug output. 2014-08-18 00:54:01 -05:00
Shyotl
54f05b409c Always use dynamic_cast when casting from an LLJoint* 2014-08-13 18:04:24 -05:00
Inusaito Sayori
350dff9b98 Cinder made some logic enhancements to hippogridmanager.cpp, I've picked them up~ 2014-08-13 02:34:52 -04:00
Inusaito Sayori
f198221812 System preferences and Menu translation updates by Nomade Zhao. 2014-08-13 02:04:17 -04:00
Inusaito Sayori
dee08b4216 Spanish translation pruning, also Manage ban list translation by Damian. 2014-08-13 02:02:34 -04:00
Damian Zhaoying
e02d074a85 Merge remote-tracking branch 'Liru/master' 2014-08-11 18:25:32 -03:00
Damian Zhaoying
8e2da87b97 Update spanish translations to reflect a lot of changes and adds in last Alphas builds. 2014-08-11 18:22:34 -03:00
Inusaito Sayori
2deba06212 Missed a spot with the date column for group bans
I'm thinking of putting a setting here instead of hardcoding the date format, actually, but for now this is good enough.
2014-08-11 14:36:37 -04:00
Latif Khalifa
a6ac8e1f71 Workaround for clang bugs 2014-08-09 11:24:22 -04:00
Inusaito Sayori
69436a9032 Add french translation for connect to neighboring regions from Nomade Zhao 2014-08-09 10:50:24 -04:00
Inusaito Sayori
50d91d13be Allow dragging and dropping to attached objects
There's now a guard serverside that'll prevent the situation that would cause things to break in the past, so there's no reason not to have this.
2014-08-08 16:26:40 -04:00
Inusaito Sayori
54a6db146e Upon further consideration and a bit of feedback, the new matching common characters behavior of gesture autocomplete is probably bad, I've commented it out and brought back the old code. 2014-08-08 14:57:14 -04:00
Inusaito Sayori
3b31fe91a6 Address Deltek's concern that the Open Attachment button wasn't changing text to just say save when the object is not the openable type. 2014-08-08 14:52:52 -04:00
Inusaito Sayori
90c5219be9 Move Media Filter from the View menu to the Singularity menu.
Moves Media Filter in all translations, no need for translators to worry~
Nomade, please translate the Singularity menu at your discretion.. in menu_viewer.xml
2014-08-08 08:43:24 -04:00
Inusaito Sayori
669fe29173 Initialize members of LLMediaFilter, fixes win64 filter being broken. 2014-08-08 08:26:48 -04:00
Inusaito Sayori
d7d06c8234 Oh, and this one too, maybe it is fixed now? 2014-08-08 07:07:51 -04:00
Inusaito Sayori
4754c1322d This should probably be a size_t, perhaps this fixes the win64 mediafilter bug. 2014-08-07 21:56:25 -04:00
Inusaito Sayori
acb093c277 Media Filter code cleanup 2014-08-07 20:37:03 -04:00
Inusaito Sayori
21d54edeb9 Per-slider reset buttons? Sure.
Adds callback to registrar: "Prefs.Reset", pass debug setting name as parameter.
2014-08-07 20:29:12 -04:00
Inusaito Sayori
20ea0968da Feature Request from friti: Add a reset button to Depth of Field tab of graphics.
Actually should've committed this last night. X3
2014-08-07 08:31:26 -04:00
Shyotl
398d8c52a2 Minor cleanup. 2014-08-07 01:57:11 -05:00
Lirusaito
f82d12d381 Fix linker errors on linux after merging Shyotl 2014-08-07 01:54:56 -05:00
Lirusaito
91ee5724ca Fix compile errors and warnings on linux after merging Shyotl. 2014-08-07 01:54:45 -05:00
Inusaito Sayori
a82443f271 Make sure that we have a token when doing sscanf in llinventory.cpp and llviewerobject.cpp
Guards against opensim grids that may leave new/blank lines of sorts after their message blocks
2014-08-06 23:29:23 -04:00
Cinder Biscuits
1cd0b70055 Fix filling in MediaAlert notification. 2014-08-06 16:34:23 -04:00
Inusaito Sayori
8f8904ad0f Feature Request: Autoselect the parcel you are on for about land floater when there's no active parcel selection. 2014-08-05 23:25:39 -04:00
Shyotl
e975e389df Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git
Conflicts:
	indra/newview/llnetmap.cpp
2014-08-05 18:17:13 -05:00
Inusaito Sayori
d3242393e0 Better default rect for those two new v3 floaters (destinations and avatar picker) from Latif. 2014-08-05 13:35:42 -04:00
Inusaito Sayori
ce7d0e81bd Toggle control_name in <floater/>'s like booleans for visibility, if they exist.
Look out for this in the UI Overhaul merge, this is gonna clash big time.
2014-08-05 12:48:28 -04:00
Inusaito Sayori
0cf16e6f8f Allow edit menu shortcuts to work while on login screen~ 2014-08-05 11:20:58 -04:00
Inusaito Sayori
0ab395794e [Warnings] "One more," says friti; "One more," fixes Liru. 2014-08-05 00:57:26 -04:00
Inusaito Sayori
ac06a8394b I'm a sillyfolf, here's a compile fix. 2014-08-05 00:48:13 -04:00
Inusaito Sayori
46dd1ad154 Merge branch 'master' of git://github.com/Shyotl/SingularityViewer 2014-08-05 00:34:06 -04:00
Inusaito Sayori
e57a7b6f3b [Warnings] Fix the "no biggie" warnings
Thanks to friti for providing the pastebin~
2014-08-05 00:31:52 -04:00
Inusaito Sayori
409128b07f [Warnings] enumeral mismatch in conditional expression: ‘DS3Keys’ vs ‘XBoxKeys’ [-Wenum-compare]
Thought I covered this one already...
2014-08-05 00:31:03 -04:00
Inusaito Sayori
fd562061ee Update simple codeless floater behavior
Such that floater's named according to their filename will now close if they were frontmost
making their menu entries and buttons, toggly.

This effects the behavior of the toolbar preferences floater, the Favorites floater, and the My Outfits floater.
(and any such simple extensions made by forks and those that will come in the future)
2014-08-04 23:36:47 -04:00
Inusaito Sayori
c6a7dc8f9c Nomade's update to Camera and Input preferences. 2014-08-04 23:32:44 -04:00
Shyotl
5275f7e852 Re-determine spatial groups for hud attachments upon teleport. Fixes missing prim issue. 2014-08-03 18:52:06 -05:00
Inusaito Sayori
6ec19e4630 Minor edits to french translation. 2014-08-01 09:01:48 -04:00
Inusaito Sayori
690ac8d4b1 Ooooops, broke showcase tab on SL, needs to expandURLSubstitutions(). 2014-08-01 05:56:20 -04:00
Inusaito Sayori
7ae1cd33be Add debug setting LiruShowTransactionThreshold for filtering out low amount transaction notifications. 2014-08-01 05:21:14 -04:00
Inusaito Sayori
a7c6c184da Now that I'm more awake, this is a far better solution for the default sim features issues.
Adds const Type mDefaultValue reset() and getDefault() to SignaledType
Cleans up code by not needing to reset to the default by value every time, nice template function to do this~
Leaves in hg boolean, but commented out in case opensim ever decides to make that a reality.
2014-07-31 22:50:02 -04:00
Inusaito Sayori
29d6b423a3 Toolbar prefs was filling up quick, gave it an extra 20 pixels of height and reordered. 2014-07-31 14:52:41 -04:00
Inusaito Sayori
b3590c5ae6 Add Default Avatar Picker Floater (World->Default Avatars)
Default Avatars button option added to Toolbar prefs.
Adds debug setting ToolbarVisibleAvatar
Hooks into "avatar_picker_url" login response on opensim.
Also includes hooking up of DestinationGuideShown to startup, which was left unstaged from the initial commit of the Destination Guide.
2014-07-31 14:45:27 -04:00
Inusaito Sayori
67f549d86d SimFeaturesHandler: Work around grids where OpenSimExtras aren't implemented by not overriding hg strings there. 2014-07-31 11:29:26 -04:00
Inusaito Sayori
9096265bff Possible solution for Issue 954: Singularity Alpha Build 4701 EULA file missing on first login. 2014-07-31 11:20:17 -04:00
Inusaito Sayori
ce265b3948 Add Destination Guide
Adds llfloaterdestinations.* and floater_destinations.xml (needs translations, but not really)
Adds GenericErrorPageURL, DestinationGuideURL (not persistent), DestinationGuideShown, and DestinationGuideRect to debug settings
Removes ShowcaseURLDefault in favor of DestinationGuideURL from upstream.
Also Adds ToolbarVisibleDestinations for the toolbar button, but I'll need to set up a nice way to make the button invisible when the url is empty before adding it to the gui... maybe.. or maybe it's just not important.

This commit comes with support for dynamically changing destination guide page based on opensimextras simulator features cap
2014-07-31 10:07:11 -04:00
Inusaito Sayori
7fee70543d Login Response support for destination_guide_url, OpenSimExtras support (properly) search-server-url, and support the new destination-guide-url from OpenSimExtras
Expands SignaledType's callback to accept const Type& as argument.
typedefs Signal::slot_type to slot_t so that SignaledType can be altered without needing to update all lines setting slots.

Merges floater_directory.xml with floater_directory(2|3).xml
Condenses translations down to one xml(, finally the nightmare is over).
Better ui code support for classic find all panel
Not like anyone cares, but ShowcaseURLDefault no longer persists value changes between sessions.

Moves SearchType and getSearchUrl(SearchType ty, bool is_web) from HippoGridInfo into a namespace in llpaneldirfind.cpp, the only place where it is used; so that it may wrap the sim feature lookup.

Thanks to Shyotl for the help in dynamically maintaining tab positions for dynamic tabs.
2014-07-31 08:12:00 -04:00
Inusaito Sayori
f3a48bb0f0 Silk Aeon wants greater precision on the Object Weights Floater. 2014-07-30 08:43:12 -04:00
Inusaito Sayori
c151c12b95 Merge branch 'master' of git://github.com/AlericInglewood/SingularityViewer 2014-07-25 20:55:39 -04:00
Aleric Inglewood
b8d999066d Allow usage of default timeout policy 2014-07-26 02:46:11 +02:00
Inusaito Sayori
0e816492b4 Merge branch 'master' of https://bitbucket.org/Shyotl/singularityviewer-internal 2014-07-23 22:08:12 -04:00
Inusaito Sayori
c6ef099e18 When we setTextEntry on a combo box, move the cursor to the beginning of the new text.
This fixes the login location combo box not displaying the location cleanly after appending coordinates and such.
2014-07-23 18:15:14 -04:00
Inusaito Sayori
1c5872da0c Fix the grids combobox on the login panel not being scrollable because of constantly reordering grids
Still select the current grid, just use its index number to select it, instead of hacking it to the top of the combo box.
2014-07-23 18:12:18 -04:00
Shyotl
d95e94fa07 Missed a cast to LLMatrix4. Was causing assorted wonkiness (most noticeably, mouselook oddities) 2014-07-23 16:55:46 -05:00
Inusaito Sayori
d7bbbd9d40 Fix Group Role Data never loading since the group bans merge. 2014-07-23 16:58:41 -04:00
Inusaito Sayori
cf56659b18 Add xcode_fix.sh to scripts/ to avoid users needing to download it. 2014-07-23 16:51:14 -04:00
Inusaito Sayori
4163b8e40b Well that's a strange bug... eh, not too important. 2014-07-22 14:38:29 -04:00
Inusaito Sayori
4ca6a5c52c Sync up most of the realistic mouselook code with alchemy.
This should fix the inverted mouselook when sitting problem
Think the bug was in llvoavatar, but keeping in sync is always good for the future overall.
2014-07-22 07:07:38 -04:00
Inusaito Sayori
511811de3b Fix Media Filtering preferences code to work right. 2014-07-22 07:05:36 -04:00
Inusaito Sayori
6ef4dfb61f Fix Media Filtering preferences UI to look proper. 2014-07-22 05:49:41 -04:00
Inusaito Sayori
5ca2a3b0f7 Feature request: Change status bar search to search in all (applicable) tabs
Opens up to last tab selected now, but puts query text and triggers searches in all tabs.

Singu TODO: Have it search marketplace?
2014-07-22 05:48:30 -04:00
Inusaito Sayori
88794d0288 Add "Connect to neighboring regions" checkbox to Vanity->Main preferences. 2014-07-22 04:40:21 -04:00
Lirusaito
30e76a7c11 Fix linker errors on linux after merging Shyotl 2014-07-22 04:24:26 -04:00
Lirusaito
41eb687243 Fix compile errors and warnings on linux after merging Shyotl. 2014-07-22 03:39:01 -04:00
Inusaito Sayori
5191baa659 Merge branch 'master' of https://bitbucket.org/Shyotl/singularityviewer-internal
Conflicts:
	indra/newview/llnetmap.cpp - Thankies Shyotl~
2014-07-21 23:31:59 -04:00
Inusaito Sayori
8159eff664 Ban From Group option belongs in the Moderation submenu on the radar. 2014-07-21 23:13:12 -04:00
Inusaito Sayori
c6eb3d790e MAINT-4241 FIXED [Group Bans] Ban member(s) button is not greyed out for banning group owners. Viewer gives message that you ejected group owner.
by Andrey Kleshchev
5598f66
2014-07-21 23:11:53 -04:00
Inusaito Sayori
f62fc8ab15 Fix right clicking on lists of avatars and selecting ban/invite not working for nonfriends who aren't nearby.
Also touch up group invite floater to show names we can't get from voavatars in the user's global namesystem preference.
2014-07-21 23:11:03 -04:00
Inusaito Sayori
75e85701c6 Add Ban From Group option to right click menu of avatar lists.
Also missed two touchups for the Responder API merge in llfloaterperms.cpp
2014-07-21 22:56:18 -04:00
Shyotl
cd85afc9a5 Quick workaround to fix issue with simple geom not rendering in deferred 'underwater' pass. 2014-07-21 20:28:23 -05:00
Inusaito Sayori
b9ba472eda Merge branch 'master' of git://github.com/AlericInglewood/SingularityViewer
Conflicts:
	indra/newview/llspeakers.cpp
Compile fixes:
	indra/newview/llgroupmgr.cpp - uncomment new API for GroupBanDataResponder
2014-07-21 19:56:35 -04:00
Inusaito Sayori
bf9d3acf33 Factor in mAvatarOffset(hover) when calculating the legacy offset, though I doubt this helps. 2014-07-21 19:07:16 -04:00
Inusaito Sayori
bd7e291787 Debug output that was once useful to me. 2014-07-21 19:05:24 -04:00
Inusaito Sayori
73b34b6d89 When there is nothing selected in a media filter list, don't enable its remove button
Also missed xml parts from last commit.
2014-07-21 18:51:20 -04:00
Inusaito Sayori
f2c7290ee8 Touchups to Cinder's new media filter code! 2014-07-21 18:30:05 -04:00
Inusaito Sayori
6f6938f5bb Function removal in LFFloaterInvPanel, in favor of boost::bind function. 2014-07-21 18:04:20 -04:00
Inusaito Sayori
601ff92871 Address Issue 1570: Make comboboxes scrollable
Note: It appears that mLabel is never set by combo boxes, this should eventually be fixed.
Checking !getFirstSelected() is sufficient to test if we're in the list, however.
2014-07-21 18:00:43 -04:00
Cinder
f119986fad Remove orphaned media filter notifications 2014-07-21 14:49:39 -04:00
Cinder
402cd21f87 Hi. 2014-07-21 14:49:33 -04:00
Cinder
8cb694af89 Orphaned local function 2014-07-21 14:49:26 -04:00
Cinder
73d8cedf7e A few changes after code review from Liru 2014-07-21 14:49:18 -04:00
Cinder
b7e8d36cf8 I do things. 2014-07-21 14:49:09 -04:00
Cinder
45f5eb9671 Replace the media filter with something a little different 2014-07-21 14:48:57 -04:00
Shyotl
16fe6d0dcf Fix compile. Remove call to temporary matrix sanity check. 2014-07-21 01:27:45 -05:00
Inusaito Sayori
b633c3ffea Fix Issue 1593: "Attachment" button on Group Notices 2014-07-15 15:37:02 -04:00
Inusaito Sayori
ca1696823c French translation updates, by me~ 2014-07-14 03:20:48 -04:00
Inusaito Sayori
c1cc9d484a Add AlchemyConnectToNeighbors 2014-07-13 19:43:00 -04:00
Liru
db75cb3e17 Fix down arrow not working in inventory after the v-t sync, I must've missed this spot. 2014-07-13 12:51:11 -04:00
Liru
b8a17c8f22 Finish work on MAINT-3119 FIXED Return common chars for triggers that matches the prefix.
Makes the code cleaner too, upstream made this too messy.
2014-07-13 10:28:41 -04:00
Aleric Inglewood
74dff061ff Support for new LL Responder API.
This adds mStatus, mReason and mContent to ResponderBase
and fills those in instead of passing it to member functions.
The added danger here is that now code can accidently try
to access these variables while they didn't already get a
correct value.

Affected members of ResponderBase (that now have less arguments):
decode_llsd_body, decode_raw_body, completedHeaders,
completed -> httpCompleted, result -> httpSuccess,
errorWithContent and error -> httpFailure.

New API:

ResponderBase::setResult
ResponderBase::getStatus()
ResponderBase::getReason()
ResponderBase::getContent()
ResponderBase::getResponseHeaders() (returns AIHTTPReceivedHeaders though, not LLSD)
ResponderBase::dumpResponse()
ResponderWithCompleted::completeResult
ResponderWithResult::failureResult (previously pubErrorWithContent)
ResponderWithResult::successResult (previously pubResult)

Not implemented:

getHTTPMethod() - use getName() instead which returns the class name of the responder.

completedHeaders() is still called as usual, although you can ignore
it (not implement in a derived responder) and call getResponseHeaders()
instead, provided you implement needsHeaders() and have it return true.

However, classes derived from ResponderHeadersOnly do not have
completedHeaders(), so they still must implement completedHeaders(),
and then call getResponseHeaders() or just access mReceivedHeaders
directly, as usual.
2014-07-12 18:29:44 +02:00
Aleric Inglewood
3dd846b600 Stop people from wearing their whole root folder. 2014-07-12 14:38:54 +02:00
Inusaito Sayori
8a2e24ecd0 Sync with viewer-tiger~
Syncs up llmath stuffs.

Thanks to Shyotl for the CMakeLists fix for Wbemuuid.
2014-07-11 20:36:19 -04:00
Aleric Inglewood
6ccca51fee Compiler warning fixes.
g_thread_init is automatically called since 2.32 (and deprecated since 2.35).
g_type_init is automatically called since 2.36 and will be deprecated in the
future.
2014-07-11 17:10:27 +02:00
Aleric Inglewood
a4b3c3d1ad Remove self dependency of llwindow.
Needed to avoid an error message from cmake 2.8.12.1 and higher
(policy 0022).
2014-07-11 16:32:55 +02:00
Inusaito Sayori
bc8947289b Sync
Includes:
MAINT-3541 (crash in std::vector >::reserve)
MAINT-3364 FIXED Call clearSelection() from root_folder
MAINT-3621 FIXED Set name to "Unnamed" if object's name consists of whitespaces.
MAINT-3412 add gpu_table line with distinct Intel Iris Pro OpenGL regex to match new MBP with forced Intel graphics
MAINT-3119 FIXED Return common chars for triggers that matches the prefix.
MAINT-3661 Fix for crash when uploading corrupt .dae file.
MAINT-3671 FIXED Rename title when new tab is added.
MAINT-3465 FIXED Add check mark to selected entry.
BUG-5537 FIX reverting breaking changes to pectorals and belly.
MAINT-535 FIXED The teleport SLAPP is changed to UNTRUSTED_THROTTLE. Confirmation dialog for teleporting via slapp is added.
2014-07-11 09:31:51 -04:00
Inusaito Sayori
e7c506c6ec MAINT-3496 FIXED Disable "Allow group access" option if "Sell passes to: group" is selected(and vice versa). 2014-07-11 06:52:25 -04:00
Inusaito Sayori
8236964029 Missed the setting for joystick button on toolbar, oops. 2014-07-11 06:42:46 -04:00
Inusaito Sayori
aadecaf102 MAINT-3530 : Add viewer checkbox to extend parcel entry limits to a higher ceiling 2014-07-11 06:42:20 -04:00
Inusaito Sayori
b55e45eef6 Add a joystick on/off toggle to the new joystick toolbar button~ 2014-07-11 01:20:22 -04:00
Inusaito Sayori
adbc928148 Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer 2014-07-10 23:46:47 -04:00
Inusaito Sayori
c4c206076a Add the option to have a toolbar button for joystick configuration 2014-07-10 23:42:43 -04:00
Inusaito Sayori
5c077d7037 Suppress the annoying 404 notification from default perms 2014-07-10 22:43:36 -04:00
Inusaito Sayori
8583a2f4f7 Idea!: Set to defaults flyout button with options for all styles of joystick controller
The button portion does nothing if there is an unknown or no controller connected, otherwise it sets defaults for the controller's identified type.

Joystick buttons are still configured based on identification, however.
DS3 users will likely find that using Motion in Joy switchboards is much more effective, however.
2014-07-10 22:38:30 -04:00
Inusaito Sayori
ed8416ea10 Add a hack to make classified panel in search actually change
We cannot know the creator when we send the request, so use null to trigger the workaround.
2014-07-09 23:22:10 -04:00
Inusaito Sayori
deb7454cf7 Cure Issue 1586: Singularity crashes when adding classified adds on opensim grids (untested in SL)
Following as it is done upstream, no more requests on null ids.
2014-07-09 16:45:40 -04:00
Inusaito Sayori
8c40af5aee Sync up llpanelclassified.* a bit for easier diffings. 2014-07-09 16:18:19 -04:00
Inusaito Sayori
dd893bab41 Work towards curing Issue 1586: Singularity crashes when adding classified adds on opensim grids (untested in SL) 2014-07-09 15:29:38 -04:00
Lirusaito
759ee62e7c /open for opening avatar profiles by id~ 2014-07-09 03:18:08 -04:00
Lirusaito
1e9b79e2c1 Fix old namesystem code that broke initially setting Legacy (w/display) for everything in general.
Also cleans up old logic and directs the friends list to update when the user changes the namesystem for it specifically.
Thanks to um... I think it was Deltek, who discovered this bug.
2014-07-09 03:08:13 -04:00
Lirusaito
315883a28c Fix Issue 1577: Color yellow hard to read on Radar
Thanks to Carla Gomes
2014-07-09 03:00:38 -04:00
Lirusaito
19b85afe12 Allow gtp with implicit current height when z is not provided. 2014-07-09 02:56:09 -04:00
Inusaito Sayori
b2e8a31d68 Address Issue 1571: Newer OSSL functions not recognized by Script Editor 2014-07-08 19:15:19 -04:00
Inusaito Sayori
b4b12732cb Add new materials script constants to keywords.ini 2014-07-08 18:48:59 -04:00
Inusaito Sayori
c714c57bb2 Solve Issue 1572: Checkbox not saving its tick 2014-07-08 18:31:23 -04:00
Shyotl
4697216c5e Utilize vector_replace_with_last 2014-07-05 19:29:10 -05:00
Shyotl
e2fa94e2c3 Fixed water normals. 2014-07-05 19:09:21 -05:00
Siana Gearz
7578a27bf7 Fix RLVa in About floater 2014-07-05 14:11:26 +02:00
Siana Gearz
14e0b3c9e6 Latif's Breakpad from Replex 2014-07-05 04:14:58 +02:00
Shyotl
815acfc7da Don't use SHGetSpecialFolderPath since it's dead. Use SHGetFolderPath instead, as that still is supported on XP, and is merely deprecated, not removed from newer SDKs (yet). 2014-07-04 20:25:35 -05:00
Shyotl
7d8af7d413 Use one shared vbo to draw fullscreen rectangles in LLPipeline, for both deferred and non-deferred. Provides a nice bit of cleanup. 2014-07-03 17:09:27 -05:00
Shyotl
39810ed516 Removed several unused variables from LLPipeline 2014-07-03 02:34:10 -05:00
Shyotl
9cbcf8fe34 Removed glh_linear and glu dependencies from viewer. 2014-07-03 02:11:45 -05:00
Inusaito Sayori
02b476035b Correct Issue 1562: Environment Editor Floater not Opening Initially 2014-06-26 15:08:04 -04:00
Inusaito Sayori
9eb338f417 Merge up RLVa in llinventorybridge.cpp and remove old commented code
Just something I did to ease mergies.
Adds RLVaDebugDeprecateExplicitPoint

Ignore space changes
2014-06-25 15:23:04 -04:00
Inusaito Sayori
15e30604fc Feature Request: Add an option to bypass closing active viewers when (un)installing 2014-06-25 00:12:12 -04:00
Shyotl
21f677cf58 Remove glh::matrix4f variant of glh_get_current_modelview. 2014-06-24 01:23:08 -05:00
Shyotl
3ead892b1c Re-worked animated linden trees to reduce duplicate code and provide a cleaner diff. 2014-06-24 01:17:47 -05:00
Shyotl
a59e87a896 Added a gradient fade to the minimap viewcone visualization. 2014-06-22 03:55:29 -05:00
Shyotl
96df7b82de Change texture default to non-auto-alphamaskable, non-pickable. Only 'fetchable' textures may qualify for either. 2014-06-22 03:53:08 -05:00
Shyotl
5cb5d284c3 Initialize LLRender::mHasTextureSwizzle to false. 2014-06-22 03:44:48 -05:00
Shyotl
869517b9c6 Evidently a line in objectSkinV.glsl escaped earlier staging. 2014-06-22 03:43:43 -05:00
Shyotl
56cefce1cc Enable auto-alphamasking for attachments, and force to use V3 auto-alphamask algorithm for said attachments. 2014-06-22 03:42:37 -05:00
Shyotl
165af85894 Altered vector_replace_with_last to work around MSVC2010 compiler bug. 2014-06-22 03:40:12 -05:00
Shyotl
7c073c1db7 Explicit enforcement of alignment for all aligned types, including structures with aligned members. (Compiler handholding) 2014-06-22 03:39:33 -05:00
Shyotl
061178ad82 Migrated gl matrix stack to LLMatrix4a 2014-06-22 03:34:51 -05:00
Inusaito Sayori
dbc7c6e74d OUYA has different defaults, store its defaultification status uniquely.
Also code cleanup/simplification in the getDescriptiony areas.
2014-06-21 19:08:52 -04:00
Inusaito Sayori
d87a48ea06 Group Bans!
Thankies Baker Linden~

Ported Ansariel's mAvatarNameCacheConnection change to mAvatarNameCacheConnections to llpanelgroupbulkimpl.h

Adds setGroupID in places, in case we ever want to add that.. but for now we don't really need/use it
Adds Refresh_Off icon from upstream.

Viewer Interesting changes:
Moves LLGroupChange out of stdenums.h into llgroupmgr.h
Moves roles_constants.h from llcommon into newview

This looks like it's better without space changes...
2014-06-21 16:44:39 -04:00
Inusaito Sayori
b36bb8b5bb Increase the maximum range of finding avatars to invite near the user
Increased from 40 to 8192, so it works across sims and all the way up.
Also made the value editable, and the slider is now as wide as the list which looks nice.
2014-06-21 15:05:46 -04:00
Inusaito Sayori
2ed16c9736 Right click menus in avatar picker lists and in group invite avatar list. 2014-06-21 15:02:20 -04:00
Inusaito Sayori
c031649979 Added Eject avatar from group notification from v-r. 2014-06-20 18:01:59 -04:00
Inusaito Sayori
e0746fca12 Sync up llgroupactions with v-r/rlv. 2014-06-20 15:53:54 -04:00
Inusaito Sayori
2075042ba7 Fix key2name not working on the first try. Also make it comply with the name system choice. 2014-06-19 12:48:00 -04:00
Inusaito Sayori
499cd48763 More touches for DS3 support. 2014-06-19 11:29:18 -04:00
Inusaito Sayori
5d826b2b62 Use Nebadon's defaults for the Ouya game controller. 2014-06-18 21:32:31 -04:00
Inusaito Sayori
b20943d497 cd36a1fe16 had some mistakes/missing pieces 2014-06-18 21:07:15 -04:00
Inusaito Sayori
b4ab9a4e57 Fix cursorZoom being broken, my bad, forgot to add the increment line 2014-06-18 20:35:03 -04:00
Inusaito Sayori
cd36a1fe16 Add MotioninJoy detection, along with a whole new control set for it.. plus bonus buttons!
Tilt up to go up/jump, tilt down to go down/crouch (flying works nicely this way)
Turn left to roll left, turn right to roll right, while in flycam only.
Controls are mapped to the same buttons as with xbox controller.

Bonus buttons:
PS3 Logo button: Toggle Sit!
L2 and R2... no idea what to make these, I'll come up with something
2014-06-18 20:32:28 -04:00
Lirusaito
1cda80cbe7 Introduce function isXboxLike, to support Xbox-like controllers, even if they don't identify as Xbox.
Support for Ouya controller added.
2014-06-18 16:15:48 -04:00
Latif Khalifa
ffd0e6b79d [Branding] Linux scripts now made from template by cmake 2014-06-18 18:35:29 +02:00
Inusaito Sayori
a7728b87fc Touchup-fix for Issue 1549: Keyboard camera panning only works in 3 directions using WASD keys.
I didn't like the way Advanced menu flickered, so I provided a setting to prevent the toggle that way altogether.

Adds LiruUseAdvancedMenuShortcut
2014-06-18 09:47:08 -04:00
Inusaito Sayori
c218789abc Repeats per meter goes negative when flipping, let it be modified while in the negative without clamping to a positive minimum. 2014-06-18 09:32:59 -04:00
Inusaito Sayori
3656cb9fdb MAINT-4001 : Make Received Items not movable (protected), consolidate Received Items folders which may have been moved
Work by Merov Linden.
2014-06-18 08:05:49 -04:00
Sim Federal
e93fdf4615 Added region positions to the world map tiles
This feature added the setting 'SFMapShowRegionPositions'
2014-06-17 14:06:42 -05:00
Inusaito Sayori
6722e25cbe Fix Issue 1182: Script Window Resize Issue 2014-06-17 13:36:29 -04:00
Lirusaito
790db4283c STORM-2018: Group invite fails to let you join groups when groups maxed even when you leave group 2014-06-17 12:57:52 -04:00
Lirusaito
a0359473ff STORM-2011: Group member lists not loading properly
Work by Ansariel

For us, this is just to disconnect properly, we didn't have this because it was broken.
2014-06-17 12:56:43 -04:00
Lirusaito
ccfdcce5c1 MAINT-3187: Name list controls do not properly resolve avatar names
Work by Ansariel

For us, this is just to disconnect properly, we had this commented out because it was broken.
2014-06-17 12:54:26 -04:00
Lirusaito
811849fa23 Attempt to fix Issue 1154: Streaming Audio Display no longer stays enabled across relogs 2014-06-17 12:51:04 -04:00
Inusaito Sayori
1051fd9d42 Feature Request: Show how many scripts are actually running when doing a script count (also shows mono!) 2014-06-17 11:39:03 -04:00
Inusaito Sayori
5490a992ca Revert "[Preferences Refactor] Remove window size combo box from graphics preferences"
The issue wasn't the resolution box, and it apparently has its uses.
This reverts commit ac106b0aff.

Conflicts:
	indra/newview/skins/default/xui/en-us/panel_preferences_graphics1.xml
2014-06-16 21:43:43 -04:00
Inusaito Sayori
2d29fb8d15 Merge branch 'master' of git://github.com/AlericInglewood/SingularityViewer 2014-06-16 16:09:29 -04:00
Aleric Inglewood
589035c1db Attempt to fix gray avatars on mobile networks.
Ported from
e879862791
2014-06-16 21:02:27 +02:00
Shyotl
8f6a578ec0 Migration to LLMatrix4a instead of glh::matrix4f 2014-06-15 22:42:32 -05:00
Inusaito Sayori
a2fcf4edac Touchup to export perm enablement in default permissions
(not convinced this feature is working, though)
2014-06-14 23:18:48 -04:00
Inusaito Sayori
f56ac5210c [Warnings] Fixed warnings that Friti reported, thanks friti! 2014-06-14 18:21:20 -04:00
Inusaito Sayori
576069a84d Fox knot 2014-06-14 16:26:29 -04:00
Inusaito Sayori
7ea7d4cf6c Fix any and all crashes relating to initialization of UI components that may need the name cache to be initialized already. 2014-06-14 15:40:36 -04:00
Inusaito Sayori
21e1359b37 Confirmation for removing users, also reposition the remove button icon 2014-06-14 15:38:33 -04:00
Inusaito Sayori
eebee9b7c1 [STORM-68b] Default permissions floater overhaul
Adds separated default permissions for Objects, Uploads, Scripts, Notecards, Gestures and Wearables.

Compatible with Export Permission
Backwards compatible with default permissions for objects on regions where AgentPreferences capability is not available (opensim users rejoice!)

These changes to llfloaterperms are made available under lgpl, if there's a v3 that wants to adopt default export permission for opensim.
2014-06-14 15:32:50 -04:00
Sim Federal
bfc986a97d Fixed the spamming of has left sim
Bumping into the edge of a region without
a neighboring simulator would spam has left
and has entered the sim. This will now check
if the position is a valid global, if position not valid
then it will assume you're still in the same simulator.
2014-06-13 04:20:17 -05:00
Inusaito Sayori
d65a52242e Fox a small mistake in the last commit. 2014-06-13 05:12:41 -04:00
Inusaito Sayori
c82c791061 Whoops, that was C++11, that won't work for Linux and Mac. (code change only) 2014-06-12 08:51:54 -04:00
Inusaito Sayori
bcd18a01d8 [Preferences Refactor] In vanity->tags, remove color swatch disable logic since it doesn't make much sense anymore and isn't refreshing soon enough. 2014-06-12 07:26:04 -04:00
Inusaito Sayori
53a4931974 Group feature request: add ability to not turn when right clicking on objects
Adds RightClickTurnsAvatar to debug settings, defaults to true.
2014-06-12 06:13:33 -04:00
Inusaito Sayori
1f7751618e Solve Issue 1541: Remove old Logins
Little trash button next to the username box added, as its tooltip explains, if you have a valid entry selected and you click it, that entry will be removed.
My test avatar was a fake entry by the name Garbage Tax
Just thought I'd give that to the googles... enjoy~
2014-06-12 01:27:54 -04:00
Inusaito Sayori
497babe8e9 Fix Issue 1540: SLURLs not openable from chat? 2014-06-11 20:52:47 -04:00
Inusaito Sayori
973a90a34d Address Issue 1063: Compatibility azerty
It's dynamic, no need to relog!
Look under input preferences for "Use azerty layout instead of qwerty layout"
2014-06-11 20:02:34 -04:00
Inusaito Sayori
3cff5cd1a8 Only determine DumpDir in one place, LLDir::getDumpDir, not in llcrashlogger.
Also spaces tabs in getDumpDir
2014-06-11 14:36:41 -04:00
Inusaito Sayori
8766335708 Up the maximum field of view to 320, from 175, on request from Tazy Scientist
Better for reallllly wide screens and multiscreen setups, apparently.

Also, let's merge with v-r while we're at it, since llcamera.h requires a large-ish recompile
Nothing functional though.
And some license updates to some identical files in llmath.
2014-06-11 03:24:46 -04:00
Inusaito Sayori
908fc939b1 Feature Request: Next owner perms for scripts
In System->Building preferences, on the top right side.
2014-06-10 11:23:27 -04:00
Inusaito Sayori
73c4557a45 STORM-1117 does not affect us, allow calling cards in prims
Issue was due to v2 name resolution, our calling cards are old school and don't do this.
2014-06-10 08:51:09 -04:00
Inusaito Sayori
accfcbbf5c Restore the old behavior of not derendering muted people
This can be switched off with LiruLegacyDisplayMuteds in debug settings.
People have been annoyed that muted avatars disappear, and since we have the derender system anyway..

Also Sync llvoavatar.cpp with v-r a bit
(okay, fine, alot)
2014-06-09 10:10:03 -04:00
Inusaito Sayori
5a36450e01 Allow multi-select for participant lists, for multi-user operations via right click menu. 2014-06-09 06:54:53 -04:00
Inusaito Sayori
839f4eab7e Feature Request: chatbar as commandline "/regionsay msg" to do region-wide messages without needing to go through the region/estate floater. 2014-06-09 06:50:48 -04:00
Inusaito Sayori
fec0559d11 Introduce debug setting, LiruNewMessageSoundIMsOn, for defaulting ding of new IMs on.
This setting is off by default and I don't intend to give it a gui yet.
It probably will go in Chat UI, eventually.
2014-06-09 00:02:54 -04:00
Inusaito Sayori
e46fc0a805 Portability Mode!
Just add --portable to the shortcut
or use the provided shortcut as a template,
though it's likely the provided shortcut will not work on other computers, because the drive letter will change
2014-06-09 00:00:43 -04:00
Inusaito Sayori
fb7751360c Update Windows 64-bit Hunspell, thankies Drake~ 2014-06-08 20:42:26 -04:00
Inusaito Sayori
0c2e7d7028 Pressing up on right stick should turn the camera up in flycam, logically. (xbox controller) 2014-06-08 09:05:39 -04:00
Inusaito Sayori
fe2e68b410 These defaults seem more effective for my DS3 in flycam.
If anyone has a real XBox 360 controller and doesn't like them, let me know, we can totally work together on this
2014-06-08 08:23:48 -04:00
Inusaito Sayori
166c4df0b3 No more gross grey bars on the sides of snapshot thumbnails!!
Also random snapshot floater code sync with upstream in small places because it'll need doing at some point..
2014-06-07 11:50:31 -04:00
Inusaito Sayori
68684855c6 Bump link num starting point from 0 to 1
Based on script testing, and the fact that the root prim is 1, not 0.
2014-06-07 06:30:52 -04:00
Inusaito Sayori
fa0de18ffe [Voice Update] Small sync, less warning spam is likely
Should fix group chats sometimes not showing anyone. (Seemed to for me! ^*^)
2014-06-07 06:27:36 -04:00
Shyotl
24ca32f9f7 Replace gluProjectf/gluUnprojectf with own versions. Also changed gGLModelView/gGLProjection and other related matrices to LLMatrix4a. 2014-06-06 01:59:04 -05:00
Inusaito Sayori
f63de0d0cc Feature Request: Make Inspect button a toggler~ 2014-06-05 23:54:15 -04:00
Inusaito Sayori
f6db6058e1 Mass fixup to appearance mode ui overhead!
Should contain no functional changes, ust that all ui in appearance mode is now cached instead of calling getChild per frame.
Switches from hiding min/max param text every frame to force-drawing in draw call and setting invisible (llscrollingpanelparam.cpp/the corresponding xml)
Cleans up some old commented out code.
Moves some simple, one-call functions into their calling bodies.
Also, for some reason I had to adjust the alpha checkboxes, totally confused why they were out of line... maybe they had been already? I don't see a changed line that did positioning.

Contains spaces to tabs fixes, please view without space changes (You have been warned!)
2014-06-05 21:41:59 -04:00
Inusaito Sayori
d23632ef46 [RLVa] Yay updates~
e4a6e0d257c1 - fixed : @recvim=n isn't actually blocking the incoming message
35869fc884e9 - internal : minor refactoring of the process of updating the navigation and top info bars when toggling @showloc

9688630000ad - changed : show a limited context menu in the nearby people panel when @shownames restricted
    -> "Offer/Request Teleport" (filtered)
    $ Singu Change: Adds Recording of teleport offers to chat (if sending less than 10), one day I'll get around to doing this right into IMs

Noticed RLV.EnableIfNot was not being used, so I plugged it in for windlight.
Future Note: This brings us up to 417d759f0fa9 on the RLVa tree.
2014-06-03 20:29:55 -04:00
Inusaito Sayori
1048f213c7 Fix maximized windows being repositioned to no longer maximized when applying graphics settings. 2014-06-03 00:56:24 -04:00
Inusaito Sayori
98d88bff94 [Preferences Refactor] Oops, that shouldn't be there. 2014-06-02 23:41:03 -04:00
Inusaito Sayori
861fccd2d6 Address Issue 1301: Depth of Field preferences
Thanks a lot to Niran for assistance in this. Tooltips are from Black Dragon's machinima panel.
Note: Moves Depth of Field checkbox into the new Depth of Field tab.
2014-06-02 23:40:35 -04:00
Inusaito Sayori
715c3b8510 [Preferences Refactor] Cleanup on llfloaterpreferences
Moves to calling refreshEnabledState directly from LLPanelDisplay instead of bouncing around in LLFloaterPreferences first or using static proxy functions
Cleans up unused cached button pointers and old style static callbacks.
2014-06-02 23:24:25 -04:00
Inusaito Sayori
3c6c7c4138 [Preferences Refactor] Further cleanup
Moves to visibility_control and enabled_control instead of using callbacks, this lightens the load on opening preferences, and makes them responsive even to debug settings changes
Removes the moving m for meter text with draw distance, I don't think anyone cares if it's a little to the side of the number.
Adjustment of tabs to spaces in xml.
Return early when disabling unavailable settings if shaders are unavailable.
Cuts back on single-call functions in favor of direct binds.
2014-06-02 23:20:30 -04:00
Inusaito Sayori
95106ca1c2 [Preferences Refactor] Handle Hardware tab earlier to avoid early return when custom isn't displayed 2014-06-02 20:25:01 -04:00
Inusaito Sayori
ac106b0aff [Preferences Refactor] Remove window size combo box from graphics preferences
Windows can be resized on their own, we do not need this box
This should also fix window resizing when applying preferences.
2014-06-02 20:22:15 -04:00
Inusaito Sayori
001e45627b Feature Request: Add an option to toggle Animating when going into Appearance Mode, option is in vanity->main preferences 2014-05-30 06:38:13 -04:00
Inusaito Sayori
b8c3457644 Set RenderTextureMemoryMultiple to 1.0 on Macs, because the people asked for it.
If this explodes, I'm sure we'll see issues reported against it soon,
but in private testing we've yielded nothing but good results.
2014-05-29 22:43:55 -04:00
Inusaito Sayori
5f6dcfa82a [UI Overhaul] Restore LLContextMenu::appendContextSubMenu definition, lost in last commit. (Thannks for catching this, Tazy!) 2014-05-29 20:12:31 -04:00
Inusaito Sayori
f2dd944acd [UI Overhaul] Migrate LLContextMenu (and LLPieMenu) to the bottom of llmenugl.cpp to better diff with upstream. 2014-05-28 23:33:53 -04:00
Inusaito Sayori
d0f69ebb75 [UI Overhaul] LLMenuGL sync: doIt() --> onCommit() 2014-05-28 23:03:00 -04:00
Inusaito Sayori
04737fb0e8 [UI Overhaul] Missed this in c640585 2014-05-28 22:59:52 -04:00
Inusaito Sayori
d78550e83e Introduce APP_SITE for easy rebranding of viewer website from strings.xml. 2014-05-28 22:54:40 -04:00
Inusaito Sayori
c640585bc3 [UI Overhaul] Introduce LLMenuGL::insert from upstream and remove append/addChild wrappers in favor of insert 2014-05-28 22:52:29 -04:00
Inusaito Sayori
a926cdc5be [UI Overhaul] LLMenuGL sync 2014-05-28 22:08:01 -04:00
Inusaito Sayori
43e66b57a0 [UI Overhaul] Scrollable Menus.. just the implementation for now, not actually used.
This worked initially(early testing yesterday), but since then it seems not to, either way, implementation part is out of the way, so committing.
2014-05-28 21:50:18 -04:00
Shyotl
ee60a9801b Appease some nVidia cards/driversets regarding skinned shaders. 2014-05-27 20:18:48 -05:00
Inusaito Sayori
fb69220b95 Merge branch 'master' of git://github.com/lkalif/SingularityViewer 2014-05-27 12:57:45 -04:00
Inusaito Sayori
1cf7f67af5 Viewer name branding fixes, make rebranding way easier.
Also fix up french menu leaving functions around..
2014-05-27 12:54:33 -04:00
Latif Khalifa
8497ba1898 Use @style@ cmake escapes for the linux wrapper script
This avoids cmake messing up shell variables
2014-05-27 17:39:37 +02:00
Lirusaito
234259da91 Fix Issue 1299: Default Build settings for transfer permission not applied to a newly rezzed box
Mostly a workaround for next owner transfer being on by default
2014-05-26 13:51:41 -04:00
Lirusaito
ef7f309012 Redundant check is redundant 2014-05-26 09:32:50 -04:00
Lirusaito
d372fa1a0f Whoops, fixup locally experienced crash with lookat beacons. 2014-05-25 14:47:45 -04:00
Lirusaito
ea9005868b Switch out bumpers being roll for bumpers being y axis (up/down) with the xbox controller
This seems more widely used, and roll does nothing in Avatar movement so this is more useful
If people want it the other way, they can just switch it themselves.
2014-05-25 12:57:48 -04:00
Lirusaito
0a3a4a51bd Feature Request: Add an option to "Make rightclick zoom instantaneous, not smooth" (in Input & Camera preferences) 2014-05-25 12:44:48 -04:00
Latif Khalifa
1dbd913d9d Branding: generate wrapper script with cmake 2014-05-25 18:18:47 +02:00
Latif Khalifa
22cded7ccc Made breakpad symbols generation branding neutral 2014-05-25 08:27:00 +02:00
Latif Khalifa
4851f1ad48 Branding support for Linux packaging 2014-05-25 04:07:34 +02:00
Inusaito Sayori
0d94dd7bf8 Pick up a few changes from Alchemy for LookAt beacons
Implements lines from avatar to their lookat beacons
Implements namesystem so that Display Names can also be shown with beacons instead of just legacy

New options are available in the Security & Privacy tab of System preferences
2014-05-24 05:26:32 -04:00
Inusaito Sayori
bbe7f6adfb Enable Multiselect in groups, and enable EditMenuHandler when a scrollable list is focused!
Allows Ctrl-A to select all in a list (Like for selecting all groups and unticking chat with a single click)
Ctrl-E to deselect
Ctrl-X/Ctrl-C to copy a list (useful for saving ban lists and such!)
2014-05-23 19:37:32 -04:00
Inusaito Sayori
828941a204 Meeting Request: Pick up LL's changes to land impact (Also introduces Land Impact floater)
Small change to lltextbox allowing us to use value attribute with <text/>'s YAY!!

Cleaned up in llfloatertools as well to better diff.
2014-05-23 06:19:43 -04:00
Inusaito Sayori
2ce3f2c131 Meeting Request: Display date not just time in Teleport History
Will not change old entries because of the stupid way teleport history is saved.
Seriously, this floater needs a rewrite... we should just use v3.
2014-05-23 03:39:35 -04:00
Inusaito Sayori
8943552c1c Meeting Request: Change System Preferences' Security tab to Security & Privacy 2014-05-22 19:58:16 -04:00
Inusaito Sayori
dadbb00b85 Introduce a setting for Automatically scrolling to the bottom of a chat when the chat gains focus
Preferences->Adv. Chat->Chat UI, Autoscroll to the end of chats when they regain focus.
This defaults to false, unlike the legacy behavior.

Partial revert of "Feature Removal!: Do not scroll to the end of chats when the corresponding chatbar regains focus!"
2014-05-22 19:46:15 -04:00
Inusaito Sayori
852a8407c8 Feature Removal!: Do not scroll to the end of chats when the corresponding chatbar regains focus!
Focus is given to chatbar on floater focus, so this got in the way.
This feature was never really worth it.
2014-05-21 22:57:08 -04:00
Inusaito Sayori
bfbbcad8e5 Feature Touchup: Add backup destination to Emergency Teleport out of region within last 20 seconds before restart feature
Falls back if first landmark is not in inventory or invalid, region is offline, or the current region is your location
Item drop target is right below the original one in System->Security prefs.

Thanks again to the citizens of Fluffy for enduring these restart tests.
2014-05-21 19:07:11 -04:00
Inusaito Sayori
c684987908 Fix bugs introduced in 77a13963bb
Fixes Shiny/Bumpy combo boxes being broken
Fixes UI warning for "label glossy" not existing, it was "label glossiness".
2014-05-20 23:37:59 -04:00
Shyotl
53b8f70de8 Merge branch 'master' of git@github.com:Shyotl/SingularityViewer.git 2014-05-17 18:26:07 -05:00
Shyotl
a1eb30ae87 Keep old non-swizzle method around since GL_ARB_texture_swizzle has poor support prior to 3.3 (on osx especially) 2014-05-17 18:25:21 -05:00
Shyotl
c4cb9de44b Merge branch 'master' of git@github.com:singularity-viewer/SingularityViewer.git 2014-05-17 16:30:21 -05:00
Shyotl
0a89503edd Renamed glUniformMatrix3x4fvARB to glUniformMatrix3x4fv, since I don't think it ever had the ARB postfix. Also use its the properly named (although identical to the current) function pointer signature. 2014-05-17 04:04:33 -05:00
Shyotl
f12bd741e2 Merge branch 'master' of git@github.com:Shyotl/SingularityViewer.git
Conflicts:
	indra/newview/llvopartgroup.cpp
2014-05-17 03:40:10 -05:00
Shyotl
e35039faf7 Remove deprecated gl call in renderComplexityDisplay. 2014-05-17 03:34:33 -05:00
Shyotl
a756943628 Fix a LLVertexBuffer::validateRange call that I hosed up pretty badly. 2014-05-17 03:33:33 -05:00
Shyotl
a9c3e13e5e Removed some diagnostic spam pertaining to shaders. 2014-05-17 03:32:40 -05:00
Shyotl
67c8ac2b04 Skinned shaders were exceeding maximum amount of vertex uniforms on amd hardware.
-Changed the transform matrix uniform to a 3x4 matrix and packed translation into it to free up uniforms. (3x3 is converted to 3x4 internally, so we were needlessly eating 3*52 extra uniform slots. translationPalette might also have been treated as a vec4 internally too, wasting 52 more slots.)
-matrix3x4 requires opengl2.1 and newer, so added a new featuretable mask.
-Also added a featuretable mask to disable hardware skinning and deferred shading on hardware with less than 1024 vertex uniforms.
NOTE: On old old old amd hardware, evidently a 3x4 matrix might be upgraded to 4x4. I'm unsure, but I doubt such hardware has 1024+ uniform components available to begin with. 4x3 supposedly doesn't do this, but opengl is column-major, so this makes little sense.
2014-05-17 03:31:45 -05:00
Inusaito Sayori
82044399e4 Brought in Realistic Mouselook option from Black Dragon
Look at the top area of Input & Camera preferences
Aside from tweaks to the code, all credit to Niran.
2014-05-15 21:01:11 -04:00
Shyotl
fdcf2eda5a Decouple vbo validation from LLDrawInfo. Such required vbo's to be initialized before drawinfo creation/modification, which is no longer the case with llvovolume. ('RenderDelayVBUpdate'[although removed in Singu] also fails the same assumption.) 2014-05-15 18:44:10 -05:00
Shyotl
e0997f1f04 Decouple vbo validation from LLDrawInfo. Such required vbo's to be initialized before drawinfo creation/modification, which is no longer the case with llvovolume. ('RenderDelayVBUpdate'[although removed in Singu] also fails the same assumption.) 2014-05-15 18:39:35 -05:00
Inusaito Sayori
58859ee709 Minor touchups to spanish translation 2014-05-15 17:36:33 -04:00
Shyotl
c3771e2fd5 Removed unused preprocessor definition in objectSkinV.glsl 2014-05-15 16:23:14 -05:00
Inusaito Sayori
2e49365b0f Merge branch 'master' of https://github.com/DamianZhaoying/SingularityViewer 2014-05-15 15:37:42 -04:00
Inusaito Sayori
cd87aadab3 Missed a spot. 2014-05-15 00:42:22 -04:00
Inusaito Sayori
e58f8856f4 Add support for Controller Keys, inspired by similar code by CtrlAltStudio Viewer
Dear Alpha Users who are curious about this:
A = Alt
B = Shift
X = Ctrl
Y = Escape
Back = Toggle Flycam mode (Use this, it's fun!!!)
Start = Toggle Cursor mode
Right Stick Click = Toggle Mouselook
Left Stick Click = Jump/Fly

Enjoy, I know I do!
2014-05-14 23:48:27 -04:00
Inusaito Sayori
18a48e6609 Fix the inverted mouse issue. 2014-05-14 23:16:55 -04:00
Inusaito Sayori
929b75989c Sync with alchemy/v-r for flying instead of jumping on button press (Left Stick Click) 2014-05-14 22:58:16 -04:00
Shyotl
7d98030edc Use the right diffuse shader for skinned deferred diffuse simple object shader. 2014-05-14 19:43:03 -05:00
Shyotl
846d573dd0 Kill stray #endif that snuck into commit. 2014-05-14 16:45:55 -05:00
Shyotl
5805fe636a Determine if to stuff shiny data into alpha component a bit differently. Cuts out a lot of crazy logic and lets us choose based off of target renderpass. 2014-05-14 03:38:16 -05:00
Shyotl
3db9c6a9ff Try mask-based object shader configuration, instead of a bazillion hard-coded shader globals. Should be a bit more consistent. (non-deferred only, for now)
Also abuse discard in alpha shaders, instead of processing invisible fragments.
2014-05-14 03:30:02 -05:00
Shyotl
22bcf83cb9 Toyed with gl init ordering. Fixes adaptive vsync. May explode on linux, not that adaptive vsync works there, but it should in theory work there if we ever port to sdl2. If it does explode, I'll know shortly... probably. 2014-05-14 03:10:34 -05:00
Shyotl
117eca3c98 Try some swizzling instead of forcing everything to rgba8 with core profile. Avoids manual conversions with scratch buffers. Works for all pixel datatypes. Cleaner. Uses less vram.
Also, fixed textures when running core pofile.
2014-05-14 03:05:53 -05:00
Inusaito Sayori
81affe719f Add a setting to automatically decline and leave incoming conferences
Look under Communication preferences for "Block incoming conference chats" to activate.
2014-05-14 03:34:32 -04:00
Inusaito Sayori
3febec4aa4 Merge up CtrlAltStudio and Alchemy for XBox360 support
Can't seem to get scrollies working in cursor mode, odd.. need to look into that.
I need to figure out if inverted Y axis is just for me on my Dual Shock 3, though it seems to work usually... if this is the case I might flip it in the code.
More work needs to be done to get ctrl/alt/shift support from CAS, too.

I just wanted to get today's work out of the way and wrapped up, so here it is.
2014-05-14 02:23:55 -04:00
Inusaito Sayori
a78c6072ce Sync llviewerjoystick with upstream sources.
Replaces old constant of dividing by 3 with debug setting for multiplying: FlycamBuildModeScale
Relicenses to lgpl.
2014-05-13 21:27:18 -04:00
Lirusaito
aa6a57be63 Remove "wanna->want to" from auto replace, it is stylistic. 2014-05-12 19:26:16 -04:00
Inusaito Sayori
fd29dd9508 Spaces to Tabs for Last commit 2014-05-09 22:19:52 -04:00
Bob Shaffer II
5080ebf88f reverting some changes to llvovolume that seems to break animated textures
Signed-off-by: Siana Gearz <siana.sg@live.de>
2014-05-10 03:13:15 +02:00
Siana Gearz
873df7805b Merge branch 'master' of git://github.com/Lirusaito/SingularityViewer 2014-05-10 03:12:32 +02:00
Inusaito Sayori
009fb10927 Feature Request: Add AutoresponseOnlyIfAway to send autoresponses only if in AFK or FakeAway modes 2014-05-09 20:32:38 -04:00
Inusaito Sayori
3898d29741 [Preferences Refactor] Touchup on voice prefs borkage. 2014-05-09 20:31:05 -04:00
Siana Gearz
1c521a3743 Merge branch 'master' of https://github.com/lkalif/SingularityViewer 2014-05-09 22:18:10 +02:00
Siana Gearz
098d1b30ff Merge branch 'master' of git://github.com/Lirusaito/SingularityViewer 2014-05-09 22:15:38 +02:00
Siana Gearz
484108dafc Fix VS2012 64-bit debug build 2014-05-09 22:14:47 +02:00
Inusaito Sayori
029d260ad8 Feature Request: Persistent setting for AllowSelectAvatar (su useful!) 2014-05-09 10:39:07 -04:00
Inusaito Sayori
e6bc8f8583 Enable custom and window resolution for snapshots to inventory and set the max size to 1024, not 512. -- on request of Vivena (and the in-world group as a whole) 2014-05-09 09:30:13 -04:00
Inusaito Sayori
77a13963bb Joint effort with Alchemy Viewer to make build floater a lot lighter on FPS
Gets rid of all those pointless callbacks and static workarounds for legacy callback system.
Should massively improve FPS while build floater is open
Fixes getChild UI Warnings
Removes dumb func
2014-05-09 06:40:53 -04:00
Inusaito Sayori
656eacbb09 Merge branch 'master' of git://github.com/Shyotl/SingularityViewer 2014-05-08 19:57:01 -04:00
Shyotl
98f9a09b39 sunlight_color_copy need only be vec3. 2014-05-08 16:39:41 -05:00
Shyotl
7e8e8bdb26 Disable some diagnostic gunk eating memory. 2014-05-08 16:35:12 -05:00
Shyotl
e2a0f801b9 Have LLRender::color4ub fall back to uniform if bound vbo lacks color attribute. Fixed fixed-function call in LLFacePool::LLOverrideFaceColor::setColor. 2014-05-08 16:29:53 -05:00
Shyotl
75b31b4151 Fix a nullptr usage. 2014-05-08 16:24:24 -05:00
Shyotl
f0763fd31c Tweaked context-recreation logic to force a 0xAA context when fbos are in use. Should also handle toggling of fbo checkbox a bit gracefully as well. 2014-05-08 15:48:08 -05:00
Shyotl
162e7b7699 Fixed a silly mistake that was causing vsync to be enabled when it should have been. Also fix typo in objectSkinV.glsl previous commit 2014-05-08 15:30:02 -05:00
Shyotl
7158a3c83d Fixed an annoying showstopper regarding rigged attachment vertex corruption. Rigged meshes have can have poor weighting, causing potential div-by-zero issues. 2014-05-08 15:11:12 -05:00
Inusaito Sayori
1fa30dd337 Fix Issue 1502: The Builders' Brewery says our prim torture behavior is nonstandard
Our uictrl limits were in need of a quick tune-up.
2014-05-07 06:54:17 -04:00
Inusaito Sayori
250049537f Feature Request: Add option to autominimize the region restart floater And Allow changing/shutting off its sound (from gui)
These new options are at the bottom of System->Security preferences.
2014-05-07 06:53:35 -04:00
Inusaito Sayori
76e5311320 [Preferences Refactor] Cleanup of voice prefs code
Also attempt to add a local enablement control, it's not quite clear where these are supposed to hook in, so it's unused for now, but it would have replaced onCommitEnableVoiceCheck.
Also fix the location of the voice is disabled textytext, it was too on top of the next checkbox.
2014-05-07 03:52:14 -04:00
Inusaito Sayori
11098cd6d4 [Preferences Refactor] Clean up of useless code for enablement and callbacks.
This tag will be used for refactor and updating of most of our preferences panels:
  This will include code changes that remove or condense old code
  This will include preferences being moved around to more logical locations
  This may include splitting up and/or condensing of tabs and/or subtabs for more logical placement of preferences
  This may include code changes that allow making changes to preferences faster and easier
  This will not include adding preferences
2014-05-07 03:20:04 -04:00
Siana Gearz
78a0b347fc Fix 64-bit project generation under Cygwin 2014-05-04 08:05:05 +02:00
Latif Khalifa
08a23de051 Restore compiler warnings flags.
Previous work on enabling the build on the latest Mac OS and
Xcode compiler mistakenly took out compiler warning flags.

This restores previously used flags.

Issue noticed by Sovereign Engineer.
2014-04-30 07:29:23 -07:00
Inusaito Sayori
a02ad53c73 Fix bulk import of notes, scripts and gestures, and clarify file menu 2014-04-28 20:36:46 -04:00
Inusaito Sayori
9400701c96 Synced up llviewerobjectbackup with Cool VL Viewer
Benefits:
-Support for exporting Materials (Normal and Specular textures)
-Fixed support for Object Physics export
-Fixed support for Light Image export
-Switch to use of Boost unordered containers
-Checking for invalid perms on textures is now optimized by saving invalid ids to a container
-GravityMultiplier parameter is now Gravity because that just makes way more sense.
-We support export of legacy flag parameters again to be compatible with older viewers
-Code comments are now a little clearer
-We now wait a little if objects haven't loaded yet when we try to export them
-We no longer allow changing default texture ids via debug settings on opensim regions that support the export permission
-Bit of reordering to better diff with Cool VL Viewer, since it's essentially our only upstream.
-Removes dead code/commented codestuffs

Please view the diff without space changes, otherwise you'll lose your mind.

Merci Henri!
2014-04-28 17:48:39 -04:00
Latif Khalifa
aa983108e8 Possible fox for crash signature 5284 by Aleric 2014-04-28 21:12:37 +02:00
Damian Zhaoying
7dca333166 Update spanish translations. Add translations for news floaters, dinamyc toolbars, RLVa and autoreplace. 2014-04-28 15:51:48 -03:00
Lirusaito
0f1ecf66ab Possible Fix for Issue 1499: Login screen disappears on non-SL grids after logging failure
Also should fix when this would happen on poor/dead connections.
2014-04-27 18:50:37 -04:00
Lirusaito
74984b5a3c Further cleanup of im floater draw call due to last commit 2014-04-27 18:46:50 -04:00
Latif Khalifa
c5d5984885 Checking for ChatSessionRequest cap is not neccessary for establishing private voice calls.
Addresses issue 1293
2014-04-27 21:37:52 +02:00
Damian Zhaoying
c1ccfcb988 Merge remote-tracking branch 'Liru/master' 2014-04-27 13:53:47 -03:00
Lirusaito
51dc0550d5 Minimap mark colors touchup
Now shown in tag without tag color statuses needing to show.
2014-04-27 11:18:31 -04:00
Lirusaito
ac9e36549b Fix right clicking dots no longer working on the minimap, broken {} pair that slipped my eyes. 2014-04-26 18:08:19 -04:00
Lirusaito
009e9a598a Introduce ExodusMapRolloverCircleColor for controlling the color of the new minimap selection circle, turn the alpha to zero to make it disappear completely (it's already quite light now) 2014-04-26 18:07:28 -04:00
Lirusaito
1502ef2661 Fix for an internal crash, could only happen if settings were copied into install improperly, but better safe than sorry. 2014-04-26 10:19:04 -04:00
Lirusaito
40f9e12bdf Fix for Issue 1472, prevent what was probably a null pointer in a bind
Oddly, this only happened to some people, but on any OS, which leads me to believe that initialization order may need some looking at, but that's not terribly important now.

Removes toolbar toggle from floater dictionary, in favor of using setting toggle
Since we could always just hook up a control to a button if we wanted to add such a button somewhere anyhow, this has no effect on future either.
2014-04-26 10:17:47 -04:00
Lirusaito
2fc783e67e The people want link parsing on! Let them have links in all text editors that aren't allow_html="false"! 2014-04-26 09:47:56 -04:00
Inusaito Sayori
4f8e6a188a Bypass canClose check for new groups by calling onClose directly. (Fixes making new groups!) 2014-04-25 11:52:25 -04:00
Inusaito Sayori
b0e44ad1bd Solve Issue 624: minimap multiple selection tool
Adds a circle when you mouse over the minimap, beneath your cursor
-This circle is the effect range of your right click+mark
-Shift+scroll to change the size of this circle (ExodusMinimapAreaEffect)
-- Set the debug to 1 to have basically the same range as before (unless dots are stacked)
-This circle is also how many avatars are shown in the tooltip
-When this circle is over avatar dots, they change color (ExodusMapRolloverColor)
The menu functions still only work on the closest dot to your cursor on right click...
Thanks to Exodus for the majority of this code, the rest is my work and updates to be closer to LL in places.
2014-04-25 04:11:35 -04:00
Inusaito Sayori
4a630b1780 Make it clear that item drop targets are for items. 2014-04-24 22:12:20 -04:00
Inusaito Sayori
ffa5e6099d Address Issue 1290: Bumps recorded in chat window
Adds debug setting AnnounceBumps and a toggle in Preferences->System->Security
2014-04-24 21:46:57 -04:00
Inusaito Sayori
8d1cd7008f Fix bug of being unable to change group owned parcel's visibility in search. 2014-04-24 19:48:27 -04:00
Inusaito Sayori
31b5c5e9dd Enter Export subpiemenu, no longer part of Tools 2014-04-24 19:47:17 -04:00
Inusaito Sayori
0e21a16c1c [STORM-1980] Singu Special: Emergency Teleport out of region within last 20 seconds before restart
Look in System preferences under the Security tab, at the bottom.
Debug setting is EmergencyTeleportLandmark, reset to turn off.

Also, thanks to everyone in Fluffy who put up with the tests of region restart notifications today,
I know it was annoying, thanks especially to the EMs for allowing me a testbed.
2014-04-24 01:33:04 -04:00
Inusaito Sayori
f666384a1d [STORM-1980] Part 3: Region Restarting camera shake reset also pokies at sound trigger
Don't send sound through the region, it's logically a UI sound. What even is that otherwise?
2014-04-24 01:25:52 -04:00
Inusaito Sayori
afacfcee94 [STORM-1980] Part 2: Floater and shakeyshake
Shake is off by default, turn on AlchemyRegionRestartShake to activate
2014-04-23 23:54:59 -04:00
Inusaito Sayori
7262bf96b8 [STORM-1980] Part 1: Notifications with timestamp and sound 2014-04-23 10:58:14 -04:00
Inusaito Sayori
3db489f4df Feature Request: When someone is marked on the minimap have that color persist on the radar and their tags
Jus' look at dat color~
2014-04-23 02:50:51 -04:00
Inusaito Sayori
6526c28e47 Fixup for "Feature Request: On login, open Local Chat, Communicate, and/or Contacts" 2014-04-23 01:35:52 -04:00
Inusaito Sayori
e473b9bf10 Fix a common crash when people would upload invalid xmls
Ill-gotten xmls just don't parse the same way...
2014-04-23 01:05:32 -04:00
Inusaito Sayori
0bde458c27 Allow minimum Sun Size of 0.01 instead of 1, like Black Dragon. 2014-04-22 22:20:46 -04:00
Inusaito Sayori
66739ac820 Preferences touchup now that we have log launching on mac 2014-04-21 18:59:49 -04:00
Inusaito Sayori
4a3763d8d1 Feature Request/Bug Fix: On login, open Local Chat, Communicate, and Contacts if they were open last session. 2014-04-21 18:31:41 -04:00
Cinder
4230127459 De-brand currency exchange 2014-04-21 18:09:08 -04:00
Cinder
a4c672252d Launch transcripts in external text editor on mac too 2014-04-21 18:05:45 -04:00
Lirusaito
d5d0473487 [LLMeshRepo sync] Fix mesh not loading 2014-04-19 01:09:12 -04:00
Lirusaito
9bbad1f8f0 [Warnings] Fix trigraph warning. 2014-04-19 00:47:02 -04:00
Lirusaito
0523965822 [LLMeshRepo sync] relwithdebinfo compile fixes 2014-04-19 00:25:11 -04:00
Lirusaito
cb8cd702e1 [LLMeshRepo sync] Linux compile fixy
Note to self: Windows compiler does not care about file casing, be more careful.
2014-04-18 23:51:52 -04:00
Liru
86b5737d51 [Floater Flexibility] French Translation~ Danke Nomade. 2014-04-18 09:17:41 -04:00
Liru
4027ec7a67 [Floater Flexibility] Fix yet another broken button, this time group titles, thanks again to the french singularity group 2014-04-18 04:58:49 -04:00
Liru
c2748a2246 [LLMeshRepo sync] The rest of the changes from upstream 2014-04-18 04:43:46 -04:00
Inusaito Sayori
5c06afc977 [LLMeshRepo sync] AICurl updates toward LLCurl
LLHTTPClient::getByteRange no longer throws AICurlNoEasyHandle, instead it returns whether or not it threw, to match the true/false convention of LLCurl.
- In addition, the header param has been shifted to earlier in this function to ease diffings.
ResponderBase now has static bool isGoodStatus, introduced into the Responder base class of LLCurl
2014-04-17 20:23:48 -04:00
Inusaito Sayori
4c82a5660f [LLMeshRepo sync] Change camelcase LLConvexDecomp to lowercase, so mergetool is happy~ 2014-04-17 18:20:34 -04:00
Inusaito Sayori
beacb5c701 [Floater Flexibility] Fix that the preferences button wasn't working, thanks Nomade for pointing this one out. 2014-04-17 15:47:50 -04:00
Damian Zhaoying
8355331cbe Merge remote-tracking branch 'Liru/master' 2014-04-17 02:18:56 -03:00
Inusaito Sayori
dc9cb07a81 [Floater Flexibility] Part four: Added a floater to change buttons shown on the toolbar
View->Change toolbar buttons

Reuses the old FloaterUploadRect because I'm allowed to be lazy after creating this large control panel
2014-04-16 19:03:07 -04:00
Inusaito Sayori
57fe7d9ad0 [Radar] WHAT?! Why wasn't this committed last night? I know it was... what the heck... 2014-04-16 16:08:20 -04:00
Latif Khalifa
00336de59a Merge branch 'osx_xcode5' of github.com:lkalif/SingularityViewer 2014-04-16 16:44:31 +02:00
Inusaito Sayori
b37b48f039 [Radar] Code overhaul
Brings a new "voice status" column, showing voice use as active speakers floater does.
- Shown by default, look in Extras tab to hide it
Attempt to blend and fix the visibility of the yellow for shout range.
- Requires user feedback, looks good on default and gemini to me

Refactors pretty much all of the code in the avatar list
-Less duplicate vars, less wasted space, more consistent spacing conventions, eradication of BOOL use.
We no longer add (or even evaluate what should be in) icon columns that are hidden
- This prevents icons from showing up even when their columns are hidden.
Minor work on focusing out of draw avatars, though that still won't work, sadly.
2014-04-16 05:30:19 -04:00
Latif Khalifa
42ca1a8994 [clang] Force build with SDK 10.6 2014-04-16 10:55:36 +02:00
Latif Khalifa
db678238ef Merge branch 'master' into osx_xcode5 2014-04-16 09:56:57 +02:00
Lirusaito
861f88dd30 Awesomeness, yayayay! (allows XML changes in indra/newview/skins/ to count for viewer running from a directory in indra on Windows) 2014-04-15 20:06:08 -04:00
Lirusaito
77d42f1eb9 Attempt to cure stupid people being unable to untar properly over old versions without causing massive issues
(Gawd, that is not even proper installation process.... I need a drink)
2014-04-15 20:03:24 -04:00
Inusaito Sayori
364a13017c Merge remote-tracking branch 'fairydust/master' 2014-04-15 19:57:31 -04:00
Latif Khalifa
8183deeb30 [xcode5] WIP: rebuilt clang friendly boost 2014-04-14 21:17:22 +02:00
Latif Khalifa
bb56d0a752 [xcode5] WIP: clang build fix 2014-04-14 21:16:24 +02:00
Latif Khalifa
41eafa4ede [xcode5] WIP: build system changes 2014-04-14 21:14:42 +02:00
Inusaito Sayori
ce7629200f Object Import/Export improvements
Support exporting "material" "clickaction" "flags" and "ExtraPhysics"
Support export of Light Texture feature, the expansion to Light feature.
Initial work to support firestorm's format.
Switched from exporting individual flags fields in favor of exporting one U32 field
- We still support the old single flag fields though we no longer export them.
2014-04-09 20:24:15 -04:00
Inusaito Sayori
5dca06d3d4 So then I said, "Compile, are you crazy?!" 2014-04-08 04:51:18 -04:00
Inusaito Sayori
b1d18c7f29 Address Issue 1298: Add Auto-replace text feature, borrowed from LL~ 2014-04-08 02:12:51 -04:00
Inusaito Sayori
0b2d019e61 Latif's requested touch-ups for IM windows in concise mode.
Profile option for concise flyout.
Fix for ding in multi-user chats breaking button alignment.
2014-04-08 01:07:19 -04:00
Inusaito Sayori
ab0dde7fe8 [Floater Flexibility] Part three and a half: Toolbar code cleanup, toolbar in mouselook option
Go into Preferences->Input and Camera, to find the new option~

Thanks to Cinder for checking that the mac changes build and look nice.
2014-04-08 00:36:44 -04:00
Inusaito Sayori
ef01d2af82 Fix "zombie" lie and tabs/spaces inconsistency in xml. 2014-04-07 16:06:33 -04:00
Damian Zhaoying
08084799b9 Merge remote-tracking branch 'Liru/master' 2014-04-06 14:42:00 -03:00
Inusaito Sayori
3642e401da Fix About and Toolbar prefs buttons being mushed together, thanks for the heads-up Friti! 2014-04-04 19:57:32 -04:00
Inusaito Sayori
094d284e62 Missed a git mv, mac should build after this. 2014-04-04 17:28:19 -04:00
Latif Khalifa
2c7459e08d Supress bool/BOOL comparison warning 2014-04-04 21:29:41 +02:00
Latif Khalifa
315d2c4daf Merge branch 'master' of git://github.com/AlericInglewood/SingularityViewer 2014-04-04 21:21:00 +02:00
Aleric Inglewood
e61cabf1ce Remove compiler warning. 2014-04-04 21:13:57 +02:00
Aleric Inglewood
994f409291 Attempt 2 2014-04-04 21:06:30 +02:00
Aleric Inglewood
7d124012c2 First attempt to fix windows compile errors. 2014-04-04 20:58:33 +02:00
Latif Khalifa
4d3c80e273 Merge branch 'master' of git://github.com/AlericInglewood/SingularityViewer 2014-04-04 20:08:19 +02:00
Aleric Inglewood
a332a7fc35 Compile fix for motions backport. 2014-04-04 17:33:45 +02:00
Aleric Inglewood
2fb945a489 Fix floating point round off error bug that caused mAnimTime to be decreased in value.
Conflicts:
	indra/llcharacter/llmotioncontroller.cpp
2014-04-04 15:22:18 +02:00
Aleric Inglewood
4d2517d163 Freeze also synchronized avatars when editing an attachment.
On the removal of permYouOwner():

Calling permYouOwner() to determine if an attachment is yours is
not correct: grid gods (and that includes BEFORE requesting admin
status) are marked as owner of everything in their sim.

The reason for that is that otherwise,
  <Melanie_T> if they only had it when actually godding u, the viewer
  would have to have an option to either show the proper menus (it
  doesn't) or allow the sim to refresh the object flags without full
  object updates (it hasn't).
  <Melanie_T> gods often have to act fast, for instance with griefers.
  Having transition to god mode take as long as a full rez just isn't an
  option, apart from the sim load caused by resending all objects.
  <Melanie_T> Then i tried resending only the object that was selected
  but there the arriving object update would close the pie menu.
  So you right-click a prim and the pie menu would close again.

The result has always been that if you are on your own sim, in opensim,
and select an attachment on another avatar, then YOU would freeze, not
the selected avatar. This patch fixes that "opensim related" bug as
well.
2014-04-04 15:19:50 +02:00
Aleric Inglewood
b4848f308f Compile fix for Release 2014-04-04 15:19:39 +02:00
Aleric Inglewood
1c8876cead Synchronize looping animations that start at the same moment. 2014-04-04 15:19:28 +02:00
Aleric Inglewood
1bcb6ad20d Version 2 of AISyncClient et al.
A tool to synchronize objects:
Objects derived from AISyncClient can signal that they are
'ready' or 'not ready' for up to 32 events (using a bitmask)
at a time. Clients that are created at roughly the same time
as other clients, and which return the same 'key' (a virtual
function returning an AISyncKey object) will be grouped together
and receive events (by means of virtual functions being called)
to notify them of all clients being ready or not for one of the
events (the least significant bit)). The other events can be polled.

This new version does away with all the templates and explicitly
remembers what events each client is ready for instead of just
updating a counter of the number of clients. This was necessary
because a client is removed then the server needs to know if it
was ready or not when it has to be able to update those counters.
This time I chose to just run over all stored clients and AND
and OR the per-client-ready-masks because 1) that information
is available now and 2) the lists will normally contain only
one or two clients, so it's fast enough.
The new version also allows for real key comparison (and derived
keys) instead of just using "hash" value that is compared.
2014-04-04 15:19:18 +02:00
Aleric Inglewood
66aaa9cf80 Add LLMotionController* LLMotion::mMotionController
This is needed for synchronization: motions will have to start
(with a specific start time offset) from a point in the code where
only the motion object is available.

I added/used LLMotionController& in a previous commit, this was
now changed into a pointer. There is (obviously) not much reason
for that, but also no disadvantage: the diff relative to LLs code
doesn't get larger since the references where already added, too.

Conflicts:
	indra/llcharacter/llkeyframemotion.cpp
	indra/llcharacter/llkeyframemotion.h
2014-04-04 15:19:02 +02:00
Aleric Inglewood
61d365e957 Removed this again... 2014-04-04 15:15:36 +02:00
Aleric Inglewood
006b319c3a Add AISyncClient<> (and AISyncServer).
A tool to synchronize objects:
Objects derived from AISyncClient can signal that they are
'ready' or 'not ready' for up to 4 events (using a bitmask)
at a time. Clients that signal to be ready for anything
at roughly the same time as other clients, and which return
the same 'hash' (a virtual function returning a 64bit value)
will be grouped together and receive events (by means of
virtual functions being called) to notify them of all clients
being ready or not for one of the events (syncevent1).
The other three events can be polled.

The memory usage is low (one pointer per client that points
to its AISyncServer object), servers are released to a cache
after about 100 ms (unless there is actual need for synchronization),
so there aren't much of those either.

The CPU usage is extremely low: all events are handled in
parallel in a 32 bit value (6 bits per event to count the
number of registered clients and the number of ready clients
for each event, and the remaining 8 bits to count the
number of reference pointers (which should only be a constant
higher, so that is overkill). To signal to a server that
a client has become ready or not is mostly a function call,
which then takes 1 clock cycle or so before returning.
Registration of a client is slightly more expensive as it
requires a pointer to be added to the end of a std::list.
This tool could easily be used as part of the graphics engine
(not that I intend to do that :p).
2014-04-04 15:15:26 +02:00
Aleric Inglewood
e38ec797fd Fix lookat and pointat shared experience.
There was a bug that when people turned off sending viewer effects,
they'd also turn off sending LookAt, while there is a seperate
checkbox to turn THAT off, while still seeing their own avatar
happily look around, breaking shared experience (most notably, most
people will be complete oblivious of the fact that they look like
zombies to others and that their friends do not see the same thing
on their screen).

This patch fixes this: both parties now see the same thing. Lookat
and PointAt are only turned off by their respective checkboxes,
and no longer silently influenced by turning off other viewer
effects.
2014-04-04 15:15:15 +02:00
Aleric Inglewood
94b42e7a9b Speed up of particular inefficient part related to motions.
For these standard motions, the viewer likes to very frequently
flood-call startMotion/stopMotion sometimes, which at the very
least needs a LLUUID lookup in a std::map. In particular, this
is done for two of them for every avatar in the sim every frame.
This code makes it possible to test if that makes sense by
merely doing a bit test.

Conflicts:
	indra/llcharacter/llkeyframemotion.h
2014-04-04 15:14:54 +02:00
Aleric Inglewood
61097dac72 Auto clean up motion cache.
Conflicts:
	indra/llcharacter/llkeyframemotion.cpp
	indra/llcharacter/llkeyframemotion.h
	indra/newview/llfloaterbvhpreview.cpp
2014-04-04 15:10:52 +02:00
Aleric Inglewood
116fe01dee Add AIDebugInstanceCounter
Prints number of instances upon construction and destruction.
Usage:

class LLSomething : public AIDebugInstanceCounter<LLSomething>
...
2014-04-04 14:57:55 +02:00
Aleric Inglewood
ba2bf9f366 Get rid of unused and irrepairable code. 2014-04-04 14:57:41 +02:00
Aleric Inglewood
a5b68f2da2 Changes to llkeyframemotionparam.cpp as result of audit.
These changes were the result of my Motion leak audit.
However, there is a serious problem with LLKeyframeMotionParam
in that it stores plain pointers to objects that can and will be deleted
by other objects. Its the classicial LL example of coding
non-Object-Oriented badly maintainable and instable code.

I cannot make sure this won't go wrong for the simple fact
that LLKeyframeMotionParam is not used at ALL in our code.
Hence, the next commit will rather delete this file.
This commit is merely to have a record of this finding.
2014-04-04 14:57:31 +02:00
Inusaito Sayori
97edb0f954 [Floater Flexibility] Part three: Create the flexible toolbar and create the temporary settings for button visibility
Look in debug settings for settings that start with ToolbarVisible
This will have an official interface by part four.
2014-04-03 14:36:20 -04:00
Inusaito Sayori
a3531b931b Feature Request: Ding for groups and conference chats. 2014-04-03 01:27:27 -04:00
Aleric Inglewood
0438f070f7 Merge remote-tracking branch 'singu/master' 2014-04-01 01:28:55 +02:00
Inusaito Sayori
f53e36c430 Fix not being able to buy land because of inversed RLVa logic. 2014-03-31 13:12:33 -04:00
Inusaito Sayori
8889e2de64 Fix icon packaging on mac. 2014-03-31 12:22:12 -04:00
Shyotl
2d0b310e19 Framerate llinfos spew was clobbering cout decimal precision. 2014-03-29 02:19:14 -05:00
Shyotl
dfb465a11b Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git 2014-03-29 02:13:26 -05:00
Shyotl
9ed2dc755c Always set materials mask if deferred for materials/alpha pools. Fixes potential crash in LLDrawPoolAlpha::renderAlpha 2014-03-28 17:14:57 -05:00
Latif Khalifa
e70342b356 Removed duplicate check introduced in the last change 2014-03-28 16:42:27 +01:00
Latif Khalifa
ba0fd794d7 Compile fix 2014-03-28 16:20:38 +01:00
Latif Khalifa
dbd7de628f Fix compilation with gcc 2014-03-28 08:50:02 +01:00
Shyotl
d6fdaa93a4 Added adaptive vsync support (selectable in preferences->graphics->hardware, provided the driver supports it). Also hide 16x fsaa on amd hardware, as it is not supported on said hardware (unsure about intel). 2014-03-28 02:34:03 -05:00
Latif Khalifa
80076833d1 Fix compilation with gcc 2014-03-28 08:30:22 +01:00
Latif Khalifa
dc9d3fbf96 Fix build with SDL prior to 1.3.0 2014-03-28 08:29:30 +01:00
Latif Khalifa
e12548ab8c Merge branch 'master' of git://github.com/Shyotl/SingularityViewer 2014-03-28 08:45:40 +01:00
Shyotl
894261862d Tweaks to stencil handling to allow masking out of sky (or geometry).
Reset stencil clear value to 0 after done clearing.
2014-03-27 22:31:47 -05:00
Shyotl
07a261a259 A little bit of cleanup. 2014-03-27 22:04:30 -05:00
Shyotl
34a7bf4dbb Comment out unused shader. 2014-03-27 21:30:23 -05:00
Shyotl
5988f6cf88 Updated rigged mesh face batch/pool handling.
Fixed issue with fullbright and glow occlusion.
RenderTransparentWater toggling should work more gracefully.
Fixed some bugs in general drawpool classification for faces. Bump pool was superceding more than it should have.
2014-03-27 21:27:40 -05:00
Inusaito Sayori
039be1f8e9 Fix Issue 1413: Local Texture Default Texture Update Settings, Also fix the side issue of the More section not having visible ui at first.
Also I got fed up with the bad code and leaks so I did some refactoring of floaterlocalassetbrowse.*, but just a bit.
2014-03-27 21:33:21 -04:00
Inusaito Sayori
70e92a1cea More helpful fixes and touchups from Cinder 2014-03-27 20:10:06 -04:00
Inusaito Sayori
2af2e37dcd Right clicking folder with only gestures (no worn items) should still offer remove from outfit if any gesture in that folder is active.
Also follow linked folders when wearing folders, this will make linked folders a lot more useful!
Also fixes a warning and some spacing issues
2014-03-27 20:02:12 -04:00
Inusaito Sayori
a6559b1e51 [Floater Flexibility] Part two: Move floater dictionary into menu commands and use a common function to ShowFloaters between LLToolBar and menus. 2014-03-27 00:31:32 -04:00
Inusaito Sayori
361b8852df Fix Issue 1419: Moving a link to an inventory folder moves the pointed folder and not the link 2014-03-25 19:56:41 -04:00
Inusaito Sayori
ff201ce3f9 Fix Issue 1448: Hard crash when emptying the mute list. 2014-03-25 19:51:49 -04:00
Inusaito Sayori
de2ce83a8d Touchups to namesystem update 2014-03-25 19:39:02 -04:00
Inusaito Sayori
f37d83abe1 [Floater Flexibility] Part one: Refactor all floaters to work with the dictionary in one way or another. 2014-03-25 00:23:56 -04:00
Inusaito Sayori
ee610ceb3f The Name System update!
Adds name list specific name settings, Removes boolean for having lists of speakers with legacy names in favor of having a more flexible setting for them
Have a look at the combo boxes on Adv. Chat->Chat UI to customize these new settings.

There is now a fourth option for name display: LegaCy Name (D is play Name)
2014-03-24 17:52:13 -04:00
Inusaito Sayori
5affacab70 Fixes, mainly for Clang/Mac, from Cinder. 2014-03-24 16:56:10 -04:00
Latif Khalifa
924011f36e Merge branch 'master' of git://github.com/Lirusaito/SingularityViewer 2014-03-23 14:24:47 +01:00
Inusaito Sayori
70b5a6f05b Prevent Issue 1445, reassess enablement of asset browser buttons when selection may have changed 2014-03-23 06:03:20 -04:00
Inusaito Sayori
05c7270dcf Merge changes for STORM-2008
"Remove from outfit" should deactivate gestures in a folder as well as take off items
Credit to Lance Corrimal
2014-03-20 03:53:11 -04:00
Inusaito Sayori
a75e34d1c2 Feature Request: Allow "wear_folder" SLapps 2014-03-20 03:34:17 -04:00
Inusaito Sayori
f7139ac20e Fix Issue 1406: Create Landmark shows name twice, not description 2014-03-18 19:45:18 -04:00
Inusaito Sayori
e43d718e0f Sappadilli's fix for the mini button 2014-03-18 19:18:57 -04:00
Inusaito Sayori
cc0b5e660d Touch missed spots for picking rigged mesh 2014-03-18 18:38:30 -04:00
Latif Khalifa
8f525a37da Typofix 2014-03-17 00:20:32 +01:00
Latif Khalifa
5e62d2b104 Revert to using Vivox SDK 2 on Linux 2014-03-16 22:44:30 +01:00
Damian Zhaoying
6c373ee31e Update Spanish languages files 2014-03-15 05:14:07 -03:00
Lirusaito
d98c46beb0 Extend SGAllowRiggedMeshSelection to work in inspect and on others 2014-03-13 01:31:11 -04:00
Lirusaito
850772a4ce [RLVa] About floater version display adjustment 2014-03-12 22:21:55 -04:00
Latif Khalifa
08be65e649 Merge branch 'master' of git://github.com/Lirusaito/SingularityViewer 2014-03-13 02:04:59 +01:00
Lirusaito
ed8e37ed89 [RLVa] Updates thanks to Kitty
1ea7389, 49be412, ed4c8e6 & 7ce9521
- changed : "Give to #RLV" agent-to-agent and script-to-agent offers can contain subfolders
-> limited to 3 levels (e.g. #RLV/~FolderA/FolderB/FolderC)
-> #RLV folder is auto-created if it doesn't currently exist

8780d84 - Incremented version number to RLVa-1.4.10
f078067 - internal : boolean (custom) debug settings should have a boolean type
72a8ad8 & 401ca14 - internal : added supporting code for "Detach Folder" RLVa lock checks

05718b5
- fixed : RenderResolutionDivisor is non-functional
-> RenderResolutionDivisor isn't actually taken into account when checking the new screen resolution against the current screen buffer size

4fa138b
- fixed : viewer clips mouse to its rectangle when switching into mouselook while it's not the active application
-> Repro:
* rez a prim with a script to llForceMouseLook(TRUE) and force-sit when clicked (with a slight delay)
* click the prim and give focus to another application
=> the viewer will center the mouse cursor on itself and restrict movement to within its own rectangle (requires alt-tab to escape)
+ Singu Note: Thanks to Kitty for this, it is possible that this would happen in our last release

14132c9
- fixed : region name and global coordinates are shown on the About floater when @showloc restricted
+ Singu Note: RLV version is now shown in help->about

9a2af62 - changed : llRegionSayTo messages are no longer subject to @recvchat(from) or @recvemote(from)

2dc4b89
- fixed : @getstatus and @getstatusall should specify an (optional) separator
-> added support for both @getstatus:tp;|=123 and @getstatus:;|=123

fbb3fb1 - Incremented API version number to 2.8.0
92c39b9 - internal : quick and dirty hack fix for RlvUtil::filterNames() but there's no time to do a proper backport from RLVa-1.5
2580f1c - internal : remove hack for legacy viewers without multi-attachment support
2014-03-12 19:41:15 -04:00
Latif Khalifa
1732d6d427 [Voice Update] Sync default voice debug level with upstream. 2014-03-12 23:48:07 +01:00
Latif Khalifa
bb9a958a1e [Voice Update] Update SLVoice prebuilds and packaging script 2014-03-12 22:50:43 +01:00
Latif Khalifa
f1b8c36a28 Merge branch 'VoiceUpdate' of git://github.com/Lirusaito/SingularityViewer 2014-03-12 22:21:43 +01:00
Aleric Inglewood
03ed12a9b1 Merge remote-tracking branch 'singu/master' 2014-03-12 20:36:12 +01:00
Lirusaito
30f5a3a162 Update qtoolalign (Fixes issue 704)
- Removes shortcut ctrl-a for align tool
-- to avoid ctrl-a for select all text in UI controls messing up prim selection
- Adds llselectmgr select all function
-- to replace ctrl-a select all prims functionality that was a side effect of qtoolalign having this shortcut
- Adds toggle button (up/down arrow) to build floater for toggling display of the lower tab container area
-- This is to satisfy users who relied on ctrl-a to use align while the build floater was minimized and out of the way
- Syncs qtoolalign from Alchemy
2014-03-09 19:00:52 -04:00
Latif Khalifa
e4a3f76f55 Fixed an artifact of Root->Avatar Center rename (Sappadilli) 2014-03-02 20:05:49 +01:00
Drake Arconis
f5bdb56a7c Crash fixes in model upload 2014-03-01 18:53:51 -05:00
Drake Arconis
64d4a9e240 Add missing header guards 2014-03-01 18:00:59 -05:00
Drake Arconis
71d9084a95 Clean out old OGPX stuff 2014-03-01 17:34:22 -05:00
Latif Khalifa
9d6092faaa Merge branch 'master' of git://github.com/Shyotl/SingularityViewer 2014-02-21 09:30:08 +01:00
Shyotl
bb0f17ae6f Fix poor batching with mac/ancient drivers. Also, some minor tweaks to sorting algorithm. 2014-02-21 02:24:42 -06:00
Latif Khalifa
ebb46999d8 Merge branch 'master' of git://github.com/Shyotl/SingularityViewer 2014-02-20 10:31:47 +01:00
Shyotl
1c48aa8f97 Added missing can_batch_texture check. Fixes unbatchable faces occasionally getting batched with the last batchable face batch. This was mostly noticeable with animated faces. 2014-02-19 22:35:43 -06:00
Shyotl
bdc0ad2b8f Experimental volume face batching changes (Cursory testing shows: +~10% larger mean batch size).
-Drive pass selection by face pools. Doing such removes a fair bit of redundant (and often buggy) code.
-Ignore irrelivant batch breakers depending on pass/pool type.
-Face sorting algorithm modified to potentially allow larger batches.
-Removed a few unused/broken things (bake_sunlight/no_materials)
-Fullbright handling should hopefully be a little more consistent.
-Prevent fullbright faces from being placed in 'simple' pool. (They are already simple-er)

Fixed attribute error that popped up with bump faces when batching was disabled.
2014-02-18 11:43:50 -06:00
Shyotl
ac8d5e5ab3 Let shaders dictate vertex buffer attributes for alpha faces (if shaders are enabled) 2014-02-18 09:21:31 -06:00
Latif Khalifa
41416dcffe Merge branch 'master' of git://github.com/Shyotl/SingularityViewer 2014-02-11 03:23:21 +01:00
Shyotl
dda7cb5791 Lazy workaround avoiding undefined behavior for rigged meshes with invalid joints. 2014-02-10 20:20:03 -06:00
Shyotl
f7fdeeea9b Be super sure not to let rigged vert weights extend beyond actual joint count. 2014-02-10 20:18:39 -06:00
Shyotl
9d7d7590a7 Prevent debug visualizations from writing to the z-buffer (caused occlusion weirdness) 2014-02-09 23:40:03 -06:00
Inusaito Sayori
77848afc94 Tiny patch for Issue 1385: Use normal folders for outfits while still creating links for everything
Adds debug setting LiruLegacyOutfitAllLinks which overrides legacy outfit settings and forces the resulting folder to consist of only links
2014-02-09 14:42:19 -05:00
Inusaito Sayori
8f7e96e2a5 Minimap enhancements!!
Much of this patch comes from upstream and Kitty Barnett, or is inspired from their works
This commit applies the World-Minimap patches from Catznip.

Catznip stuffs:
- Issue 1383: Parcel lines on mini map
 - Show parcels on the minimap
 - Minimap menu: "Show" submenu: "Property Lines" "Parcels for Sale"
- Option to have world map textures on the minimap
 - Minimap menu: "World Map Textures"
 - Singular touch: Made this comply with hypergridding.

The minimap will now scroll zoom based on where your mouse is if centering on camera is off.

A lot of cruft was cleaned up in this merge, a lot of gSavedSettings lookups in draw were converted to LLCachedControls, some license updates were performed.

Finally: By myself, but inspired by upstream and requested in the group before:
- Option to show tracking circles around people selected on the radar while the radar is visible
 - Minimap menu: "Show" submenu: "Radar Tracking Circles"
2014-02-08 18:26:18 -05:00
Shyotl
eab807daeb Fix fullbright alpha in fixed-function. 2014-02-08 01:47:22 -06:00
Inusaito Sayori
c4bfdcbeac Address Issue 1381: Mouse look cross hair coloration
Adds debug setting LiruCrosshairColor
2014-02-07 14:59:03 -05:00
Inusaito Sayori
3801949887 Little bit more touching up to the italian XML, this time for overlay bar 2014-02-06 17:27:53 -05:00
Inusaito Sayori
29d5c951c5 [STORM-1981] Change tracking beacons to extend to the ground and (optionally) vertically indicate direction
Jonathan Yap's beacon enhancements, with a Singular twist!
2014-02-06 17:23:28 -05:00
Inusaito Sayori
eb4b0d630f [MAINT-2287] The rest of the updates so far to outbox. 2014-02-06 14:53:13 -05:00
Inusaito Sayori
b6225d1d9a [MAINT-2287] Handle refactor 2014-02-06 14:51:36 -05:00
Inusaito Sayori
32ec2be0b6 SimFeatures spew demoted to logcontrol debugs. 2014-02-05 21:39:50 -05:00
Inusaito Sayori
d7dfa91f6f Remove incorrect "You should upgrade your viewer." spew, and demote it to lldebugs. 2014-02-05 20:59:10 -05:00
Inusaito Sayori
c4cc9dd417 Stop leaking in object import! 2014-02-05 15:17:44 -05:00
Inusaito Sayori
884b707385 Hey toolbar, toolbar italiano! 2014-02-04 18:41:10 -05:00
Inusaito Sayori
acbc81c1ea Further Italian Translation purification, fixup, and touches. 2014-02-04 18:33:02 -05:00
Inusaito Sayori
cc60dcc8a4 Languages preferences in order with actual languages in the right place above, please, thank you? 2014-02-04 16:20:24 -05:00
Inusaito Sayori
275f85e7a6 Fix god chat not showing up in god color if the god is using a display name. 2014-02-04 15:21:13 -05:00
Latif Khalifa
24f99a2920 Merge remote-tracking branch 'lirusaito/master' 2014-02-04 01:40:42 +01:00
Inusaito Sayori
2acfbf12ed Fix Issue 1368: Camera viewing angle resets after mouselook.
Only reset FOV when right click was held or released just before leaving, now.
2014-02-03 17:20:25 -05:00
Inusaito Sayori
b0972de510 Address Issue 1371: Enhancement: in Edit object Positions X & Y for OpenSim VarRegion 2014-02-02 16:53:55 -05:00
Inusaito Sayori
af58636c7c Fix the Login Panel such that it persists until a successful login and maintains ui values between failed logins
When the login panel used to die, it now hides instead, we only truly kill it upon successful login.
Much of the opening and setting behaviors have been cleaned up to ensure fields are autofilled by the viewer without any user action once
Everything else like changing saved logins will still work the same.
2014-02-02 16:45:37 -05:00
Inusaito Sayori
7341ad5e6e Support the Script Message API 2014-02-02 16:36:05 -05:00
Inusaito Sayori
744e6c63b6 Fix Issue 1237: Last online says 01/01/1970 for group members
For real this time!
2014-02-02 16:29:06 -05:00
Inusaito Sayori
31aa30e3d0 Group Feature Request: Option to Copy SLURL for an avatar's profile
Added to avatar list menus and instant message drop down menu.
2014-02-02 16:27:20 -05:00
Aleric Inglewood
ebb4489c01 Merge remote-tracking branch 'singu/master' 2014-02-01 22:34:13 +01:00
Inusaito Sayori
31b3ae584e Feature request: menus on the region estate panel's scroll lists. 2014-01-31 00:52:59 -05:00
Inusaito Sayori
151afe4663 Translations fix ups 2014-01-31 00:52:16 -05:00
Inusaito Sayori
b03f7c1504 [RLVa] Version 1.4.9
Thanks to Trinity and, of course, her Kitty!
2014-01-31 00:50:45 -05:00
Inusaito Sayori
bceaee6e41 [RLVa] rlva strings floater!
Generalized toggle() visible() call pattern of rlv floaters to a template struct.
2014-01-31 00:47:19 -05:00
Inusaito Sayori
0c33c0de2e [RLVa] rlva_strings update.
rlva strings floater coming soon!

I highly doubt the translations work anymore
If they still can be translated, I leave it up to translators to decide if they should be
Contact me if you need translation code improved here.
2014-01-28 04:41:16 -05:00
Inusaito Sayori
1b32c79a5e [RLVa] Miscellaneous other touches to rlva code 2014-01-28 04:38:05 -05:00
Inusaito Sayori
dd35f1bd68 [RLVa] Missed sections of canStand update in that last commit. 2014-01-28 04:35:43 -05:00
Inusaito Sayori
9c0d8bbeb1 [RLVa] "blocked_wireframe"? Seems half baked, but it compiles. 2014-01-28 04:34:12 -05:00
Inusaito Sayori
02753bfc7d [RLVa] gRlvHandler.canStand --> RlvActions::canStand 2014-01-28 04:31:34 -05:00
Inusaito Sayori
88ae36f4e1 [RLVa] Forced TPRequest response is now supported! 2014-01-28 04:27:38 -05:00
Inusaito Sayori
4dcf8f3f45 [RLVa] Removal of z offset restrictions 2014-01-28 03:16:35 -05:00
Inusaito Sayori
9e82297303 [RLVa] rlvfloaterbehaviour.* -> rlvfloaters.* 2014-01-28 00:31:40 -05:00
Inusaito Sayori
14a885f8d0 [RLVa] Modernizations
License updates, comment updates, settings cleanup, macros cleanup, dead code removal, etc.
2014-01-27 23:43:16 -05:00
Inusaito Sayori
94aee52c64 [RLVa] b15fdd026026 ported
- internal : reviewed @recvim and @sendim for CHUI (SL-3.5)

Singu changes:
- Updated busy to be referred to as do_not_disturb in llviewermessage.cpp
- Don't send autoresponse if we can't send an IM by rlva
- Updated checks for from name being system to be to_id and from_id null checks.
- Minor compile fix in rlvui.cpp for last commit.
2014-01-27 23:42:09 -05:00
Inusaito Sayori
755d3be89b [RLVa] Disallow inventory floaters when inventory restricted.
Formatting eases the diff with rlva upstream
2014-01-27 20:14:02 -05:00
Inusaito Sayori
6a3ee5fac4 [RLVa] f9f8dbe23ec3 ported
- internal : reviewed @startim for CHUI (SL-3.5)
    -> fixed : "Start Conference Chat" on a selection of multiple calling cards opens an IM session
    -> fixed : actions that would result in an IM window opening shouldn't be blocked if the session is already open
    -> added : RlvActions class to mimick LLAvatarActions and lowering the rlvhandler.h include dependency
2014-01-27 13:54:13 -05:00
Aleric Inglewood
6547452136 Merge remote-tracking branch 'singu/master' 2014-01-25 20:29:46 +01:00
Inusaito Sayori
42bf70849c Fix Issue 1344: Weird mesh distorted bug
Animations require consistent names for points like Avatar Center between viewers
To fix this, we now use Avatar Center instead of Root at the lower levels,
but this is okay, we translate Avatar Center into Root at UI level!
2014-01-25 09:44:42 -05:00
Inusaito Sayori
236fa2a284 Fix Issue 870: Crouch toggle not reset when pressing "Fly" button, causes avatar to run/fly downhill.
Reimplements crouch toggle such that crouch is now tracked by the agent object
Fixes crouch being reset when restoring focus to the viewer window, as well.
2014-01-24 22:57:19 -05:00
Inusaito Sayori
2450b435a7 Combine commonly created scroll list menus into single menus identified by menu_num instead of their menu_file
sScrollListMenus is an array such that it will hold more menus in the future, such as groups.
fmenu_file still exists and will still exhibit its old behavior if used.
2014-01-24 21:41:56 -05:00
Inusaito Sayori
353e2977d6 [Voice Update] Further sync llvoiceclient and llvoicevivox with upstream
Mainly tiny motions to ease merging as viewer-vivox2 work continues
Condenses MultiVoice block
2013-07-27 16:48:35 -04:00
Inusaito Sayori
641067c399 [Voice Update] Apply updates from Viewer-Vivox2
Applies the following commits:
 4c13e7c - Interim version with SLIM removed from voice.
   4c13e7c753
 9cad21a - Thanks mercurial.
   9cad21adc1
   Only the changes that should have been in 4c13e7c (removal of LLVivoxVoiceClient::accountListBlockRulesSendMessage() and LLVivoxVoiceClient::accountListAutoAcceptRulesSendMessage())
 9c94b96 - Removed debugging.
   9c94b96ed3
 ec77595 - Turn off logging.
   ec775958ef
 857cab1 - Kill all the vivox logs
   857cab153e
2013-07-27 16:41:08 -04:00
972 changed files with 43637 additions and 27900 deletions

6
.gitignore vendored
View File

@@ -29,3 +29,9 @@ qtcreator-build/
/indra/newview/res/viewerRes.rc
/indra/newview/res/viewerRes_bc.rc
/indra/newview/English.lproj/InfoPlist.strings
/indra/newview/linux_tools/handle_secondlifeprotocol.sh
/indra/newview/linux_tools/install.sh
/indra/newview/linux_tools/refresh_desktop_app_entry.sh
/indra/newview/linux_tools/wrapper.sh

View File

@@ -0,0 +1,29 @@
INTEL LICENSE AGREEMENT
IMPORTANT - READ BEFORE COPYING OR USING.
Do not use or load this library and any associated materials (collectively,
the "Software") until you have read the following terms and conditions. By
loading or using the Software, you agree to the terms of this Agreement. If
you do not wish to so agree, do not use the Software.
LICENSE: Subject to the restrictions below, Intel Corporation ("Intel")
grants to you the permission to use, copy, distribute and prepare derivative
works of this Software for any purpose and without fee, provided, that
Intel's copyright notice appear in all copies of the Software files.
The distribution of derivative works of the Software is also subject to the
following limitations: you (i) are solely responsible to your customers for
any liability which may arise from the distribution, (ii) do not make any
statement that your product is "certified", or that its performance is
guaranteed, by Intel, and (iii) do not use Intel's name or trademarks to
market your product without written permission.
EXCLUSION OF ALL WARRANTIES. The Software is provided "AS IS" without any
express or implies warranty of any kind including warranties of
merchantability, noninfringement, or fitness for a particular purpose.
Intel does not warrant or assume responsibility for the accuracy or
completeness of any information contained within the Software.
As this Software is given free of charge, in no event shall Intel be liable
for any damages whatsoever arising out of the use of or inability to use the
Software, even if Intel has been adviced of the possibility of such damages.
Intel does not assume any responsibility for any errors which may appear in
this Software nor any responsibility to update it.

View File

@@ -293,7 +293,36 @@ void AIEngine::add(AIStateMachine* state_machine)
}
}
extern void print_statemachine_diagnostics(U64 total_clocks, U64 max_delta, AIEngine::queued_type::const_reference slowest_state_machine);
#if STATE_MACHINE_PROFILING
// Called from AIStateMachine::mainloop
void print_statemachine_diagnostics(U64 total_clocks, AIStateMachine::StateTimerBase::TimeData& slowest_timer, AIEngine::queued_type::const_reference slowest_element)
{
AIStateMachine const& slowest_state_machine = slowest_element.statemachine();
F64 const tfactor = 1000 / calc_clock_frequency();
std::ostringstream msg;
U64 max_delta = slowest_timer.GetDuration();
if (total_clocks > max_delta)
{
msg << "AIStateMachine::mainloop did run for " << (total_clocks * tfactor) << " ms. The slowest ";
}
else
{
msg << "AIStateMachine::mainloop: A ";
}
msg << "state machine " << "(" << slowest_state_machine.getName() << ") " << "ran for " << (max_delta * tfactor) << " ms";
if (slowest_state_machine.getRuntime() > max_delta)
{
msg << " (" << (slowest_state_machine.getRuntime() * tfactor) << " ms in total now)";
}
msg << ".\n";
AIStateMachine::StateTimerBase::DumpTimers(msg);
llwarns << msg.str() << llendl;
}
#endif
// MAIN-THREAD
void AIEngine::mainloop(void)
@@ -305,28 +334,33 @@ void AIEngine::mainloop(void)
queued_element = engine_state_w->list.begin();
}
U64 total_clocks = 0;
#ifndef LL_RELEASE_FOR_DOWNLOAD
U64 max_delta = 0;
#if STATE_MACHINE_PROFILING
queued_type::value_type slowest_element(NULL);
AIStateMachine::StateTimerRoot::TimeData slowest_timer;
#endif
while (queued_element != end)
{
AIStateMachine& state_machine(queued_element->statemachine());
U64 start = get_clock_count();
if (!state_machine.sleep(start))
AIStateMachine::StateTimerBase::TimeData time_data;
if (!state_machine.sleep(get_clock_count()))
{
state_machine.multiplex(AIStateMachine::normal_run);
AIStateMachine::StateTimerRoot timer(state_machine.getName());
state_machine.multiplex(AIStateMachine::normal_run);
time_data = timer.GetTimerData();
}
U64 delta = get_clock_count() - start;
state_machine.add(delta);
total_clocks += delta;
#ifndef LL_RELEASE_FOR_DOWNLOAD
if (delta > max_delta)
if (U64 delta = time_data.GetDuration())
{
max_delta = delta;
slowest_element = *queued_element;
}
state_machine.add(delta);
total_clocks += delta;
#if STATE_MACHINE_PROFILING
if (delta > slowest_timer.GetDuration())
{
slowest_element = *queued_element;
slowest_timer = time_data;
}
#endif
}
bool active = state_machine.active(this); // This locks mState shortly, so it must be called before locking mEngineState because add() locks mEngineState while holding mState.
engine_state_type_wat engine_state_w(mEngineState);
if (!active)
@@ -340,8 +374,8 @@ void AIEngine::mainloop(void)
}
if (total_clocks >= sMaxCount)
{
#ifndef LL_RELEASE_FOR_DOWNLOAD
print_statemachine_diagnostics(total_clocks, max_delta, slowest_element);
#if STATE_MACHINE_PROFILING
print_statemachine_diagnostics(total_clocks, slowest_timer, slowest_element);
#endif
Dout(dc::statemachine, "Sorting " << engine_state_w->list.size() << " state machines.");
engine_state_w->list.sort(QueueElementComp());
@@ -373,7 +407,7 @@ void AIEngine::setMaxCount(F32 StateMachineMaxTime)
sMaxCount = calc_clock_frequency() * StateMachineMaxTime / 1000;
}
#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
#ifdef CWDEBUG
char const* AIStateMachine::event_str(event_type event)
{
switch(event)
@@ -752,6 +786,22 @@ void AIStateMachine::multiplex(event_type event)
}
}
#if STATE_MACHINE_PROFILING
std::vector<AIStateMachine::StateTimerBase*> AIStateMachine::StateTimerBase::mTimerStack;
AIStateMachine::StateTimerBase::TimeData AIStateMachine::StateTimerBase::TimeData::sRoot("");
void AIStateMachine::StateTimer::TimeData::DumpTimer(std::ostringstream& msg, std::string prefix)
{
F64 const tfactor = 1000 / calc_clock_frequency();
msg << prefix << mName << " " << (mEnd - mStart)*tfactor << "ms" << std::endl;
prefix.push_back(' ');
std::vector<TimeData>::iterator it;
for (it = mChildren.begin(); it != mChildren.end(); ++it)
{
it->DumpTimer(msg, prefix);
}
}
#endif
AIStateMachine::state_type AIStateMachine::begin_loop(base_state_type base_state)
{
DoutEntering(dc::statemachine(mSMDebug), "AIStateMachine::begin_loop(" << state_str(base_state) << ") [" << (void*)this << "]");

View File

@@ -36,6 +36,7 @@
#include "aithreadsafe.h"
#include <llpointer.h>
#include "lltimer.h"
#include <list>
#include <boost/signals2.hpp>
@@ -98,11 +99,143 @@ class AIEngine
extern AIEngine gMainThreadEngine;
extern AIEngine gStateMachineThreadEngine;
#ifndef STATE_MACHINE_PROFILING
#ifndef LL_RELEASE_FOR_DOWNLOAD
#define STATE_MACHINE_PROFILING 1
#endif
#endif
class AIStateMachine : public LLThreadSafeRefCount
{
public:
typedef U32 state_type; //!< The type of run_state
// A simple timer class that will calculate time delta between ctor and GetTimerData call.
// Time data is stored as a nested TimeData object.
// If STATE_MACHINE_PROFILING is defined then a stack of all StateTimers from root is maintained for debug output.
class StateTimerBase
{
public:
class TimeData
{
friend class StateTimerBase;
public:
TimeData() : mStart(-1), mEnd(-1) {}
U64 GetDuration() { return mEnd - mStart; }
private:
U64 mStart, mEnd;
#if !STATE_MACHINE_PROFILING
TimeData(const std::string& name) : mStart(get_clock_count()), mEnd(get_clock_count()) {}
#else
TimeData(const std::string& name) : mName(name), mStart(get_clock_count()), mEnd(get_clock_count()) {}
void DumpTimer(std::ostringstream& msg, std::string prefix);
std::vector<TimeData> mChildren;
std::string mName;
static TimeData sRoot;
#endif
};
#if !STATE_MACHINE_PROFILING
StateTimerBase(const std::string& name) : mData(name) {}
~StateTimerBase() {}
protected:
TimeData mData;
// Return a copy of the underlying timer data.
// This allows the data live beyond the scope of the state timer.
public:
const TimeData GetTimerData()
{
mData.mEnd = get_clock_count(); //set mEnd to current time, since GetTimerData() will always be called before the dtor, obv.
return mData;
}
#else
protected:
// Ctors/dtors are hidden. Only StateTimerRoot and StateTimer are permitted to access them.
StateTimerBase() : mData(NULL) {}
~StateTimerBase()
{
// If mData is null then the timer was not registered due to being in the wrong thread or the root timer wasn't in the expected state.
if (!mData)
return;
mData->mEnd = get_clock_count();
mTimerStack.pop_back();
}
// Also hide internals from everything except StateTimerRoot and StateTimer
bool AddAsRoot(const std::string& name)
{
if (!is_main_thread())
return true; //Ignoring this timer, but pretending it was added.
if (!mTimerStack.empty())
return false;
TimeData::sRoot = TimeData(name);
mData = &TimeData::sRoot;
mData->mChildren.clear();
mTimerStack.push_back(this);
return true;
}
bool AddAsChild(const std::string& name)
{
if (!is_main_thread())
return true; //Ignoring this timer, but pretending it was added.
if (mTimerStack.empty())
return false;
mTimerStack.back()->mData->mChildren.push_back(TimeData(name));
mData = &mTimerStack.back()->mData->mChildren.back();
mTimerStack.push_back(this);
return true;
}
TimeData* mData;
static std::vector<StateTimerBase*> mTimerStack;
public:
// Debug spew
static void DumpTimers(std::ostringstream& msg)
{
TimeData::sRoot.DumpTimer(msg, "");
}
// Return a copy of the underlying timer data.
// This allows the data live beyond the scope of the state timer.
const TimeData GetTimerData() const
{
if (mData)
{
TimeData ret = *mData;
ret.mEnd = get_clock_count(); //set mEnd to current time, since GetTimerData() will always be called before the dtor, obv.
return ret;
}
return TimeData();
}
#endif
};
public:
#if !STATE_MACHINE_PROFILING
typedef StateTimerBase StateTimerRoot;
typedef StateTimerBase StateTimer;
#else
class StateTimerRoot : public StateTimerBase
{ //A StateTimerRoot can become a child if a root already exists.
public:
StateTimerRoot(const std::string& name)
{
if(!AddAsRoot(name))
AddAsChild(name);
}
};
class StateTimer : public StateTimerBase
{ //A StateTimer can never become a root
public:
StateTimer(const std::string& name)
{
AddAsChild(name);
}
};
#endif
protected:
// The type of event that causes multiplex() to be called.
enum event_type {
@@ -197,7 +330,7 @@ class AIStateMachine : public LLThreadSafeRefCount
bool mDebugAdvanceStatePending; // True while advance_state() was called by not handled yet.
bool mDebugRefCalled; // True when ref() is called (or will be called within the critial area of mMultiplexMutex).
#endif
#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
#ifdef CWDEBUG
protected:
bool mSMDebug; // Print debug output only when true.
#endif
@@ -210,7 +343,7 @@ class AIStateMachine : public LLThreadSafeRefCount
mThreadId(AIThreadID::none), mDebugLastState(bs_killed), mDebugShouldRun(false), mDebugAborted(false), mDebugContPending(false),
mDebugSetStatePending(false), mDebugAdvanceStatePending(false), mDebugRefCalled(false),
#endif
#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
#ifdef CWDEBUG
mSMDebug(debug),
#endif
mRuntime(0)
@@ -295,13 +428,16 @@ class AIStateMachine : public LLThreadSafeRefCount
// Return stringified state, for debugging purposes.
char const* state_str(base_state_type state);
#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
#ifdef CWDEBUG
char const* event_str(event_type event);
#endif
void add(U64 count) { mRuntime += count; }
U64 getRuntime(void) const { return mRuntime; }
// For diagnostics. Every derived class must override this.
virtual const char* getName() const = 0;
protected:
virtual void initialize_impl(void) = 0;
virtual void multiplex_impl(state_type run_state) = 0;

View File

@@ -182,7 +182,7 @@ class AIStateMachineThreadBase : public AIStateMachine {
protected:
AIStateMachineThreadBase(CWD_ONLY(bool debug))
#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
#ifdef CWDEBUG
: AIStateMachine(debug)
#endif
{ }
@@ -222,7 +222,7 @@ class AIStateMachineThread : public AIStateMachineThreadBase {
public:
// Constructor.
AIStateMachineThread(CWD_ONLY(bool debug))
#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
#ifdef CWDEBUG
: AIStateMachineThreadBase(debug)
#endif
{
@@ -232,6 +232,13 @@ class AIStateMachineThread : public AIStateMachineThreadBase {
// Accessor.
THREAD_IMPL& thread_impl(void) { return mThreadImpl; }
/*virtual*/ const char* getName() const
{
#define STRIZE(arg) #arg
return "AIStateMachineThread<"STRIZE(THREAD_IMPL)">";
#undef STRIZE
}
protected:
/*virtual*/ AIThreadImpl& impl(void) { return mThreadImpl; }
};

View File

@@ -77,7 +77,7 @@ class AITimer : public AIStateMachine {
public:
AITimer(CWD_ONLY(bool debug = false)) :
#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
#ifdef CWDEBUG
AIStateMachine(debug),
#endif
mInterval(0) { DoutEntering(dc::statemachine(mSMDebug), "AITimer(void) [" << (void*)this << "]"); }
@@ -98,6 +98,8 @@ class AITimer : public AIStateMachine {
*/
F64 getInterval(void) const { return mInterval; }
/*virtual*/ const char* getName() const { return "AITimer"; }
protected:
// Call finish() (or abort()), not delete.
/*virtual*/ ~AITimer() { DoutEntering(dc::statemachine(mSMDebug), "~AITimer() [" << (void*)this << "]"); mFrameTimer.cancel(); }

View File

@@ -54,6 +54,9 @@ if (WINDOWS)
# Remove default /Zm1000 flag that cmake inserts
string (REPLACE "/Zm1000" " " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
# Always use /Zm140
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zm140")
# Don't build DLLs.
set(BUILD_SHARED_LIBS OFF)
@@ -246,30 +249,28 @@ endif (LINUX)
if (DARWIN)
add_definitions(-DLL_DARWIN=1 -D_XOPEN_SOURCE)
set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first")
add_definitions(-DLL_DARWIN=1)
set(CMAKE_CXX_LINK_FLAGS "-Wl,-no_compact_unwind -Wl,-headerpad_max_install_names,-search_paths_first")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS}")
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mlong-branch")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mlong-branch")
# NOTE: it's critical that the optimization flag is put in front.
# NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered.
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O3 -msse3 -mtune=generic -mfpmath=sse ${GCC_EXTRA_OPTIMIZATIONS}")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# NOTE: it's critical that the optimization flag is put in front.
# NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered.
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -msse3")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 -msse3")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3 -msse3")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O3 -msse3")
endif()
set(DARWIN_extra_cstar_flags "-g")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DARWIN_extra_cstar_flags} -ftemplate-depth=256")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${DARWIN_extra_cstar_flags}")
# NOTE: it's critical that the optimization flag is put in front.
# NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered.
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O0 ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O0 ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_X86_VECTOR_INSTRUCTIONS SSE3)
set(CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL -O3)
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -msse3 ${CMAKE_CXX_FLAGS_RELEASE}")
set(CMAKE_C_FLAGS_RELEASE "-O3 -msse3 ${CMAKE_C_FLAGS_RELEASE}")
if (XCODE_VERSION GREATER 4.2)
set(ENABLE_SIGNING TRUE)
set(SIGNING_IDENTITY "Developer ID Application: Linden Research, Inc.")
endif (XCODE_VERSION GREATER 4.2)
endif (DARWIN)
if (LINUX OR DARWIN)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
add_definitions(-DLL_GNUC=1)
@@ -277,13 +278,11 @@ if (LINUX OR DARWIN)
set(UNIX_CXX_WARNINGS "${UNIX_WARNINGS} -Wno-reorder -Wno-non-virtual-dtor -Woverloaded-virtual")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
add_definitions(-DLL_CLANG=1)
set(UNIX_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs -Wno-tautological-compare -Wno-char-subscripts -Wno-gnu -Wno-logical-op-parentheses -Wno-non-virtual-dtor")
set(UNIX_WARNINGS "${UNIX_WARNINGS} -Woverloaded-virtual -Wno-parentheses-equality -Wno-reorder -Wno-unused-function -Wno-unused-value -Wno-unused-variable")
set(UNIX_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs -Wno-tautological-compare -Wno-char-subscripts -Wno-gnu -Wno-logical-op-parentheses -Wno-logical-not-parentheses -Wno-non-virtual-dtor -Wno-deprecated")
set(UNIX_WARNINGS "${UNIX_WARNINGS} -Woverloaded-virtual -Wno-parentheses-equality -Wno-reorder -Wno-unused-function -Wno-unused-value -Wno-unused-variable -Wno-unused-private-field -Wno-parentheses")
set(UNIX_CXX_WARNINGS "${UNIX_WARNINGS}")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
add_definitions(-DLL_ICC=1)
set(UNIX_WARNINGS "-wd327 -wd597 -wd858")
set(UNIX_CXX_WARNINGS "${UNIX_WARNINGS}")
endif ()
if (NOT DISABLE_FATAL_WARNINGS)

View File

@@ -52,6 +52,29 @@ if (DARWIN)
)
endif (DARWIN)
if (LINUX)
configure_file(
${CMAKE_SOURCE_DIR}/newview/linux_tools/wrapper.sh.in
${CMAKE_SOURCE_DIR}/newview/linux_tools/wrapper.sh
@ONLY
)
configure_file(
${CMAKE_SOURCE_DIR}/newview/linux_tools/handle_secondlifeprotocol.sh.in
${CMAKE_SOURCE_DIR}/newview/linux_tools/handle_secondlifeprotocol.sh
@ONLY
)
configure_file(
${CMAKE_SOURCE_DIR}/newview/linux_tools/install.sh.in
${CMAKE_SOURCE_DIR}/newview/linux_tools/install.sh
@ONLY
)
configure_file(
${CMAKE_SOURCE_DIR}/newview/linux_tools/refresh_desktop_app_entry.sh.in
${CMAKE_SOURCE_DIR}/newview/linux_tools/refresh_desktop_app_entry.sh
@ONLY
)
endif (LINUX)
# Compose the version.
set(viewer_VERSION "${vMAJOR}.${vMINOR}.${vPATCH}.${vBUILD}")
if (viewer_VERSION MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$")

View File

@@ -16,11 +16,14 @@ endif(WORD_SIZE EQUAL 32)
set(vivox_src_dir "${CMAKE_SOURCE_DIR}/newview/vivox-runtime/i686-win32")
set(vivox_files
SLVoice.exe
alut.dll
vivoxsdk.dll
ca-bundle.crt
libsndfile-1.dll
ortp.dll
wrap_oal.dll
SLVoice.exe
vivoxoal.dll
vivoxplatform.dll
vivoxsdk.dll
zlib1.dll
)
copy_if_different(
${vivox_src_dir}

View File

@@ -97,24 +97,54 @@ endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(DARWIN 1)
if(${CMAKE_GENERATOR} MATCHES "Xcode")
#SDK Compiler and Deployment targets for XCode
if (${XCODE_VERSION} VERSION_LESS 4.0.0)
set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk)
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5)
else (${XCODE_VERSION} VERSION_LESS 4.0.0)
set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.6.sdk)
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
endif (${XCODE_VERSION} VERSION_LESS 4.0.0)
else(${CMAKE_GENERATOR} MATCHES "Xcode")
set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.6.sdk)
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
endif(${CMAKE_GENERATOR} MATCHES "Xcode")
execute_process(
COMMAND sh -c "xcodebuild -version | grep Xcode | cut -d ' ' -f2 | cut -d'.' -f1-2"
OUTPUT_VARIABLE XCODE_VERSION )
string(REGEX REPLACE "(\r?\n)+$" "" XCODE_VERSION "${XCODE_VERSION}")
# # To support a different SDK update these Xcode settings:
# if (XCODE_VERSION GREATER 4.9) # (Which would be 5.0+)
# set(CMAKE_OSX_DEPLOYMENT_TARGET 10.8)
# set(CMAKE_OSX_SYSROOT macosx10.9)
# else (XCODE_VERION GREATER 4.9)
# if (XCODE_VERSION GREATER 4.5)
# set(CMAKE_OSX_DEPLOYMENT_TARGET 10.7)
# set(CMAKE_OSX_SYSROOT macosx10.8)
# else (XCODE_VERSION GREATER 4.5)
# if (XCODE_VERSION GREATER 4.2)
# set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
# set(CMAKE_OSX_SYSROOT macosx10.7)
# else (XCODE_VERSION GREATER 4.2)
# set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
# set(CMAKE_OSX_SYSROOT macosx10.7)
# endif (XCODE_VERSION GREATER 4.2)
# endif (XCODE_VERSION GREATER 4.5)
# endif (XCODE_VERSION GREATER 4.9)
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42")
# Hardcode SDK we build against until we can test and allow newer ones
# as autodetected in the code above
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
set(CMAKE_OSX_SYSROOT macosx10.6)
# Support for Unix Makefiles generator
if (CMAKE_GENERATOR STREQUAL "Unix Makefiles")
execute_process(COMMAND xcodebuild -version -sdk "${CMAKE_OSX_SYSROOT}" Path | head -n 1 OUTPUT_VARIABLE CMAKE_OSX_SYSROOT)
string(REGEX REPLACE "(\r?\n)+$" "" CMAKE_OSX_SYSROOT "${CMAKE_OSX_SYSROOT}")
endif (CMAKE_GENERATOR STREQUAL "Unix Makefiles")
# LLVM-GCC has been removed in Xcode5
if (XCODE_VERSION GREATER 4.9)
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvm.clang.1_0")
else (XCODE_VERSION GREATER 4.9)
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42")
endif (XCODE_VERSION GREATER 4.9)
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf-with-dsym)
message(STATUS "Xcode version: ${XCODE_VERSION}")
message(STATUS "OSX sysroot: ${CMAKE_OSX_SYSROOT}")
message(STATUS "OSX deployment target: ${CMAKE_OSX_DEPLOYMENT_TARGET}")
# Build only for i386 by default, system default on MacOSX 10.6 is x86_64
set(CMAKE_OSX_ARCHITECTURES i386)
set(ARCH i386)

View File

@@ -28,97 +28,16 @@
#ifndef CWDEBUG
#ifdef DEBUG_CURLIO
// If CWDEBUG is not defined, but DEBUG_CURLIO is, then replace
// some of the cwd macro's with something that generates viewer
// specific debug output. Note that this generates a LOT of
// output and should not normally be defined.
#include <string>
#include "llpreprocessor.h"
namespace debug {
namespace libcwd {
struct buf2str {
buf2str(char const* buf, int size) : mBuf(buf), mSize(size) { }
char const* mBuf;
int mSize;
};
struct libcwd_do_type {
void on() const { }
};
extern LL_COMMON_API libcwd_do_type const libcw_do;
} // namespace libcwd
enum print_thread_id_t { print_thread_id };
inline void init() { }
struct Indent {
int M_indent;
static ll_thread_local int S_indentation;
enum LL_COMMON_API print_nt { print };
LL_COMMON_API Indent(int indent);
LL_COMMON_API ~Indent();
};
extern LL_COMMON_API std::ostream& operator<<(std::ostream& os, libcwd::buf2str const& b2s);
extern LL_COMMON_API std::ostream& operator<<(std::ostream& os, Indent::print_nt);
extern LL_COMMON_API std::ostream& operator<<(std::ostream& os, print_thread_id_t);
namespace dc {
struct fake_channel {
int mOn;
char const* mLabel;
fake_channel(int on, char const* label) : mOn(on), mLabel(label) { }
fake_channel(void) : mOn(0) { }
fake_channel& operator()(bool) { return *this; }
fake_channel const& operator()(bool) const { return *this; }
bool is_on() const { return !!mOn; }
bool is_off() const { return !mOn; }
void on() const { }
void off() const { }
};
extern LL_COMMON_API fake_channel const warning;
extern LL_COMMON_API fake_channel const curl;
extern LL_COMMON_API fake_channel const curlio;
extern LL_COMMON_API fake_channel const curltr;
extern LL_COMMON_API fake_channel const statemachine;
extern LL_COMMON_API fake_channel const notice;
extern LL_COMMON_API fake_channel const snapshot;
} // namespace dc
} // namespace debug
#define LIBCWD_DEBUG_CHANNELS debug
#define LibcwDoutScopeBegin(a, b, c) do { using namespace debug; using namespace debug::libcwd; llinfos_nf << print_thread_id << (c).mLabel << ": " << Indent::print;
#define LibcwDoutStream llcont
#define LibcwDoutScopeEnd llcont << llendl; } while(0)
#define Debug(x) do { using namespace debug; using namespace debug::libcwd; x; } while(0)
#define Dout(a, b) do { using namespace debug; using namespace debug::libcwd; if ((a).mOn) { llinfos_nf << print_thread_id << (a).mLabel << ": " << Indent::print << b << llendl; } } while(0)
#define DoutEntering(a, b) \
int __slviewer_debug_indentation = 2; \
{ \
using namespace debug; \
using namespace debug::libcwd; \
if ((a).mOn) \
llinfos_nf << print_thread_id << (a).mLabel << ": " << Indent::print << "Entering " << b << llendl; \
else \
__slviewer_debug_indentation = 0; \
} \
debug::Indent __slviewer_debug_indent(__slviewer_debug_indentation);
#else // !DEBUG_CURLIO
#error DEBUG_CURLIO is not supported without libcwd.
// In order to use DEBUG_CURLIO you must install and use libcwd.
// Download libcwd:
// git clone https://github.com/CarloWood/libcwd.git
#endif
#define Debug(x)
#define Dout(a, b)
#define DoutEntering(a, b)
#endif // !DEBUG_CURLIO
#ifndef DOXYGEN // No need to document this. See http://libcwd.sourceforge.net/ for more info.
#include <iostream>
@@ -392,6 +311,40 @@ void InstanceTracker<T>::dump(void)
} // namespace debug
template<class T>
class AIDebugInstanceCounter
{
public:
static int sInstanceCount;
protected:
static void print_count(char const* name, int count, bool destruction);
AIDebugInstanceCounter()
{
print_count(typeid(T).name(), ++sInstanceCount, false);
}
AIDebugInstanceCounter(AIDebugInstanceCounter const&)
{
print_count(typeid(T).name(), ++sInstanceCount, false);
}
~AIDebugInstanceCounter()
{
print_count(typeid(T).name(), --sInstanceCount, true);
}
};
//static
template<class T>
int AIDebugInstanceCounter<T>::sInstanceCount;
//static
template<class T>
void AIDebugInstanceCounter<T>::print_count(char const* name, int count, bool destruction)
{
Dout(dc::notice, (destruction ? "Destructed " : "Constructing ") << name << ", now " << count << " instance" << ((count == 1) ? "." : "s."));
}
//! Debugging macro.
//
// Print "Entering " << \a data to channel \a cntrl and increment

View File

@@ -169,7 +169,7 @@ class PlatformSetup(object):
raise
def parse_build_opts(self, arguments):
opts, targets = getopt.getopt(arguments, 'o:', ['option='])
opts, targets = getopt.getopt(arguments, 'D:o:', ['option='])
build_opts = []
for o, a in opts:
if o in ('-o', '--option'):
@@ -221,6 +221,7 @@ class UnixSetup(PlatformSetup):
exe_suffixes = ('',)
def __init__(self):
PlatformSetup.__init__(self)
super(UnixSetup, self).__init__()
self.generator = 'Unix Makefiles'
@@ -263,6 +264,7 @@ class UnixSetup(PlatformSetup):
class LinuxSetup(UnixSetup):
def __init__(self):
UnixSetup.__init__(self)
super(LinuxSetup, self).__init__()
try:
self.debian_sarge = open('/etc/debian_version').read().strip() == '3.1'
@@ -384,6 +386,7 @@ class LinuxSetup(UnixSetup):
class DarwinSetup(UnixSetup):
def __init__(self):
UnixSetup.__init__(self)
super(DarwinSetup, self).__init__()
self.generator = 'Xcode'
@@ -457,6 +460,7 @@ class WindowsSetup(PlatformSetup):
exe_suffixes = ('.exe', '.bat', '.com')
def __init__(self):
PlatformSetup.__init__(self)
super(WindowsSetup, self).__init__()
self._generator = None
self.incredibuild = False
@@ -497,7 +501,10 @@ class WindowsSetup(PlatformSetup):
return 'win32'
def build_dirs(self):
return ['build-' + self.generator]
if self.word_size == 64:
return ['build-' + self.generator + '-Win64']
else:
return ['build-' + self.generator]
def cmake_commandline(self, src_dir, build_dir, opts, simple):
args = dict(
@@ -605,15 +612,15 @@ class WindowsSetup(PlatformSetup):
if environment == '':
environment = self.find_visual_studio_express()
if environment == '':
environment = self.find_visual_studio_express_single()
if environment == '':
print >> sys.stderr, "Something went very wrong during build stage, could not find a Visual Studio?"
else:
build_dirs=self.build_dirs()
print >> sys.stderr, "\nSolution generation complete, it can can now be found in:", build_dirs[0]
print >> sys.stderr, "\nAs you are using an Express Visual Studio, the build step cannot be automated"
print >> sys.stderr, "\nPlease see https://wiki.secondlife.com/wiki/Microsoft_Visual_Studio#Extra_steps_for_Visual_Studio_Express_editions for Visual Studio Express specific information"
exit(0)
environment = self.find_visual_studio_express_single()
if environment == '':
print >> sys.stderr, "Something went very wrong during build stage, could not find a Visual Studio?"
else:
build_dirs=self.build_dirs()
print >> sys.stderr, "\nSolution generation complete, it can can now be found in:", build_dirs[0]
print >> sys.stderr, "\nAs you are using an Express Visual Studio, the build step cannot be automated"
print >> sys.stderr, "\nPlease see https://wiki.secondlife.com/wiki/Microsoft_Visual_Studio#Extra_steps_for_Visual_Studio_Express_editions for Visual Studio Express specific information"
exit(0)
# devenv.com is CLI friendly, devenv.exe... not so much.
return ('"%sdevenv.com" %s.sln /build %s' %
@@ -655,7 +662,7 @@ class WindowsSetup(PlatformSetup):
os.path.join(build_dir,'Singularity.sln') +
' --config ' + self.build_type +
' --startup secondlife-bin')
print 'Running %r in %r' % (vstool_cmd, getcwd())
print 'Running vstool %r in %r' % (vstool_cmd, getcwd())
self.run(vstool_cmd)
print >> open(stamp, 'w'), self.build_type
@@ -669,11 +676,11 @@ class WindowsSetup(PlatformSetup):
if targets:
for t in targets:
cmd = '%s /project %s %s' % (build_cmd, t, ' '.join(opts))
print 'Running %r in %r' % (cmd, d)
print 'Running build(targets) %r in %r' % (cmd, d)
self.run(cmd)
else:
cmd = '%s %s' % (build_cmd, ' '.join(opts))
print 'Running %r in %r' % (cmd, d)
print 'Running build %r in %r' % (cmd, d)
self.run(cmd)
finally:
os.chdir(cwd)
@@ -694,6 +701,8 @@ class CygwinSetup(WindowsSetup):
project_name=self.project_name,
word_size=self.word_size,
)
if self.word_size == 64:
args["generator"] += r' Win64'
#if simple:
# return 'cmake %(opts)s "%(dir)s"' % args
return ('cmake -G "%(generator)s" '

View File

@@ -39,6 +39,7 @@ import shutil
import sys
import tarfile
import errno
import subprocess
def path_ancestors(path):
drive, path = os.path.splitdrive(os.path.normpath(path))
@@ -393,20 +394,19 @@ class LLManifest(object):
debugging/informational purpoases, prints out the command's
output as it is received."""
print "Running command:", command
fd = os.popen(command, 'r')
fd = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
lines = []
while True:
lines.append(fd.readline())
lines.append(fd.stdout.readline())
if lines[-1] == '':
break
else:
print lines[-1],
print lines[-1].rstrip('\n'),
output = ''.join(lines)
status = fd.close()
if status:
if fd.returncode:
raise RuntimeError(
"Command %s returned non-zero status (%s) \noutput:\n%s"
% (command, status, output) )
% (command, fd.returncode, output) )
return output
def created_path(self, path):

View File

@@ -317,7 +317,7 @@ namespace HACD
bool m_addFacesPoints; //>! specifies whether to add faces points or not
bool m_addExtraDistPoints; //>! specifies whether to add extra points for concave shapes or not
friend HACD * const CreateHACD(HeapManager * heapManager = 0);
friend HACD * const CreateHACD(HeapManager * heapManager);
friend void DestroyHACD(HACD * const hacd);
};
inline HACD * const CreateHACD(HeapManager * heapManager)

View File

@@ -7,7 +7,7 @@ include(00-Common)
include_directories(${LIBS_OPEN_DIR}/libhacd)
set (libndhacd_SOURCE_FILES
LLConvexDecomposition.cpp
llconvexdecomposition.cpp
nd_hacdConvexDecomposition.cpp
nd_hacdStructs.cpp
nd_hacdUtils.cpp
@@ -16,12 +16,12 @@ set (libndhacd_SOURCE_FILES
)
set (libndhacd_HEADER_FILES
LLConvexDecomposition.h
llconvexdecomposition.h
ndConvexDecomposition.h
nd_hacdConvexDecomposition.h
nd_hacdStructs.h
nd_StructTracer.h
LLConvexDecompositionStubImpl.h
llconvexdecompositionstubimpl.h
nd_EnterExitTracer.h
nd_hacdDefines.h
nd_hacdUtils.h

View File

@@ -1,5 +1,5 @@
/**
* @file LLConvexDecomposition.cpp
* @file llconvexdecomposition.cpp
* @author falcon@lindenlab.com
* @brief A stub implementation of LLConvexDecomposition interface
*
@@ -35,7 +35,7 @@
#include "nd_hacdConvexDecomposition.h"
#include "LLConvexDecomposition.h"
#include "llconvexdecomposition.h"
/*static */bool LLConvexDecomposition::s_isInitialized = false;

View File

@@ -1,5 +1,5 @@
/**
* @file LLConvexDecomposition.cpp
* @file llconvexdecomposition.cpp
* @brief LLConvexDecomposition interface definition
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$

View File

@@ -1,5 +1,5 @@
/**
* @file LLConvexDecompositionStubImpl.cpp
* @file llconvexdecompositionstubimpl.cpp
* @author falcon@lindenlab.com
* @brief A stub implementation of LLConvexDecomposition
*
@@ -28,7 +28,7 @@
#include <string.h>
#include <memory>
#include "LLConvexDecompositionStubImpl.h"
#include "llconvexdecompositionstubimpl.h"
LLConvexDecomposition* LLConvexDecompositionImpl::getInstance()
{

View File

@@ -1,5 +1,5 @@
/**
* @file LLConvexDecompositionStubImpl.h
* @file llconvexdecompositionstubimpl.h
* @author falcon@lindenlab.com
* @brief A stub implementation of LLConvexDecomposition
*
@@ -29,7 +29,7 @@
#ifndef LL_CONVEX_DECOMP_UTIL_H
#define LL_CONVEX_DECOMP_UTIL_H
#include "LLConvexDecomposition.h"
#include "llconvexdecomposition.h"
class LLConvexDecompositionImpl : public LLConvexDecomposition
{

View File

@@ -21,7 +21,7 @@
#include "ndConvexDecomposition.h"
#include "LLConvexDecomposition.h"
#include "llconvexdecomposition.h"
#include "nd_hacdStructs.h"
namespace ndStructTracer

View File

@@ -19,7 +19,7 @@
#ifndef ND_HACD_CONVEXDECOMP_H
#define ND_HACD_CONVEXDECOMP_H
#include "LLConvexDecomposition.h"
#include "llconvexdecomposition.h"
#include <map>
#include <vector>

View File

@@ -17,7 +17,6 @@
*/
#include "nd_hacdStructs.h"
#include "LLConvexDecomposition.h"
void DecompHull::clear()
{

View File

@@ -21,7 +21,7 @@
#include "nd_hacdDefines.h"
#include "hacdHACD.h"
#include "LLConvexDecomposition.h"
#include "llconvexdecomposition.h"
#include <vector>
struct LLCDHull;

View File

@@ -20,7 +20,6 @@
#define ND_HACD_UTILS_H
#include "nd_hacdStructs.h"
#include "LLConvexDecomposition.h"
tHACD* init( int nConcavity, int nClusters, int nMaxVerticesPerHull, double dMaxConnectDist, HACDDecoder *aData );
DecompData decompose( tHACD *aHACD );

View File

@@ -983,19 +983,19 @@ BOOL LLAvatarAppearance::loadSkeletonNode ()
mRoot->addChild(mMeshLOD[MESH_ID_SKIRT]);
mRoot->addChild(mMeshLOD[MESH_ID_HEAD]);
LLAvatarJoint *skull = (LLAvatarJoint*)mRoot->findJoint("mSkull");
LLJoint *skull = mRoot->findJoint("mSkull");
if (skull)
{
skull->addChild(mMeshLOD[MESH_ID_HAIR] );
}
LLAvatarJoint *eyeL = (LLAvatarJoint*)mRoot->findJoint("mEyeLeft");
LLJoint *eyeL = mRoot->findJoint("mEyeLeft");
if (eyeL)
{
eyeL->addChild( mMeshLOD[MESH_ID_EYEBALL_LEFT] );
}
LLAvatarJoint *eyeR = (LLAvatarJoint*)mRoot->findJoint("mEyeRight");
LLJoint *eyeR = mRoot->findJoint("mEyeRight");
if (eyeR)
{
eyeR->addChild( mMeshLOD[MESH_ID_EYEBALL_RIGHT] );

View File

@@ -105,8 +105,9 @@ void LLAvatarJoint::setValid( BOOL valid, BOOL recursive )
for (child_list_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = (LLAvatarJoint*)(*iter);
joint->setValid(valid, TRUE);
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
if (joint)
joint->setValid(valid, TRUE);
}
}
@@ -124,7 +125,8 @@ void LLAvatarJoint::setSkeletonComponents( U32 comp, BOOL recursive )
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
joint->setSkeletonComponents(comp, recursive);
if (joint)
joint->setSkeletonComponents(comp, recursive);
}
}
}
@@ -138,8 +140,9 @@ void LLAvatarJoint::setVisible(BOOL visible, BOOL recursive)
for (child_list_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = (LLAvatarJoint*)(*iter);
joint->setVisible(visible, recursive);
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
if(joint)
joint->setVisible(visible, recursive);
}
}
}
@@ -150,7 +153,8 @@ void LLAvatarJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pix
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
joint->updateFaceSizes(num_vertices, num_indices, pixel_area);
if (joint)
joint->updateFaceSizes(num_vertices, num_indices, pixel_area);
}
}
@@ -160,7 +164,8 @@ void LLAvatarJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind,
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
joint->updateFaceData(face, pixel_area, damp_wind, terse_update);
if (joint)
joint->updateFaceData(face, pixel_area, damp_wind, terse_update);
}
}
@@ -170,7 +175,8 @@ void LLAvatarJoint::updateJointGeometry()
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
joint->updateJointGeometry();
if (joint)
joint->updateJointGeometry();
}
}
@@ -184,6 +190,9 @@ BOOL LLAvatarJoint::updateLOD(F32 pixel_area, BOOL activate)
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
if (!joint)
continue;
F32 jointLOD = joint->getLOD();
if (found_lod || jointLOD == DEFAULT_AVATAR_JOINT_LOD)
@@ -213,7 +222,8 @@ void LLAvatarJoint::dump()
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
joint->dump();
if (joint)
joint->dump();
}
}
@@ -260,7 +270,7 @@ void LLAvatarJointCollisionVolume::renderCollision()
updateWorldMatrix();
gGL.pushMatrix();
gGL.multMatrix( &mXform.getWorldMatrix().mMatrix[0][0] );
gGL.multMatrix( mXform.getWorldMatrix() );
gGL.diffuseColor3f( 0.f, 0.f, 1.f );

View File

@@ -83,30 +83,28 @@ LLSkinJoint::~LLSkinJoint()
//-----------------------------------------------------------------------------
// LLSkinJoint::setupSkinJoint()
//-----------------------------------------------------------------------------
BOOL LLSkinJoint::setupSkinJoint( LLAvatarJoint *joint)
void LLSkinJoint::setupSkinJoint( LLJoint *joint)
{
mRootToJointSkinOffset.clearVec();
mRootToParentJointSkinOffset.clearVec();
// find the named joint
mJoint = joint;
if ( !mJoint )
if (!(mJoint = joint))
{
llinfos << "Can't find joint" << llendl;
return;
}
// compute the inverse root skin matrix
mRootToJointSkinOffset.clearVec();
LLVector3 rootSkinOffset;
while (joint)
do
{
rootSkinOffset += joint->getSkinOffset();
joint = (LLAvatarJoint*)joint->getParent();
}
mRootToJointSkinOffset -= joint->getSkinOffset();
} while (joint = joint->getParent());
mRootToJointSkinOffset = -rootSkinOffset;
mRootToParentJointSkinOffset = mRootToJointSkinOffset;
mRootToParentJointSkinOffset += mJoint->getSkinOffset();
return TRUE;
return;
}
@@ -307,15 +305,14 @@ void LLAvatarJointMesh::setMesh( LLPolyMesh *mesh )
for (jn = 0; jn < numJointNames; jn++)
{
//llinfos << "Setting up joint " << jointNames[jn] << llendl;
LLAvatarJoint* joint = (LLAvatarJoint*)(getRoot()->findJoint(jointNames[jn]) );
mSkinJoints[jn].setupSkinJoint( joint );
mSkinJoints[jn].setupSkinJoint( getRoot()->findJoint(jointNames[jn]) );
}
}
// setup joint array
if (!mMesh->isLOD())
{
setupJoint((LLAvatarJoint*)getRoot());
setupJoint(getRoot());
}
// llinfos << "joint render entries: " << mMesh->mJointRenderData.count() << llendl;
@@ -324,7 +321,7 @@ void LLAvatarJointMesh::setMesh( LLPolyMesh *mesh )
//-----------------------------------------------------------------------------
// setupJoint()
//-----------------------------------------------------------------------------
void LLAvatarJointMesh::setupJoint(LLAvatarJoint* current_joint)
void LLAvatarJointMesh::setupJoint(LLJoint* current_joint)
{
// llinfos << "Mesh: " << getName() << llendl;
@@ -345,7 +342,7 @@ void LLAvatarJointMesh::setupJoint(LLAvatarJoint* current_joint)
if(mMesh->mJointRenderData.count() && mMesh->mJointRenderData[mMesh->mJointRenderData.count() - 1]->mWorldMatrix == &current_joint->getParent()->getWorldMatrix())
{
// ...then just add ourselves
LLAvatarJoint* jointp = js.mJoint;
LLJoint* jointp = js.mJoint;
mMesh->mJointRenderData.put(new LLJointRenderData(&jointp->getWorldMatrix(), &js));
// llinfos << "joint " << joint_count << js.mJoint->getName() << llendl;
// joint_count++;
@@ -366,8 +363,9 @@ void LLAvatarJointMesh::setupJoint(LLAvatarJoint* current_joint)
for (LLJoint::child_list_t::iterator iter = current_joint->mChildren.begin();
iter != current_joint->mChildren.end(); ++iter)
{
LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter);
setupJoint(child_joint);
LLAvatarJoint* child_joint = dynamic_cast<LLAvatarJoint*>(*iter);
if(child_joint)
setupJoint(child_joint);
}
}

View File

@@ -49,9 +49,9 @@ class LLSkinJoint
public:
LLSkinJoint();
~LLSkinJoint();
BOOL setupSkinJoint( LLAvatarJoint *joint);
void setupSkinJoint( LLJoint *joint);
LLAvatarJoint *mJoint;
LLJoint* mJoint;
LLVector3 mRootToJointSkinOffset;
LLVector3 mRootToParentJointSkinOffset;
};
@@ -122,7 +122,7 @@ public:
void setMesh( LLPolyMesh *mesh );
// Sets up joint matrix data for rendering
void setupJoint(LLAvatarJoint* current_joint);
void setupJoint(LLJoint* current_joint);
// Sets ID for picking
void setMeshID( S32 id ) {mMeshID = id;}

View File

@@ -231,9 +231,9 @@ BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices )
mBaseCoords = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a));
mBaseNormals = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a));
mBaseBinormals = (LLVector4a*) ll_aligned_malloc_16(numVertices*sizeof(LLVector4a));
mTexCoords = (LLVector2*) ll_aligned_malloc_16(numVertices*sizeof(LLVector2));
mDetailTexCoords = (LLVector2*) ll_aligned_malloc_16(numVertices*sizeof(LLVector2));
mWeights = (F32*) ll_aligned_malloc_16(numVertices*sizeof(F32));
mTexCoords = (LLVector2*) ll_aligned_malloc_16((numVertices+numVertices%2)*sizeof(LLVector2));
mDetailTexCoords = (LLVector2*) ll_aligned_malloc_16((numVertices+numVertices%2)*sizeof(LLVector2));
mWeights = (F32*) ll_aligned_malloc_16(((numVertices)*sizeof(F32)+0xF) & ~0xF);
for (i = 0; i < numVertices; i++)
{
mBaseCoords[i].clear();

View File

@@ -146,10 +146,10 @@ public:
class LLJointRenderData
{
public:
LLJointRenderData(const LLMatrix4* world_matrix, LLSkinJoint* skin_joint) : mWorldMatrix(world_matrix), mSkinJoint(skin_joint) {}
LLJointRenderData(const LLMatrix4a* world_matrix, LLSkinJoint* skin_joint) : mWorldMatrix(world_matrix), mSkinJoint(skin_joint) {}
~LLJointRenderData(){}
const LLMatrix4* mWorldMatrix;
const LLMatrix4a* mWorldMatrix;
LLSkinJoint* mSkinJoint;
};

View File

@@ -154,13 +154,13 @@ BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
iter != joint->mChildren.end(); ++iter)
{
LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter);
if (child_joint->inheritScale())
{
LLVector3 childDeformation = LLVector3(child_joint->getScale());
childDeformation.scaleVec(bone_info->mScaleDeformation);
mJointScales[child_joint] = childDeformation;
}
LLAvatarJoint* child_joint = dynamic_cast<LLAvatarJoint*>(*iter);
if (child_joint && child_joint->inheritScale())
{
LLVector3 childDeformation = LLVector3(child_joint->getScale());
childDeformation.scaleVec(bone_info->mScaleDeformation);
mJointScales[child_joint] = childDeformation;
}
}
if (bone_info->mHasPositionDeformation)

View File

@@ -68,7 +68,16 @@ class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo
{
friend class LLPolySkeletalDistortion;
public:
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}
LLPolySkeletalDistortionInfo();
/*virtual*/ ~LLPolySkeletalDistortionInfo() {};
@@ -77,12 +86,12 @@ public:
protected:
typedef std::vector<LLPolySkeletalBoneInfo> bone_info_list_t;
bone_info_list_t mBoneInfoList;
};
} LL_ALIGN_POSTFIX(16);
//-----------------------------------------------------------------------------
// LLPolySkeletalDeformation
// A set of joint scale data for deforming the avatar mesh
//-----------------------------------------------------------------------------
LL_ALIGN_PREFIX(16)
class LLPolySkeletalDistortion : public LLViewerVisualParam
{
public:

View File

@@ -24,7 +24,7 @@
*/
#ifndef LL_LLAUDIODECODEMGR_H
#define LL_LLAUDIODECODEMG_H
#define LL_LLAUDIODECODEMGR_H
#include "stdtypes.h"

View File

@@ -29,7 +29,6 @@ set(llcharacter_SOURCE_FILES
lljointsolverrp3.cpp
llkeyframefallmotion.cpp
llkeyframemotion.cpp
llkeyframemotionparam.cpp
llkeyframestandmotion.cpp
llkeyframewalkmotion.cpp
llmotion.cpp
@@ -57,7 +56,6 @@ set(llcharacter_HEADER_FILES
lljointstate.h
llkeyframefallmotion.h
llkeyframemotion.h
llkeyframemotionparam.h
llkeyframestandmotion.h
llkeyframewalkmotion.h
llmotion.h

View File

@@ -72,21 +72,11 @@ LLCharacter::~LLCharacter()
delete param;
}
U32 i ;
U32 size = sInstances.size() ;
for(i = 0 ; i < size ; i++)
{
if(sInstances[i] == this)
{
break ;
}
}
bool erased = vector_replace_with_last(sInstances,this);
llassert_always(i < size) ;
llassert_always(erased) ;
llassert_always(sAllowInstancesChange) ;
sInstances[i] = sInstances[size - 1] ;
sInstances.pop_back() ;
}
@@ -136,7 +126,6 @@ LLMotion* LLCharacter::findMotion( const LLUUID &id )
//-----------------------------------------------------------------------------
// createMotion()
// NOTE: Always assign the result to a LLPointer!
//-----------------------------------------------------------------------------
LLMotion* LLCharacter::createMotion( const LLUUID &id )
{
@@ -195,11 +184,26 @@ void LLCharacter::updateMotions(e_update_t update_type)
{
if (update_type == HIDDEN_UPDATE)
{
//<singu>
// Keep updating avatars that have at least one motion that is synchronized with a still running motion.
// This call tells the other controllers that we are in principle hidden.
// It returns false if we need to keep updating anyway.
if (!mMotionController.hidden(true))
{
mMotionController.updateMotions(LLCharacter::NORMAL_UPDATE);
return;
}
//</singu>
LLFastTimer t(FTM_UPDATE_HIDDEN_ANIMATION);
mMotionController.updateMotionsMinimal();
}
else
{
//<singu>
// This call tells the other controllers that we are visible and that they need
// to keep updating if they are synchronized with us, even if they are hidden.
mMotionController.hidden(false);
//</singu>
LLFastTimer t(FTM_UPDATE_ANIMATION);
// unpause if the number of outstanding pause requests has dropped to the initial one
if (mMotionController.isPaused() && mPauseRequest->getNumRefs() == 1)
@@ -529,3 +533,17 @@ LLAnimPauseRequest LLCharacter::requestPause()
return mPauseRequest;
}
void LLCharacter::requestPause(std::vector<LLAnimPauseRequest>& avatar_pause_handles)
{
mMotionController.pauseAllMotions();
avatar_pause_handles.push_back(mPauseRequest);
}
void LLCharacter::pauseAllSyncedCharacters(std::vector<LLAnimPauseRequest>& avatar_pause_handles)
{
// Pause this avatar.
requestPause(avatar_pause_handles);
// Also pause all avatars with synchronized motions.
mMotionController.pauseAllSyncedCharacters(avatar_pause_handles);
}

View File

@@ -146,6 +146,7 @@ public:
// is this motion active?
BOOL isMotionActive( const LLUUID& id );
bool isMotionActive(U32 bit) const { return mMotionController.isactive(bit); }
// Event handler for motion deactivation.
// Called when a motion has completely stopped and has been deactivated.
@@ -158,6 +159,8 @@ public:
void updateMotions(e_update_t update_type);
LLAnimPauseRequest requestPause();
void requestPause(std::vector<LLAnimPauseRequest>& avatar_pause_handles);
void pauseAllSyncedCharacters(std::vector<LLAnimPauseRequest>& avatar_pause_handles);
BOOL areAnimationsPaused() const { return mMotionController.isPaused(); }
void setAnimTimeFactor(F32 factor) { mMotionController.setTimeFactor(factor); }
void setTimeStep(F32 time_step) { mMotionController.setTimeStep(time_step); }

View File

@@ -49,7 +49,7 @@ S32 LLEditingMotion::sHandPosePriority = 3;
// LLEditingMotion()
// Class Constructor
//-----------------------------------------------------------------------------
LLEditingMotion::LLEditingMotion( const LLUUID &id) : LLMotion(id)
LLEditingMotion::LLEditingMotion(LLUUID const& id, LLMotionController* controller) : AIMaskedMotion(id, controller, ANIM_AGENT_EDITING)
{
mCharacter = NULL;
@@ -155,7 +155,7 @@ BOOL LLEditingMotion::onActivate()
mShoulderJoint.setRotation( mShoulderState->getJoint()->getRotation() );
mElbowJoint.setRotation( mElbowState->getJoint()->getRotation() );
return TRUE;
return AIMaskedMotion::onActivate();
}
//-----------------------------------------------------------------------------
@@ -256,12 +256,4 @@ BOOL LLEditingMotion::onUpdate(F32 time, U8* joint_mask)
return result;
}
//-----------------------------------------------------------------------------
// LLEditingMotion::onDeactivate()
//-----------------------------------------------------------------------------
void LLEditingMotion::onDeactivate()
{
}
// End

View File

@@ -49,11 +49,11 @@
// class LLEditingMotion
//-----------------------------------------------------------------------------
class LLEditingMotion :
public LLMotion
public AIMaskedMotion
{
public:
// Constructor
LLEditingMotion(const LLUUID &id);
LLEditingMotion(LLUUID const& id, LLMotionController* controller);
// Destructor
virtual ~LLEditingMotion();
@@ -65,7 +65,7 @@ public:
// static constructor
// all subclasses must implement such a function and register it
static LLMotion *create(const LLUUID &id) { return new LLEditingMotion(id); }
static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLEditingMotion(id, controller); }
public:
//-------------------------------------------------------------------------
@@ -107,9 +107,6 @@ public:
// must return FALSE when the motion is completed.
virtual BOOL onUpdate(F32 time, U8* joint_mask);
// called when a motion is deactivated
virtual void onDeactivate();
public:
//-------------------------------------------------------------------------
// joint states to be animated

View File

@@ -61,7 +61,7 @@ const F32 HAND_MORPH_BLEND_TIME = 0.2f;
// LLHandMotion()
// Class Constructor
//-----------------------------------------------------------------------------
LLHandMotion::LLHandMotion(const LLUUID &id) : LLMotion(id)
LLHandMotion::LLHandMotion(LLUUID const& id, LLMotionController* controller) : AIMaskedMotion(id, controller, ANIM_AGENT_HAND_MOTION)
{
mCharacter = NULL;
mLastTime = 0.f;
@@ -112,7 +112,7 @@ BOOL LLHandMotion::onActivate()
mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], 1.f);
mCharacter->updateVisualParams();
}
return TRUE;
return AIMaskedMotion::onActivate();
}
@@ -235,14 +235,6 @@ BOOL LLHandMotion::onUpdate(F32 time, U8* joint_mask)
return TRUE;
}
//-----------------------------------------------------------------------------
// LLHandMotion::onDeactivate()
//-----------------------------------------------------------------------------
void LLHandMotion::onDeactivate()
{
}
//-----------------------------------------------------------------------------
// LLHandMotion::getHandPoseName()
//-----------------------------------------------------------------------------

View File

@@ -45,7 +45,7 @@
// class LLHandMotion
//-----------------------------------------------------------------------------
class LLHandMotion :
public LLMotion
public AIMaskedMotion
{
public:
typedef enum e_hand_pose
@@ -68,7 +68,7 @@ public:
} eHandPose;
// Constructor
LLHandMotion(const LLUUID &id);
LLHandMotion(LLUUID const& id, LLMotionController* controller);
// Destructor
virtual ~LLHandMotion();
@@ -80,7 +80,7 @@ public:
// static constructor
// all subclasses must implement such a function and register it
static LLMotion *create(const LLUUID &id) { return new LLHandMotion(id); }
static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLHandMotion(id, controller); }
public:
//-------------------------------------------------------------------------
@@ -122,9 +122,6 @@ public:
// must return FALSE when the motion is completed.
virtual BOOL onUpdate(F32 time, U8* joint_mask);
// called when a motion is deactivated
virtual void onDeactivate();
virtual BOOL canDeprecate() { return FALSE; }
static std::string getHandPoseName(eHandPose pose);

View File

@@ -76,8 +76,8 @@ const F32 EYE_BLINK_TIME_DELTA = 0.005f; // time between one eye starting a blin
// LLHeadRotMotion()
// Class Constructor
//-----------------------------------------------------------------------------
LLHeadRotMotion::LLHeadRotMotion(const LLUUID &id) :
LLMotion(id),
LLHeadRotMotion::LLHeadRotMotion(LLUUID const& id, LLMotionController* controller) :
AIMaskedMotion(id, controller, ANIM_AGENT_HEAD_ROT),
mCharacter(NULL),
mTorsoJoint(NULL),
mHeadJoint(NULL)
@@ -104,7 +104,10 @@ LLHeadRotMotion::~LLHeadRotMotion()
LLMotion::LLMotionInitStatus LLHeadRotMotion::onInitialize(LLCharacter *character)
{
if (!character)
{
llwarns << "character is NULL." << llendl;
return STATUS_FAILURE;
}
mCharacter = character;
mPelvisJoint = character->getJoint("mPelvis");
@@ -169,16 +172,6 @@ LLMotion::LLMotionInitStatus LLHeadRotMotion::onInitialize(LLCharacter *characte
return STATUS_SUCCESS;
}
//-----------------------------------------------------------------------------
// LLHeadRotMotion::onActivate()
//-----------------------------------------------------------------------------
BOOL LLHeadRotMotion::onActivate()
{
return TRUE;
}
//-----------------------------------------------------------------------------
// LLHeadRotMotion::onUpdate()
//-----------------------------------------------------------------------------
@@ -263,19 +256,11 @@ BOOL LLHeadRotMotion::onUpdate(F32 time, U8* joint_mask)
}
//-----------------------------------------------------------------------------
// LLHeadRotMotion::onDeactivate()
//-----------------------------------------------------------------------------
void LLHeadRotMotion::onDeactivate()
{
}
//-----------------------------------------------------------------------------
// LLEyeMotion()
// Class Constructor
//-----------------------------------------------------------------------------
LLEyeMotion::LLEyeMotion(const LLUUID &id) : LLMotion(id)
LLEyeMotion::LLEyeMotion(LLUUID const& id, LLMotionController* controller) : AIMaskedMotion(id, controller, ANIM_AGENT_EYE)
{
mCharacter = NULL;
mEyeJitterTime = 0.f;
@@ -343,16 +328,6 @@ LLMotion::LLMotionInitStatus LLEyeMotion::onInitialize(LLCharacter *character)
return STATUS_SUCCESS;
}
//-----------------------------------------------------------------------------
// LLEyeMotion::onActivate()
//-----------------------------------------------------------------------------
BOOL LLEyeMotion::onActivate()
{
return TRUE;
}
//-----------------------------------------------------------------------------
// LLEyeMotion::onUpdate()
//-----------------------------------------------------------------------------
@@ -533,6 +508,8 @@ void LLEyeMotion::onDeactivate()
{
joint->setRotation(LLQuaternion::DEFAULT);
}
AIMaskedMotion::onDeactivate();
}
// End

View File

@@ -46,11 +46,11 @@
// class LLHeadRotMotion
//-----------------------------------------------------------------------------
class LLHeadRotMotion :
public LLMotion
public AIMaskedMotion
{
public:
// Constructor
LLHeadRotMotion(const LLUUID &id);
LLHeadRotMotion(LLUUID const& id, LLMotionController* controller);
// Destructor
virtual ~LLHeadRotMotion();
@@ -62,7 +62,7 @@ public:
// static constructor
// all subclasses must implement such a function and register it
static LLMotion *create(const LLUUID &id) { return new LLHeadRotMotion(id); }
static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLHeadRotMotion(id, controller); }
public:
//-------------------------------------------------------------------------
@@ -94,19 +94,11 @@ public:
// must return true to indicate success and be available for activation
virtual LLMotionInitStatus onInitialize(LLCharacter *character);
// called when a motion is activated
// must return TRUE to indicate success, or else
// it will be deactivated
virtual BOOL onActivate();
// called per time step
// must return TRUE while it is active, and
// must return FALSE when the motion is completed.
virtual BOOL onUpdate(F32 time, U8* joint_mask);
// called when a motion is deactivated
virtual void onDeactivate();
public:
//-------------------------------------------------------------------------
// joint states to be animated
@@ -129,11 +121,11 @@ public:
// class LLEyeMotion
//-----------------------------------------------------------------------------
class LLEyeMotion :
public LLMotion
public AIMaskedMotion
{
public:
// Constructor
LLEyeMotion(const LLUUID &id);
LLEyeMotion(LLUUID const& id, LLMotionController* controller);
// Destructor
virtual ~LLEyeMotion();
@@ -145,7 +137,7 @@ public:
// static constructor
// all subclasses must implement such a function and register it
static LLMotion *create( const LLUUID &id) { return new LLEyeMotion(id); }
static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLEyeMotion(id, controller); }
public:
//-------------------------------------------------------------------------
@@ -177,11 +169,6 @@ public:
// must return true to indicate success and be available for activation
virtual LLMotionInitStatus onInitialize(LLCharacter *character);
// called when a motion is activated
// must return TRUE to indicate success, or else
// it will be deactivated
virtual BOOL onActivate();
// called per time step
// must return TRUE while it is active, and
// must return FALSE when the motion is completed.

View File

@@ -312,19 +312,15 @@ void LLJoint::setWorldPosition( const LLVector3& pos )
return;
}
LLMatrix4 temp_matrix = getWorldMatrix();
temp_matrix.mMatrix[VW][VX] = pos.mV[VX];
temp_matrix.mMatrix[VW][VY] = pos.mV[VY];
temp_matrix.mMatrix[VW][VZ] = pos.mV[VZ];
LLMatrix4a temp_matrix = getWorldMatrix();
temp_matrix.setTranslate_affine(pos);
LLMatrix4 parentWorldMatrix = mParent->getWorldMatrix();
LLMatrix4 invParentWorldMatrix = parentWorldMatrix.invert();
LLMatrix4a invParentWorldMatrix = mParent->getWorldMatrix();
invParentWorldMatrix.invert();
temp_matrix *= invParentWorldMatrix;
invParentWorldMatrix.mul(temp_matrix);
LLVector3 localPos( temp_matrix.mMatrix[VW][VX],
temp_matrix.mMatrix[VW][VY],
temp_matrix.mMatrix[VW][VZ] );
LLVector3 localPos( invParentWorldMatrix.getRow<LLMatrix4a::ROW_TRANS>().getF32ptr() );
setPosition( localPos );
}
@@ -383,19 +379,19 @@ void LLJoint::setWorldRotation( const LLQuaternion& rot )
this->setRotation( rot );
return;
}
LLMatrix4a parentWorldMatrix = mParent->getWorldMatrix();
LLQuaternion2 rota(rot);
LLMatrix4a temp_mat(rota);
LLMatrix4 temp_mat(rot);
LLMatrix4a invParentWorldMatrix = mParent->getWorldMatrix();
invParentWorldMatrix.setTranslate_affine(LLVector3(0.f));
LLMatrix4 parentWorldMatrix = mParent->getWorldMatrix();
parentWorldMatrix.mMatrix[VW][VX] = 0;
parentWorldMatrix.mMatrix[VW][VY] = 0;
parentWorldMatrix.mMatrix[VW][VZ] = 0;
invParentWorldMatrix.invert();
LLMatrix4 invParentWorldMatrix = parentWorldMatrix.invert();
invParentWorldMatrix.mul(temp_mat);
temp_mat *= invParentWorldMatrix;
setRotation(LLQuaternion(temp_mat));
setRotation(LLQuaternion(LLMatrix4(invParentWorldMatrix.getF32ptr())));
}
@@ -425,7 +421,7 @@ void LLJoint::setScale( const LLVector3& scale )
//--------------------------------------------------------------------
// getWorldMatrix()
//--------------------------------------------------------------------
const LLMatrix4 &LLJoint::getWorldMatrix()
const LLMatrix4a &LLJoint::getWorldMatrix()
{
updateWorldMatrixParent();

View File

@@ -41,7 +41,7 @@
#include "lldarray.h"
const S32 LL_CHARACTER_MAX_JOINTS_PER_MESH = 15;
const U32 LL_CHARACTER_MAX_JOINTS = 32; // must be divisible by 4!
const U32 LL_CHARACTER_MAX_JOINTS = 32; // must be divisible by 16!
const U32 LL_HAND_JOINT_NUM = 31;
const U32 LL_FACE_JOINT_NUM = 30;
const S32 LL_CHARACTER_MAX_PRIORITY = 7;
@@ -162,7 +162,7 @@ public:
void setScale( const LLVector3& scale );
// get/set world matrix
const LLMatrix4 &getWorldMatrix();
const LLMatrix4a &getWorldMatrix();
void setWorldMatrix( const LLMatrix4& mat );
void updateWorldMatrixChildren();

View File

@@ -171,12 +171,14 @@ void LLJointSolverRP3::solve()
//-------------------------------------------------------------------------
// get the poleVector in world space
//-------------------------------------------------------------------------
LLMatrix4 worldJointAParentMat;
LLVector3 poleVec = mPoleVector;
if ( mJointA->getParent() )
{
worldJointAParentMat = mJointA->getParent()->getWorldMatrix();
LLVector4a pole_veca;
pole_veca.load3(mPoleVector.mV);
mJointA->getParent()->getWorldMatrix().rotate(pole_veca,pole_veca);
poleVec.set(pole_veca.getF32ptr());
}
LLVector3 poleVec = rotate_vector( mPoleVector, worldJointAParentMat );
//-------------------------------------------------------------------------
// compute the following:

View File

@@ -49,7 +49,7 @@
// LLKeyframeFallMotion()
// Class Constructor
//-----------------------------------------------------------------------------
LLKeyframeFallMotion::LLKeyframeFallMotion(const LLUUID &id) : LLKeyframeMotion(id)
LLKeyframeFallMotion::LLKeyframeFallMotion(LLUUID const& id, LLMotionController* controller) : LLKeyframeMotion(id, controller)
{
mVelocityZ = 0.f;
mCharacter = NULL;

View File

@@ -47,7 +47,7 @@ class LLKeyframeFallMotion :
{
public:
// Constructor
LLKeyframeFallMotion(const LLUUID &id);
LLKeyframeFallMotion(LLUUID const& id, LLMotionController* controller);
// Destructor
virtual ~LLKeyframeFallMotion();
@@ -59,7 +59,7 @@ public:
// static constructor
// all subclasses must implement such a function and register it
static LLMotion *create(const LLUUID &id) { return new LLKeyframeFallMotion(id); }
static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLKeyframeFallMotion(id, controller); }
public:
//-------------------------------------------------------------------------

View File

@@ -84,38 +84,55 @@ LLKeyframeMotion::JointMotionList::~JointMotionList()
for_each(mJointMotionArray.begin(), mJointMotionArray.end(), DeletePointer());
}
U32 LLKeyframeMotion::JointMotionList::dumpDiagInfo()
//Singu: add parameter 'silent'.
U32 LLKeyframeMotion::JointMotionList::dumpDiagInfo(bool silent) const
{
S32 total_size = sizeof(JointMotionList);
for (U32 i = 0; i < getNumJointMotions(); i++)
{
LLKeyframeMotion::JointMotion* joint_motion_p = mJointMotionArray[i];
LLKeyframeMotion::JointMotion const* joint_motion_p = mJointMotionArray[i];
llinfos << "\tJoint " << joint_motion_p->mJointName << llendl;
if (!silent)
{
llinfos << "\tJoint " << joint_motion_p->mJointName << llendl;
}
if (joint_motion_p->mUsage & LLJointState::SCALE)
{
llinfos << "\t" << joint_motion_p->mScaleCurve.mNumKeys << " scale keys at "
<< joint_motion_p->mScaleCurve.mNumKeys * sizeof(ScaleKey) << " bytes" << llendl;
if (!silent)
{
llinfos << "\t" << joint_motion_p->mScaleCurve.mNumKeys << " scale keys at "
<< joint_motion_p->mScaleCurve.mNumKeys * sizeof(ScaleKey) << " bytes" << llendl;
}
total_size += joint_motion_p->mScaleCurve.mNumKeys * sizeof(ScaleKey);
}
if (joint_motion_p->mUsage & LLJointState::ROT)
{
llinfos << "\t" << joint_motion_p->mRotationCurve.mNumKeys << " rotation keys at "
<< joint_motion_p->mRotationCurve.mNumKeys * sizeof(RotationKey) << " bytes" << llendl;
if (!silent)
{
llinfos << "\t" << joint_motion_p->mRotationCurve.mNumKeys << " rotation keys at "
<< joint_motion_p->mRotationCurve.mNumKeys * sizeof(RotationKey) << " bytes" << llendl;
}
total_size += joint_motion_p->mRotationCurve.mNumKeys * sizeof(RotationKey);
}
if (joint_motion_p->mUsage & LLJointState::POS)
{
llinfos << "\t" << joint_motion_p->mPositionCurve.mNumKeys << " position keys at "
<< joint_motion_p->mPositionCurve.mNumKeys * sizeof(PositionKey) << " bytes" << llendl;
if (!silent)
{
llinfos << "\t" << joint_motion_p->mPositionCurve.mNumKeys << " position keys at "
<< joint_motion_p->mPositionCurve.mNumKeys * sizeof(PositionKey) << " bytes" << llendl;
}
total_size += joint_motion_p->mPositionCurve.mNumKeys * sizeof(PositionKey);
}
}
llinfos << "Size: " << total_size << " bytes" << llendl;
//Singu: Also add memory used by the constraints.
S32 constraints_size = mConstraints.size() * sizeof(constraint_list_t::value_type);
total_size += constraints_size;
if (!silent)
{
llinfos << "\t" << mConstraints.size() << " constraints at " << constraints_size << " bytes" << llendl;
llinfos << "Size: " << total_size << " bytes" << llendl;
}
return total_size;
}
@@ -427,9 +444,8 @@ void LLKeyframeMotion::JointMotion::update(LLJointState* joint_state, F32 time,
// LLKeyframeMotion()
// Class Constructor
//-----------------------------------------------------------------------------
LLKeyframeMotion::LLKeyframeMotion(const LLUUID &id)
: LLMotion(id),
mJointMotionList(NULL),
LLKeyframeMotion::LLKeyframeMotion(const LLUUID &id, LLMotionController* controller)
: LLMotion(id, controller),
mPelvisp(NULL),
mLastSkeletonSerialNum(0),
mLastUpdateTime(0.f),
@@ -452,9 +468,9 @@ LLKeyframeMotion::~LLKeyframeMotion()
//-----------------------------------------------------------------------------
// create()
//-----------------------------------------------------------------------------
LLMotion *LLKeyframeMotion::create(const LLUUID &id)
LLMotion* LLKeyframeMotion::create(LLUUID const& id, LLMotionController* controller)
{
return new LLKeyframeMotion(id);
return new LLKeyframeMotion(id, controller);
}
//-----------------------------------------------------------------------------
@@ -517,6 +533,7 @@ LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *charact
case ASSET_FETCHED:
return STATUS_HOLD;
case ASSET_FETCH_FAILED:
llwarns << "Trying to initialize a motion that failed to be fetched." << llendl;
return STATUS_FAILURE;
case ASSET_LOADED:
return STATUS_SUCCESS;
@@ -526,7 +543,7 @@ LLMotion::LLMotionInitStatus LLKeyframeMotion::onInitialize(LLCharacter *charact
break;
}
LLKeyframeMotion::JointMotionList* joint_motion_list = LLKeyframeDataCache::getKeyframeData(getID());
LLKeyframeMotion::JointMotionListPtr joint_motion_list = LLKeyframeDataCache::getKeyframeData(getID());
if(joint_motion_list)
{
@@ -801,7 +818,44 @@ void LLKeyframeMotion::onDeactivate()
//-----------------------------------------------------------------------------
// setStopTime()
//-----------------------------------------------------------------------------
// time is in seconds since character creation
//
// Consider a looping animation of 20 frames, where the loop in point is at 3 frames
// and the loop out point at 16 frames:
//
// The first 3 frames of the animation would be the "loop in" animation.
// The last 4 frames of the animation would be the "loop out" animation.
// Frames 4 through 15 would be the looping animation frames.
//
// If the animation would not be looping, all frames would just be played once sequentially:
//
// mActivationTimestamp -.
// v
// 0 3 15 16 20
// | | \| |
// ---------------------
// <--> <-- mLoopInPoint (relative to mActivationTimestamp)
// <--------------> <-- mLoopOutPoint (relative to mActivationTimestamp)
// <----mDuration------>
//
// When looping the animation would repeat frames 3 to 16 (loop) a few times, for example:
//
// 0 3 15 3 15 3 15 3 15 16 20
// | | loop 1 \| loop 2 \| loop 3 \| loop 4 \| |
// ------------------------------------------------------------
//LOOP^ ^ LOOP
// IN | <----->| OUT
// start_loop_time loop_fraction_time-' time
//
// The time at which the animation is started corresponds to frame 0 and is stored
// in mActivationTimestamp (in seconds since character creation).
//
// If setStopTime() is called with a time somewhere inside loop 4,
// then 'loop_fraction_time' is the time from the beginning of
// loop 4 till 'time'. Thus 'time - loop_fraction_time' is the first
// frame of loop 4, and '(time - loop_fraction_time) +
// (mJointMotionList->mDuration - mJointMotionList->mLoopInPoint)'
// would correspond to frame 20.
//
void LLKeyframeMotion::setStopTime(F32 time)
{
LLMotion::setStopTime(time);
@@ -819,6 +873,8 @@ void LLKeyframeMotion::setStopTime(F32 time)
loop_fraction_time = fmod(time - start_loop_time,
mJointMotionList->mLoopOutPoint - mJointMotionList->mLoopInPoint);
}
// This sets mStopTimestamp to the time that corresponds to the end of the animation (ie, frame 20 in the above example)
// minus the ease out duration, so that the animation eases out during the loop out and finishes exactly at the end.
mStopTimestamp = llmax(time,
(time - loop_fraction_time) + (mJointMotionList->mDuration - mJointMotionList->mLoopInPoint) - getEaseOutDuration());
}
@@ -1227,13 +1283,42 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8
}
}
// Helper class.
template<typename T>
struct AIAutoDestruct
{
T* mPtr;
AIAutoDestruct() : mPtr(NULL) { }
~AIAutoDestruct() { delete mPtr; }
void add(T* ptr) { mPtr = ptr; }
};
//-----------------------------------------------------------------------------
// deserialize()
//-----------------------------------------------------------------------------
BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
{
BOOL old_version = FALSE;
mJointMotionList = new LLKeyframeMotion::JointMotionList;
//<singu>
// First add a new LLKeyframeMotion::JointMotionList to the cache, then assign a pointer
// to that to mJointMotionList. In LLs code the cache is never deleted again. Now it is
// is deleted when the last mJointMotionList pointer is destructed.
//
// It is possible that we get here for an already added animation, because animations can
// be requested multiple times (we get here from LLKeyframeMotion::onLoadComplete) when
// the animation was still downloading from a previous request for another LLMotionController
// object (avatar). In that case we just overwrite the old data while decoding it again.
mJointMotionList = LLKeyframeDataCache::getKeyframeData(getID());
bool singu_new_joint_motion_list = !mJointMotionList;
if (singu_new_joint_motion_list)
{
// Create a new JointMotionList.
mJointMotionList = LLKeyframeDataCache::createKeyframeData(getID());
}
//</singu>
//-------------------------------------------------------------------------
// get base priority
@@ -1396,8 +1481,10 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
return FALSE;
}
mJointMotionList->mJointMotionArray.clear();
mJointMotionList->mJointMotionArray.reserve(num_motions);
if (singu_new_joint_motion_list)
{
mJointMotionList->mJointMotionArray.reserve(num_motions);
}
mJointStates.clear();
mJointStates.reserve(num_motions);
@@ -1407,8 +1494,19 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
for(U32 i=0; i<num_motions; ++i)
{
AIAutoDestruct<JointMotion> watcher;
JointMotion* joint_motion = new JointMotion;
mJointMotionList->mJointMotionArray.push_back(joint_motion);
if (singu_new_joint_motion_list)
{
// Pass ownership to mJointMotionList.
mJointMotionList->mJointMotionArray.push_back(joint_motion);
}
else
{
// Just delete this at the end.
watcher.add(joint_motion);
}
std::string joint_name;
if (!dp.unpackString(joint_name, "joint_name"))
@@ -1836,7 +1934,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
return FALSE;
}
mJointMotionList->mConstraints.push_front(constraintp);
AIAutoDestruct<JointConstraintSharedData> watcher;
if (singu_new_joint_motion_list)
{
mJointMotionList->mConstraints.push_front(constraintp);
}
else
{
watcher.add(constraintp);
}
constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; // note: mChainLength is size-limited - comes from a byte
@@ -1876,15 +1982,12 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp)
if (constraintp->mJointStateIndices[i] < 0 )
{
llwarns << "No joint index for constraint " << i << llendl;
delete constraintp;
return FALSE;
}
}
}
}
// *FIX: support cleanup of old keyframe data
LLKeyframeDataCache::addKeyframeData(getID(), mJointMotionList);
mAssetStatus = ASSET_LOADED;
setupPose();
@@ -2226,16 +2329,24 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs,
//--------------------------------------------------------------------
// LLKeyframeDataCache::dumpDiagInfo()
//--------------------------------------------------------------------
void LLKeyframeDataCache::dumpDiagInfo()
// <singu>
// quiet = 0 : print everything in detail.
// 1 : print the UUIDs of all animations in the cache and the total memory usage.
// 2 : only print the total memory usage.
// </singu>
void LLKeyframeDataCache::dumpDiagInfo(int quiet)
{
// keep track of totals
U32 total_size = 0;
char buf[1024]; /* Flawfinder: ignore */
llinfos << "-----------------------------------------------------" << llendl;
llinfos << " Global Motion Table (DEBUG only)" << llendl;
llinfos << "-----------------------------------------------------" << llendl;
if (quiet < 2)
{
llinfos << "-----------------------------------------------------" << llendl;
llinfos << " Global Motion Table" << llendl;
llinfos << "-----------------------------------------------------" << llendl;
}
// print each loaded mesh, and it's memory usage
for (keyframe_data_map_t::iterator map_it = sKeyframeDataMap.begin();
@@ -2243,30 +2354,46 @@ void LLKeyframeDataCache::dumpDiagInfo()
{
U32 joint_motion_kb;
LLKeyframeMotion::JointMotionList *motion_list_p = map_it->second;
LLKeyframeMotion::JointMotionList const* motion_list_p = map_it->get();
llinfos << "Motion: " << map_it->first << llendl;
if (quiet < 2)
{
llinfos << "Motion: " << map_it->key() << llendl;
}
joint_motion_kb = motion_list_p->dumpDiagInfo();
total_size += joint_motion_kb;
if (motion_list_p)
{
joint_motion_kb = motion_list_p->dumpDiagInfo(quiet);
total_size += joint_motion_kb;
}
}
llinfos << "-----------------------------------------------------" << llendl;
if (quiet < 2)
{
llinfos << "-----------------------------------------------------" << llendl;
}
llinfos << "Motions\tTotal Size" << llendl;
snprintf(buf, sizeof(buf), "%d\t\t%d bytes", (S32)sKeyframeDataMap.size(), total_size ); /* Flawfinder: ignore */
llinfos << buf << llendl;
llinfos << "-----------------------------------------------------" << llendl;
if (quiet < 2)
{
llinfos << "-----------------------------------------------------" << llendl;
}
}
//--------------------------------------------------------------------
// LLKeyframeDataCache::addKeyframeData()
// LLKeyframeDataCache::createKeyframeData()
//--------------------------------------------------------------------
void LLKeyframeDataCache::addKeyframeData(const LLUUID& id, LLKeyframeMotion::JointMotionList* joint_motion_listp)
//<singu> This function replaces LLKeyframeDataCache::addKeyframeData and was rewritten to fix a memory leak (aka, the usage of AICachedPointer).
LLKeyframeMotion::JointMotionListPtr LLKeyframeDataCache::createKeyframeData(LLUUID const& id)
{
sKeyframeDataMap[id] = joint_motion_listp;
std::pair<keyframe_data_map_t::iterator, bool> result =
sKeyframeDataMap.insert(AICachedPointer<LLUUID, LLKeyframeMotion::JointMotionList>(id, new LLKeyframeMotion::JointMotionList, &sKeyframeDataMap));
llassert(result.second); // id may not already exist in the cache.
return &*result.first; // Construct and return a JointMotionListPt from a pointer to the actually inserted AICachedPointer.
}
//</singu>
//--------------------------------------------------------------------
// LLKeyframeDataCache::removeKeyframeData()
@@ -2276,7 +2403,6 @@ void LLKeyframeDataCache::removeKeyframeData(const LLUUID& id)
keyframe_data_map_t::iterator found_data = sKeyframeDataMap.find(id);
if (found_data != sKeyframeDataMap.end())
{
delete found_data->second;
sKeyframeDataMap.erase(found_data);
}
}
@@ -2284,14 +2410,14 @@ void LLKeyframeDataCache::removeKeyframeData(const LLUUID& id)
//--------------------------------------------------------------------
// LLKeyframeDataCache::getKeyframeData()
//--------------------------------------------------------------------
LLKeyframeMotion::JointMotionList* LLKeyframeDataCache::getKeyframeData(const LLUUID& id)
LLKeyframeMotion::JointMotionListPtr LLKeyframeDataCache::getKeyframeData(const LLUUID& id)
{
keyframe_data_map_t::iterator found_data = sKeyframeDataMap.find(id);
if (found_data == sKeyframeDataMap.end())
{
return NULL;
}
return found_data->second;
return &*found_data; // Construct and return a JointMotionListPt from a pointer to the found AICachedPointer.
}
//--------------------------------------------------------------------
@@ -2307,7 +2433,6 @@ LLKeyframeDataCache::~LLKeyframeDataCache()
//-----------------------------------------------------------------------------
void LLKeyframeDataCache::clear()
{
for_each(sKeyframeDataMap.begin(), sKeyframeDataMap.end(), DeletePairedPointer());
sKeyframeDataMap.clear();
}

View File

@@ -5,6 +5,7 @@
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
* AICachedPointer and AICachedPointPtr copyright (c) 2013, Aleric Inglewood.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
@@ -48,10 +49,12 @@
#include "v3dmath.h"
#include "v3math.h"
#include "llbvhconsts.h"
#include <boost/intrusive_ptr.hpp>
class LLKeyframeDataCache;
class LLVFS;
class LLDataPacker;
class LLMotionController;
#define MIN_REQUIRED_PIXEL_AREA_KEYFRAME (40.f)
#define MAX_CHAIN_LENGTH (4)
@@ -59,6 +62,112 @@ class LLDataPacker;
const S32 KEYFRAME_MOTION_VERSION = 1;
const S32 KEYFRAME_MOTION_SUBVERSION = 0;
//-----------------------------------------------------------------------------
// <singu>
template<typename KEY, typename T>
class AICachedPointer;
template<typename KEY, typename T>
void intrusive_ptr_add_ref(AICachedPointer<KEY, T> const* p);
template<typename KEY, typename T>
void intrusive_ptr_release(AICachedPointer<KEY, T> const* p);
template<typename KEY, typename T>
class AICachedPointer
{
public:
typedef std::set<AICachedPointer<KEY, T> > container_type;
private:
KEY mKey; // The unique key.
LLPointer<T> mData; // The actual data pointer.
container_type* mCache; // Pointer to the underlaying cache.
mutable int mRefCount; // Number of AICachedPointerPtr's pointing to this object.
public:
// Construct a NULL pointer. This is needed when adding a new entry to a std::set, it is always first default constructed.
AICachedPointer(void) : mCache(NULL) { }
// Copy constructor. This is needed to replace the std::set inserted instance with its actual value.
AICachedPointer(AICachedPointer const& cptr) : mKey(cptr.mKey), mData(cptr.mData), mCache(cptr.mCache), mRefCount(0) { }
// Construct a AICachedPointer that points to 'ptr' with key 'key'.
AICachedPointer(KEY const& key, T* ptr, container_type* cache) : mKey(key), mData(ptr), mCache(cache), mRefCount(-1) { }
// Construct a temporary NULL pointer that can be used in a search for a key.
AICachedPointer(KEY const& key) : mKey(key), mCache(NULL) { }
// Accessors for key and data.
KEY const& key(void) const { return mKey; }
T const* get(void) const { return mData.get(); }
T* get(void) { return mData.get(); }
// Order only by key.
friend bool operator<(AICachedPointer const& cp1, AICachedPointer const& cp2) { return cp1.mKey < cp2.mKey; }
private:
friend void intrusive_ptr_add_ref<>(AICachedPointer<KEY, T> const* p);
friend void intrusive_ptr_release<>(AICachedPointer<KEY, T> const* p);
private:
AICachedPointer& operator=(AICachedPointer const&);
};
template<typename KEY, typename T>
void intrusive_ptr_add_ref(AICachedPointer<KEY, T> const* p)
{
llassert(p->mCache);
if (p->mCache)
{
p->mRefCount++;
}
}
template<typename KEY, typename T>
void intrusive_ptr_release(AICachedPointer<KEY, T> const* p)
{
llassert(p->mCache);
if (p->mCache)
{
if (--p->mRefCount == 0)
{
p->mCache->erase(p->mKey);
}
}
}
template<typename KEY, typename T>
class AICachedPointerPtr
{
private:
boost::intrusive_ptr<AICachedPointer<KEY, T> const> mPtr;
static int sCnt;
public:
AICachedPointerPtr(void) { ++sCnt; }
AICachedPointerPtr(AICachedPointerPtr const& cpp) : mPtr(cpp.mPtr) { ++sCnt; }
AICachedPointerPtr(AICachedPointer<KEY, T> const* cp) : mPtr(cp) { ++sCnt; }
~AICachedPointerPtr() { --sCnt; }
typedef boost::intrusive_ptr<AICachedPointer<KEY, T> const> const AICachedPointerPtr<KEY, T>::* const bool_type;
operator bool_type() const { return mPtr ? &AICachedPointerPtr<KEY, T>::mPtr : NULL; }
T const* operator->() const { return mPtr->get(); }
T* operator->() { return const_cast<AICachedPointer<KEY, T>&>(*mPtr).get(); }
T const& operator*() const { return *mPtr->get(); }
T& operator*() { return *const_cast<AICachedPointer<KEY, T>&>(*mPtr).get(); }
AICachedPointerPtr& operator=(AICachedPointerPtr const& cpp) { mPtr = cpp.mPtr; return *this; }
};
template<typename KEY, typename T>
int AICachedPointerPtr<KEY, T>::sCnt;
// </singu>
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// class LLKeyframeMotion
//-----------------------------------------------------------------------------
@@ -68,7 +177,7 @@ class LLKeyframeMotion :
friend class LLKeyframeDataCache;
public:
// Constructor
LLKeyframeMotion(const LLUUID &id);
LLKeyframeMotion(const LLUUID &id, LLMotionController* controller);
// Destructor
virtual ~LLKeyframeMotion();
@@ -85,7 +194,7 @@ public:
// static constructor
// all subclasses must implement such a function and register it
static LLMotion *create(const LLUUID& id);
static LLMotion* create(LLUUID const& id, LLMotionController* controller);
public:
//-------------------------------------------------------------------------
@@ -158,7 +267,7 @@ public:
U32 getFileSize();
BOOL serialize(LLDataPacker& dp) const;
BOOL deserialize(LLDataPacker& dp);
BOOL isLoaded() { return mJointMotionList != NULL; }
BOOL isLoaded() { return !!mJointMotionList; }
// setters for modifying a keyframe animation
@@ -393,7 +502,7 @@ public:
//-------------------------------------------------------------------------
// JointMotionList
//-------------------------------------------------------------------------
class JointMotionList
class JointMotionList : public LLRefCount
{
public:
std::vector<JointMotion*> mJointMotionArray;
@@ -416,19 +525,22 @@ public:
public:
JointMotionList();
~JointMotionList();
U32 dumpDiagInfo();
U32 dumpDiagInfo(bool silent = false) const;
JointMotion* getJointMotion(U32 index) const { llassert(index < mJointMotionArray.size()); return mJointMotionArray[index]; }
U32 getNumJointMotions() const { return mJointMotionArray.size(); }
};
// Singu: Type of a pointer to the cached pointer (in LLKeyframeDataCache::sKeyframeDataMap) to a JointMotionList object.
typedef AICachedPointerPtr<LLUUID, JointMotionList> JointMotionListPtr;
protected:
static LLVFS* sVFS;
//-------------------------------------------------------------------------
// Member Data
//-------------------------------------------------------------------------
JointMotionList* mJointMotionList;
JointMotionListPtr mJointMotionList; // singu: automatically clean up cache entry when destructed.
std::vector<LLPointer<LLJointState> > mJointStates;
LLJoint* mPelvisp;
LLCharacter* mCharacter;
@@ -442,21 +554,24 @@ protected:
class LLKeyframeDataCache
{
public:
// *FIX: implement this as an actual singleton member of LLKeyframeMotion
private:
friend class LLKeyframeMotion;
LLKeyframeDataCache(){};
~LLKeyframeDataCache();
typedef std::map<LLUUID, class LLKeyframeMotion::JointMotionList*> keyframe_data_map_t;
public:
typedef AICachedPointer<LLUUID, LLKeyframeMotion::JointMotionList>::container_type keyframe_data_map_t; // singu: add automatic cache cleanup.
static keyframe_data_map_t sKeyframeDataMap;
static void addKeyframeData(const LLUUID& id, LLKeyframeMotion::JointMotionList*);
static LLKeyframeMotion::JointMotionList* getKeyframeData(const LLUUID& id);
//<singu>
static LLKeyframeMotion::JointMotionListPtr createKeyframeData(LLUUID const& id); // id may not exist.
static LLKeyframeMotion::JointMotionListPtr getKeyframeData(LLUUID const& id); // id may or may not exists. Returns a NULL pointer when it doesn't exist.
//</singu>
static void removeKeyframeData(const LLUUID& id);
//print out diagnostic info
static void dumpDiagInfo();
static void dumpDiagInfo(int quiet = 0); // singu: added param 'quiet'.
static void clear();
};

View File

@@ -1,456 +0,0 @@
/**
* @file llkeyframemotionparam.cpp
* @brief Implementation of LLKeyframeMotion class.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
//-----------------------------------------------------------------------------
// Header Files
//-----------------------------------------------------------------------------
#include "linden_common.h"
#include "llkeyframemotionparam.h"
#include "llcharacter.h"
#include "llmath.h"
#include "m3math.h"
#include "lldir.h"
#include "llanimationstates.h"
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLKeyframeMotionParam class
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLKeyframeMotionParam()
// Class Constructor
//-----------------------------------------------------------------------------
LLKeyframeMotionParam::LLKeyframeMotionParam( const LLUUID &id) : LLMotion(id)
{
mDefaultKeyframeMotion = NULL;
mCharacter = NULL;
mEaseInDuration = 0.f;
mEaseOutDuration = 0.f;
mDuration = 0.f;
mPriority = LLJoint::LOW_PRIORITY;
}
//-----------------------------------------------------------------------------
// ~LLKeyframeMotionParam()
// Class Destructor
//-----------------------------------------------------------------------------
LLKeyframeMotionParam::~LLKeyframeMotionParam()
{
for (motion_map_t::iterator iter = mParameterizedMotions.begin();
iter != mParameterizedMotions.end(); ++iter)
{
motion_list_t& motionList = iter->second;
for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
{
const ParameterizedMotion& paramMotion = *iter2;
delete paramMotion.mMotion;
}
motionList.clear();
}
mParameterizedMotions.clear();
}
//-----------------------------------------------------------------------------
// LLKeyframeMotionParam::onInitialize(LLCharacter *character)
//-----------------------------------------------------------------------------
LLMotion::LLMotionInitStatus LLKeyframeMotionParam::onInitialize(LLCharacter *character)
{
mCharacter = character;
if (!loadMotions())
{
return STATUS_FAILURE;
}
for (motion_map_t::iterator iter = mParameterizedMotions.begin();
iter != mParameterizedMotions.end(); ++iter)
{
motion_list_t& motionList = iter->second;
for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
{
const ParameterizedMotion& paramMotion = *iter2;
LLMotion* motion = paramMotion.mMotion;
motion->onInitialize(character);
if (motion->getDuration() > mEaseInDuration)
{
mEaseInDuration = motion->getEaseInDuration();
}
if (motion->getEaseOutDuration() > mEaseOutDuration)
{
mEaseOutDuration = motion->getEaseOutDuration();
}
if (motion->getDuration() > mDuration)
{
mDuration = motion->getDuration();
}
if (motion->getPriority() > mPriority)
{
mPriority = motion->getPriority();
}
LLPose *pose = motion->getPose();
mPoseBlender.addMotion(motion);
for (LLJointState *jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState())
{
LLPose *blendedPose = mPoseBlender.getBlendedPose();
blendedPose->addJointState(jsp);
}
}
}
return STATUS_SUCCESS;
}
//-----------------------------------------------------------------------------
// LLKeyframeMotionParam::onActivate()
//-----------------------------------------------------------------------------
BOOL LLKeyframeMotionParam::onActivate()
{
for (motion_map_t::iterator iter = mParameterizedMotions.begin();
iter != mParameterizedMotions.end(); ++iter)
{
motion_list_t& motionList = iter->second;
for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
{
const ParameterizedMotion& paramMotion = *iter2;
paramMotion.mMotion->activate(mActivationTimestamp);
}
}
return TRUE;
}
//-----------------------------------------------------------------------------
// LLKeyframeMotionParam::onUpdate()
//-----------------------------------------------------------------------------
BOOL LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask)
{
F32 weightFactor = 1.f / (F32)mParameterizedMotions.size();
// zero out all pose weights
for (motion_map_t::iterator iter = mParameterizedMotions.begin();
iter != mParameterizedMotions.end(); ++iter)
{
motion_list_t& motionList = iter->second;
for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
{
const ParameterizedMotion& paramMotion = *iter2;
// llinfos << "Weight for pose " << paramMotion.mMotion->getName() << " is " << paramMotion.mMotion->getPose()->getWeight() << llendl;
paramMotion.mMotion->getPose()->setWeight(0.f);
}
}
for (motion_map_t::iterator iter = mParameterizedMotions.begin();
iter != mParameterizedMotions.end(); ++iter)
{
const std::string& paramName = iter->first;
F32* paramValue = (F32 *)mCharacter->getAnimationData(paramName);
if (NULL == paramValue) // unexpected, but...
{
llwarns << "paramValue == NULL" << llendl;
continue;
}
// DANGER! Do not modify mParameterizedMotions while using these pointers!
const ParameterizedMotion* firstMotion = NULL;
const ParameterizedMotion* secondMotion = NULL;
motion_list_t& motionList = iter->second;
for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
{
const ParameterizedMotion& paramMotion = *iter2;
paramMotion.mMotion->onUpdate(time, joint_mask);
F32 distToParam = paramMotion.mParam - *paramValue;
if ( distToParam <= 0.f)
{
// keep track of the motion closest to the parameter value
firstMotion = &paramMotion;
}
else
{
// we've passed the parameter value
// so store the first motion we find as the second one we want to blend...
if (firstMotion && !secondMotion )
{
secondMotion = &paramMotion;
}
//...or, if we've seen no other motion so far, make sure we blend to this only
else if (!firstMotion)
{
firstMotion = &paramMotion;
secondMotion = &paramMotion;
}
}
}
LLPose *firstPose;
LLPose *secondPose;
if (firstMotion)
firstPose = firstMotion->mMotion->getPose();
else
firstPose = NULL;
if (secondMotion)
secondPose = secondMotion->mMotion->getPose();
else
secondPose = NULL;
// now modify weight of the subanim (only if we are blending between two motions)
if (firstMotion && secondMotion)
{
if (firstMotion == secondMotion)
{
firstPose->setWeight(weightFactor);
}
else if (firstMotion->mParam == secondMotion->mParam)
{
firstPose->setWeight(0.5f * weightFactor);
secondPose->setWeight(0.5f * weightFactor);
}
else
{
F32 first_weight = 1.f -
((llclamp(*paramValue - firstMotion->mParam, 0.f, (secondMotion->mParam - firstMotion->mParam))) /
(secondMotion->mParam - firstMotion->mParam));
first_weight = llclamp(first_weight, 0.f, 1.f);
F32 second_weight = 1.f - first_weight;
firstPose->setWeight(first_weight * weightFactor);
secondPose->setWeight(second_weight * weightFactor);
// llinfos << "Parameter " << *paramName << ": " << *paramValue << llendl;
// llinfos << "Weights " << firstPose->getWeight() << " " << secondPose->getWeight() << llendl;
}
}
else if (firstMotion && !secondMotion)
{
firstPose->setWeight(weightFactor);
}
}
// blend poses
mPoseBlender.blendAndApply();
llinfos << "Param Motion weight " << mPoseBlender.getBlendedPose()->getWeight() << llendl;
return TRUE;
}
//-----------------------------------------------------------------------------
// LLKeyframeMotionParam::onDeactivate()
//-----------------------------------------------------------------------------
void LLKeyframeMotionParam::onDeactivate()
{
for (motion_map_t::iterator iter = mParameterizedMotions.begin();
iter != mParameterizedMotions.end(); ++iter)
{
motion_list_t& motionList = iter->second;
for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
{
const ParameterizedMotion& paramMotion = *iter2;
paramMotion.mMotion->onDeactivate();
}
}
}
//-----------------------------------------------------------------------------
// LLKeyframeMotionParam::addKeyframeMotion()
//-----------------------------------------------------------------------------
BOOL LLKeyframeMotionParam::addKeyframeMotion(char *name, const LLUUID &id, char *param, F32 value)
{
LLMotion *newMotion = mCharacter->createMotion( id );
if (!newMotion)
{
return FALSE;
}
newMotion->setName(name);
// now add motion to this list
mParameterizedMotions[param].insert(ParameterizedMotion(newMotion, value));
return TRUE;
}
//-----------------------------------------------------------------------------
// LLKeyframeMotionParam::setDefaultKeyframeMotion()
//-----------------------------------------------------------------------------
void LLKeyframeMotionParam::setDefaultKeyframeMotion(char *name)
{
for (motion_map_t::iterator iter = mParameterizedMotions.begin();
iter != mParameterizedMotions.end(); ++iter)
{
motion_list_t& motionList = iter->second;
for (motion_list_t::iterator iter2 = motionList.begin(); iter2 != motionList.end(); ++iter2)
{
const ParameterizedMotion& paramMotion = *iter2;
if (paramMotion.mMotion->getName() == name)
{
mDefaultKeyframeMotion = paramMotion.mMotion;
}
}
}
}
//-----------------------------------------------------------------------------
// loadMotions()
//-----------------------------------------------------------------------------
BOOL LLKeyframeMotionParam::loadMotions()
{
//-------------------------------------------------------------------------
// Load named file by concatenating the character prefix with the motion name.
// Load data into a buffer to be parsed.
//-------------------------------------------------------------------------
//std::string path = gDirUtilp->getExpandedFilename(LL_PATH_MOTIONS,mCharacter->getAnimationPrefix())
// + "_" + getName() + ".llp";
//RN: deprecated unused reference to "motion" directory
std::string path;
//-------------------------------------------------------------------------
// open the file
//-------------------------------------------------------------------------
S32 fileSize = 0;
LLAPRFile infile(path, LL_APR_R, &fileSize);
apr_file_t* fp = infile.getFileHandle() ;
if (!fp || fileSize == 0)
{
llinfos << "ERROR: can't open: " << path << llendl;
return FALSE;
}
// allocate a text buffer
try
{
std::vector<char> text(fileSize+1);
//-------------------------------------------------------------------------
// load data from file into buffer
//-------------------------------------------------------------------------
bool error = false;
char *p = &text[0];
while ( 1 )
{
if (apr_file_eof(fp) == APR_EOF)
{
break;
}
if (apr_file_gets(p, 1024, fp) != APR_SUCCESS)
{
error = true;
break;
}
while ( *(++p) )
;
}
//-------------------------------------------------------------------------
// close the file
//-------------------------------------------------------------------------
infile.close();
//-------------------------------------------------------------------------
// check for error
//-------------------------------------------------------------------------
llassert( p <= (&text[0] + fileSize) );
if ( error )
{
llinfos << "ERROR: error while reading from " << path << llendl;
return FALSE;
}
llinfos << "Loading parametric keyframe data for: " << getName() << llendl;
//-------------------------------------------------------------------------
// parse the text and build keyframe data structures
//-------------------------------------------------------------------------
p = &text[0];
S32 num;
char strA[80]; /* Flawfinder: ignore */
char strB[80]; /* Flawfinder: ignore */
F32 floatA = 0.0f;
//-------------------------------------------------------------------------
// get priority
//-------------------------------------------------------------------------
BOOL isFirstMotion = TRUE;
num = sscanf(p, "%79s %79s %f", strA, strB, &floatA); /* Flawfinder: ignore */
while(1)
{
if (num == 0 || num == EOF) break;
if ((num != 3))
{
llinfos << "WARNING: can't read parametric motion" << llendl;
return FALSE;
}
addKeyframeMotion(strA, gAnimLibrary.stringToAnimState(std::string(strA)), strB, floatA);
if (isFirstMotion)
{
isFirstMotion = FALSE;
setDefaultKeyframeMotion(strA);
}
p = strstr(p, "\n");
if (!p)
{
break;
}
p++;
num = sscanf(p, "%79s %79s %f", strA, strB, &floatA); /* Flawfinder: ignore */
}
return TRUE;
}
catch(std::bad_alloc)
{
llinfos << "ERROR: Unable to allocate keyframe text buffer." << llendl;
return FALSE;
}
}
// End

View File

@@ -1,176 +0,0 @@
/**
* @file llkeyframemotionparam.h
* @brief Implementation of LLKeframeMotionParam class.
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLKEYFRAMEMOTIONPARAM_H
#define LL_LLKEYFRAMEMOTIONPARAM_H
//-----------------------------------------------------------------------------
// Header files
//-----------------------------------------------------------------------------
#include <string>
#include "llmotion.h"
#include "lljointstate.h"
#include "v3math.h"
#include "llquaternion.h"
#include "linked_lists.h"
#include "llkeyframemotion.h"
//-----------------------------------------------------------------------------
// class LLKeyframeMotionParam
//-----------------------------------------------------------------------------
class LLKeyframeMotionParam :
public LLMotion
{
public:
// Constructor
LLKeyframeMotionParam(const LLUUID &id);
// Destructor
virtual ~LLKeyframeMotionParam();
public:
//-------------------------------------------------------------------------
// functions to support MotionController and MotionRegistry
//-------------------------------------------------------------------------
// static constructor
// all subclasses must implement such a function and register it
static LLMotion *create(const LLUUID &id) { return new LLKeyframeMotionParam(id); }
public:
//-------------------------------------------------------------------------
// animation callbacks to be implemented by subclasses
//-------------------------------------------------------------------------
// motions must specify whether or not they loop
virtual BOOL getLoop() {
return TRUE;
}
// motions must report their total duration
virtual F32 getDuration() {
return mDuration;
}
// motions must report their "ease in" duration
virtual F32 getEaseInDuration() {
return mEaseInDuration;
}
// motions must report their "ease out" duration.
virtual F32 getEaseOutDuration() {
return mEaseOutDuration;
}
// motions must report their priority
virtual LLJoint::JointPriority getPriority() {
return mPriority;
}
virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; }
// called to determine when a motion should be activated/deactivated based on avatar pixel coverage
virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_KEYFRAME; }
// run-time (post constructor) initialization,
// called after parameters have been set
// must return true to indicate success and be available for activation
virtual LLMotionInitStatus onInitialize(LLCharacter *character);
// called when a motion is activated
// must return TRUE to indicate success, or else
// it will be deactivated
virtual BOOL onActivate();
// called per time step
// must return TRUE while it is active, and
// must return FALSE when the motion is completed.
virtual BOOL onUpdate(F32 time, U8* joint_mask);
// called when a motion is deactivated
virtual void onDeactivate();
virtual LLPose* getPose() { return mPoseBlender.getBlendedPose();}
protected:
//-------------------------------------------------------------------------
// new functions defined by this subclass
//-------------------------------------------------------------------------
struct ParameterizedMotion
{
ParameterizedMotion(LLMotion* motion, F32 param) : mMotion(motion), mParam(param) {}
LLMotion* mMotion;
F32 mParam;
};
// add a motion and associated parameter triplet
BOOL addKeyframeMotion(char *name, const LLUUID &id, char *param, F32 value);
// set default motion for LOD and retrieving blend constants
void setDefaultKeyframeMotion(char *);
BOOL loadMotions();
protected:
//-------------------------------------------------------------------------
// Member Data
//-------------------------------------------------------------------------
struct compare_motions
{
bool operator() (const ParameterizedMotion& a, const ParameterizedMotion& b) const
{
if (a.mParam != b.mParam)
return (a.mParam < b.mParam);
else
return a.mMotion < b.mMotion;
}
};
typedef std::set < ParameterizedMotion, compare_motions > motion_list_t;
typedef std::map <std::string, motion_list_t > motion_map_t;
motion_map_t mParameterizedMotions;
LLMotion* mDefaultKeyframeMotion;
LLCharacter* mCharacter;
LLPoseBlender mPoseBlender;
F32 mEaseInDuration;
F32 mEaseOutDuration;
F32 mDuration;
LLJoint::JointPriority mPriority;
LLUUID mTransactionID;
};
#endif // LL_LLKEYFRAMEMOTIONPARAM_H

View File

@@ -50,7 +50,7 @@ const F32 POSITION_THRESHOLD = 0.1f;
// LLKeyframeStandMotion()
// Class Constructor
//-----------------------------------------------------------------------------
LLKeyframeStandMotion::LLKeyframeStandMotion(const LLUUID &id) : LLKeyframeMotion(id)
LLKeyframeStandMotion::LLKeyframeStandMotion(LLUUID const& id, LLMotionController* controller) : LLKeyframeMotion(id, controller)
{
mFlipFeet = FALSE;
mCharacter = NULL;
@@ -286,40 +286,38 @@ BOOL LLKeyframeStandMotion::onUpdate(F32 time, U8* joint_mask)
//-------------------------------------------------------------------------
if ( mTrackAnkles )
{
LLVector4 dirLeft4 = mAnkleLeftJoint.getWorldMatrix().getFwdRow4();
LLVector4 dirRight4 = mAnkleRightJoint.getWorldMatrix().getFwdRow4();
LLVector3 dirLeft = vec4to3( dirLeft4 );
LLVector3 dirRight = vec4to3( dirRight4 );
const LLVector4a& dirLeft4 = mAnkleLeftJoint.getWorldMatrix().getRow<LLMatrix4a::ROW_FWD>();
const LLVector4a& dirRight4 = mAnkleRightJoint.getWorldMatrix().getRow<LLMatrix4a::ROW_FWD>();
LLVector3 up;
LLVector3 dir;
LLVector3 left;
LLVector4a up;
LLVector4a dir;
LLVector4a left;
up = mNormalLeft;
up.normVec();
up.load3(mNormalLeft.mV);
up.normalize3fast();
if (mFlipFeet)
{
up *= -1.0f;
up.negate();
}
dir = dirLeft;
dir.normVec();
left = up % dir;
left.normVec();
dir = left % up;
mRotationLeft = LLQuaternion( dir, left, up );
dir = dirLeft4;
dir.normalize3fast();
left.setCross3(up,dir);
left.normalize3fast();
dir.setCross3(left,up);
mRotationLeft = LLQuaternion( LLVector3(dir.getF32ptr()), LLVector3(left.getF32ptr()), LLVector3(up.getF32ptr()));
up = mNormalRight;
up.normVec();
up.load3(mNormalRight.mV);
up.normalize3fast();
if (mFlipFeet)
{
up *= -1.0f;
up.negate();
}
dir = dirRight;
dir.normVec();
left = up % dir;
left.normVec();
dir = left % up;
mRotationRight = LLQuaternion( dir, left, up );
dir = dirRight4;
dir.normalize3fast();
left.setCross3(up,dir);
left.normalize3fast();
dir.setCross3(left,up);
mRotationRight = LLQuaternion( LLVector3(dir.getF32ptr()), LLVector3(left.getF32ptr()), LLVector3(up.getF32ptr()));
}
mAnkleLeftJoint.setWorldRotation( mRotationLeft );
mAnkleRightJoint.setWorldRotation( mRotationRight );

View File

@@ -48,7 +48,7 @@ class LLKeyframeStandMotion :
{
public:
// Constructor
LLKeyframeStandMotion(const LLUUID &id);
LLKeyframeStandMotion(LLUUID const& id, LLMotionController* controller);
// Destructor
virtual ~LLKeyframeStandMotion();
@@ -60,7 +60,7 @@ public:
// static constructor
// all subclasses must implement such a function and register it
static LLMotion *create(const LLUUID &id) { return new LLKeyframeStandMotion(id); }
static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLKeyframeStandMotion(id, controller); }
public:
//-------------------------------------------------------------------------

View File

@@ -55,8 +55,8 @@ const F32 SPEED_ADJUST_TIME_CONSTANT = 0.1f; // time constant for speed adjustm
// LLKeyframeWalkMotion()
// Class Constructor
//-----------------------------------------------------------------------------
LLKeyframeWalkMotion::LLKeyframeWalkMotion(const LLUUID &id)
: LLKeyframeMotion(id),
LLKeyframeWalkMotion::LLKeyframeWalkMotion(LLUUID const& id, LLMotionController* controller)
: LLKeyframeMotion(id, controller),
mCharacter(NULL),
mCyclePhase(0.0f),
mRealTimeLast(0.0f),
@@ -138,8 +138,8 @@ BOOL LLKeyframeWalkMotion::onUpdate(F32 time, U8* joint_mask)
// LLWalkAdjustMotion()
// Class Constructor
//-----------------------------------------------------------------------------
LLWalkAdjustMotion::LLWalkAdjustMotion(const LLUUID &id) :
LLMotion(id),
LLWalkAdjustMotion::LLWalkAdjustMotion(LLUUID const& id, LLMotionController* controller) :
AIMaskedMotion(id, controller, ANIM_AGENT_WALK_ADJUST),
mLastTime(0.f),
mAnimSpeed(0.f),
mAdjustedSpeed(0.f),
@@ -193,7 +193,7 @@ BOOL LLWalkAdjustMotion::onActivate()
F32 rightAnkleOffset = (mRightAnkleJoint->getWorldPosition() - mCharacter->getCharacterPosition()).magVec();
mAnkleOffset = llmax(leftAnkleOffset, rightAnkleOffset);
return TRUE;
return AIMaskedMotion::onActivate();
}
//-----------------------------------------------------------------------------
@@ -325,13 +325,14 @@ BOOL LLWalkAdjustMotion::onUpdate(F32 time, U8* joint_mask)
void LLWalkAdjustMotion::onDeactivate()
{
mCharacter->removeAnimationData("Walk Speed");
AIMaskedMotion::onDeactivate();
}
//-----------------------------------------------------------------------------
// LLFlyAdjustMotion::LLFlyAdjustMotion()
//-----------------------------------------------------------------------------
LLFlyAdjustMotion::LLFlyAdjustMotion(const LLUUID &id)
: LLMotion(id),
LLFlyAdjustMotion::LLFlyAdjustMotion(LLUUID const& id, LLMotionController* controller)
: AIMaskedMotion(id, controller, ANIM_AGENT_FLY_ADJUST),
mRoll(0.f)
{
mName = "fly_adjust";
@@ -368,7 +369,7 @@ BOOL LLFlyAdjustMotion::onActivate()
mPelvisState->setPosition(LLVector3::zero);
mPelvisState->setRotation(LLQuaternion::DEFAULT);
mRoll = 0.f;
return TRUE;
return AIMaskedMotion::onActivate();
}
//-----------------------------------------------------------------------------

View File

@@ -52,7 +52,7 @@ class LLKeyframeWalkMotion :
friend class LLWalkAdjustMotion;
public:
// Constructor
LLKeyframeWalkMotion(const LLUUID &id);
LLKeyframeWalkMotion(LLUUID const& id, LLMotionController* controller);
// Destructor
virtual ~LLKeyframeWalkMotion();
@@ -64,7 +64,7 @@ public:
// static constructor
// all subclasses must implement such a function and register it
static LLMotion *create(const LLUUID &id) { return new LLKeyframeWalkMotion(id); }
static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLKeyframeWalkMotion(id, controller); }
public:
//-------------------------------------------------------------------------
@@ -86,11 +86,11 @@ public:
S32 mDownFoot;
};
class LLWalkAdjustMotion : public LLMotion
class LLWalkAdjustMotion : public AIMaskedMotion
{
public:
// Constructor
LLWalkAdjustMotion(const LLUUID &id);
LLWalkAdjustMotion(LLUUID const& id, LLMotionController* controller);
public:
//-------------------------------------------------------------------------
@@ -99,7 +99,7 @@ public:
// static constructor
// all subclasses must implement such a function and register it
static LLMotion *create(const LLUUID &id) { return new LLWalkAdjustMotion(id); }
static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLWalkAdjustMotion(id, controller); }
public:
//-------------------------------------------------------------------------
@@ -136,11 +136,11 @@ public:
F32 mAnkleOffset;
};
class LLFlyAdjustMotion : public LLMotion
class LLFlyAdjustMotion : public AIMaskedMotion
{
public:
// Constructor
LLFlyAdjustMotion(const LLUUID &id);
LLFlyAdjustMotion(LLUUID const& id, LLMotionController* controller);
public:
//-------------------------------------------------------------------------
@@ -149,7 +149,7 @@ public:
// static constructor
// all subclasses must implement such a function and register it
static LLMotion *create(const LLUUID &id) { return new LLFlyAdjustMotion(id); }
static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLFlyAdjustMotion(id, controller); }
public:
//-------------------------------------------------------------------------
@@ -157,7 +157,6 @@ public:
//-------------------------------------------------------------------------
virtual LLMotionInitStatus onInitialize(LLCharacter *character);
virtual BOOL onActivate();
virtual void onDeactivate() {};
virtual BOOL onUpdate(F32 time, U8* joint_mask);
virtual LLJoint::JointPriority getPriority(){return LLJoint::HIGHER_PRIORITY;}
virtual BOOL getLoop() { return TRUE; }

View File

@@ -37,6 +37,125 @@
#include "llmotion.h"
#include "llcriticaldamp.h"
#include "llmotioncontroller.h"
//<singu>
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// AISyncClientMotion class
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
AISyncKey* AISyncClientMotion::createSyncKey(AISyncKey const* from_key) const
{
// The const cast is needed because getDuration() is non-const while it should have been.
AISyncClientMotion* self = const_cast<AISyncClientMotion*>(this);
// Only synchronize motions with the same duration and loop value.
return new AISyncKeyMotion(from_key, self->getDuration(), self->getLoop());
}
void AISyncClientMotion::aisync_loading(void)
{
// Register the motion for (possible) synchronization: this marks the time at which is should have started.
unregister_client(); // In case it is already registered. Getting here means we are being (re)started now, we need to synchronize with other motions that start now.
register_client();
}
void AISyncClientMotion::aisync_loaded(void)
{
AISyncServer* server = this->server();
if (!server)
{
// Already expired without being synchronized (no other motion was started at the same time).
return;
}
AISyncKey const& key = server->key(); // The allocation of this is owned by server.
// There is no need to resync if there was not another motion started at the same time and the key already expired.
bool need_resync = !(server->never_synced() && key.expired());
AISyncKey* new_key = NULL;
if (need_resync)
{
// Create a new key using the old start time.
new_key = createSyncKey(&key);
}
server->remove(this); // This resets mServer and might even delete server.
if (need_resync)
{
// Add the client to another server (based on the new key). This takes ownership of the key allocation.
AISyncServerMap::instance().register_client(this, new_key);
}
}
F32 LLMotion::getRuntime(void) const
{
llassert(mActive);
return mController->getAnimTime() - mActivationTimestamp;
}
F32 LLMotion::getAnimTime(void) const
{
return mController->getAnimTime();
}
F32 LLMotion::syncActivationTime(F32 time)
{
AISyncServer* server = this->server();
if (!server)
{
register_client();
server = this->server();
}
AISyncServer::client_list_t const& clients = server->getClients();
if (clients.size() > 1)
{
// Look for the client with the smallest runtime.
AISyncClientMotion* motion_with_smallest_runtime = NULL;
F32 runtime = 1e10;
// Run over all motions in this to be synchronized group.
for (AISyncServer::client_list_t::const_iterator client = clients.begin(); client != clients.end(); ++client)
{
if ((client->mReadyEvents & 2)) // Is this motion active? Motions that aren't loaded yet are not active.
{
// Currently, if event 2 is set then this is an LLMotion.
llassert(dynamic_cast<AISyncClientMotion*>(client->mClientPtr));
AISyncClientMotion* motion = static_cast<AISyncClientMotion*>(client->mClientPtr);
// Deactivated motions should have been deregistered, certainly not have event 2 set.
llassert(static_cast<LLMotion*>(motion)->isActive());
if (motion->getRuntime() < runtime)
{
// This is a bit fuzzy since theoretically the runtime of all active motions in the list should be the same.
// Just use the smallest value to get rid of some randomness. We might even synchronizing with ourselves
// in which case 'time' would be set to a value such that mActivationTimestamp won't change.
// In practise however, this list will contain only two clients: this, being inactive, and our partner.
runtime = motion->getRuntime();
motion_with_smallest_runtime = motion;
}
}
}
//-----------------------------------------------------------------------------------------
// Here is where the actual synchronization takes place.
// Current we only synchronize looped motions.
if (getLoop())
{
if (motion_with_smallest_runtime)
{
// Pretend the motion was started in the past at the same time as the other motion(s).
time = getAnimTime() - runtime;
}
}
//-----------------------------------------------------------------------------------------
}
return time;
}
void AISyncClientMotion::deregistered(void)
{
#ifdef SHOW_ASSERT
mReadyEvents = 0;
#endif
}
//</singu>
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
@@ -48,10 +167,11 @@
// LLMotion()
// Class Constructor
//-----------------------------------------------------------------------------
LLMotion::LLMotion( const LLUUID &id ) :
LLMotion::LLMotion(LLUUID const& id, LLMotionController* controller) :
mStopped(TRUE),
mActive(FALSE),
mID(id),
mController(controller),
mActivationTimestamp(0.f),
mStopTimestamp(0.f),
mSendStopTimestamp(F32_MAX),
@@ -147,6 +267,19 @@ void LLMotion::activate(F32 time)
{
mActivationTimestamp = time;
mStopped = FALSE;
//<singu>
if (mController && !mController->syncing_disabled()) // Avoid being registered when syncing is disabled for this motion.
{
if (mActive)
{
// If the motion is already active then we are being restarted.
// Unregister it first (if it is registered) so that the call to ready will cause it to be registered
// and be synchronized with other motions that are started at this moment.
unregister_client();
}
ready(6, 2 | (mController->isHidden() ? 0 : 4)); // Signal that mActivationTimestamp is set/valid (2), and that this server has a visible motion (4) (or not).
}
//</singu>
mActive = TRUE;
onActivate();
}
@@ -159,6 +292,14 @@ void LLMotion::deactivate()
mActive = FALSE;
mPose.setWeight(0.f);
//<singu>
if (server()) // Only when this motion is already registered.
{
ready(6, 0); // Signal that mActivationTimestamp is no longer valid.
unregister_client(); // No longer running, so no longer a part of this sync group.
}
//</singu>
if (mDeactivateCallback)
{
(*mDeactivateCallback)(mDeactivateCallbackUserData);
@@ -174,4 +315,19 @@ BOOL LLMotion::canDeprecate()
return TRUE;
}
//-----------------------------------------------------------------------------
// AIMaskedMotion
//-----------------------------------------------------------------------------
BOOL AIMaskedMotion::onActivate()
{
mController->activated(mMaskBit);
return TRUE;
}
void AIMaskedMotion::onDeactivate()
{
mController->deactivated(mMaskBit);
}
// End

View File

@@ -38,16 +38,85 @@
//-----------------------------------------------------------------------------
#include <string>
#include "aisyncclient.h"
#include "llerror.h"
#include "llpose.h"
#include "lluuid.h"
class LLCharacter;
class LLMotionController;
//-----------------------------------------------------------------------------
// class AISync* stuff
//-----------------------------------------------------------------------------
class AISyncKeyMotion : public AISyncKey
{
private:
F32 mDuration;
bool mLoop;
public:
AISyncKeyMotion(AISyncKey const* from_key, F32 duration, bool loop) : AISyncKey(from_key), mDuration(duration), mLoop(loop) { }
// Virtual functions of AISyncKey.
public:
/*virtual*/ synckeytype_t getkeytype(void) const
{
// Return a unique identifier for this class, where the low 8 bits represent the syncgroup.
return synckeytype_motion;
}
/*virtual*/ bool equals(AISyncKey const& key) const
{
switch (key.getkeytype())
{
case synckeytype_motion:
{
// The other key is of the same type.
AISyncKeyMotion const& motion_key = static_cast<AISyncKeyMotion const&>(key);
return mLoop == motion_key.mLoop && is_approx_equal(mDuration, motion_key.mDuration);
}
default:
// The keys must be in the same syncgroup.
break;
}
return false;
}
};
class AISyncClientMotion : public AISyncClient
{
protected:
// Make sure that clients that are destroyed are first unregistered.
// This is needed, for example, when loading fails or when excess motions are being purged.
/*virtual*/ ~AISyncClientMotion() { unregister_client(); }
// AISyncClient events.
/*virtual*/ AISyncKey* createSyncKey(AISyncKey const* from_key = NULL) const;
/*virtual*/ void event1_ready(void) { }
/*virtual*/ void event1_not_ready(void) { }
/*virtual*/ void deregistered(void);
protected:
// This is called when the server sent us a message that it wants us to play this animation, but we can't because it isn't fully downloaded yet.
void aisync_loading(void);
// This is called when that motion is successfully loaded and it has to be re-registered because now the duration etc is known.
void aisync_loaded(void);
public:
// Virtual functions of AISyncClientMotion.
// These are defined by classes derived from LLMotion (which is derived from this class).
virtual BOOL getLoop() = 0;
virtual F32 getDuration() = 0;
virtual F32 getAnimTime(void) const = 0;
virtual F32 getRuntime(void) const = 0;
};
//-----------------------------------------------------------------------------
// class LLMotion
//-----------------------------------------------------------------------------
class LLMotion
class LLMotion : public AISyncClientMotion
{
friend class LLMotionController;
@@ -66,7 +135,7 @@ public:
};
// Constructor
LLMotion(const LLUUID &id);
LLMotion(LLUUID const& id, LLMotionController* controller);
// Destructor
virtual ~LLMotion();
@@ -114,7 +183,22 @@ protected:
BOOL isActive() { return mActive; }
public:
void activate(F32 time);
//<singu>
// Returns the time that this motion has been running.
virtual F32 getRuntime(void) const;
// Return the current time (in seconds since creation of the controller).
virtual F32 getAnimTime(void) const;
// This is called when a motion is to be activated, but might need synchronization.
// It adjusts the start time to match that of other motions in the same synchronization group that were already started.
F32 syncActivationTime(F32 time);
// Accessor.
LLMotionController* getController(void) const { return mController; }
//</singu>
public:
//-------------------------------------------------------------------------
// animation callbacks to be implemented by subclasses
@@ -181,6 +265,9 @@ protected:
//-------------------------------------------------------------------------
std::string mName; // instance name assigned by motion controller
LLUUID mID;
//<singu>
LLMotionController* mController;
//</singu>
F32 mActivationTimestamp; // time when motion was activated
F32 mStopTimestamp; // time when motion was told to stop
@@ -199,9 +286,9 @@ protected:
class LLTestMotion : public LLMotion
{
public:
LLTestMotion(const LLUUID &id) : LLMotion(id){}
LLTestMotion(LLUUID const& id, LLMotionController* controller) : LLMotion(id, controller){}
~LLTestMotion() {}
static LLMotion *create(const LLUUID& id) { return new LLTestMotion(id); }
static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLTestMotion(id, controller); }
BOOL getLoop() { return FALSE; }
F32 getDuration() { return 0.0f; }
F32 getEaseInDuration() { return 0.0f; }
@@ -223,9 +310,9 @@ public:
class LLNullMotion : public LLMotion
{
public:
LLNullMotion(const LLUUID &id) : LLMotion(id) {}
LLNullMotion(LLUUID const& id, LLMotionController* controller) : LLMotion(id, controller) {}
~LLNullMotion() {}
static LLMotion *create(const LLUUID &id) { return new LLNullMotion(id); }
static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLNullMotion(id, controller); }
// motions must specify whether or not they loop
/*virtual*/ BOOL getLoop() { return TRUE; }
@@ -266,5 +353,41 @@ public:
// called when a motion is deactivated
/*virtual*/ void onDeactivate() {}
};
//-----------------------------------------------------------------------------
// AIMaskedMotion
//-----------------------------------------------------------------------------
// These motions have a bit assigned in LLMotionController::mActiveMask
// that is set and uset upon activation/deactivation.
// This must be in the same order as ANIM_AGENT_BODY_NOISE_ID through ANIM_AGENT_WALK_ADJUST_ID in llvoavatar.cpp.
U32 const ANIM_AGENT_BODY_NOISE = 0x001;
U32 const ANIM_AGENT_BREATHE_ROT = 0x002;
U32 const ANIM_AGENT_PHYSICS_MOTION = 0x004;
U32 const ANIM_AGENT_EDITING = 0x008;
U32 const ANIM_AGENT_EYE = 0x010;
U32 const ANIM_AGENT_FLY_ADJUST = 0x020;
U32 const ANIM_AGENT_HAND_MOTION = 0x040;
U32 const ANIM_AGENT_HEAD_ROT = 0x080;
U32 const ANIM_AGENT_PELVIS_FIX = 0x100;
U32 const ANIM_AGENT_TARGET = 0x200;
U32 const ANIM_AGENT_WALK_ADJUST = 0x400;
class AIMaskedMotion : public LLMotion
{
private:
U32 mMaskBit;
public:
AIMaskedMotion(LLUUID const& id, LLMotionController* controller, U32 mask_bit) : LLMotion(id, controller), mMaskBit(mask_bit) { }
/*virtual*/ BOOL onActivate();
/*virtual*/ void onDeactivate();
U32 getMaskBit(void) const { return mMaskBit; }
};
#endif // LL_LLMOTION_H

View File

@@ -97,7 +97,7 @@ void LLMotionRegistry::markBad( const LLUUID& id )
//-----------------------------------------------------------------------------
// createMotion()
//-----------------------------------------------------------------------------
LLMotion *LLMotionRegistry::createMotion( const LLUUID &id )
LLMotion* LLMotionRegistry::createMotion(LLUUID const& id, LLMotionController* controller)
{
LLMotionConstructor constructor = get_if_there(mMotionTable, id, LLMotionConstructor(NULL));
LLMotion* motion = NULL;
@@ -105,11 +105,11 @@ LLMotion *LLMotionRegistry::createMotion( const LLUUID &id )
if ( constructor == NULL )
{
// *FIX: need to replace with a better default scheme. RN
motion = LLKeyframeMotion::create(id);
motion = LLKeyframeMotion::create(id, controller);
}
else
{
motion = constructor(id);
motion = constructor(id, controller);
}
return motion;
@@ -126,18 +126,22 @@ LLMotion *LLMotionRegistry::createMotion( const LLUUID &id )
// Class Constructor
//-----------------------------------------------------------------------------
LLMotionController::LLMotionController()
: mTimeFactor(sCurrentTimeFactor),
: mIsSelf(FALSE),
mTimeFactor(sCurrentTimeFactor),
mCharacter(NULL),
mAnimTime(0.f),
mActiveMask(0),
mDisableSyncing(0),
mHidden(false),
mHaveVisibleSyncedMotions(false),
mPrevTimerElapsed(0.f),
mAnimTime(0.f),
mLastTime(0.0f),
mHasRunOnce(FALSE),
mPaused(FALSE),
mPauseTime(0.f),
mTimeStep(0.f),
mTimeStepCount(0),
mLastInterp(0.f),
mIsSelf(FALSE)
mLastInterp(0.f)
{
}
@@ -168,7 +172,15 @@ void LLMotionController::deleteAllMotions()
mLoadingMotions.clear();
mLoadedMotions.clear();
mActiveMotions.clear();
//<singu>
mActiveMask = 0;
for_each(mDeprecatedMotions.begin(), mDeprecatedMotions.end(), DeletePointer());
mDeprecatedMotions.clear();
for (motion_map_t::iterator iter = mAllMotions.begin(); iter != mAllMotions.end(); ++iter)
{
iter->second->unregister_client();
}
//</singu>
for_each(mAllMotions.begin(), mAllMotions.end(), DeletePairedPointer());
mAllMotions.clear();
}
@@ -178,26 +190,19 @@ void LLMotionController::deleteAllMotions()
//-----------------------------------------------------------------------------
void LLMotionController::purgeExcessMotions()
{
if (mLoadedMotions.size() > MAX_MOTION_INSTANCES)
//<singu>
// The old code attempted to remove non-active motions from mDeprecatedMotions,
// but that is nonsense: there are no motions in mDeprecatedMotions that are not active.
if (mLoadedMotions.size() <= MAX_MOTION_INSTANCES)
{
// clean up deprecated motions
for (motion_set_t::iterator deprecated_motion_it = mDeprecatedMotions.begin();
deprecated_motion_it != mDeprecatedMotions.end(); )
{
motion_set_t::iterator cur_iter = deprecated_motion_it++;
LLMotion* cur_motionp = *cur_iter;
if (!isMotionActive(cur_motionp))
{
// Motion is deprecated so we know it's not cannonical,
// we can safely remove the instance
removeMotionInstance(cur_motionp); // modifies mDeprecatedMotions
mDeprecatedMotions.erase(cur_iter);
}
}
// Speed up, no need to create motions_to_kill.
return;
}
//</singu>
std::set<LLUUID> motions_to_kill;
if (mLoadedMotions.size() > MAX_MOTION_INSTANCES)
if (1) // Singu: leave indentation alone...
{
// too many motions active this frame, kill all blenders
mPoseBlender.clearBlenders();
@@ -308,24 +313,44 @@ BOOL LLMotionController::registerMotion( const LLUUID& id, LLMotionConstructor c
void LLMotionController::removeMotion( const LLUUID& id)
{
LLMotion* motionp = findMotion(id);
mAllMotions.erase(id);
removeMotionInstance(motionp);
//<singu>
// If a motion is erased from mAllMotions, it must be deleted.
if (motionp)
{
mAllMotions.erase(id);
removeMotionInstance(motionp);
delete motionp;
}
//</singu>
}
// removes instance of a motion from all runtime structures, but does
// not erase entry by ID, as this could be a duplicate instance
// use removeMotion(id) to remove all references to a given motion by id.
// use removeMotion(id) to remove a reference to a given motion by id
// (that will not remove (active) deprecated motions).
void LLMotionController::removeMotionInstance(LLMotion* motionp)
{
if (motionp)
{
llassert(findMotion(motionp->getID()) != motionp);
if (motionp->isActive())
motionp->deactivate();
mLoadingMotions.erase(motionp);
mLoadedMotions.erase(motionp);
mActiveMotions.remove(motionp);
delete motionp;
//<singu>
// Deactivation moved here. Only delete motionp when it is being removed from mDeprecatedMotions.
if (motionp->isActive())
{
motionp->deactivate();
// If a motion is deactivated, it must be removed from mDeprecatedMotions if there.
motion_set_t::iterator found_it = mDeprecatedMotions.find(motionp);
if (found_it != mDeprecatedMotions.end())
{
mDeprecatedMotions.erase(found_it);
// If a motion is erased from mDeprecatedMotions, it must be deleted.
delete motionp;
}
}
//</singu>
}
}
@@ -341,7 +366,7 @@ LLMotion* LLMotionController::createMotion( const LLUUID &id )
if (!motion)
{
// look up constructor and create it
motion = sRegistry.createMotion(id);
motion = sRegistry.createMotion(id, this);
if (!motion)
{
return NULL;
@@ -393,6 +418,7 @@ BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset)
if (motion
&& !mPaused
&& motion->canDeprecate()
&& motion->isActive() // singu: do not deprecate motions that are not active.
&& motion->getFadeWeight() > 0.01f // not LOD-ed out
&& (motion->isBlending() || motion->getStopTime() != 0.f))
{
@@ -418,7 +444,19 @@ BOOL LLMotionController::startMotion(const LLUUID &id, F32 start_offset)
}
// llinfos << "Starting motion " << name << llendl;
return activateMotionInstance(motion, mAnimTime - start_offset);
//<singu>
F32 start_time = mAnimTime - start_offset;
if (!mDisableSyncing)
{
start_time = motion->syncActivationTime(start_time);
}
++mDisableSyncing;
//</singu>
BOOL res = activateMotionInstance(motion, start_time);
//<singu>
--mDisableSyncing;
//</singu>
return res;
}
@@ -774,7 +812,19 @@ void LLMotionController::updateLoadingMotions()
// this motion should be playing
if (!motionp->isStopped())
{
activateMotionInstance(motionp, mAnimTime);
//<singu>
F32 start_time = mAnimTime;
if (!mDisableSyncing)
{
motionp->aisync_loaded();
start_time = motionp->syncActivationTime(start_time);
}
++mDisableSyncing;
//</singu>
activateMotionInstance(motionp, start_time);
//<singu>
--mDisableSyncing;
//</singu>
}
}
else if (status == LLMotion::STATUS_FAILURE)
@@ -782,12 +832,15 @@ void LLMotionController::updateLoadingMotions()
llinfos << "Motion " << motionp->getID() << " init failed." << llendl;
sRegistry.markBad(motionp->getID());
mLoadingMotions.erase(curiter);
motion_set_t::iterator found_it = mDeprecatedMotions.find(motionp);
if (found_it != mDeprecatedMotions.end())
{
mDeprecatedMotions.erase(found_it);
}
// Singu note: a motion in mLoadingMotions will not be in mActiveMotions
// and therefore not be in mDeprecatedMotions. So, we don't have to
// check for it's existence there.
llassert(mDeprecatedMotions.find(motionp) == mDeprecatedMotions.end());
mAllMotions.erase(motionp->getID());
//<singu>
// Make sure we're not registered anymore.
motionp->unregister_client();
//</singu>
delete motionp;
}
}
@@ -821,8 +874,15 @@ void LLMotionController::updateMotions(bool force_update)
{
F32 time_interval = fmodf(update_time, mTimeStep);
// always animate *ahead* of actual time
S32 quantum_count = llmax(0, llfloor((update_time - time_interval) / mTimeStep)) + 1;
//<singu>
// This old code is nonsense.
//S32 quantum_count = llmax(0, llround((update_time - time_interval) / mTimeStep)) + 1;
// (update_time - time_interval) / mTimeStep is an integer! We need llround to get rid of floating point errors, not llfloor.
// Moreover, just rounding off to the nearest integer with llround(update_time / mTimeStep) makes a lot more sense:
// it is the best we can do to get as close to what we should draw as possible.
// However, mAnimTime may only be incremented; therefore make sure of that with the llmax.
S32 quantum_count = llmax(llround(update_time / mTimeStep), llceil(mAnimTime / mTimeStep));
//</singu>
if (quantum_count == mTimeStepCount)
{
// we're still in same time quantum as before, so just interpolate and exit
@@ -848,7 +908,8 @@ void LLMotionController::updateMotions(bool force_update)
}
else
{
mAnimTime = update_time;
// Singu note: mAnimTime may never be set back in time.
mAnimTime = llmax(mAnimTime, update_time);
}
}
@@ -915,6 +976,12 @@ BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time)
if (mLoadingMotions.find(motion) != mLoadingMotions.end())
{
//<singu>
if (!syncing_disabled())
{
motion->aisync_loading();
}
//</singu>
// we want to start this motion, but we can't yet, so flag it as started
motion->setStopped(FALSE);
// report pending animations as activated
@@ -970,18 +1037,16 @@ BOOL LLMotionController::activateMotionInstance(LLMotion *motion, F32 time)
//-----------------------------------------------------------------------------
BOOL LLMotionController::deactivateMotionInstance(LLMotion *motion)
{
motion->deactivate();
motion_set_t::iterator found_it = mDeprecatedMotions.find(motion);
if (found_it != mDeprecatedMotions.end())
{
// deprecated motions need to be completely excised
removeMotionInstance(motion);
mDeprecatedMotions.erase(found_it);
removeMotionInstance(motion); // singu note: this deactivates motion and removes it from mDeprecatedMotions.
}
else
{
// for motions that we are keeping, simply remove from active queue
motion->deactivate(); // singu note: moved here from the top of the function.
mActiveMotions.remove(motion);
}
@@ -1049,11 +1114,26 @@ void LLMotionController::dumpMotions()
state_string += std::string("L");
if (std::find(mActiveMotions.begin(), mActiveMotions.end(), motion)!=mActiveMotions.end())
state_string += std::string("A");
if (mDeprecatedMotions.find(motion) != mDeprecatedMotions.end())
state_string += std::string("D");
llassert(mDeprecatedMotions.find(motion) == mDeprecatedMotions.end()); // singu: it's impossible that a motion is in mAllMotions and mDeprecatedMotions at the same time.
llinfos << gAnimLibrary.animationName(id) << " " << state_string << llendl;
}
//<singu>
// Also dump the deprecated motions.
for (motion_set_t::iterator iter = mDeprecatedMotions.begin();
iter != mDeprecatedMotions.end(); ++iter)
{
std::string state_string;
LLMotion* motion = *iter;
LLUUID id = motion->getID();
llassert(mLoadingMotions.find(motion) == mLoadingMotions.end());
if (mLoadedMotions.find(motion) != mLoadedMotions.end())
state_string += std::string("L");
if (std::find(mActiveMotions.begin(), mActiveMotions.end(), motion)!=mActiveMotions.end())
state_string += std::string("A");
state_string += "D";
llinfos << gAnimLibrary.animationName(id) << " " << state_string << llendl;
}
//</singu>
}
//-----------------------------------------------------------------------------
@@ -1061,11 +1141,11 @@ void LLMotionController::dumpMotions()
//-----------------------------------------------------------------------------
void LLMotionController::deactivateAllMotions()
{
for (motion_map_t::iterator iter = mAllMotions.begin();
iter != mAllMotions.end(); iter++)
// Singu note: this must run over mActiveMotions: other motions are not active,
// and running over mAllMotions will miss the ones in mDeprecatedMotions.
for (motion_list_t::iterator iter = mActiveMotions.begin(); iter != mActiveMotions.end();)
{
LLMotion* motionp = iter->second;
deactivateMotionInstance(motionp);
deactivateMotionInstance(*iter++); // This might invalidate iter by erasing it from mActiveMotions.
}
}
@@ -1086,8 +1166,7 @@ void LLMotionController::flushAllMotions()
active_motions.push_back(std::make_pair(motionp->getID(),dtime));
motionp->deactivate(); // don't call deactivateMotionInstance() because we are going to reactivate it
}
mActiveMotions.clear();
// delete all motion instances
deleteAllMotions();
@@ -1096,13 +1175,136 @@ void LLMotionController::flushAllMotions()
mCharacter->removeAnimationData("Hand Pose");
// restart motions
//<singu>
// Because we called motionp->deactivate() above, instead of deactivateMotionInstance(),
// prevent calling AISyncClientMotion::activateInstance in startMotion below.
disable_syncing();
//</singu>
for (std::vector<std::pair<LLUUID,F32> >::iterator iter = active_motions.begin();
iter != active_motions.end(); ++iter)
{
startMotion(iter->first, iter->second);
}
//<singu>
enable_syncing();
//</singu>
}
//<singu>
//-----------------------------------------------------------------------------
// toggle_hidden()
//-----------------------------------------------------------------------------
void LLMotionController::toggle_hidden(void)
{
mHaveVisibleSyncedMotions = mHidden; // Default is false if we just became invisible (otherwise this value isn't used).
mHidden = !mHidden;
synceventset_t const visible = mHidden ? 0 : 4;
// Run over all motions.
for (motion_list_t::iterator iter = mActiveMotions.begin(); iter != mActiveMotions.end(); ++iter)
{
LLMotion* motionp = *iter;
AISyncServer* server = motionp->server();
if (server && !server->never_synced() && motionp->isActive()) // Skip motions that aren't synchronized at all or that are not active.
{
bool visible_before = server->events_with_at_least_one_client_ready() & 4;
server->ready(4, visible, motionp); // Mark that now we are visible or no longer visible.
bool visible_after = server->events_with_at_least_one_client_ready() & 4;
if (visible_after) // Are there any synchronized motions (left) that ARE visible?
{
mHaveVisibleSyncedMotions = true;
}
if (visible_before != visible_after)
{
// The group as a whole now might need to change whether or not it is animated.
AISyncServer::client_list_t const& clients = server->getClients();
for (AISyncServer::client_list_t::const_iterator client = clients.begin(); client != clients.end(); ++client)
{
LLMotion* motion = dynamic_cast<LLMotion*>(client->mClientPtr);
if (!motion)
{
continue;
}
LLMotionController* controller = motion->getController();
if (controller == this)
{
continue;
}
if (visible_after)
{
// Us becoming visible means that all synchronized avatars need to be animated again too.
controller->setHaveVisibleSyncedMotions();
}
else
{
// Us becoming hidden means that all synchronized avatars might stop animating.
controller->refresh_hidden(); // It is extremely unlikely, but harmless, to call this twice on the same controller.
}
}
}
}
}
}
void LLMotionController::refresh_hidden(void)
{
mHaveVisibleSyncedMotions = !mHidden;
// Run over all motions.
for (motion_list_t::iterator iter = mActiveMotions.begin(); iter != mActiveMotions.end(); ++iter)
{
LLMotion* motionp = *iter;
AISyncServer* server = motionp->server();
if (server && !server->never_synced() && motionp->isActive()) // Skip motions that aren't synchronized at all or that are not active.
{
bool visible_after = server->events_with_at_least_one_client_ready() & 4;
if (visible_after) // Are there any synchronized motions (left) that ARE visible?
{
mHaveVisibleSyncedMotions = true;
}
}
}
}
void LLMotionController::pauseAllSyncedCharacters(std::vector<LLAnimPauseRequest>& avatar_pause_handles)
{
// Run over all motions.
for (motion_list_t::iterator iter = mActiveMotions.begin(); iter != mActiveMotions.end(); ++iter)
{
LLMotion* motionp = *iter;
AISyncServer* server = motionp->server();
if (server && !server->never_synced() && motionp->isActive()) // Skip motions that aren't synchronized at all or that are not active.
{
// Run over all clients of the found servers.
AISyncServer::client_list_t const& clients = server->getClients();
for (AISyncServer::client_list_t::const_iterator client = clients.begin(); client != clients.end(); ++client)
{
LLMotion* motion = dynamic_cast<LLMotion*>(client->mClientPtr);
if (!motion)
{
continue;
}
LLMotionController* controller = motion->getController();
if (controller == this)
{
continue;
}
controller->requestPause(avatar_pause_handles);
}
}
}
}
void LLMotionController::requestPause(std::vector<LLAnimPauseRequest>& avatar_pause_handles)
{
if (mCharacter)
{
mCharacter->requestPause(avatar_pause_handles);
}
}
//</singu>
//-----------------------------------------------------------------------------
// pause()
//-----------------------------------------------------------------------------

View File

@@ -51,11 +51,14 @@
// This is necessary because llcharacter.h includes this file.
//-----------------------------------------------------------------------------
class LLCharacter;
class LLMotionController;
class LLPauseRequestHandle;
typedef LLPointer<LLPauseRequestHandle> LLAnimPauseRequest;
//-----------------------------------------------------------------------------
// LLMotionRegistry
//-----------------------------------------------------------------------------
typedef LLMotion*(*LLMotionConstructor)(const LLUUID &id);
typedef LLMotion* (*LLMotionConstructor)(LLUUID const& id, LLMotionController*);
class LLMotionRegistry
{
@@ -72,7 +75,7 @@ public:
// creates a new instance of a named motion
// returns NULL motion is not registered
LLMotion *createMotion( const LLUUID &id );
LLMotion* createMotion(LLUUID const& id, LLMotionController* controller);
// initialization of motion failed, don't try to create this motion again
void markBad( const LLUUID& id );
@@ -115,7 +118,6 @@ public:
// unregisters a motion with the controller
// (actually just forwards call to motion registry)
// returns true if successfull
void removeMotion( const LLUUID& id );
// start motion
@@ -150,10 +152,20 @@ public:
//Flush is a liar.
void deactivateAllMotions();
//<singu>
void activated(U32 bit) { mActiveMask |= bit; }
void deactivated(U32 bit) { mActiveMask &= ~bit; }
bool isactive(U32 bit) const { return (mActiveMask & bit) != 0; }
//</singu>
// pause and continue all motions
void pauseAllMotions();
void unpauseAllMotions();
BOOL isPaused() const { return mPaused; }
//<singu>
void requestPause(std::vector<LLAnimPauseRequest>& avatar_pause_handles);
void pauseAllSyncedCharacters(std::vector<LLAnimPauseRequest>& avatar_pause_handles);
//</singu>
void setTimeStep(F32 step);
@@ -180,7 +192,10 @@ protected:
// internal operations act on motion instances directly
// as there can be duplicate motions per id during blending overlap
void deleteAllMotions();
// singu: LLMotion needs access to activateMotionInstance.
public:
BOOL activateMotionInstance(LLMotion *motion, F32 time);
protected:
BOOL deactivateMotionInstance(LLMotion *motion);
void deprecateMotionInstance(LLMotion* motion);
BOOL stopMotionInstance(LLMotion *motion, BOOL stop_imemdiate);
@@ -205,10 +220,13 @@ protected:
// Life cycle of an animation:
//
// Animations are instantiated and immediately put in the mAllMotions map for their entire lifetime.
// Singu note: that is not true, they are moved to mDeprecatedMotions (often) for the last part of their lifetime.
// If the animations depend on any asset data, the appropriate data is fetched from the data server,
// and the animation is put on the mLoadingMotions list.
// Once an animations is loaded, it will be initialized and put on the mLoadedMotions list.
// Any animation that is currently playing also sits in the mActiveMotions list.
// Singu note: animations are only put in mDeprecatedMotions if and while they are playing,
// therefore animations in mDeprecatedMotions will be (must be) active and in mActiveMotions.
typedef std::map<LLUUID, LLMotion*> motion_map_t;
motion_map_t mAllMotions;
@@ -217,7 +235,13 @@ protected:
motion_set_t mLoadedMotions;
motion_list_t mActiveMotions;
motion_set_t mDeprecatedMotions;
//<singu>
U32 mActiveMask;
int mDisableSyncing; // Set while LLMotion::onActivate (and onDeactivate) are called for this controller.
bool mHidden; // The value of the last call to hidden().
bool mHaveVisibleSyncedMotions; // Set when we are synchronized with one or more motions of a controller that is not hidden.
//</singu>
LLFrameTimer mTimer;
F32 mPrevTimerElapsed;
F32 mAnimTime;
@@ -230,6 +254,26 @@ protected:
F32 mLastInterp;
U8 mJointSignature[2][LL_CHARACTER_MAX_JOINTS];
//<singu>
public:
// Internal administration for AISync.
void disable_syncing(void) { mDisableSyncing += 100; }
void enable_syncing(void) { mDisableSyncing -= 100; }
bool syncing_disabled(void) const { return mDisableSyncing >= 100; }
// Accessors needed for synchronization.
F32 getAnimTime(void) const { return mAnimTime; }
bool isHidden(void) const { return mHidden; }
// Called often. Should return false if we still need to keep updating our motions even if we're not visible.
bool hidden(bool not_visible) { if (mHidden != not_visible) toggle_hidden(); return !mHaveVisibleSyncedMotions; }
private:
void toggle_hidden(void);
void refresh_hidden(void);
void setHaveVisibleSyncedMotions(void) { mHaveVisibleSyncedMotions = true; }
//</singu>
};
//-----------------------------------------------------------------------------

View File

@@ -52,7 +52,7 @@ const F32 TORSO_ROT_FRACTION = 0.5f;
// LLTargetingMotion()
// Class Constructor
//-----------------------------------------------------------------------------
LLTargetingMotion::LLTargetingMotion(const LLUUID &id) : LLMotion(id)
LLTargetingMotion::LLTargetingMotion(LLUUID const& id, LLMotionController* controller) : AIMaskedMotion(id, controller, ANIM_AGENT_TARGET)
{
mCharacter = NULL;
mName = "targeting";
@@ -99,14 +99,6 @@ LLMotion::LLMotionInitStatus LLTargetingMotion::onInitialize(LLCharacter *charac
return STATUS_SUCCESS;
}
//-----------------------------------------------------------------------------
// LLTargetingMotion::onActivate()
//-----------------------------------------------------------------------------
BOOL LLTargetingMotion::onActivate()
{
return TRUE;
}
//-----------------------------------------------------------------------------
// LLTargetingMotion::onUpdate()
//-----------------------------------------------------------------------------
@@ -166,12 +158,4 @@ BOOL LLTargetingMotion::onUpdate(F32 time, U8* joint_mask)
return result;
}
//-----------------------------------------------------------------------------
// LLTargetingMotion::onDeactivate()
//-----------------------------------------------------------------------------
void LLTargetingMotion::onDeactivate()
{
}
// End

View File

@@ -48,11 +48,11 @@
// class LLTargetingMotion
//-----------------------------------------------------------------------------
class LLTargetingMotion :
public LLMotion
public AIMaskedMotion
{
public:
// Constructor
LLTargetingMotion(const LLUUID &id);
LLTargetingMotion(LLUUID const& id, LLMotionController* controller);
// Destructor
virtual ~LLTargetingMotion();
@@ -64,7 +64,7 @@ public:
// static constructor
// all subclasses must implement such a function and register it
static LLMotion *create(const LLUUID &id) { return new LLTargetingMotion(id); }
static LLMotion* create(LLUUID const& id, LLMotionController* controller) { return new LLTargetingMotion(id, controller); }
public:
//-------------------------------------------------------------------------
@@ -96,19 +96,11 @@ public:
// must return true to indicate success and be available for activation
virtual LLMotionInitStatus onInitialize(LLCharacter *character);
// called when a motion is activated
// must return TRUE to indicate success, or else
// it will be deactivated
virtual BOOL onActivate();
// called per time step
// must return TRUE while it is active, and
// must return FALSE when the motion is completed.
virtual BOOL onUpdate(F32 time, U8* joint_mask);
// called when a motion is deactivated
virtual void onDeactivate();
public:
LLCharacter *mCharacter;

View File

@@ -20,6 +20,7 @@ set(llcommon_SOURCE_FILES
aialert.cpp
aifile.cpp
aiframetimer.cpp
aisyncclient.cpp
aithreadid.cpp
imageids.cpp
indra_constants.cpp
@@ -59,7 +60,6 @@ set(llcommon_SOURCE_FILES
llformat.cpp
llframetimer.cpp
llheartbeat.cpp
llindraconfigfile.cpp
llinitparam.cpp
llinstancetracker.cpp
llliveappconfig.cpp
@@ -112,11 +112,13 @@ set(llcommon_HEADER_FILES
aifile.h
aiframetimer.h
airecursive.h
aisyncclient.h
aithreadid.h
aithreadsafe.h
bitpack.h
ctype_workaround.h
doublelinkedlist.h
fix_macros.h
imageids.h
indra_constants.h
linden_common.h
@@ -183,7 +185,6 @@ set(llcommon_HEADER_FILES
llheartbeat.h
llhttpstatuscodes.h
llindexedqueue.h
llindraconfigfile.h
llinitparam.h
llinstancetracker.h
llkeythrottle.h
@@ -253,7 +254,6 @@ set(llcommon_HEADER_FILES
metapropertyt.h
reflective.h
reflectivet.h
roles_constants.h
stdenums.h
stdtypes.h
string_table.h
@@ -270,6 +270,9 @@ list(APPEND llcommon_SOURCE_FILES ${cwdebug_SOURCE_FILES})
list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
add_library (llcommon SHARED ${llcommon_SOURCE_FILES})
if(WINDOWS)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL")
endif(WINDOWS)
add_dependencies(llcommon prepare)
target_link_libraries(
llcommon

View File

@@ -0,0 +1,698 @@
/**
* @file aisyncclient.cpp
*
* Copyright (c) 2013, Aleric Inglewood.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution.
*
* CHANGELOG
* and additional copyright holders.
*
* 13/12/2013
* - Initial version, written by Aleric Inglewood @ SL
*/
/*
* AISyncClient : the base class of a client object (LLMotion) that needs to be informed
* of the state of other such objects and/or to poll a server object about the state of
* other such objects, in order to be and stay synchronized with those other objects.
* In the case of an LLMotion (animation), all clients would be started and stopped at
* the same time, as long as they are part of the same synchronization group (AISyncServer).
*
* AISyncKey: object that determines what synchronization group a client belongs to.
* When a new client is created, a new AISyncKey is created too, using information from
* the client, the current frame number and the current frame time. If two AISyncKey
* compare equal, using operator==(AISyncKey const& key1, AISyncKey const& key2),
* then the clients that created them need to be synchronized.
*
* AISyncServer: object that represents a group of clients that need to be synchronized:
* it's a wrapper around a std::list<AISyncClientData> with pointers to all the clients
* that need to be synchronized. It also stores the AISyncKey of the first (oldest) client
* that was added. Clients with keys that compare equal to that will be added.
* If a client is added with a synckeytype_t that is larger then it always replaces
* the existing key however.
*
* AISyncServerMap: A wrapper around std::list<boost::intrusive_ptr<AISyncServer> >
* that stores pointers to all currently existing AISyncServer objects. New entries
* are added at the end, so the oldest key is at the front.
*
* AISyncServerMap list + - - - - - - + - - - - - - + ... The AISyncServerMap is
* | | | a list with refcounted
* V V V pointers to AISyncServers.
* AISyncClient +--> AISyncServer
* | <--- list key ---> AISyncKey Each AISyncServer is a
* DerivedClient . list of normal pointers
* . AISyncClients and one
* <--- . pointer to a AISyncKey.
* Each AISyncClient is the
* base class of a DerivedClient
* and pointers back to the
* server with a refcounted
* pointer.
*
* A new client is passed to the AISyncServerMap to be stored in a new or existing AISyncServer
* object, using the key that the client produces. A boost::intrusive_ptr<AISyncServer> member
* of the client is set to point to this server.
*
* The lifetime of the server objects is determined by the intrusive_ptr objects that
* point to it: all the clients (which have an externally determined lifetime) and one
* pointer in the AISyncServerMap. However, regularly a check is done on all servers in
* the list to find expired servers: objects with keys older than two frames and older
* than 0.1 seconds; if such a server is found and it has zero or one client, then the
* client is unregistered and the pointer (and thus the server) removed from the
* AISyncServerMap. If it has two or more clients then the entry is kept until both
* clients are removed, which therefore can only be detected in intrusive_ptr_release
* which only has access to the server object. The server then is removed from the list
* by searching through it for the pointer to the server.
*/
#include "sys.h"
#include "aisyncclient.h"
#include <cmath>
#include <algorithm>
#include "debug.h"
bool operator==(AISyncKey const& key1, AISyncKey const& key2)
{
// Test if these keys match based on time.
if (std::abs((S32)(key1.mStartFrameCount - key2.mStartFrameCount)) > 1 &&
std::abs(key1.mFrameTimer.getStartTime() - key2.mFrameTimer.getStartTime()) >= sSyncKeyExpirationTime)
{
return false;
}
// Time matches, let the derived classes determine if they also match otherwise.
return key1.equals(key2);
}
#ifdef CWDEBUG
struct SyncEventSet {
synceventset_t mBits;
SyncEventSet(synceventset_t bits) : mBits(bits) { }
};
std::ostream& operator<<(std::ostream& os, SyncEventSet const& ses)
{
for (int b = sizeof(ses.mBits) * 8 - 1; b >= 0; --b)
{
int m = 1 << b;
os << ((ses.mBits & m) ? '1' : '0');
}
return os;
}
void print_clients(AISyncServer const* server, AISyncServer::client_list_t const& client_list)
{
Dout(dc::notice, "Clients of server " << server << ": ");
for (AISyncServer::client_list_t::const_iterator iter = client_list.begin(); iter != client_list.end(); ++ iter)
{
llassert(iter->mClientPtr->mReadyEvents == iter->mReadyEvents);
Dout(dc::notice, "-> " << iter->mClientPtr << " : " << SyncEventSet(iter->mReadyEvents));
}
}
#endif
void AISyncServerMap::register_client(AISyncClient* client, AISyncKey* new_key)
{
// client must always be a new client that has to be stored somewhere.
llassert(client->server() == NULL);
// Obviously the client can't be ready for anything when it isn't registered yet.
llassert(!client->mReadyEvents);
// Find if a server with this key already exists.
AISyncServer* server = NULL;
for (server_list_t::iterator iter = mServers.begin(); iter != mServers.end();)
{
boost::intrusive_ptr<AISyncServer>& server_ptr = *iter++; // Immediately increment iter because the call to unregister_last_client will erase it.
AISyncKey const& server_key(server_ptr->key());
if (server_key.is_older_than(*new_key)) // This means that the server key is expired: a new key will never match.
{
if (server_ptr->never_synced()) // This means that it contains one or zero clients and will never contain more.
{
// Get rid of this server.
server_ptr->unregister_last_client(); // This will cause the server to be deleted, and erased from mServers.
}
continue;
}
if (*new_key == server_key)
{
server = server_ptr.get();
// mServers stores new servers in strict order of the creation time of the keys,
// so once we find a server with a key that is equal, none of the remaining servers
// will have expired if they were never synced and we're done with the loop.
// Servers that synced might have been added later, but we don't unregister
// clients from those anyway because their sync partner might still show up.
break;
}
}
if (server)
{
// A server already exists.
// Keep the oldest key, unless this new key has a synckeytype_t that is larger!
if (new_key->getkeytype() > server->key().getkeytype())
{
server->swapkey(new_key);
}
delete new_key;
}
else
{
// Create a new server for this client. Transfers the ownership of the key allocation to the server.
server = new AISyncServer(new_key);
// Add it to mServers, before the last server that is younger then the new key.
server_list_t::iterator where = mServers.end(); // Insert the new server before 'where',
server_list_t::iterator new_where = where;
while (where != mServers.begin()) // unless there exists a server before that
{
--new_where;
if (new_key->getCreationTime() > (*new_where)->key().getCreationTime()) // and the new key is not younger then that,
{
break;
}
where = new_where; // then insert it before that element (etc).
}
// This method causes a single call to intrusive_ptr_add_ref and none to intrusive_ptr_release.
server_ptr_t server_ptr = server;
mServers.insert(where, server_ptr_t())->swap(server_ptr);
}
// Add the client to the server.
server->add(client);
}
#ifdef SYNC_TESTSUITE
void AISyncServer::sanity_check(void) const
{
synceventset_t ready_events = (synceventset_t)-1; // All clients are ready.
client_list_t::const_iterator client_iter = mClients.begin();
while (client_iter != mClients.end())
{
ready_events &= client_iter->mReadyEvents;
++client_iter;
}
synceventset_t pending_events = 0; // At least one client is ready.
client_iter = mClients.begin();
while (client_iter != mClients.end())
{
pending_events |= client_iter->mReadyEvents;
++client_iter;
}
llassert(ready_events == mReadyEvents);
llassert(pending_events == mPendingEvents);
}
#endif
void AISyncServer::add(AISyncClient* client)
{
#ifdef SYNC_TESTSUITE
sanity_check();
#endif
// The client can't already be ready when it isn't even added to a server yet.
llassert(!client->mReadyEvents);
synceventset_t old_ready_events = mReadyEvents;
// A new client is not ready for anything.
mReadyEvents = 0;
// Set mSynchronized if after adding client we'll have more than 1 client (that prevents the
// server from being deleted unless all clients are actually destructed or explicitly unregistered).
if (!mSynchronized && mClients.size() > 0)
{
mSynchronized = true;
}
// Trigger the existing clients to be not-ready anymore (if we were before).
trigger(old_ready_events);
// Only then add the new client (so that it didn't get not-ready trigger).
mClients.push_back(client);
client->mServer = this;
#ifdef SYNC_TESTSUITE
sanity_check();
#endif
}
void AISyncServer::remove(AISyncClient* client)
{
#ifdef SYNC_TESTSUITE
sanity_check();
#endif
client_list_t::iterator client_iter = mClients.begin();
synceventset_t remaining_ready_events = (synceventset_t)-1; // All clients are ready.
synceventset_t remaining_pending_events = 0; // At least one client is ready (waiting for the other clients thus).
client_list_t::iterator found_client = mClients.end();
while (client_iter != mClients.end())
{
if (client_iter->mClientPtr == client)
{
found_client = client_iter;
}
else
{
remaining_ready_events &= client_iter->mReadyEvents;
remaining_pending_events |= client_iter->mReadyEvents;
}
++client_iter;
}
llassert(found_client != mClients.end());
// This must be the same as client->mReadyEvents.
llassert(found_client->mReadyEvents == client->mReadyEvents);
mClients.erase(found_client);
synceventset_t old_ready_events = mReadyEvents;
mReadyEvents = remaining_ready_events;
mPendingEvents = remaining_pending_events;
trigger(old_ready_events);
client->mServer.reset();
client->deregistered();
#ifdef SYNC_TESTSUITE
sanity_check();
#endif
}
void AISyncServer::unregister_last_client(void)
{
#ifdef SYNC_TESTSUITE
sanity_check();
#endif
// This function may only be called for servers with exactly one client that was never (potentially) synchronized.
llassert(!mSynchronized && mClients.size() == 1);
AISyncClient* client = mClients.begin()->mClientPtr;
mClients.clear();
client->mServer.reset();
llassert(mReadyEvents == client->mReadyEvents);
llassert(mPendingEvents == mReadyEvents);
// No need to update mReadyEvents/mPendingEvents because the server is going to be deleted,
// but inform the client that is no longer has a server.
client->deregistered();
#ifdef SYNC_TESTSUITE
sanity_check();
#endif
}
void AISyncServer::trigger(synceventset_t old_ready_events)
{
// If event 1 changed, informat all clients about it.
if (((old_ready_events ^ mReadyEvents) & 1))
{
for (client_list_t::iterator client_iter = mClients.begin(); client_iter != mClients.end(); ++client_iter)
{
if ((mReadyEvents & 1))
{
client_iter->mClientPtr->event1_ready();
}
else
{
client_iter->mClientPtr->event1_not_ready();
}
}
}
}
void AISyncServer::ready(synceventset_t events, synceventset_t yesno, AISyncClient* client)
{
#ifdef SYNC_TESTSUITE
sanity_check();
#endif
synceventset_t added_events = events & yesno;
synceventset_t removed_events = events & ~yesno;
// Run over all clients to find the client and calculate the current state.
synceventset_t remaining_ready_events = (synceventset_t)-1; // All clients are ready.
synceventset_t remaining_pending_events = 0; // At least one client is ready (waiting for the other clients thus).
client_list_t::iterator found_client = mClients.end();
for (client_list_t::iterator client_iter = mClients.begin(); client_iter != mClients.end(); ++client_iter)
{
if (client_iter->mClientPtr == client)
{
found_client = client_iter;
}
else
{
remaining_ready_events &= client_iter->mReadyEvents;
remaining_pending_events |= client_iter->mReadyEvents;
}
}
llassert(mReadyEvents == (remaining_ready_events & found_client->mReadyEvents));
llassert(mPendingEvents == (remaining_pending_events | found_client->mReadyEvents));
found_client->mReadyEvents &= ~removed_events;
found_client->mReadyEvents |= added_events;
#ifdef SHOW_ASSERT
client->mReadyEvents = found_client->mReadyEvents;
#endif
synceventset_t old_ready_events = mReadyEvents;
mReadyEvents = remaining_ready_events & found_client->mReadyEvents;
mPendingEvents = remaining_pending_events | found_client->mReadyEvents;
trigger(old_ready_events);
#ifdef SYNC_TESTSUITE
sanity_check();
#endif
}
void intrusive_ptr_add_ref(AISyncServer* server)
{
server->mRefCount++;
}
void intrusive_ptr_release(AISyncServer* server)
{
llassert(server->mRefCount > 0);
server->mRefCount--;
if (server->mRefCount == 0)
{
delete server;
}
else if (server->mRefCount == 1)
{
// If the the last pointer to this server is in the the AISyncServerMap, then delete that too.
AISyncServerMap::instance().remove_server(server);
}
}
void AISyncServerMap::remove_server(AISyncServer* server)
{
for (server_list_t::iterator iter = mServers.begin(); iter != mServers.end(); ++iter)
{
if (server == iter->get())
{
mServers.erase(iter); // This causes server to be deleted too.
return;
}
}
// The server must be found: this function is only called from intrusive_ptr_release for servers
// with just a single server_ptr_t left, which must be the one in mServers (otherwise it wasn't
// even registered properly!)
llassert(false);
}
//=============================================================================
// SYNC_TESTSUITE
//=============================================================================
#ifdef SYNC_TESTSUITE
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <boost/io/ios_state.hpp>
//static
U32 LLFrameTimer::sFrameCount;
double innerloop_count = 0;
double LLFrameTimer::getCurrentTime()
{
return innerloop_count * 0.001;
}
template<synckeytype_t synckeytype>
class TestsuiteKey : public AISyncKey
{
private:
int mIndex;
public:
TestsuiteKey(int index) : mIndex(index) { }
int getIndex(void) const { return mIndex; }
// Virtual functions of AISyncKey.
public:
/*virtual*/ synckeytype_t getkeytype(void) const
{
// Return a unique identifier for this class, where the low 8 bits represent the syncgroup.
return synckeytype;
}
/*virtual*/ bool equals(AISyncKey const& key) const
{
synckeytype_t const theotherkey = (synckeytype_t)(synckeytype ^ 0x100);
switch (key.getkeytype())
{
case synckeytype:
{
// The other key is of the same type.
TestsuiteKey<synckeytype> const& test_key = static_cast<TestsuiteKey<synckeytype> const&>(key);
return (mIndex & 1) == (test_key.mIndex & 1);
}
case theotherkey:
{
TestsuiteKey<theotherkey> const& test_key = static_cast<TestsuiteKey<theotherkey> const&>(key);
return (mIndex & 2) == (test_key.getIndex() & 2);
}
default:
// The keys must be in the same syncgroup.
break;
}
return false;
}
};
template<synckeytype_t synckeytype>
class TestsuiteClient : public AISyncClient
{
// AISyncClient events.
protected:
/*virtual*/ AISyncKey* createSyncKey(void) const
{
return new TestsuiteKey<synckeytype>(mIndex);
}
private:
int mIndex;
bool mRequestedRegistered;
synceventset_t mRequestedReady;
bool mActualReady1;
public:
TestsuiteClient() : mIndex(-1), mRequestedRegistered(false), mRequestedReady(0), mActualReady1(false) { }
~TestsuiteClient() { if (is_registered()) this->ready(mRequestedReady, (synceventset_t)0); }
void setIndex(int index) { mIndex = index; }
protected:
/*virtual*/ void event1_ready(void)
{
#ifdef DEBUG_SYNCOUTPUT
Dout(dc::notice, "Calling TestsuiteClient<" << synckeytype << ">::event1_ready() (mIndex = " << mIndex << ") of client " << this);
#endif
llassert(!mActualReady1);
mActualReady1 = true;
}
/*virtual*/ void event1_not_ready(void)
{
#ifdef DEBUG_SYNCOUTPUT
Dout(dc::notice, "Calling TestsuiteClient<" << synckeytype << ">::event1_not_ready() (mIndex = " << mIndex << ") of client " << this);
#endif
llassert(mActualReady1);
mActualReady1 = false;
}
// This is called when the server expired and we're the only client on it.
/*virtual*/ void deregistered(void)
{
#ifdef DEBUG_SYNCOUTPUT
DoutEntering(dc::notice, "TestsuiteClient<" << synckeytype << ">::deregistered(), with this = " << this);
#endif
mRequestedRegistered = false;
mRequestedReady = 0;
mActualReady1 = false;
this->mReadyEvents = 0;
}
private:
bool is_registered(void) const { return this->server(); }
public:
void change_state(unsigned long r);
bool getRequestedRegistered(void) const { return mRequestedRegistered; }
synceventset_t getRequestedReady(void) const { return mRequestedReady; }
};
TestsuiteClient<synckeytype_test1a>* client1ap;
TestsuiteClient<synckeytype_test1b>* client1bp;
TestsuiteClient<synckeytype_test2a>* client2ap;
TestsuiteClient<synckeytype_test2b>* client2bp;
int const number_of_clients_per_syncgroup = 8;
template<synckeytype_t synckeytype>
void TestsuiteClient<synckeytype>::change_state(unsigned long r)
{
bool change_registered = r & 1;
r >>= 1;
synceventset_t toggle_events = r & 15;
r >>= 4;
if (change_registered)
{
if (mRequestedRegistered && !mRequestedReady)
{
mRequestedRegistered = false;
this->unregister_client();
}
}
else if (toggle_events)
{
mRequestedReady ^= toggle_events;
mRequestedRegistered = true;
this->ready(toggle_events, mRequestedReady & toggle_events);
}
llassert(mRequestedRegistered == is_registered());
AISyncServer* server = this->server();
if (mRequestedRegistered)
{
synceventset_t all_ready = synceventset_t(-1);
synceventset_t any_ready = 0;
int nr = 0;
for (int cl = 0; cl < number_of_clients_per_syncgroup; ++cl)
{
switch ((synckeytype & 0xff))
{
case syncgroup_test1:
{
if (client1ap[cl].server() == server)
{
if (client1ap[cl].getRequestedRegistered())
{
++nr;
all_ready &= client1ap[cl].getRequestedReady();
any_ready |= client1ap[cl].getRequestedReady();
}
}
if (client1bp[cl].server() == server)
{
if (client1bp[cl].getRequestedRegistered())
{
++nr;
all_ready &= client1bp[cl].getRequestedReady();
any_ready |= client1bp[cl].getRequestedReady();
}
}
break;
}
case syncgroup_test2:
{
if (client2ap[cl].server() == server)
{
if (client2ap[cl].getRequestedRegistered())
{
++nr;
all_ready &= client2ap[cl].getRequestedReady();
any_ready |= client2ap[cl].getRequestedReady();
}
}
if (client2bp[cl].server() == server)
{
if (client2bp[cl].getRequestedRegistered())
{
++nr;
all_ready &= client2bp[cl].getRequestedReady();
any_ready |= client2bp[cl].getRequestedReady();
}
}
break;
}
}
}
llassert(nr == server->getClients().size());
llassert(!!(all_ready & 1) == mActualReady1);
llassert(this->server()->events_with_all_clients_ready() == all_ready);
llassert(this->server()->events_with_at_least_one_client_ready() == any_ready);
llassert(nr == 0 || (any_ready & all_ready) == all_ready);
}
llassert(mRequestedReady == this->mReadyEvents);
}
int main()
{
Debug(libcw_do.on());
Debug(dc::notice.on());
Debug(libcw_do.set_ostream(&std::cout));
Debug(list_channels_on(libcw_do));
unsigned short seed16v[3] = { 0x1234, 0xfedc, 0x7091 };
for (int k = 0;; ++k)
{
std::cout << "Loop: " << k << "; SEED: " << std::hex << seed16v[0] << ", " << seed16v[1] << ", " << seed16v[2] << std::dec << std::endl;
++LLFrameTimer::sFrameCount;
seed48(seed16v);
seed16v[0] = lrand48() & 0xffff;
seed16v[1] = lrand48() & 0xffff;
seed16v[2] = lrand48() & 0xffff;
TestsuiteClient<synckeytype_test1a> client1a[number_of_clients_per_syncgroup];
TestsuiteClient<synckeytype_test1b> client1b[number_of_clients_per_syncgroup];
TestsuiteClient<synckeytype_test2a> client2a[number_of_clients_per_syncgroup];
TestsuiteClient<synckeytype_test2b> client2b[number_of_clients_per_syncgroup];
client1ap = client1a;
client1bp = client1b;
client2ap = client2a;
client2bp = client2b;
for (int i = 0; i < number_of_clients_per_syncgroup; ++i)
{
client1a[i].setIndex(i);
client1b[i].setIndex(i);
client2a[i].setIndex(i);
client2b[i].setIndex(i);
}
for (int j = 0; j < 1000000; ++j)
{
innerloop_count += 1;
#ifdef DEBUG_SYNCOUTPUT
Dout(dc::notice, "Innerloop: " << j);
#endif
unsigned long r = lrand48();
synckeytype_t keytype = (r & 1) ? ((r & 2) ? synckeytype_test1a : synckeytype_test1b) : ((r & 2) ? synckeytype_test2a : synckeytype_test2b);
r >>= 2;
int cl = (r & 255) % number_of_clients_per_syncgroup;
r >>= 8;
switch (keytype)
{
case synckeytype_test1a:
client1a[cl].change_state(r);
break;
case synckeytype_test1b:
client1b[cl].change_state(r);
break;
case synckeytype_test2a:
client2a[cl].change_state(r);
break;
case synckeytype_test2b:
client2b[cl].change_state(r);
break;
}
}
}
}
#endif

View File

@@ -0,0 +1,304 @@
/**
* @file aisyncclient.h
* @brief Declaration of AISyncClient.
*
* Copyright (c) 2013, Aleric Inglewood.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution.
*
* CHANGELOG
* and additional copyright holders.
*
* 12/12/2013
* Initial version, written by Aleric Inglewood @ SL
*/
#ifndef AI_SYNC_CLIENT_H
#define AI_SYNC_CLIENT_H
#ifdef SYNC_TESTSUITE
/*
* To compile the testsuite, run:
*
* cd indra/llcommon
* g++ -O3 -DCWDEBUG -DSYNC_TESTSUITE -I. -I../cwdebug aisyncclient.cpp -lcwd
*/
#include <stdint.h>
#include <cassert>
typedef uint32_t U32;
typedef int32_t S32;
typedef uint64_t U64;
typedef float F32;
typedef double F64;
#define LL_COMMON_API
#define SHOW_ASSERT
#define ASSERT_ONLY_COMMA(...) , __VA_ARGS__
#define llassert assert
struct LLFrameTimer
{
double mStartTime;
double mExpiry;
static double getCurrentTime(void);
static U32 sFrameCount;
static U32 getFrameCount() { return sFrameCount; }
F64 getStartTime() const { return mStartTime; }
void reset(double expiration) { mStartTime = getCurrentTime(); mExpiry = mStartTime + expiration; }
bool hasExpired(void) const { return getCurrentTime() > mExpiry; }
};
template<typename T>
struct LLSingleton
{
static T sInstance;
static T& instance(void) { return sInstance; }
};
template<typename T>
T LLSingleton<T>::sInstance;
#else // !SYNC_TESTSUITE
#include "llsingleton.h"
#include "llframetimer.h"
#endif
#include <list>
#include <boost/intrusive_ptr.hpp>
//---------------------------------------------------------------------------------------------------------------------
// Keys with a different syncgroup are never equal (so they are never synchronized).
enum syncgroups
{
#ifdef SYNC_TESTSUITE
syncgroup_test1,
syncgroup_test2,
#else
syncgroup_motions, // Syncgroup used for animations.
#endif
syncgroup_size
};
// Each key type must return a unique identifier that exists of its syncgroup (the least significant 8 bit) plus a few bit to make it unique (bit 9 and higher).
enum synckeytype_t
{
#ifdef SYNC_TESTSUITE
synckeytype_test1a = 0x000 + syncgroup_test1,
synckeytype_test1b = 0x100 + syncgroup_test1,
synckeytype_test2a = 0x000 + syncgroup_test2,
synckeytype_test2b = 0x100 + syncgroup_test2,
#else
synckeytype_motion = syncgroup_motions // There is currently only one key type in the syncgroup_motions group: AISyncKeyMotion.
#endif
};
typedef U32 synceventset_t; // A mask where each bit represents a ready state.
static F32 const sSyncKeyExpirationTime = 0.25; // In seconds.
class LL_COMMON_API AISyncKey
{
private:
LLFrameTimer mFrameTimer; // This timer is started at the moment the sync key is created.
U32 mStartFrameCount; // The frame count at which the timer was started.
public:
// Constructor.
AISyncKey(AISyncKey const* from_key) : mStartFrameCount(from_key ? from_key->mStartFrameCount : LLFrameTimer::getFrameCount())
{
if (from_key)
{
mFrameTimer.copy(from_key->mFrameTimer);
}
else
{
mFrameTimer.reset(sSyncKeyExpirationTime);
}
}
// Destructor.
virtual ~AISyncKey() { }
// Return true if this key expired.
bool expired(void) const
{
// The key has expired when sSyncKeyExpirationTime seconds have elapsed AND at least two frames have passed.
return mFrameTimer.getFrameCount() > mStartFrameCount + 1 && mFrameTimer.hasExpired();
}
// Returns true if this object and key would not compare equal based on time because this object is too old.
bool is_older_than(AISyncKey const& key) const
{
return key.mStartFrameCount > mStartFrameCount + 1 && key.mFrameTimer.getStartTime() > mFrameTimer.getStartTime() + sSyncKeyExpirationTime;
}
// Return the creation time of this key (in number of seconds since application start).
F64 getCreationTime(void) const { return mFrameTimer.getStartTime(); }
// Returns true if the two keys match, meaning that they should be synchronized.
friend bool operator==(AISyncKey const& key1, AISyncKey const& key2);
// Returns an ID that uniquely identifies the derived type.
// Currently the only derived type is AISyncKeyMotion with ID synckeytype_motion.
virtual synckeytype_t getkeytype(void) const = 0;
// Returns true if the data in the derived objects match, meaning that they should be synchronized.
virtual bool equals(AISyncKey const& key) const = 0;
};
// Forward declaration.
class AISyncClient;
class AISyncServer;
LL_COMMON_API extern void intrusive_ptr_add_ref(AISyncServer* server);
LL_COMMON_API extern void intrusive_ptr_release(AISyncServer* server);
struct LL_COMMON_API AISyncClientData
{
AISyncClient* mClientPtr;
synceventset_t mReadyEvents;
AISyncClientData(AISyncClient* client) : mClientPtr(client), mReadyEvents(0) { }
};
class LL_COMMON_API AISyncServer
{
public:
typedef std::list<AISyncClientData> client_list_t;
private:
int mRefCount; // Number of boost::intrusive_ptr objects pointing to this object.
AISyncKey* mKey; // The key of the first client that was added.
client_list_t mClients; // A list with pointers to all registered clients.
bool mSynchronized; // Set when a server gets more than one client, and not reset anymore after that.
synceventset_t mReadyEvents; // 0xFFFFFFFF bitwise-AND-ed with all clients.
synceventset_t mPendingEvents; // The bitwise-OR of all clients.
public:
AISyncServer(AISyncKey* key) : mRefCount(0), mKey(key), mSynchronized(false), mReadyEvents((synceventset_t)-1), mPendingEvents(0) { }
~AISyncServer() { delete mKey; }
// Add a new client to this server.
void add(AISyncClient* client);
// Remove a client from this server.
void remove(AISyncClient* client);
// Return the key associated to this server (which is the key produced by the first client of the largest synckeytype_t that was added).
AISyncKey const& key(void) const { return *mKey; }
// Replace they key with another key (of larger synckeytype_t).
void swapkey(AISyncKey*& key_ptr) { AISyncKey* tmp = key_ptr; key_ptr = mKey; mKey = tmp; }
// Returns true if this server never had more than one client.
bool never_synced(void) const { return !mSynchronized; }
// Set readiness of all events at once.
void ready(synceventset_t events, synceventset_t yesno, AISyncClient* client);
// Unregister the (only) client because it's own its own and will never need synchronization.
void unregister_last_client(void);
// Return the events that all clients for.
synceventset_t events_with_all_clients_ready(void) const { return mReadyEvents; }
// Return events that at least one client is ready for.
synceventset_t events_with_at_least_one_client_ready(void) const { return mPendingEvents; }
// Return a list of all registered clients.
client_list_t const& getClients(void) const { return mClients; }
private:
// Call event1_ready() or event1_not_ready() on all clients if the least significant bit of mReadyEvents changed.
void trigger(synceventset_t old_ready_events);
#ifdef SYNC_TESTSUITE
void sanity_check(void) const;
#endif
private:
friend LL_COMMON_API void intrusive_ptr_add_ref(AISyncServer* server);
friend LL_COMMON_API void intrusive_ptr_release(AISyncServer* server);
};
class LL_COMMON_API AISyncServerMap : public LLSingleton<AISyncServerMap>
{
public:
typedef boost::intrusive_ptr<AISyncServer> server_ptr_t; // The type of a (stored) pointer to the server objects.
typedef std::list<server_ptr_t> server_list_t; // The type of the list with pointers to the server objects.
private:
server_list_t mServers; // A list with pointers to all server objects.
public:
// Find or create a server object that the client belongs to and store the client in it.
// If a new server is created, it is stored in mServers.
void register_client(AISyncClient* client, AISyncKey* new_key);
private:
friend LL_COMMON_API void intrusive_ptr_release(AISyncServer* server);
// Remove a server from the map, only called by intrusive_ptr_release when there is one pointer left;
// therefore, the server should not have any clients.
void remove_server(AISyncServer* server);
};
class LL_COMMON_API AISyncClient
{
private:
friend class AISyncServer;
boost::intrusive_ptr<AISyncServer> mServer; // The server this client was registered with, or NULL when unregistered.
public:
#ifdef SHOW_ASSERT
synceventset_t mReadyEvents;
AISyncClient(void) : mReadyEvents(0) { }
#endif
virtual ~AISyncClient() { llassert(!mServer); /* If this fails then you need to add unregister_client() to the top of the destructor of the derived class that implements deregistered(). */ }
virtual AISyncKey* createSyncKey(AISyncKey const* from_key = NULL) const = 0;
virtual void event1_ready(void) = 0;
virtual void event1_not_ready(void) = 0;
// Only client. Client was forcefully deregistered from expired server because it was the only client.
virtual void deregistered(void)
{
#ifdef SHOW_ASSERT
mReadyEvents = 0;
#endif
}
AISyncServer* server(void) const { return mServer.get(); }
// Add this client to a server with matching sync key. Optionally the server is first created.
void register_client(void) { AISyncServerMap::instance().register_client(this, createSyncKey()); }
// Remove this client from its server, if any.
void unregister_client(void) { if (mServer) mServer->remove(this); }
// Call 'ready' when you are ready (or not) to get a call to start().
// Returns true if that call was made (immediately), otherwise it may happen later.
// Set readiness of all events at once.
void ready(synceventset_t events, synceventset_t yesno)
{
if (!mServer)
{
register_client();
}
mServer->ready(events, yesno, this);
}
};
#endif

View File

@@ -0,0 +1,25 @@
/**
* @file fix_macros.h
* @author Nat Goodspeed
* @date 2012-11-16
* @brief The Mac system headers seem to #define macros with obnoxiously
* generic names, preventing any library from using those names. We've
* had to fix these in so many places that it's worth making a header
* file to handle it.
*
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
* Copyright (c) 2012, Linden Research, Inc.
* $/LicenseInfo$
*/
// DON'T use an #include guard: every time we encounter this header, #undef
// these macros all over again.
// who injects MACROS with such generic names?! Grr.
#ifdef equivalent
#undef equivalent
#endif
#ifdef check
#undef check
#endif

View File

@@ -47,6 +47,10 @@ public:
// Create an LLFrameTimer and start it. After creation it is running and in the state expired (hasExpired will return true).
LLFrameTimer(void) : mExpiry(0), mRunning(true), mPaused(false) { if (!sGlobalMutex) global_initialization(); setAge(0.0); }
//<singu>
void copy(LLFrameTimer const& timer) { mStartTime = timer.mStartTime; mExpiry = timer.mExpiry; mRunning = timer.mRunning; mPaused = timer.mPaused; }
//</singu>
// Atomic reads of static variables.
// Return the number of seconds since the start of the application.
@@ -142,6 +146,9 @@ public:
bool hasExpired() const { return getElapsedSeconds() >= mExpiry; }
F32 getElapsedTimeF32() const { llassert(mRunning); return mPaused ? (F32)mStartTime : (F32)(getElapsedSeconds() - mStartTime); }
bool getStarted() const { return mRunning; }
//<singu>
F64 getStartTime() const { llassert(!mPaused); return mStartTime; }
//</singu>
// return the seconds since epoch when this timer will expire.
F64 expiresAt() const;

View File

@@ -1,119 +0,0 @@
/**
* @file llindraconfigfile.cpp
*
*
* This class is an LLLiveFile that has config info for indra
* Currently only whether it's blacklisted
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llindraconfigfile.h"
#include "llfile.h"
#include "llsd.h"
#include "llsdserialize.h"
#include "llframetimer.h"
static std::string sConfigDir = "";
static const char indraConfigFileName[] = "indra.xml";
LLIndraConfigFile::LLIndraConfigFile()
: LLLiveFile(filename()),
mConfig(LLSD())
{
}
//static
void LLIndraConfigFile::initClass(const std::string& config_dir)
{
sConfigDir = config_dir;
llinfos << "LLIndraConfigFile::initClass config dir "
<< config_dir << "/" << indraConfigFileName << llendl;
}
LLSD LLIndraConfigFile::getConfig(const std::string& config_name)
{
if (sConfigDir.empty())
{
llerrs << "LLIndraConfigFile::initClass() not called" << llendl;
}
LLFrameTimer::updateFrameTime();
static LLIndraConfigFile the_file;
the_file.checkAndReload();
return the_file.mConfig[config_name];
}
std::string LLIndraConfigFile::filename()
{
std::ostringstream ostr;
ostr << sConfigDir
<< "/" << indraConfigFileName;
return ostr.str();
}
/* virtual */
bool LLIndraConfigFile::loadFile()
{
llinfos << "LLIndraConfigFile::loadFile: reading from "
<< filename() << llendl;
LLSD config;
{
llifstream file(filename());
if (file.is_open())
{
LLSDSerialize::fromXML(config, file);
}
if (config.isUndefined())
{
llinfos << "LLIndraConfigFile::loadFile: file missing, ill-formed,"
" or simply undefined; not changing the blacklist" << llendl;
return false;
}
}
if (config.isMap())
{
mConfig = config;
return true;
}
else
{
llwarns << "LLIndraConfigFile: " << indraConfigFileName << " expects a map; wrong format" << llendl;
return false;
}
}

View File

@@ -1,61 +0,0 @@
/**
* @file llindraconfigfile.h
* @brief manages configuration file for indra.xml
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLINDRACONFIGFILE_H
#define LL_LLINDRACONFIGFILE_H
#include "linden_common.h"
#include <string>
#include "lllivefile.h"
#include "llsd.h"
// To use, call LLIndraConfigFile::initClass(config_dir);
// Then whenever getConfig is called, it will check and reload automatically
class LLIndraConfigFile : public LLLiveFile
{
public:
LLIndraConfigFile();
static void initClass(const std::string& config_dir);
static LLSD getConfig(const std::string& config_name);
private:
static std::string filename();
protected:
/* virtual */ bool loadFile();
LLSD mConfig;
};
#endif //LL_LLINDRACONFIGFILE_H

View File

@@ -239,14 +239,14 @@ inline typename T::mapped_type get_ptr_in_map(const T& inmap, typename T::key_ty
//
//Singu note: This has been generalized to support a broader range of sequence containers
template <typename T>
inline typename T::iterator vector_replace_with_last(T& invec, typename T::iterator& iter)
inline typename T::iterator vector_replace_with_last(T& invec, typename T::iterator iter)
{
typename T::iterator last = invec.end(); --last;
typename T::iterator last = invec.end();
if (iter == invec.end())
{
return iter;
}
else if (iter == last)
else if (iter == --last)
{
invec.pop_back();
return invec.end();

View File

@@ -1288,7 +1288,7 @@ public:
LL_CONT << "slowest framerate for last " << int(prevSize * MEM_INFO_THROTTLE)
<< " seconds ";
}
LL_CONT << std::fixed << std::setprecision(1) << framerate << '\n'
LL_CONT << std::fixed << std::setprecision(1) << framerate << std::setprecision(6) << '\n'
<< LLMemoryInfo() << LL_ENDL;
return false;

View File

@@ -35,7 +35,7 @@
const S32 LL_VERSION_MAJOR = 1;
const S32 LL_VERSION_MINOR = 8;
const S32 LL_VERSION_PATCH = 5;
const S32 LL_VERSION_PATCH = 6;
const S32 LL_VERSION_BUILD = ${vBUILD};
const char * const LL_CHANNEL = "${VIEWER_CHANNEL}";

View File

@@ -118,16 +118,6 @@ enum EAddPosition
ADD_BOTTOM
};
enum LLGroupChange
{
GC_PROPERTIES,
GC_MEMBER_DATA,
GC_ROLE_DATA,
GC_ROLE_MEMBER_DATA,
GC_TITLES,
GC_ALL
};
//----------------------------------------------------------------------------
// DEPRECATED - create new, more specific files for shared enums/constants
//----------------------------------------------------------------------------

View File

@@ -178,7 +178,7 @@ BOOL LLInventoryObject::importLegacyStream(std::istream& input_stream)
while(input_stream.good())
{
input_stream.getline(buffer, MAX_STRING);
sscanf(buffer, " %254s %254s", keyword, valuestr); /* Flawfinder: ignore */
if (sscanf(buffer, " %254s %254s", keyword, valuestr) < 1) continue;
if(0 == strcmp("{",keyword))
{
continue;
@@ -268,7 +268,7 @@ void LLInventoryObject::updateServer(BOOL) const
llwarns << "LLInventoryObject::updateServer() called. Doesn't do anything." << llendl;
}
inline
// inline
void LLInventoryObject::correctInventoryName(std::string& name)
{
LLStringUtil::replaceNonstandardASCII(name, ' ');
@@ -610,7 +610,7 @@ BOOL LLInventoryItem::importFile(LLFILE* fp)
buffer[0] = '\0';
}
sscanf(buffer, " %254s %254s", keyword, valuestr); /* Flawfinder: ignore */
if (sscanf(buffer, " %254s %254s", keyword, valuestr) < 1) continue;
if(0 == strcmp("{",keyword))
{
continue;
@@ -813,10 +813,10 @@ BOOL LLInventoryItem::importLegacyStream(std::istream& input_stream)
while(success && input_stream.good())
{
input_stream.getline(buffer, MAX_STRING);
sscanf( /* Flawfinder: ignore */
if (sscanf(
buffer,
" %254s %254s",
keyword, valuestr);
keyword, valuestr) < 1) continue;
if(0 == strcmp("{",keyword))
{
continue;
@@ -1169,7 +1169,7 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd)
// Because WT_UNKNOWN now has locally a special meaning, make sure we don't receive it from the server.
if (wt == WT_UNKNOWN)
{
llwarns << "Received inventory item with wearable type WT_UNKNOWN from server! You should upgrade your viewer." << llendl;
lldebugs << "Received inventory item with wearable type WT_UNKNOWN from server!" << llendl;
// Change this new wearable type to WT_COUNT, as if when we had not inserted WT_UNKNOWN locally.
mFlags += 1;
wt = WT_COUNT;
@@ -1489,10 +1489,10 @@ BOOL LLInventoryCategory::importFile(LLFILE* fp)
buffer[0] = '\0';
}
sscanf( /* Flawfinder: ignore */
if (sscanf(
buffer,
" %254s %254s",
keyword, valuestr);
keyword, valuestr) < 1) continue;
if(0 == strcmp("{",keyword))
{
continue;
@@ -1568,10 +1568,10 @@ BOOL LLInventoryCategory::importLegacyStream(std::istream& input_stream)
while(input_stream.good())
{
input_stream.getline(buffer, MAX_STRING);
sscanf( /* Flawfinder: ignore */
if (sscanf(
buffer,
" %254s %254s",
keyword, valuestr);
keyword, valuestr) < 1) continue;
if(0 == strcmp("{",keyword))
{
continue;

View File

@@ -84,9 +84,13 @@ public:
void setParent(const LLUUID& new_parent);
void setType(LLAssetType::EType type);
private:
// [RLVa:KB] - Checked: 2014-01-07 (RLVa-1.4.10)
// in place correction for inventory name string
void correctInventoryName(std::string& name);
static void correctInventoryName(std::string& name);
// [/RLVa:KB]
private:
// // in place correction for inventory name string
// void correctInventoryName(std::string& name);
//--------------------------------------------------------------------
// File Support

View File

@@ -2,31 +2,25 @@
* @file camera.h
* @brief Legacy wrapper header.
*
* $LicenseInfo:firstyear=2000&license=viewergpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* 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.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/

View File

@@ -2,31 +2,25 @@
* @file coordframe.h
* @brief Legacy wrapper header.
*
* $LicenseInfo:firstyear=2000&license=viewergpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* 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.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/

View File

@@ -2,36 +2,28 @@
* @file llbbox.cpp
* @brief General purpose bounding box class (Not axis aligned)
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2010, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlife.com/developers/opensource/gplv2
* 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.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlife.com/developers/opensource/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*
*/
#include "linden_common.h"
// self include

View File

@@ -2,36 +2,28 @@
* @file llbbox.h
* @brief General purpose bounding box class
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2010, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlife.com/developers/opensource/gplv2
* 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.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlife.com/developers/opensource/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*
*/
#ifndef LL_BBOX_H
#define LL_BBOX_H

View File

@@ -2,31 +2,25 @@
* @file llbboxlocal.cpp
* @brief General purpose bounding box class (Not axis aligned).
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* 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.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/

View File

@@ -2,31 +2,25 @@
* @file llbboxlocal.h
* @brief General purpose bounding box class.
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* 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.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/

View File

@@ -2,31 +2,25 @@
* @file llcamera.cpp
* @brief Implementation of the LLCamera class.
*
* $LicenseInfo:firstyear=2000&license=viewergpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* 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.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -189,8 +183,30 @@ static const LLVector4a sFrustumScaler[] =
LLVector4a( 1, 1, 1) // 8 entries
};
S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius)
bool LLCamera::isChanged()
{
bool changed = false;
for (U32 i = 0; i < mPlaneCount; i++)
{
U8 mask = mPlaneMask[i];
if (mask != 0xff && !changed)
{
changed = !mAgentPlanes[i].equal(mLastAgentPlanes[i]);
}
mLastAgentPlanes[i].set(mAgentPlanes[i]);
}
return changed;
}
S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius, const LLPlane* planes)
{
if(!planes)
{
//use agent space
planes = mAgentPlanes;
}
U8 mask = 0;
bool result = false;
LLVector4a rscale, maxp, minp;
@@ -201,7 +217,7 @@ S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius)
mask = mPlaneMask[i];
if (mask < PLANE_MASK_NUM)
{
const LLPlane& p(mAgentPlanes[i]);
const LLPlane& p(planes[i]);
p.getAt<3>(d);
rscale.setMul(radius, sFrustumScaler[mask]);
minp.setSub(center, rscale);
@@ -222,9 +238,21 @@ S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius)
return result?1:2;
}
S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius)
//exactly same as the function AABBInFrustum(...)
//except uses mRegionPlanes instead of mAgentPlanes.
S32 LLCamera::AABBInRegionFrustum(const LLVector4a& center, const LLVector4a& radius)
{
return AABBInFrustum(center, radius, mRegionPlanes);
}
S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes)
{
if(!planes)
{
//use agent space
planes = mAgentPlanes;
}
U8 mask = 0;
bool result = false;
LLVector4a rscale, maxp, minp;
@@ -235,7 +263,7 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a&
mask = mPlaneMask[i];
if ((i != 5) && (mask < PLANE_MASK_NUM))
{
const LLPlane& p(mAgentPlanes[i]);
const LLPlane& p(planes[i]);
p.getAt<3>(d);
rscale.setMul(radius, sFrustumScaler[mask]);
minp.setSub(center, rscale);
@@ -256,6 +284,13 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a&
return result?1:2;
}
//exactly same as the function AABBInFrustumNoFarClip(...)
//except uses mRegionPlanes instead of mAgentPlanes.
S32 LLCamera::AABBInRegionFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius)
{
return AABBInFrustumNoFarClip(center, radius, mRegionPlanes);
}
int LLCamera::sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius)
{
LLVector3 dist = sphere_center-mFrustCenter;
@@ -592,6 +627,47 @@ void LLCamera::calcAgentFrustumPlanes(LLVector3* frust)
}
}
//calculate regional planes from mAgentPlanes.
//vector "shift" is the vector of the region origin in the agent space.
void LLCamera::calcRegionFrustumPlanes(const LLVector3& shift, F32 far_clip_distance)
{
F32 far_w;
{
LLVector3 p = getOrigin();
LLVector3 n(mAgentPlanes[5][0], mAgentPlanes[5][1], mAgentPlanes[5][2]);
F32 dd = n * p;
if(dd + mAgentPlanes[5][3] < 0) //signed distance
{
far_w = -far_clip_distance - dd;
}
else
{
far_w = far_clip_distance - dd;
}
far_w += n * shift;
}
F32 d;
LLVector3 n;
for(S32 i = 0 ; i < 7; i++)
{
if (mPlaneMask[i] != 0xff)
{
n.setVec(mAgentPlanes[i][0], mAgentPlanes[i][1], mAgentPlanes[i][2]);
if(i != 5)
{
d = mAgentPlanes[i][3] + n * shift;
}
else
{
d = far_w;
}
mRegionPlanes[i].setVec(n, d);
}
}
}
void LLCamera::calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom)
{
LLVector3 a, b, c;

View File

@@ -2,31 +2,25 @@
* @file llcamera.h
* @brief Header file for the LLCamera class.
*
* $LicenseInfo:firstyear=2000&license=viewergpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* 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.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -55,7 +49,7 @@ const F32 MIN_FAR_PLANE = 0.2f;
// Min/Max FOV values for square views. Call getMin/MaxView to get extremes based on current aspect ratio.
static const F32 MIN_FIELD_OF_VIEW = 5.0f * DEG_TO_RAD;
static const F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD;
static const F32 MAX_FIELD_OF_VIEW = 320.f * DEG_TO_RAD;
// An LLCamera is an LLCoorFrame with a view frustum.
// This means that it has several methods for moving it around
@@ -128,6 +122,8 @@ public:
private:
LL_ALIGN_16(LLPlane mAgentPlanes[AGENT_PLANE_USER_CLIP_NUM]); //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
LL_ALIGN_16(LLPlane mRegionPlanes[AGENT_PLANE_USER_CLIP_NUM]); //frustum planes in a local region space, derived from mAgentPlanes
LL_ALIGN_16(LLPlane mLastAgentPlanes[AGENT_PLANE_USER_CLIP_NUM]);
U8 mPlaneMask[PLANE_MASK_NUM]; // 8 for alignment
F32 mView; // angle between top and bottom frustum planes in radians.
@@ -156,6 +152,7 @@ public:
LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane);
virtual ~LLCamera();
bool isChanged(); //check if mAgentPlanes changed since last frame.
void setUserClipPlane(const LLPlane& plane);
void disableUserClipPlane();
@@ -197,6 +194,7 @@ public:
// Return number of bytes copied.
size_t readFrustumFromBuffer(const char *buffer);
void calcAgentFrustumPlanes(LLVector3* frust);
void calcRegionFrustumPlanes(const LLVector3& shift, F32 far_clip_distance); //calculate regional planes from mAgentPlanes.
void ignoreAgentFrustumPlane(S32 idx);
// Returns 1 if partly in, 2 if fully in.
@@ -205,8 +203,10 @@ public:
S32 sphereInFrustum(const LLVector3 &center, const F32 radius) const;
S32 pointInFrustum(const LLVector3 &point) const { return sphereInFrustum(point, 0.0f); }
S32 sphereInFrustumFull(const LLVector3 &center, const F32 radius) const { return sphereInFrustum(center, radius); }
S32 AABBInFrustum(const LLVector4a& center, const LLVector4a& radius);
S32 AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius);
S32 AABBInFrustum(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes = NULL);
S32 AABBInRegionFrustum(const LLVector4a& center, const LLVector4a& radius);
S32 AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius, const LLPlane* planes = NULL);
S32 AABBInRegionFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius);
//does a quick 'n dirty sphere-sphere check
S32 sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius);

View File

@@ -2,31 +2,25 @@
* @file llcoordframe.cpp
* @brief LLCoordFrame class implementation.
*
* $LicenseInfo:firstyear=2000&license=viewergpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* 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.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/

View File

@@ -2,31 +2,25 @@
* @file llcoordframe.h
* @brief LLCoordFrame class header file.
*
* $LicenseInfo:firstyear=2000&license=viewergpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* Copyright (C) 2010, Linden Research, Inc.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* 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$
*/

View File

@@ -1,31 +1,25 @@
/**
* @file llinterp.h
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* Copyright (C) 2010, Linden Research, Inc.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/

View File

@@ -3,31 +3,25 @@
* @author Andrew Meadows
* @brief Simple line class that can compute nearest approach between two lines
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* 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.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/

View File

@@ -4,31 +4,25 @@
* @author Andrew Meadows
* @brief Simple line for computing nearest approach between two infinite lines
*
* $LicenseInfo:firstyear=2006&license=viewergpl$
*
* Copyright (c) 2006-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* Copyright (C) 2010, Linden Research, Inc.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* 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$
*/

View File

@@ -30,6 +30,7 @@
#include <cmath>
#include <cstdlib>
#include <vector>
#include <limits>
#include "lldefs.h"
//#include "llstl.h" // *TODO: Remove when LLString is gone
//#include "llstring.h" // *TODO: Remove when LLString is gone
@@ -72,15 +73,21 @@ const F32 F_E = 2.71828182845904523536f;
const F32 F_SQRT2 = 1.4142135623730950488016887242097f;
const F32 F_SQRT3 = 1.73205080756888288657986402541f;
const F32 OO_SQRT2 = 0.7071067811865475244008443621049f;
const F32 OO_SQRT3 = 0.577350269189625764509f;
const F32 DEG_TO_RAD = 0.017453292519943295769236907684886f;
const F32 RAD_TO_DEG = 57.295779513082320876798154814105f;
const F32 F_APPROXIMATELY_ZERO = 0.00001f;
const F32 F_LN10 = 2.3025850929940456840179914546844f;
const F32 OO_LN10 = 0.43429448190325182765112891891661f;
const F32 F_LN2 = 0.69314718056f;
const F32 OO_LN2 = 1.4426950408889634073599246810019f;
const F32 F_ALMOST_ZERO = 0.0001f;
const F32 F_ALMOST_ONE = 1.0f - F_ALMOST_ZERO;
const F32 GIMBAL_THRESHOLD = 0.000436f; // sets the gimballock threshold 0.025 away from +/-90 degrees
// formula: GIMBAL_THRESHOLD = sin(DEG_TO_RAD * gimbal_threshold_angle);
// BUG: Eliminate in favor of F_APPROXIMATELY_ZERO above?
const F32 FP_MAG_THRESHOLD = 0.0000001f;
@@ -111,6 +118,12 @@ inline bool is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f <
// WARNING: Infinity is comparable with F32_MAX and negative
// infinity is comparable with F32_MIN
// handles negative and positive zeros
inline bool is_zero(F32 x)
{
return (*(U32*)(&x) & 0x7fffffff) == 0;
}
inline bool is_approx_equal(F32 x, F32 y)
{
const S32 COMPARE_MANTISSA_UP_TO_BIT = 0x02;

View File

@@ -24,7 +24,6 @@
* $/LicenseInfo$
*/
#include "sys.h"
#include "llmath.h"
static LL_ALIGN_16(const F32 M_IDENT_3A[12]) =

View File

@@ -40,6 +40,7 @@
// LLMatrix3a is the base class for LLRotation, which should be used instead any time you're dealing with a
// rotation matrix.
LL_ALIGN_PREFIX(16)
class LLMatrix3a
{
public:
@@ -113,8 +114,9 @@ protected:
LL_ALIGN_16(LLVector4a mColumns[3]);
};
} LL_ALIGN_POSTFIX(16);
LL_ALIGN_PREFIX(16)
class LLRotation : public LLMatrix3a
{
public:
@@ -123,6 +125,6 @@ public:
// Returns true if this rotation is orthonormal with det ~= 1
inline bool isOkRotation() const;
};
} LL_ALIGN_POSTFIX(16);
#endif

View File

@@ -31,10 +31,72 @@
#include "m4math.h"
#include "m3math.h"
LL_ALIGN_PREFIX(16)
class LLMatrix4a
{
public:
private:
LL_ALIGN_16(LLVector4a mMatrix[4]);
public:
enum
{
ROW_FWD = 0,
ROW_LEFT,
ROW_UP,
ROW_TRANS
};
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}
LLMatrix4a()
{}
LLMatrix4a(const LLQuad& q1,const LLQuad& q2,const LLQuad& q3,const LLQuad& q4)
{
mMatrix[0] = q1;
mMatrix[1] = q2;
mMatrix[2] = q3;
mMatrix[3] = q4;
}
LLMatrix4a(const LLQuaternion2& quat)
{
const LLVector4a& xyzw = quat.getVector4a();
LLVector4a nyxwz = _mm_shuffle_ps(xyzw, xyzw, _MM_SHUFFLE(2,3,0,1));
nyxwz.negate();
const LLVector4a xnyynx = _mm_unpacklo_ps(xyzw,nyxwz);
const LLVector4a znwwnz = _mm_unpackhi_ps(xyzw,nyxwz);
LLMatrix4a mata;
mata.setRow<0>(_mm_shuffle_ps(xyzw, xnyynx, _MM_SHUFFLE(0,1,2,3)));
mata.setRow<1>(_mm_shuffle_ps(znwwnz, xyzw, _MM_SHUFFLE(1,0,2,3)));
mata.setRow<2>(_mm_shuffle_ps(xnyynx, xyzw, _MM_SHUFFLE(2,3,3,2)));
mata.setRow<3>(_mm_shuffle_ps(xnyynx, znwwnz, _MM_SHUFFLE(2,3,1,3)));
LLMatrix4a matb;
matb.setRow<0>(_mm_shuffle_ps(xyzw, xnyynx, _MM_SHUFFLE(3,1,2,3)));
matb.setRow<1>(_mm_shuffle_ps(znwwnz, xnyynx, _MM_SHUFFLE(1,0,2,3)));
matb.setRow<2>(_mm_shuffle_ps(xnyynx, znwwnz, _MM_SHUFFLE(3,2,3,2)));
matb.setRow<3>(xyzw);
setMul(matb,mata);
}
inline F32* getF32ptr()
{
return mMatrix[0].getF32ptr();
}
inline const F32* getF32ptr() const
{
return mMatrix[0].getF32ptr();
}
inline void clear()
{
@@ -44,13 +106,21 @@ public:
mMatrix[3].clear();
}
inline void setIdentity()
{
static __m128 ones = _mm_set_ps(1.f,0.f,0.f,1.f);
mMatrix[0] = _mm_movelh_ps(ones,_mm_setzero_ps());
mMatrix[1] = _mm_movehl_ps(_mm_setzero_ps(),ones);
mMatrix[2] = _mm_movelh_ps(_mm_setzero_ps(),ones);
mMatrix[3] = _mm_movehl_ps(ones,_mm_setzero_ps());
}
inline void loadu(const LLMatrix4& src)
{
mMatrix[0] = _mm_loadu_ps(src.mMatrix[0]);
mMatrix[1] = _mm_loadu_ps(src.mMatrix[1]);
mMatrix[2] = _mm_loadu_ps(src.mMatrix[2]);
mMatrix[3] = _mm_loadu_ps(src.mMatrix[3]);
mMatrix[0].loadua(src.mMatrix[0]);
mMatrix[1].loadua(src.mMatrix[1]);
mMatrix[2].loadua(src.mMatrix[2]);
mMatrix[3].loadua(src.mMatrix[3]);
}
inline void loadu(const LLMatrix3& src)
@@ -61,6 +131,14 @@ public:
mMatrix[3].set(0,0,0,1.f);
}
inline void loadu(const F32* src)
{
mMatrix[0].loadua(src+0);
mMatrix[1].loadua(src+4);
mMatrix[2].loadua(src+8);
mMatrix[3].loadua(src+12);
}
inline void add(const LLMatrix4a& rhs)
{
mMatrix[0].add(rhs.mMatrix[0]);
@@ -69,6 +147,75 @@ public:
mMatrix[3].add(rhs.mMatrix[3]);
}
inline void mul(const LLMatrix4a& rhs)
{
//Not using rotate4 to avoid extra copy of *this.
LLVector4a x0,y0,z0,w0;
LLVector4a x1,y1,z1,w1;
LLVector4a x2,y2,z2,w2;
LLVector4a x3,y3,z3,w3;
//16 shuffles
x0.splat<0>(rhs.mMatrix[0]);
x1.splat<0>(rhs.mMatrix[1]);
x2.splat<0>(rhs.mMatrix[2]);
x3.splat<0>(rhs.mMatrix[3]);
y0.splat<1>(rhs.mMatrix[0]);
y1.splat<1>(rhs.mMatrix[1]);
y2.splat<1>(rhs.mMatrix[2]);
y3.splat<1>(rhs.mMatrix[3]);
z0.splat<2>(rhs.mMatrix[0]);
z1.splat<2>(rhs.mMatrix[1]);
z2.splat<2>(rhs.mMatrix[2]);
z3.splat<2>(rhs.mMatrix[3]);
w0.splat<3>(rhs.mMatrix[0]);
w1.splat<3>(rhs.mMatrix[1]);
w2.splat<3>(rhs.mMatrix[2]);
w3.splat<3>(rhs.mMatrix[3]);
//16 muls
x0.mul(mMatrix[0]);
x1.mul(mMatrix[0]);
x2.mul(mMatrix[0]);
x3.mul(mMatrix[0]);
y0.mul(mMatrix[1]);
y1.mul(mMatrix[1]);
y2.mul(mMatrix[1]);
y3.mul(mMatrix[1]);
z0.mul(mMatrix[2]);
z1.mul(mMatrix[2]);
z2.mul(mMatrix[2]);
z3.mul(mMatrix[2]);
w0.mul(mMatrix[3]);
w1.mul(mMatrix[3]);
w2.mul(mMatrix[3]);
w3.mul(mMatrix[3]);
//12 adds
x0.add(y0);
z0.add(w0);
x1.add(y1);
z1.add(w1);
x2.add(y2);
z2.add(w2);
x3.add(y3);
z3.add(w3);
mMatrix[0].setAdd(x0,z0);
mMatrix[1].setAdd(x1,z1);
mMatrix[2].setAdd(x2,z2);
mMatrix[3].setAdd(x3,z3);
}
inline void setRows(const LLVector4a& r0, const LLVector4a& r1, const LLVector4a& r2)
{
mMatrix[0] = r0;
@@ -76,6 +223,44 @@ public:
mMatrix[2] = r2;
}
template<int N>
inline void setRow(const LLVector4a& row)
{
mMatrix[N] = row;
}
template<int N>
inline const LLVector4a& getRow() const
{
return mMatrix[N];
}
template<int N>
inline LLVector4a& getRow()
{
return mMatrix[N];
}
template<int N>
inline void setColumn(const LLVector4a& col)
{
mMatrix[0].copyComponent<N>(col.getScalarAt<0>());
mMatrix[1].copyComponent<N>(col.getScalarAt<1>());
mMatrix[2].copyComponent<N>(col.getScalarAt<2>());
mMatrix[3].copyComponent<N>(col.getScalarAt<3>());
}
template<int N>
inline LLVector4a getColumn()
{
LLVector4a v;
v.copyComponent<0>(mMatrix[0].getScalarAt<N>());
v.copyComponent<1>(mMatrix[1].getScalarAt<N>());
v.copyComponent<2>(mMatrix[2].getScalarAt<N>());
v.copyComponent<3>(mMatrix[3].getScalarAt<N>());
return v;
}
inline void setMul(const LLMatrix4a& m, const F32 s)
{
mMatrix[0].setMul(m.mMatrix[0], s);
@@ -84,6 +269,14 @@ public:
mMatrix[3].setMul(m.mMatrix[3], s);
}
inline void setMul(const LLMatrix4a& m0, const LLMatrix4a& m1)
{
m0.rotate4(m1.mMatrix[0],mMatrix[0]);
m0.rotate4(m1.mMatrix[1],mMatrix[1]);
m0.rotate4(m1.mMatrix[2],mMatrix[2]);
m0.rotate4(m1.mMatrix[3],mMatrix[3]);
}
inline void setLerp(const LLMatrix4a& a, const LLMatrix4a& b, F32 w)
{
LLVector4a d0,d1,d2,d3;
@@ -107,13 +300,14 @@ public:
//Singu Note: Don't mess with this. It's intentionally different from LL's.
// Note how res isn't manipulated until the very end.
//Fast(er). Treats v[VW] as 0.f
inline void rotate(const LLVector4a& v, LLVector4a& res) const
{
LLVector4a x,y,z;
x = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0));
y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1));
z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2));
x.splat<0>(v);
y.splat<1>(v);
z.splat<2>(v);
x.mul(mMatrix[0]);
y.mul(mMatrix[1]);
@@ -123,14 +317,15 @@ public:
res.setAdd(x,z);
}
//Proper. v[VW] as v[VW]
inline void rotate4(const LLVector4a& v, LLVector4a& res) const
{
LLVector4a x,y,z,w;
x = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0));
y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1));
z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2));
w = _mm_shuffle_ps(v, v, _MM_SHUFFLE(3, 3, 3, 3));
x.splat<0>(v);
y.splat<1>(v);
z.splat<2>(v);
w.splat<3>(v);
x.mul(mMatrix[0]);
y.mul(mMatrix[1]);
@@ -142,14 +337,15 @@ public:
res.setAdd(x,z);
}
//Fast(er). Treats v[VW] as 1.f
inline void affineTransform(const LLVector4a& v, LLVector4a& res) const
{
LLVector4a x,y,z;
x = _mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0));
y = _mm_shuffle_ps(v, v, _MM_SHUFFLE(1, 1, 1, 1));
z = _mm_shuffle_ps(v, v, _MM_SHUFFLE(2, 2, 2, 2));
x.splat<0>(v);
y.splat<1>(v);
z.splat<2>(v);
x.mul(mMatrix[0]);
y.mul(mMatrix[1]);
z.mul(mMatrix[2]);
@@ -158,6 +354,348 @@ public:
z.add(mMatrix[3]);
res.setAdd(x,z);
}
};
inline void perspectiveTransform(const LLVector4a& v, LLVector4a& res) const
{
LLVector4a x,y,z,s,t,p,q;
x.splat<0>(v);
y.splat<1>(v);
z.splat<2>(v);
s.splat<3>(mMatrix[0]);
t.splat<3>(mMatrix[1]);
p.splat<3>(mMatrix[2]);
q.splat<3>(mMatrix[3]);
s.mul(x);
t.mul(y);
p.mul(z);
q.add(s);
t.add(p);
q.add(t);
x.mul(mMatrix[0]);
y.mul(mMatrix[1]);
z.mul(mMatrix[2]);
x.add(y);
z.add(mMatrix[3]);
res.setAdd(x,z);
res.div(q);
}
inline void transpose()
{
__m128 q1 = _mm_unpackhi_ps(mMatrix[0],mMatrix[1]);
__m128 q2 = _mm_unpacklo_ps(mMatrix[0],mMatrix[1]);
__m128 q3 = _mm_unpacklo_ps(mMatrix[2],mMatrix[3]);
__m128 q4 = _mm_unpackhi_ps(mMatrix[2],mMatrix[3]);
mMatrix[0] = _mm_movelh_ps(q2,q3);
mMatrix[1] = _mm_movehl_ps(q3,q2);
mMatrix[2] = _mm_movelh_ps(q1,q4);
mMatrix[3] = _mm_movehl_ps(q4,q1);
}
// Following procedure adapted from:
// http://software.intel.com/en-us/articles/optimized-matrix-library-for-use-with-the-intel-pentiumr-4-processors-sse2-instructions/
//
// License/Copyright Statement:
//
// Copyright (c) 2001 Intel Corporation.
//
// Permition is granted to use, copy, distribute and prepare derivative works
// of this library for any purpose and without fee, provided, that the above
// copyright notice and this statement appear in all copies.
// Intel makes no representations about the suitability of this library for
// any purpose, and specifically disclaims all warranties.
// See LEGAL-intel_matrixlib.TXT for all the legal information.
inline float invert()
{
LL_ALIGN_16(const unsigned int Sign_PNNP[4]) = { 0x00000000, 0x80000000, 0x80000000, 0x00000000 };
// The inverse is calculated using "Divide and Conquer" technique. The
// original matrix is divide into four 2x2 sub-matrices. Since each
// register holds four matrix element, the smaller matrices are
// represented as a registers. Hence we get a better locality of the
// calculations.
LLVector4a A = _mm_movelh_ps(mMatrix[0], mMatrix[1]), // the four sub-matrices
B = _mm_movehl_ps(mMatrix[1], mMatrix[0]),
C = _mm_movelh_ps(mMatrix[2], mMatrix[3]),
D = _mm_movehl_ps(mMatrix[3], mMatrix[2]);
LLVector4a iA, iB, iC, iD, // partial inverse of the sub-matrices
DC, AB;
LLSimdScalar dA, dB, dC, dD; // determinant of the sub-matrices
LLSimdScalar det, d, d1, d2;
LLVector4a rd;
// AB = A# * B
AB.setMul(_mm_shuffle_ps(A,A,0x0F), B);
AB.sub(_mm_mul_ps(_mm_shuffle_ps(A,A,0xA5), _mm_shuffle_ps(B,B,0x4E)));
// DC = D# * C
DC.setMul(_mm_shuffle_ps(D,D,0x0F), C);
DC.sub(_mm_mul_ps(_mm_shuffle_ps(D,D,0xA5), _mm_shuffle_ps(C,C,0x4E)));
// dA = |A|
dA = _mm_mul_ps(_mm_shuffle_ps(A, A, 0x5F),A);
dA -= _mm_movehl_ps(dA,dA);
// dB = |B|
dB = _mm_mul_ps(_mm_shuffle_ps(B, B, 0x5F),B);
dB -= _mm_movehl_ps(dB,dB);
// dC = |C|
dC = _mm_mul_ps(_mm_shuffle_ps(C, C, 0x5F),C);
dC -= _mm_movehl_ps(dC,dC);
// dD = |D|
dD = _mm_mul_ps(_mm_shuffle_ps(D, D, 0x5F),D);
dD -= _mm_movehl_ps(dD,dD);
// d = trace(AB*DC) = trace(A#*B*D#*C)
d = _mm_mul_ps(_mm_shuffle_ps(DC,DC,0xD8),AB);
// iD = C*A#*B
iD.setMul(_mm_shuffle_ps(C,C,0xA0), _mm_movelh_ps(AB,AB));
iD.add(_mm_mul_ps(_mm_shuffle_ps(C,C,0xF5), _mm_movehl_ps(AB,AB)));
// iA = B*D#*C
iA.setMul(_mm_shuffle_ps(B,B,0xA0), _mm_movelh_ps(DC,DC));
iA.add(_mm_mul_ps(_mm_shuffle_ps(B,B,0xF5), _mm_movehl_ps(DC,DC)));
// d = trace(AB*DC) = trace(A#*B*D#*C) [continue]
d = _mm_add_ps(d, _mm_movehl_ps(d, d));
d += _mm_shuffle_ps(d, d, 1);
d1 = dA*dD;
d2 = dB*dC;
// iD = D*|A| - C*A#*B
iD.setSub(_mm_mul_ps(D,_mm_shuffle_ps(dA,dA,0)), iD);
// iA = A*|D| - B*D#*C;
iA.setSub(_mm_mul_ps(A,_mm_shuffle_ps(dD,dD,0)), iA);
// det = |A|*|D| + |B|*|C| - trace(A#*B*D#*C)
det = d1+d2-d;
__m128 is_zero_mask = _mm_cmpeq_ps(det,_mm_setzero_ps());
rd = _mm_div_ss(_mm_set_ss(1.f),_mm_or_ps(_mm_andnot_ps(is_zero_mask, det), _mm_and_ps(is_zero_mask, _mm_set_ss(1.f))));
#ifdef ZERO_SINGULAR
rd = _mm_and_ps(_mm_cmpneq_ss(det,_mm_setzero_ps()), rd);
#endif
// iB = D * (A#B)# = D*B#*A
iB.setMul(D, _mm_shuffle_ps(AB,AB,0x33));
iB.sub(_mm_mul_ps(_mm_shuffle_ps(D,D,0xB1), _mm_shuffle_ps(AB,AB,0x66)));
// iC = A * (D#C)# = A*C#*D
iC.setMul(A, _mm_shuffle_ps(DC,DC,0x33));
iC.sub(_mm_mul_ps(_mm_shuffle_ps(A,A,0xB1), _mm_shuffle_ps(DC,DC,0x66)));
rd = _mm_shuffle_ps(rd,rd,0);
rd = _mm_xor_ps(rd, _mm_load_ps((const float*)Sign_PNNP));
// iB = C*|B| - D*B#*A
iB.setSub(_mm_mul_ps(C,_mm_shuffle_ps(dB,dB,0)), iB);
// iC = B*|C| - A*C#*D;
iC.setSub(_mm_mul_ps(B,_mm_shuffle_ps(dC,dC,0)), iC);
// iX = iX / det
iA.mul(rd);
iB.mul(rd);
iC.mul(rd);
iD.mul(rd);
mMatrix[0] = _mm_shuffle_ps(iA,iB,0x77);
mMatrix[1] = _mm_shuffle_ps(iA,iB,0x22);
mMatrix[2] = _mm_shuffle_ps(iC,iD,0x77);
mMatrix[3] = _mm_shuffle_ps(iC,iD,0x22);
F32 ret;
_mm_store_ss(&ret,det);
return ret;
}
//=============Affine transformation matrix only=========================
//Multiply matrix with a pure translation matrix.
inline void applyTranslation_affine(const F32& x, const F32& y, const F32& z)
{
const LLVector4a xyz0(x,y,z,0); //load
LLVector4a xxxx;
xxxx.splat<0>(xyz0);
LLVector4a yyyy;
yyyy.splat<1>(xyz0);
LLVector4a zzzz;
zzzz.splat<2>(xyz0);
LLVector4a sum1;
LLVector4a sum2;
LLVector4a sum3;
sum1.setMul(xxxx,mMatrix[0]);
sum2.setMul(yyyy,mMatrix[1]);
sum3.setMul(zzzz,mMatrix[2]);
mMatrix[3].add(sum1);
mMatrix[3].add(sum2);
mMatrix[3].add(sum3);
}
//Multiply matrix with a pure translation matrix.
inline void applyTranslation_affine(const LLVector3& trans)
{
applyTranslation_affine(trans.mV[VX],trans.mV[VY],trans.mV[VZ]);
}
//Multiply matrix with a pure scale matrix.
inline void applyScale_affine(const F32& x, const F32& y, const F32& z)
{
const LLVector4a xyz0(x,y,z,0); //load
LLVector4a xxxx;
xxxx.splat<0>(xyz0);
LLVector4a yyyy;
yyyy.splat<1>(xyz0);
LLVector4a zzzz;
zzzz.splat<2>(xyz0);
mMatrix[0].mul(xxxx);
mMatrix[1].mul(yyyy);
mMatrix[2].mul(zzzz);
}
//Multiply matrix with a pure scale matrix.
inline void applyScale_affine(const LLVector3& scale)
{
applyScale_affine(scale.mV[VX],scale.mV[VY],scale.mV[VZ]);
}
//Multiply matrix with a pure scale matrix.
inline void applyScale_affine(const F32& s)
{
const LLVector4a scale(s); //load
mMatrix[0].mul(scale);
mMatrix[1].mul(scale);
mMatrix[2].mul(scale);
}
//Direct addition to row3.
inline void translate_affine(const LLVector3& trans)
{
LLVector4a translation;
translation.load3(trans.mV);
mMatrix[3].add(translation);
}
//Direct assignment of row3.
inline void setTranslate_affine(const LLVector3& trans)
{
static const LLVector4Logical mask = _mm_load_ps((F32*)&S_V4LOGICAL_MASK_TABLE[3*4]);
LLVector4a translation;
translation.load3(trans.mV);
mMatrix[3].setSelectWithMask(mask,mMatrix[3],translation);
}
inline void mul_affine(const LLMatrix4a& rhs)
{
LLVector4a x0,y0,z0;
LLVector4a x1,y1,z1;
LLVector4a x2,y2,z2;
LLVector4a x3,y3,z3;
//12 shuffles
x0.splat<0>(rhs.mMatrix[0]);
x1.splat<0>(rhs.mMatrix[1]);
x2.splat<0>(rhs.mMatrix[2]);
x3.splat<0>(rhs.mMatrix[3]);
y0.splat<1>(rhs.mMatrix[0]);
y1.splat<1>(rhs.mMatrix[1]);
y2.splat<1>(rhs.mMatrix[2]);
y3.splat<1>(rhs.mMatrix[3]);
z0.splat<2>(rhs.mMatrix[0]);
z1.splat<2>(rhs.mMatrix[1]);
z2.splat<2>(rhs.mMatrix[2]);
z3.splat<2>(rhs.mMatrix[3]);
//12 muls
x0.mul(mMatrix[0]);
x1.mul(mMatrix[0]);
x2.mul(mMatrix[0]);
x3.mul(mMatrix[0]);
y0.mul(mMatrix[1]);
y1.mul(mMatrix[1]);
y2.mul(mMatrix[1]);
y3.mul(mMatrix[1]);
z0.mul(mMatrix[2]);
z1.mul(mMatrix[2]);
z2.mul(mMatrix[2]);
z3.mul(mMatrix[2]);
//9 adds
x0.add(y0);
x1.add(y1);
x2.add(y2);
x3.add(y3);
z3.add(mMatrix[3]);
mMatrix[0].setAdd(x0,z0);
mMatrix[1].setAdd(x1,z1);
mMatrix[2].setAdd(x2,z2);
mMatrix[3].setAdd(x3,z3);
}
inline void extractRotation_affine()
{
static const LLVector4Logical mask = _mm_load_ps((F32*)&S_V4LOGICAL_MASK_TABLE[3*4]);
mMatrix[0].setSelectWithMask(mask,_mm_setzero_ps(),mMatrix[0]);
mMatrix[1].setSelectWithMask(mask,_mm_setzero_ps(),mMatrix[1]);
mMatrix[2].setSelectWithMask(mask,_mm_setzero_ps(),mMatrix[2]);
mMatrix[3].setSelectWithMask(mask,LLVector4a(1.f),_mm_setzero_ps());
}
//======================Logic====================
private:
template<bool mins> inline void init_foos(LLMatrix4a& foos) const
{
static bool done(false);
if (done) return;
const LLVector4a delta(0.0001f);
foos.setIdentity();
foos.getRow<0>().sub(delta);
foos.getRow<1>().sub(delta);
foos.getRow<2>().sub(delta);
foos.getRow<3>().sub(delta);
done = true;
}
public:
inline bool isIdentity() const
{
static LLMatrix4a mins;
static LLMatrix4a maxs;
init_foos<false>(mins);
init_foos<true>(maxs);
LLVector4a mask1 = _mm_and_ps(_mm_cmpgt_ps(mMatrix[0],mins.getRow<0>()), _mm_cmplt_ps(mMatrix[0],maxs.getRow<0>()));
LLVector4a mask2 = _mm_and_ps(_mm_cmpgt_ps(mMatrix[1],mins.getRow<1>()), _mm_cmplt_ps(mMatrix[1],maxs.getRow<1>()));
LLVector4a mask3 = _mm_and_ps(_mm_cmpgt_ps(mMatrix[2],mins.getRow<2>()), _mm_cmplt_ps(mMatrix[2],maxs.getRow<2>()));
LLVector4a mask4 = _mm_and_ps(_mm_cmpgt_ps(mMatrix[3],mins.getRow<3>()), _mm_cmplt_ps(mMatrix[3],maxs.getRow<3>()));
mask1 = _mm_and_ps(mask1,mask2);
mask2 = _mm_and_ps(mask3,mask4);
return _mm_movemask_epi8(_mm_castps_si128(_mm_and_ps(mask1, mask2))) == 0xFFFF;
}
} LL_ALIGN_POSTFIX(16);
#endif

View File

@@ -2,36 +2,28 @@
* @file llmodularmath.cpp
* @brief LLModularMath class implementation
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2010, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlife.com/developers/opensource/gplv2
* 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.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlife.com/developers/opensource/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*
*/
#include "linden_common.h"
// implementation is all in the header, this include dep ensures the unit test is rerun if the implementation changes.

View File

@@ -2,31 +2,25 @@
* @file llmodularmath.h
* @brief Useful modular math functions.
*
* $LicenseInfo:firstyear=2008&license=viewergpl$
*
* Copyright (c) 2008-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2008&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* Copyright (C) 2010, Linden Research, Inc.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* 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$
*/

View File

@@ -932,10 +932,10 @@ protected:
MIN = 3
} eDName;
LLVector4a mCenter;
LLVector4a mSize;
LLVector4a mMax;
LLVector4a mMin;
LL_ALIGN_16(LLVector4a mCenter);
LL_ALIGN_16(LLVector4a mSize);
LL_ALIGN_16(LLVector4a mMax);
LL_ALIGN_16(LLVector4a mMin);
oct_node* mParent;
U8 mOctant;
@@ -964,6 +964,26 @@ public:
: BaseType(center, size, parent)
{
}
#ifdef LL_OCTREE_POOLS
void* operator new(size_t size)
{
return LLOctreeNode<T>::getPool(size).malloc();
}
void operator delete(void* ptr)
{
LLOctreeNode<T>::getPool(sizeof(LLOctreeNode<T>)).free(ptr);
}
#else
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}
#endif
bool balance()
{

View File

@@ -1,31 +1,25 @@
/**
* @file llperlin.cpp
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* Copyright (C) 2010, Linden Research, Inc.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* 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$
*/

View File

@@ -1,31 +1,25 @@
/**
* @file llperlin.h
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* Copyright (C) 2010, Linden Research, Inc.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* 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$
*/

View File

@@ -1,31 +1,25 @@
/**
* @file llplane.h
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* 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.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -100,8 +94,14 @@ public:
return mV.greaterEqual(LLVector4a::getZero()).getGatheredBits() & LLVector4Logical::MASK_XYZ;
}
//check if two planes are nearly same
bool equal(const LLPlane& p) const
{
return mV.equals4(p.mV);
}
private:
LLVector4a mV;
LL_ALIGN_16(LLVector4a mV);
} LL_ALIGN_POSTFIX(16);

View File

@@ -3,31 +3,25 @@
* @brief useful routines for quantizing floats to various length ints
* and back out again
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* 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.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/

View File

@@ -2,31 +2,25 @@
* @file llquaternion.cpp
* @brief LLQuaternion class implementation.
*
* $LicenseInfo:firstyear=2000&license=viewergpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* 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.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -64,34 +58,40 @@ LLQuaternion::LLQuaternion(const LLMatrix3 &mat)
LLQuaternion::LLQuaternion(F32 angle, const LLVector4 &vec)
{
LLVector3 v(vec.mV[VX], vec.mV[VY], vec.mV[VZ]);
v.normalize();
F32 c, s;
c = cosf(angle*0.5f);
s = sinf(angle*0.5f);
mQ[VX] = v.mV[VX] * s;
mQ[VY] = v.mV[VY] * s;
mQ[VZ] = v.mV[VZ] * s;
mQ[VW] = c;
normalize();
F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]);
if (mag > FP_MAG_THRESHOLD)
{
angle *= 0.5;
F32 c = cosf(angle);
F32 s = sinf(angle) / mag;
mQ[VX] = vec.mV[VX] * s;
mQ[VY] = vec.mV[VY] * s;
mQ[VZ] = vec.mV[VZ] * s;
mQ[VW] = c;
}
else
{
loadIdentity();
}
}
LLQuaternion::LLQuaternion(F32 angle, const LLVector3 &vec)
{
LLVector3 v(vec);
v.normalize();
F32 c, s;
c = cosf(angle*0.5f);
s = sinf(angle*0.5f);
mQ[VX] = v.mV[VX] * s;
mQ[VY] = v.mV[VY] * s;
mQ[VZ] = v.mV[VZ] * s;
mQ[VW] = c;
normalize();
F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]);
if (mag > FP_MAG_THRESHOLD)
{
angle *= 0.5;
F32 c = cosf(angle);
F32 s = sinf(angle) / mag;
mQ[VX] = vec.mV[VX] * s;
mQ[VY] = vec.mV[VY] * s;
mQ[VZ] = vec.mV[VZ] * s;
mQ[VW] = c;
}
else
{
loadIdentity();
}
}
LLQuaternion::LLQuaternion(const LLVector3 &x_axis,
@@ -142,57 +142,61 @@ void LLQuaternion::quantize8(F32 lower, F32 upper)
const LLQuaternion& LLQuaternion::setAngleAxis(F32 angle, F32 x, F32 y, F32 z)
{
LLVector3 vec(x, y, z);
vec.normalize();
angle *= 0.5f;
F32 c, s;
c = cosf(angle);
s = sinf(angle);
mQ[VX] = vec.mV[VX]*s;
mQ[VY] = vec.mV[VY]*s;
mQ[VZ] = vec.mV[VZ]*s;
mQ[VW] = c;
normalize();
F32 mag = sqrtf(x * x + y * y + z * z);
if (mag > FP_MAG_THRESHOLD)
{
angle *= 0.5;
F32 c = cosf(angle);
F32 s = sinf(angle) / mag;
mQ[VX] = x * s;
mQ[VY] = y * s;
mQ[VZ] = z * s;
mQ[VW] = c;
}
else
{
loadIdentity();
}
return (*this);
}
const LLQuaternion& LLQuaternion::setAngleAxis(F32 angle, const LLVector3 &vec)
{
LLVector3 v(vec);
v.normalize();
angle *= 0.5f;
F32 c, s;
c = cosf(angle);
s = sinf(angle);
mQ[VX] = v.mV[VX]*s;
mQ[VY] = v.mV[VY]*s;
mQ[VZ] = v.mV[VZ]*s;
mQ[VW] = c;
normalize();
F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]);
if (mag > FP_MAG_THRESHOLD)
{
angle *= 0.5;
F32 c = cosf(angle);
F32 s = sinf(angle) / mag;
mQ[VX] = vec.mV[VX] * s;
mQ[VY] = vec.mV[VY] * s;
mQ[VZ] = vec.mV[VZ] * s;
mQ[VW] = c;
}
else
{
loadIdentity();
}
return (*this);
}
const LLQuaternion& LLQuaternion::setAngleAxis(F32 angle, const LLVector4 &vec)
{
LLVector3 v(vec.mV[VX], vec.mV[VY], vec.mV[VZ]);
v.normalize();
F32 c, s;
c = cosf(angle*0.5f);
s = sinf(angle*0.5f);
mQ[VX] = v.mV[VX]*s;
mQ[VY] = v.mV[VY]*s;
mQ[VZ] = v.mV[VZ]*s;
mQ[VW] = c;
normalize();
F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]);
if (mag > FP_MAG_THRESHOLD)
{
angle *= 0.5;
F32 c = cosf(angle);
F32 s = sinf(angle) / mag;
mQ[VX] = vec.mV[VX] * s;
mQ[VY] = vec.mV[VY] * s;
mQ[VZ] = vec.mV[VZ] * s;
mQ[VW] = c;
}
else
{
loadIdentity();
}
return (*this);
}
@@ -225,68 +229,80 @@ const LLQuaternion& LLQuaternion::set(const LLMatrix4 &mat)
// deprecated
const LLQuaternion& LLQuaternion::setQuat(F32 angle, F32 x, F32 y, F32 z)
{
LLVector3 vec(x, y, z);
vec.normalize();
angle *= 0.5f;
F32 c, s;
c = cosf(angle);
s = sinf(angle);
mQ[VX] = vec.mV[VX]*s;
mQ[VY] = vec.mV[VY]*s;
mQ[VZ] = vec.mV[VZ]*s;
mQ[VW] = c;
normalize();
F32 mag = sqrtf(x * x + y * y + z * z);
if (mag > FP_MAG_THRESHOLD)
{
angle *= 0.5;
F32 c = cosf(angle);
F32 s = sinf(angle) / mag;
mQ[VX] = x * s;
mQ[VY] = y * s;
mQ[VZ] = z * s;
mQ[VW] = c;
}
else
{
loadIdentity();
}
return (*this);
}
// deprecated
const LLQuaternion& LLQuaternion::setQuat(F32 angle, const LLVector3 &vec)
{
LLVector3 v(vec);
v.normalize();
angle *= 0.5f;
F32 c, s;
c = cosf(angle);
s = sinf(angle);
mQ[VX] = v.mV[VX]*s;
mQ[VY] = v.mV[VY]*s;
mQ[VZ] = v.mV[VZ]*s;
mQ[VW] = c;
normalize();
F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]);
if (mag > FP_MAG_THRESHOLD)
{
angle *= 0.5;
F32 c = cosf(angle);
F32 s = sinf(angle) / mag;
mQ[VX] = vec.mV[VX] * s;
mQ[VY] = vec.mV[VY] * s;
mQ[VZ] = vec.mV[VZ] * s;
mQ[VW] = c;
}
else
{
loadIdentity();
}
return (*this);
}
const LLQuaternion& LLQuaternion::setQuat(F32 angle, const LLVector4 &vec)
{
LLVector3 v(vec.mV[VX], vec.mV[VY], vec.mV[VZ]);
v.normalize();
F32 c, s;
c = cosf(angle*0.5f);
s = sinf(angle*0.5f);
mQ[VX] = v.mV[VX]*s;
mQ[VY] = v.mV[VY]*s;
mQ[VZ] = v.mV[VZ]*s;
mQ[VW] = c;
normalize();
F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]);
if (mag > FP_MAG_THRESHOLD)
{
angle *= 0.5;
F32 c = cosf(angle);
F32 s = sinf(angle) / mag;
mQ[VX] = vec.mV[VX] * s;
mQ[VY] = vec.mV[VY] * s;
mQ[VZ] = vec.mV[VZ] * s;
mQ[VW] = c;
}
else
{
loadIdentity();
}
return (*this);
}
const LLQuaternion& LLQuaternion::setQuat(F32 roll, F32 pitch, F32 yaw)
{
LLMatrix3 rot_mat(roll, pitch, yaw);
rot_mat.orthogonalize();
*this = rot_mat.quaternion();
normalize();
roll *= 0.5f;
pitch *= 0.5f;
yaw *= 0.5f;
F32 sinX = sinf(roll);
F32 cosX = cosf(roll);
F32 sinY = sinf(pitch);
F32 cosY = cosf(pitch);
F32 sinZ = sinf(yaw);
F32 cosZ = cosf(yaw);
mQ[VW] = cosX * cosY * cosZ - sinX * sinY * sinZ;
mQ[VX] = sinX * cosY * cosZ + cosX * sinY * sinZ;
mQ[VY] = cosX * sinY * cosZ - sinX * cosY * sinZ;
mQ[VZ] = cosX * cosY * sinZ + sinX * sinY * cosZ;
return (*this);
}
@@ -431,68 +447,44 @@ LLMatrix4 LLQuaternion::getMatrix4(void) const
// calculate the shortest rotation from a to b
void LLQuaternion::shortestArc(const LLVector3 &a, const LLVector3 &b)
{
// Make a local copy of both vectors.
LLVector3 vec_a = a;
LLVector3 vec_b = b;
// Make sure neither vector is zero length. Also normalize
// the vectors while we are at it.
F32 vec_a_mag = vec_a.normalize();
F32 vec_b_mag = vec_b.normalize();
if (vec_a_mag < F_APPROXIMATELY_ZERO ||
vec_b_mag < F_APPROXIMATELY_ZERO)
F32 ab = a * b; // dotproduct
LLVector3 c = a % b; // crossproduct
F32 cc = c * c; // squared length of the crossproduct
if (ab * ab + cc) // test if the arguments have sufficient magnitude
{
// Can't calculate a rotation from this.
// Just return ZERO_ROTATION instead.
loadIdentity();
return;
}
// Create an axis to rotate around, and the cos of the angle to rotate.
LLVector3 axis = vec_a % vec_b;
F32 cos_theta = vec_a * vec_b;
// Check the angle between the vectors to see if they are parallel or anti-parallel.
if (cos_theta > 1.0 - F_APPROXIMATELY_ZERO)
{
// a and b are parallel. No rotation is necessary.
loadIdentity();
}
else if (cos_theta < -1.0 + F_APPROXIMATELY_ZERO)
{
// a and b are anti-parallel.
// Rotate 180 degrees around some orthogonal axis.
// Find the projection of the x-axis onto a, and try
// using the vector between the projection and the x-axis
// as the orthogonal axis.
LLVector3 proj = vec_a.mV[VX] / (vec_a * vec_a) * vec_a;
LLVector3 ortho_axis(1.f, 0.f, 0.f);
ortho_axis -= proj;
// Turn this into an orthonormal axis.
F32 ortho_length = ortho_axis.normalize();
// If the axis' length is 0, then our guess at an orthogonal axis
// was wrong (a is parallel to the x-axis).
if (ortho_length < F_APPROXIMATELY_ZERO)
if (cc > 0.0f) // test if the arguments are (anti)parallel
{
// Use the z-axis instead.
ortho_axis.setVec(0.f, 0.f, 1.f);
F32 s = sqrtf(ab * ab + cc) + ab; // note: don't try to optimize this line
F32 m = 1.0f / sqrtf(cc + s * s); // the inverted magnitude of the quaternion
mQ[VX] = c.mV[VX] * m;
mQ[VY] = c.mV[VY] * m;
mQ[VZ] = c.mV[VZ] * m;
mQ[VW] = s * m;
return;
}
if (ab < 0.0f) // test if the angle is bigger than PI/2 (anti parallel)
{
c = a - b; // the arguments are anti-parallel, we have to choose an axis
F32 m = sqrtf(c.mV[VX] * c.mV[VX] + c.mV[VY] * c.mV[VY]); // the length projected on the XY-plane
if (m > FP_MAG_THRESHOLD)
{
mQ[VX] = -c.mV[VY] / m; // return the quaternion with the axis in the XY-plane
mQ[VY] = c.mV[VX] / m;
mQ[VZ] = 0.0f;
mQ[VW] = 0.0f;
return;
}
else // the vectors are parallel to the Z-axis
{
mQ[VX] = 1.0f; // rotate around the X-axis
mQ[VY] = 0.0f;
mQ[VZ] = 0.0f;
mQ[VW] = 0.0f;
return;
}
}
// Construct a quaternion from this orthonormal axis.
mQ[VX] = ortho_axis.mV[VX];
mQ[VY] = ortho_axis.mV[VY];
mQ[VZ] = ortho_axis.mV[VZ];
mQ[VW] = 0.f;
}
else
{
// a and b are NOT parallel or anti-parallel.
// Return the rotation between these vectors.
F32 theta = (F32)acos(cos_theta);
setAngleAxis(theta, axis);
}
loadIdentity();
}
// constrains rotation to a cone angle specified in radians
@@ -844,79 +836,82 @@ LLQuaternion::Order StringToOrder( const char *str )
void LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) const
{
F32 cos_a = mQ[VW];
if (cos_a > 1.0f) cos_a = 1.0f;
if (cos_a < -1.0f) cos_a = -1.0f;
F32 sin_a = (F32) sqrt( 1.0f - cos_a * cos_a );
if ( fabs( sin_a ) < 0.0005f )
sin_a = 1.0f;
else
sin_a = 1.f/sin_a;
F32 temp_angle = 2.0f * (F32) acos( cos_a );
if (temp_angle > F_PI)
F32 v = sqrtf(mQ[VX] * mQ[VX] + mQ[VY] * mQ[VY] + mQ[VZ] * mQ[VZ]); // length of the vector-component
if (v > FP_MAG_THRESHOLD)
{
// The (angle,axis) pair should never have angles outside [PI, -PI]
// since we want the _shortest_ (angle,axis) solution.
// Since acos is defined for [0, PI], and we multiply by 2.0, we
// can push the angle outside the acceptible range.
// When this happens we set the angle to the other portion of a
// full 2PI rotation, and negate the axis, which reverses the
// direction of the rotation (by the right-hand rule).
*angle = 2.f * F_PI - temp_angle;
vec.mV[VX] = - mQ[VX] * sin_a;
vec.mV[VY] = - mQ[VY] * sin_a;
vec.mV[VZ] = - mQ[VZ] * sin_a;
F32 oomag = 1.0f / v;
F32 w = mQ[VW];
if (mQ[VW] < 0.0f)
{
w = -w; // make VW positive
oomag = -oomag; // invert the axis
}
vec.mV[VX] = mQ[VX] * oomag; // normalize the axis
vec.mV[VY] = mQ[VY] * oomag;
vec.mV[VZ] = mQ[VZ] * oomag;
*angle = 2.0f * atan2f(v, w); // get the angle
}
else
{
*angle = temp_angle;
vec.mV[VX] = mQ[VX] * sin_a;
vec.mV[VY] = mQ[VY] * sin_a;
vec.mV[VZ] = mQ[VZ] * sin_a;
*angle = 0.0f; // no rotation
vec.mV[VX] = 0.0f; // around some dummy axis
vec.mV[VY] = 0.0f;
vec.mV[VZ] = 1.0f;
}
}
// quaternion does not need to be normalized
void LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const
{
LLMatrix3 rot_mat(*this);
rot_mat.orthogonalize();
rot_mat.getEulerAngles(roll, pitch, yaw);
// // NOTE: LLQuaternion's are actually inverted with respect to
// // the matrices, so this code also assumes inverted quaternions
// // (-x, -y, -z, w). The result is that roll,pitch,yaw are applied
// // in reverse order (yaw,pitch,roll).
// F32 x = -mQ[VX], y = -mQ[VY], z = -mQ[VZ], w = mQ[VW];
// F64 m20 = 2.0*(x*z-y*w);
// if (1.0f - fabsf(m20) < F_APPROXIMATELY_ZERO)
// {
// *roll = 0.0f;
// *pitch = (F32)asin(m20);
// *yaw = (F32)atan2(2.0*(x*y-z*w), 1.0 - 2.0*(x*x+z*z));
// }
// else
// {
// *roll = (F32)atan2(-2.0*(y*z+x*w), 1.0-2.0*(x*x+y*y));
// *pitch = (F32)asin(m20);
// *yaw = (F32)atan2(-2.0*(x*y+z*w), 1.0-2.0*(y*y+z*z));
// }
F32 sx = 2 * (mQ[VX] * mQ[VW] - mQ[VY] * mQ[VZ]); // sine of the roll
F32 sy = 2 * (mQ[VY] * mQ[VW] + mQ[VX] * mQ[VZ]); // sine of the pitch
F32 ys = mQ[VW] * mQ[VW] - mQ[VY] * mQ[VY]; // intermediate cosine 1
F32 xz = mQ[VX] * mQ[VX] - mQ[VZ] * mQ[VZ]; // intermediate cosine 2
F32 cx = ys - xz; // cosine of the roll
F32 cy = sqrtf(sx * sx + cx * cx); // cosine of the pitch
if (cy > GIMBAL_THRESHOLD) // no gimbal lock
{
*roll = atan2f(sx, cx);
*pitch = atan2f(sy, cy);
*yaw = atan2f(2 * (mQ[VZ] * mQ[VW] - mQ[VX] * mQ[VY]), ys + xz);
}
else // gimbal lock
{
if (sy > 0)
{
*pitch = F_PI_BY_TWO;
*yaw = 2 * atan2f(mQ[VZ] + mQ[VX], mQ[VW] + mQ[VY]);
}
else
{
*pitch = -F_PI_BY_TWO;
*yaw = 2 * atan2f(mQ[VZ] - mQ[VX], mQ[VW] - mQ[VY]);
}
*roll = 0;
}
}
// Saves space by using the fact that our quaternions are normalized
LLVector3 LLQuaternion::packToVector3() const
{
F32 x = mQ[VX];
F32 y = mQ[VY];
F32 z = mQ[VZ];
F32 w = mQ[VW];
F32 mag = sqrtf(x * x + y * y + z * z + w * w);
if (mag > FP_MAG_THRESHOLD)
{
x /= mag;
y /= mag;
z /= mag; // no need to normalize w, it's not used
}
if( mQ[VW] >= 0 )
{
return LLVector3( mQ[VX], mQ[VY], mQ[VZ] );
return LLVector3( x, y , z );
}
else
{
return LLVector3( -mQ[VX], -mQ[VY], -mQ[VZ] );
return LLVector3( -x, -y, -z );
}
}

View File

@@ -2,31 +2,25 @@
* @file llquaternion.h
* @brief LLQuaternion class header file.
*
* $LicenseInfo:firstyear=2000&license=viewergpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* 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.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* 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.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* 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
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -310,43 +304,29 @@ inline const LLQuaternion& LLQuaternion::setQuat(const F32 *q)
return (*this);
}
// There may be a cheaper way that avoids the sqrt.
// Does sin_a = VX*VX + VY*VY + VZ*VZ?
// Copied from Matrix and Quaternion FAQ 1.12
inline void LLQuaternion::getAngleAxis(F32* angle, F32* x, F32* y, F32* z) const
{
F32 cos_a = mQ[VW];
if (cos_a > 1.0f) cos_a = 1.0f;
if (cos_a < -1.0f) cos_a = -1.0f;
F32 sin_a = (F32) sqrt( 1.0f - cos_a * cos_a );
if ( fabs( sin_a ) < 0.0005f )
sin_a = 1.0f;
else
sin_a = 1.f/sin_a;
F32 temp_angle = 2.0f * (F32) acos( cos_a );
if (temp_angle > F_PI)
F32 v = sqrtf(mQ[VX] * mQ[VX] + mQ[VY] * mQ[VY] + mQ[VZ] * mQ[VZ]); // length of the vector-component
if (v > FP_MAG_THRESHOLD)
{
// The (angle,axis) pair should never have angles outside [PI, -PI]
// since we want the _shortest_ (angle,axis) solution.
// Since acos is defined for [0, PI], and we multiply by 2.0, we
// can push the angle outside the acceptible range.
// When this happens we set the angle to the other portion of a
// full 2PI rotation, and negate the axis, which reverses the
// direction of the rotation (by the right-hand rule).
*angle = 2.f * F_PI - temp_angle;
*x = - mQ[VX] * sin_a;
*y = - mQ[VY] * sin_a;
*z = - mQ[VZ] * sin_a;
F32 oomag = 1.0f / v;
F32 w = mQ[VW];
if (w < 0.0f)
{
w = -w; // make VW positive
oomag = -oomag; // invert the axis
}
*x = mQ[VX] * oomag; // normalize the axis
*y = mQ[VY] * oomag;
*z = mQ[VZ] * oomag;
*angle = 2.0f * atan2f(v, w); // get the angle
}
else
{
*angle = temp_angle;
*x = mQ[VX] * sin_a;
*y = mQ[VY] * sin_a;
*z = mQ[VZ] * sin_a;
*angle = 0.0f; // no rotation
*x = 0.0f; // around some dummy axis
*y = 0.0f;
*z = 1.0f;
}
}

Some files were not shown because too many files have changed in this diff Show More