Compare commits

...

293 Commits

Author SHA1 Message Date
Latif Khalifa
5c8e436401 Fix windows build: warnings management 2013-01-30 05:45:00 +01:00
Latif Khalifa
4d805da6ac Package glod and colladadom dlls 2013-01-30 05:43:17 +01:00
Latif Khalifa
085800f6e0 Tell the compiler we are using colladadom dll, and not a static lib. Use our current boost libs 2013-01-30 05:27:10 +01:00
Latif Khalifa
1934fc9bd4 Temporarily disable HACD file save functions (not used) to avoid strange linking issue on windows 2013-01-30 05:25:05 +01:00
Latif Khalifa
8c1848b487 Silence secure CRT warnings when building HACD 2013-01-30 05:14:48 +01:00
Latif Khalifa
8edb10fb88 Merge remote-tracking branch 'aleric/meshupload' into meshupload 2013-01-30 05:12:04 +01:00
Aleric Inglewood
8aecc49456 Add missing notifications. 2013-01-30 03:58:42 +01:00
Latif Khalifa
b8919c21d8 Merge remote-tracking branch 'aleric/meshupload' into meshupload 2013-01-30 03:46:45 +01:00
Aleric Inglewood
9203b24eb9 Remove AIStateMachineThreadBase* argument from AIThreadImpl constructor.
Also removes the use of 'this' to initialize base classes, which led to
a compiler warning on vs2010.
2013-01-30 03:44:02 +01:00
Latif Khalifa
8584e6da4c Merge branch 'master' into meshupload
Conflicts:
	indra/llcommon/llhash.h
	indra/newview/CMakeLists.txt
	indra/newview/llfloatermodelpreview.cpp
	indra/newview/llfloatermodelpreview.h
	indra/newview/llpanelprofile.h
2013-01-30 00:36:31 +01:00
Aleric Inglewood
1d673df1bd Add AIMeshUpload and fix LLMeshUploadThread
* Removes polling stuff (call to gMeshRepo.update()) which did
  nothing but check if uploads already finished.
* Just creates and runs the state machine (AIMeshUpload) instead
  of creating an LLThread derived class (LLMeshUploadThread) and
  adding that to a queue, then have the main thread start it
  after adding it to another queue in order to keep track of
  the instances (both queues are gone).
* mWholeModelUploadURL was moved to the state machine, because
  it needs a life time till the responders finishes (can't be
  part of the thread object).
* LLMeshUploadThread is now derived from AIThreadImpl instead
  of LLThread, so it can be run in a state machine thread.
* The call to LLHTTPClient::post is now done from the main
  thread instead of from the thread, but I don't think that is
  a problem.
2013-01-29 23:42:06 +01:00
Aleric Inglewood
b3adf71ed7 Remember floater rectangle 2013-01-29 23:20:02 +01:00
Aleric Inglewood
7ba0b6482c Fix example code. 2013-01-29 20:49:53 +01:00
Aleric Inglewood
e99175444f Bike fix: Always set mStatus to STOPPED 2013-01-29 20:45:08 +01:00
Aleric Inglewood
d5ed31ca9b Allow passing a name to underlaying LLThread in debug mode. 2013-01-29 20:44:14 +01:00
Aleric Inglewood
1c8027b1e6 Add statemachine parent callback support to LLHTTPClient::post 2013-01-27 22:02:19 +01:00
Aleric Inglewood
ebac80b5b7 Fix termination race condition. 2013-01-27 20:52:21 +01:00
Aleric Inglewood
c528a15e95 Added AIStateMachineThread 2013-01-26 19:19:09 +01:00
Aleric Inglewood
6dc4a60724 Changes to LLThread
* Call a virtual terminated() that by default sets mStatus to STOPPED,
  instead of setting it to STOPPED directly, allowing to override
  the behavior of a LLThread derived class when the thread is about
  the exit.
* Make setQuitting() public, so it can also be used to hint to a
  thread that it should stop at its earliest convience.
2013-01-26 19:15:57 +01:00
Aleric Inglewood
f6785c399d Added support for LLCondition to AIThreadSafeSimple. 2013-01-26 18:35:42 +01:00
Latif Khalifa
237f84cde0 Merge remote-tracking branch 'shyotl/sunshine' 2013-01-26 13:49:50 +01:00
Shyotl
485ad8e645 Reworked name loading for vivox speaker list. LLSpeaker now boost::signals2::trackable to avoid accessing after destruction. Opening new sessions via doubleclick on list(sessions managed by legacyname) or using the mute button(legacyname needed to exclude lindens) are both disabled until namecache lookup complete. 2013-01-26 01:57:13 -06:00
Aleric Inglewood
a1fa43850b Comment fixes. 2013-01-25 16:09:34 +01:00
Latif Khalifa
5e799b1f81 Respect always rez under owned land group setting for objects
duplicated by shift-dragging or duplicating.

Based on Phoenix changeset 5b50018c63d4 by Kadah
2013-01-23 12:02:04 +01:00
Aleric Inglewood
0296812e88 Add cmake file for collada and glod.
This fixes standalone when those libraries are installed
elsewhere. Note that it "breaks" standalone if you just
installed the prebuilt manually. For that to work you
have to add /.../libraries/include to CMAKE_INCLUDE_PATH,
which is not recommended because it would pick up any
other prebuilt over your system installed libraries.

Instead, for standalone, install the libraries somewhere
with some prefix and then add that prefix to the environment
variable CMAKE_PREFIX_PATH.

For example, $prefix/include/collada and $prefix/lib/libcollada4dom.so
2013-01-22 20:51:43 +01:00
Latif Khalifa
d8c846288e Merge remote-tracking branch 'lirusato/master' 2013-01-22 20:06:03 +01:00
Lirusaito
dd1e9a68d4 Removal of the deprecated lltabcontainervertical. 2013-01-22 01:38:25 -05:00
Lirusaito
21860ded90 Support web_profile_url response from OSGrid servers for setting WebProfileURL 2013-01-21 21:27:53 -05:00
Lirusaito
48113f8506 AuroraSim: HippoLimits and HippoGridManager update, and support for Aurora's MaxDrag 2013-01-21 21:22:04 -05:00
Aleric Inglewood
db7155666d Merge branch 'master' into meshupload
Conflicts:
	indra/cmake/00-Common.cmake

One diff added /MP to CMAKE_CXX_FLAGS_DEBUG while
another removed /arch:SSE2 from the same line.

Fixed to honor both changes.
2013-01-21 19:16:06 +01:00
Latif Khalifa
b758014ebc Adjust to recent change in the API for Responder objects 2013-01-21 11:25:32 +01:00
Latif Khalifa
18816ae146 Merge remote-tracking branch 'shyotl/sunshine' 2013-01-21 11:25:10 +01:00
Shyotl
dc106c5442 Fix some compiler warnings/errors. Error in llinventorymodelbackgroundfetch was introduced by partial commit. 2013-01-20 17:10:38 -06:00
Lirusaito
aa3228be76 French translation update, thanks Nomade~ 2013-01-20 10:25:19 -05:00
Lirusaito
c2ce72ed94 Issue 604: Reset Button for inventory
Attempted Spanish translation.
Nomade Zhao provided French.
2013-01-20 10:15:23 -05:00
Siana Gearz
4cd2de0fff Version 1.7.3 2013-01-20 05:57:05 +01:00
Siana Gearz
b318a0703b Use standard way on windows to find default file picker path 2013-01-20 05:55:18 +01:00
Siana Gearz
ea67aca955 This should de-clog the tubes on the map 2013-01-20 03:32:51 +01:00
Siana Gearz
0ab140a071 Potential permission fix 2013-01-20 01:49:55 +01:00
Siana Gearz
d5eb2432ef Merge branch 'master' of github.com:singularity-viewer/SingularityViewer 2013-01-20 01:49:14 +01:00
Lirusaito
a6c2d256c6 Hooked up RLVaTopLevelMenu setting so it actually works.
Changes to llviewermenu.cpp are better viewed without space changes
^Put together both RLVa Embedded and RLVa Main menus while building Advanced menu, labeling them RLVa; once the advanced menu is built and added to MenuBar, rlvMenuToggleVisible() is called.
Added onChangedMenuLevel() to rlvcommon.cpp
Added rlvMenuToggleVisible(), tweaked to only perform necessary operations for now, other parts left commented out for future use.
Removed menu visibility handling from RlvHandler::setEnabled()

NOTE: RLVa has only been updated in pertinent areas, from what I can tell we are a bit behind in other places, too.
2013-01-18 15:14:33 -05:00
Aleric Inglewood
7a8a2757db Add comment for sake of translation. 2013-01-18 16:10:18 +01:00
Aleric Inglewood
d8d3cafc32 Merge remote-tracking branch 'singu/master' 2013-01-18 02:28:17 +01:00
Aleric Inglewood
604824335c Keep focus during Freeze Time so that pressing ESC always leaves Freeze Time. 2013-01-18 02:26:43 +01:00
Latif Khalifa
9240147874 Merge remote-tracking branch 'lirusato/master' 2013-01-17 17:26:00 +01:00
Lirusaito
05a6323d2c French antispam controls touchup 2013-01-17 09:17:43 -05:00
Lirusaito
1dd0b7713b French translation fixies~ 2013-01-17 03:38:53 -05:00
Lirusaito
795f70a0b0 d520053 - MAINT-852 / VWR-8761 : Cannot delete object description. Now you can. 2013-01-17 01:11:59 -05:00
Lirusaito
5831af0fb6 OPEN-161: Typo in the header guard of lltexturecache.h 2013-01-17 01:10:47 -05:00
Aleric Inglewood
e8e3e43711 Update llqtwebkit with recompiled version. 2013-01-17 00:43:21 +01:00
Latif Khalifa
460b05d37a Merge remote-tracking branch 'shyotl/master' 2013-01-16 16:25:51 +01:00
Latif Khalifa
f03405ca47 Merge remote-tracking branch 'lirusato/master' 2013-01-16 16:25:37 +01:00
Lirusaito
0405ed9e3d French Translation update. 2013-01-16 09:27:25 -05:00
Lirusaito
2eb8f2f84a 07e5202 MAINT-1942 Increase maximum animation length from 30 seconds to 60 seconds 2013-01-16 05:00:35 -05:00
Shyotl
6894d4c0bc Changed how the 'client' column in avatar radar is handled. Initially was not designed nor tested to be toggleable on user-demand (was one shot deal depending on detected grid). 2013-01-15 23:14:58 -06:00
Lirusaito
53c04b7299 Issue 220: Copy/paste params in the build tools like phoenix
Adds mClipboardFlexiParams, mClipboardLightParams, mClipboardSculptParams, and mClipboardLightImageParams to LLPanelObject.
Corrects the tooltip on the the copy button.
2013-01-15 22:43:22 -05:00
Latif Khalifa
3bf307abb0 Merge remote-tracking branch 'shyotl/master' 2013-01-15 18:37:09 +01:00
Latif Khalifa
4928d29a8e Merge remote-tracking branch 'aleric/master' 2013-01-15 18:36:51 +01:00
Latif Khalifa
8cec9c7b73 Merge remote-tracking branch 'lirusato/master' 2013-01-15 18:36:39 +01:00
Shyotl
a6e3352073 Setting camera toolset as current sticks us into build mode (??)... Avoid when taking snapshots. 2013-01-14 23:09:12 -06:00
Aleric Inglewood
0eeea37662 Fix 'Open floater in Freeze Time mode'
When the floater was opened in Freeze Time mode, then parent of the
widget that triggers it to open is the 'Floater View'. We do NOT
want to set that MouseOpaque :p. Using getParent here is just
nonsense.
2013-01-15 03:31:57 +01:00
Shyotl
2a8f55e99e Updated gesture floater to use more modern (and actual working) method of adding list elements via xml. 2013-01-14 18:41:48 -06:00
Aleric Inglewood
db7b0c1785 Revert last part (work in progress of last two commits, I guess). 2013-01-15 00:11:17 +01:00
Aleric Inglewood
55e64f6ab0 Fix for last commit.
Show sculpties with no (or not enough) data as spheres with default LOD
stepping.
2013-01-14 23:53:58 +01:00
Aleric Inglewood
6fce7062e5 Fix gcc 4.4 problem.
When a sculptie has too few vertices, especially when we bluntly assume
it's stitched around and don't want to get less than 4 vertices in
either direction, then instead we end up with even ZERO vertices, which
causes a division by zero in LLPath::genNGon with undefined behavior.
2013-01-14 23:14:29 +01:00
Aleric Inglewood
2df8ba19f4 Fix last compiler warning. 2013-01-14 22:59:49 +01:00
Aleric Inglewood
e4a3b3b5ba Merge remote-tracking branch 'shyotl/master' 2013-01-14 16:12:57 +01:00
Lirusaito
0494dc8d32 Fix Issue 432: Radar Keeps Popping Up and side issue I got still the window "An object owned by you ..."
Unified key message sending to function send_keys_message()
Switched a few getBOOLs to CachedControls
Added RadarChatKeysStopAsking, and RadarChatKeysRequest as a three button notification so the user can decide to permanently say no.
Corrected RadarChatKeys description to be more accurate.
If we want to know if the radar is open, we check instanceExists, not getInstance.
Also enabled using the announce button when RadarChatKeys is false to announce keys, for manual updates.
2013-01-14 06:34:27 -05:00
Latif Khalifa
3dd33518c4 Merge remote-tracking branch 'shyotl/master' 2013-01-14 10:53:27 +01:00
Shyotl
db8225a078 Fixup LLScrollListCtrl::setCommentText, and incorrect behaviors with script editor and bulk perm editor pertaining to setCommentText inherited from V3. 2013-01-14 03:36:04 -06:00
Siana Gearz
8bc05f6d15 Fix double upload dialog 2013-01-14 00:04:43 +01:00
Damian Zhaoying
00fb7804da Spanish Translate for new Group/Chat/IM floaters and some general string fixed 2013-01-13 19:05:35 -03:00
Siana Gearz
3091d9c847 Potential permission fix 2013-01-13 21:50:31 +01:00
Siana Gearz
d1de4d53fe Merge branch 'meshupload' of git://github.com/LightDrake/SingularityViewer into meshupload 2013-01-13 20:37:04 +01:00
Commander Cupcake
c08c2a55e5 Revert changes that broke bump 2013-01-13 14:30:41 -05:00
Siana Gearz
cddd21d879 Merge branch 'master' of github.com:singularity-viewer/SingularityViewer 2013-01-13 20:11:15 +01:00
Siana Gearz
188e42ee4a Merge branch 'meshupload' of git://github.com/AlericInglewood/SingularityViewer into meshup 2013-01-13 20:10:25 +01:00
Aleric Inglewood
f606477ae5 Use "mesh" as context everywhere (for loading and saving). 2013-01-13 19:48:35 +01:00
Aleric Inglewood
5250b218c5 LLPanelProfile is not a floater: onOpen is not virtual. 2013-01-13 19:47:32 +01:00
Aleric Inglewood
909247a179 Keep decimal format the default. 2013-01-13 19:46:35 +01:00
Aleric Inglewood
e7dea2714e Merge branch 'master' into meshupload 2013-01-13 18:02:28 +01:00
Aleric Inglewood
dcc2e52c61 Merge remote-tracking branch 'singu/master' 2013-01-13 18:01:48 +01:00
Aleric Inglewood
db17b93156 Merge branch 'master' into meshupload
Conflicts:
	indra/newview/llmeshrepository.cpp

Added /* */ around the 'virtual' keyword in two places
that collided with changes in meshupload from lightdrake.
2013-01-13 17:59:49 +01:00
Latif Khalifa
11c5e1cf4c Merge branch 'master' into 1.7.3-dev 2013-01-13 12:45:43 +01:00
Latif Khalifa
cef7ea9f5e Merge remote-tracking branch 'lirusato/master' into 1.7.3-dev 2013-01-13 12:45:37 +01:00
Latif Khalifa
31d2a15957 Merge remote-tracking branch 'aleric/master' into 1.7.3-dev 2013-01-13 12:45:25 +01:00
Shyotl
e622e03d2a Bulk of server-baking impelmentation and a bit of cleanup. 2013-01-13 02:37:12 -06:00
Siana Gearz
5b0597ea47 Suppress 400 GCC warnings in Collada DOM headers 2013-01-13 06:27:02 +01:00
Siana Gearz
5f3ca7fda0 Linux64 support, integrated physics/decomposition 2013-01-13 03:23:56 +01:00
Aleric Inglewood
3a414b21fa Temporary workaround for release. 2013-01-13 02:18:00 +01:00
Aleric Inglewood
e99a906f54 Testsuite part 1: make it compile alone. 2013-01-13 01:58:49 +01:00
Aleric Inglewood
fc4b02cee8 Moved HTTPTimeout to it's own files. 2013-01-12 23:00:21 +01:00
Aleric Inglewood
e01567553e Added default message for feed uploads.
By default show 'Type your message here...' and if the text editor
never got focus, replace that with a default message.
2013-01-12 21:31:21 +01:00
Aleric Inglewood
bf7b0bf4bf Hide floater until success/failure (or floater is re-opened) 2013-01-12 21:16:40 +01:00
Lirusaito
ece92a1b7c Optionally, have group chat and conference buttons on title line.
Adds UseConciseGroupChatButtons, and UseConciseConferenceButtons
Adds "Buttons on group chat name line (Affects new group chats)" and "Buttons on conference title line (Affects new conferences)" checkboxes to Adv. Chat's Chat UI tab.
Adds floater_instant_message_ad_hoc_concisebuttons.xml, floater_instant_message_group_concisebuttons.xml

Brings panel_speaker_controls.xml's speakers_list down by 7 pixels, which is necessary because it is awkwardly high in old places as well, such as Local Chat.
2013-01-12 14:42:55 -05:00
Aleric Inglewood
2da5c51e42 Do not freeze UI when snapshot floater is opened the first time. 2013-01-12 17:35:01 +01:00
Aleric Inglewood
57228fa208 Fix upload snapshot to inventory callback mechanism. 2013-01-12 17:27:33 +01:00
Aleric Inglewood
024c62aed4 Fix the "map/set iterators incompatible" bug.
cookies is only valid when AIHTTPReceivedHeaders::getValues return true.
2013-01-12 04:24:21 +01:00
Aleric Inglewood
e56f14502e Fill fd_sets AFTER processing command queue. 2013-01-12 02:51:44 +01:00
Lirusaito
82eb1a946e Fix group buttons in horizontal and allow the horizontal buttoned friends and groups floater to take up minimal space. 2013-01-11 19:17:06 -05:00
Siana Gearz
85855ecd85 Merge branch 'meshupload' of git://github.com/LightDrake/SingularityViewer into meshup 2013-01-12 01:12:33 +01:00
Siana Gearz
cbfd31a576 Merge branch 'master' of git://github.com/LightDrake/SingularityViewer into meshup 2013-01-12 01:11:01 +01:00
Siana Gearz
b6f1bb570f Merge branch 'master' of git://github.com/Lirusaito/SingularityViewer 2013-01-12 00:59:06 +01:00
Siana Gearz
896036b3c2 Removing ReSit, because it's not so very nice 2013-01-12 00:50:24 +01:00
Lirusaito
e51937cee7 Warn more clearly about LLRadioGroup::setValue being used wrong, and attempt to recover with LLUICtrl::setValue. 2013-01-11 18:21:48 -05:00
Lirusaito
a47dbf88bb Fix Issue 590: Debug Settings parameters setting is seriously bugged 2013-01-11 15:50:47 -05:00
Aleric Inglewood
f9a868a979 Compile fix for VC++ 2013-01-11 17:16:05 +01:00
Latif Khalifa
56542a02e8 Use multiple cores for compilation of the Debug build 2013-01-11 11:28:21 +01:00
Lirusaito
2dda9499fa Unhide Client column properly on non-SL Grids. 2013-01-11 03:56:55 -05:00
Aleric Inglewood
f9738cb611 Add getName() to every non-base class Responder object. 2013-01-11 04:15:55 +01:00
Aleric Inglewood
741a160913 Fine tune of private (libcwd) assertion.
It turns out that it's possible to receive data before an upload
finished when the server sends HTTP_BAD_REQUEST in the middle of the
upload (this happens to me when I try to upload a 6000x6000 image to my
profile feed, with is a 44MB file). So, in that case the finished upload
detection did not fail and we shouldn't assert.
2013-01-11 01:28:46 +01:00
Aleric Inglewood
5daf817e7e Upload larger original to profile feed. 2013-01-10 19:42:19 +01:00
Aleric Inglewood
9175bc0e16 Fixed LLUploadDialog to display it's text.
Also made the view rectangle have some minimal size (1/10th of the
screens width and height).
Increased the used font a bit.
Fixed removal of the dialog in the case of uploading to profile feed.
2013-01-10 18:48:02 +01:00
Lirusaito
b7f1fdd9cc Vertical space recovered 2013-01-09 11:25:46 -05:00
Lirusaito
07f88d21bd Applied STORM-1209 and added string AGroupMemberNamed for translation. 2013-01-09 11:05:37 -05:00
Lirusaito
a7d1a4611f Optionally, have IM buttons on the same line as the person's name.
Adds UseConciseIMButtons.
Adds floater_instant_message_concisebuttons.xml
Adds Have buttons on the same line as name for IMs (Affects new IMs) checkbox to Adv. Chat's Chat UI tab.
2013-01-09 10:19:41 -05:00
Lirusaito
c96b840c53 Split off certain preferences into new Adv. Chat subtab Chat UI
From Text Chat: Disallow communicate shortcut opening detached friends list
From Vanity: Use horizontal buttons for contacts floater (needs restart)
The rest were in Chat/IM of Vanity.
2013-01-09 07:30:49 -05:00
Lirusaito
70445ab8a3 Add option for Horizontal buttons on Contacts floater.
Adds Use horizontal buttons for contacts floater (needs restart) to Vanity Preferences.
Adds ContactsUseHorizontalButtons.
Adds FloaterContactsHorizRect for saving horizontal contacts rect.
Adds panel_friends_horiz.xml, panel_group_horiz.xml, and floater_my_friends_horiz.xml

Also corrects string value for FloaterContactsRect
2013-01-08 20:21:15 -05:00
Aleric Inglewood
136e6dd389 New debug channel dc::snapshot. 2013-01-09 00:54:53 +01:00
Siana Gearz
94edef2c3f Merge branch 'master' of git://github.com/AlericInglewood/SingularityViewer 2013-01-09 00:07:57 +01:00
Siana Gearz
1434e8d6e9 Merge branch 'master' of git://github.com/Lirusaito/SingularityViewer 2013-01-09 00:07:34 +01:00
Siana Gearz
54a53b574f Follow fix and clean-up 2013-01-09 00:07:17 +01:00
Shyotl
c9954cf14e Some cleanup missed in merge. 2013-01-08 17:07:05 -06:00
Shyotl
7ca974f731 Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer.git into sunshine 2013-01-08 17:06:08 -06:00
Shyotl
54771409d6 Merge branch 'master' into sunshine
Conflicts:
	indra/llimage/llimage.cpp
	indra/llui/llui.cpp
	indra/newview/llvoavatar.cpp
2013-01-08 17:05:29 -06:00
Aleric Inglewood
63ae33eca7 Fix crash in AICurlPrivate::curlthread::PollSet::next
Introduced in
6dcda3595e
(Add recovery for randomly closed socket desciptors.)

By copying CurlSocketInfo* into mCopiedFileDescriptors, it was possible
that we accessed a deleted CurlSocketInfo for it's filedescriptor,
returning a random value, which, when passed to FD_ISSET could cause a
SIGSEGV.

I reverted this change and now store the literal socket descriptors in
mCopiedFileDescriptors again. It is not a problem when libcurl deletes
the corresponding CurlSocketInfo (through a callback to
MultiHandle::socket_callback) in that case, because the fd_set we test
against isn't updated as a result of that, not until we're down with
mCopiedFileDescriptors (at the re-entry of select()).
2013-01-08 23:43:25 +01:00
Lirusaito
b485048f6b Show local chat bar in floater... (Needs restart) 2013-01-08 17:17:52 -05:00
Lirusaito
3ed2da9282 Once more change the behavior of minimizing new chats in open in separate floater mode, to be a little more truthful. 2013-01-08 14:53:08 -05:00
Drake Arconis
7aa95debf1 Merge branch 'master' into meshupload 2013-01-08 14:37:54 -05:00
Drake Arconis
f178de2ff8 Merge remote-tracking branch 'Lirusaito/master' 2013-01-08 14:37:45 -05:00
Drake Arconis
2d9402fd2d Merge branch 'master' into meshupload 2013-01-08 14:37:25 -05:00
Aleric Inglewood
5188693469 Compile fix for last commit and Release 2013-01-08 20:33:29 +01:00
Lirusaito
68911876b9 Option to Disallow communicate shortcut opening detached friends list
Added CommunicateSpecificShortcut
Added checkbox to Text Chat preferences
2013-01-08 13:48:18 -05:00
Drake Arconis
10c19731b3 Merge remote-tracking branch 'Aleric/master' 2013-01-08 13:11:43 -05:00
Lirusaito
820b4ea358 Optionally, remove chatbar from local chat floater.
FloaterChatBarlessRect keeps the size of this separate, for those who want to switch by mood.
ShowLocalChatFloaterBar toggles this.
Show local chat bar in floater entry added to Adv. Chat prefs.
floater_chat_history_barless.xml added for this.
2013-01-08 12:16:51 -05:00
Aleric Inglewood
d8485350e7 Address clang warnings.
* Split off AIThreadSafeBitsPOD, because offsetof may only be used on POD types.
* Added ASSERT_ONLY and ASSERT_ONLY_COMMA
* Removed a few unused class members
* Fixed a bug in AIHTTPReceivedHeaders::equal that more or less only
  compared the length of the headers before :/
2013-01-08 17:50:09 +01:00
Lirusaito
b4b6186f54 Re: 3ea353bef3, fix minimize case to minimize and not steal focus. Also apply to group chats. 2013-01-08 08:43:55 -05:00
Drake Arconis
8889f6b837 Merge remote-tracking branch 'Lirusaito/master' 2013-01-08 06:38:08 -05:00
Lirusaito
3ea353bef3 Change default behavior of separated non-local chats mode to open minimized. 2013-01-08 06:33:07 -05:00
Drake Arconis
ca746f3b47 Merge remote-tracking branch 'Lirusaito/master' into altcompilers 2013-01-08 06:17:47 -05:00
Drake Arconis
9f7e81cec2 Alt Compiler fixes 2013-01-08 06:17:39 -05:00
Drake Arconis
bc3ad59dd5 Revert "Fixed a build issue in clang"
This reverts commit 6d379448be.
2013-01-08 06:16:28 -05:00
Drake Arconis
979adcd6e2 Minor fix to OSX 2013-01-07 22:11:19 -05:00
Shyotl
c5c1294d7d Finished LLGLTexture. Migrated opengl related code from llui.h/cpp to llrender2dutils.h/cpp. Moved lluiimage to llrender library. 2013-01-07 20:12:14 -06:00
Drake Arconis
0ce91ce5ed Build fixes 2013-01-07 18:44:51 -05:00
Lirusaito
67e4518132 Scroll to the object's texture if the user has a copy in their inventory. EXT-5403? Fixes part of Issue 501. 2013-01-07 18:32:54 -05:00
Drake Arconis
b76cb36c0f Merge remote-tracking branch 'Lirusaito/meshupload' into meshupload 2013-01-07 18:31:02 -05:00
Lirusaito
0636f0049a Rectify the problem in which profile images would be below the window border when first opened. 2013-01-07 18:20:02 -05:00
Drake Arconis
8346ce4cd8 Merge remote-tracking branch 'Aleric/meshupload' into meshupload 2013-01-07 18:10:38 -05:00
Drake Arconis
e565341e90 Merge branch 'master' into meshupload 2013-01-07 18:09:56 -05:00
Lirusaito
1b2c0ba02b v-d llviewermenufile.cpp functions (and order) for meshupload, decide when Upload Mesh entry should be enabled. 2013-01-07 18:08:42 -05:00
Aleric Inglewood
cbbe678f9e Remove FloaterModelPreviewRect 2013-01-07 23:31:40 +01:00
Aleric Inglewood
5efcc7186e Fixed mesh file picker and then some 2013-01-07 23:12:09 +01:00
Aleric Inglewood
d188ecae70 Fix crash because of missing debug setting 2013-01-07 23:01:10 +01:00
Shyotl
d71210e942 Trivial changes, mostly to clean up diff noise. Majority of changes are comment corrections or licenseinfo updates. (does not include newview directory) 2013-01-07 14:44:54 -06:00
Aleric Inglewood
9c20139ae8 Fix memory leak. This auto deletes the file picker, the old code did't. 2013-01-07 20:21:45 +01:00
Aleric Inglewood
da19e770a2 Renamed FFLOAD/SAVE_LSL to FFLOAD/SAVE_SCRIPT 2013-01-07 20:11:18 +01:00
Aleric Inglewood
5e7acb9f3a Add support for ".dae" (and others) to filepicker load filter.
* Brought llfilepicker.{cpp,h} up to speed with V3 by adding
  FFLOAD_MODEL, FFLOAD_COLLADA, FFLOAD_SCRIPT, FFLOAD_DICTIONARY
  However, note that we used FFLOAD_LSL, so I renamed their
  FFLOAD_SCRIPT to FFLOAD_LSL and kept our way of filtering.
* Fixed the filter token that is sent to the plugin for
  collada (from "dae" to "collada").
2013-01-07 20:00:54 +01:00
Drake Arconis
6d379448be Fixed a build issue in clang 2013-01-07 11:59:25 -05:00
Aleric Inglewood
79763aacf7 Merge branch 'master' into meshupload 2013-01-07 17:59:21 +01:00
Aleric Inglewood
4b592f7507 Merge remote-tracking branch 'singu/master' 2013-01-07 17:58:53 +01:00
Aleric Inglewood
e7ef9eff4f Merge branch 'master' into meshupload 2013-01-07 17:50:03 +01:00
Drake Arconis
9e2049c463 Added darwin and windows libraries and added copying of collada and glod 2013-01-06 21:58:26 -05:00
Drake Arconis
8aa7113480 Merge branch 'master' into meshupload 2013-01-06 21:46:34 -05:00
Drake Arconis
b1b9172f28 Merge branch 'meshupload' of https://bitbucket.org/LightDrake/singularityviewer-test into meshupload 2013-01-06 21:21:02 -05:00
Drake Arconis
3a691e0c23 Fixed linking 2013-01-06 21:20:41 -05:00
Aleric Inglewood
a9a308e5e9 Never freeze again.
Put snapshot related floaters always on top of the full screen preview.
Make having multiple running uploads more robust.
Fix infinite recursion when clicking on the bottom 'Snapshot' button
under certain conditions.
Unfreeze time more robust; unfreeze time out of precaution when
starting an upload (if 'Keep open' not checked).
Fixed a bug that caused all callbacks for successful feed uploads to be
ignored.
2013-01-06 23:40:53 +01:00
Lirusaito
e7f4fc7107 Added colors for mesh upload MeshImportTableNormalColor and MeshImportTableHighlightColor to default/colors_base.xml 2013-01-06 12:46:56 -05:00
Lirusaito
ac60260da2 Update LLFloaterModelPreview and make it compile~
Collada include_directories and llfloatermodelpreview.*s added to CMakeLists.txt
Update to v-d, compile with AIFilePicker, comment spelling fixes.
Upload Mesh... entry added to File menu.
Updated AIFilePicker to have FFLOAD_COLLADA with an mFilter of "dae"
And, finally, add floater_model_preview.xml~
2013-01-06 11:56:33 -05:00
Drake Arconis
364cf1ec73 Bug fix from v3 2013-01-06 09:47:02 -05:00
Drake Arconis
297c386b16 Fixed glod 2013-01-06 07:30:42 -05:00
Drake Arconis
152a3685fa Merge branch 'master' into meshupload 2013-01-06 04:03:49 -05:00
Drake Arconis
bb7464a975 Merge branch 'master' of https://bitbucket.org/LightDrake/singularityviewer-test 2013-01-06 04:03:14 -05:00
Drake Arconis
9c1237ca05 Initial work. 2013-01-06 03:59:38 -05:00
Siana Gearz
cd27184332 Take out buggy padding removal in OJ 2013-01-06 04:01:28 +01:00
Drake Arconis
cadf654fae Merge branch 'master' of github.com:singularity-viewer/SingularityViewer 2013-01-05 20:50:49 -05:00
Siana Gearz
d5892bbb32 My preliminary thoughts on OpenJPEG 2013-01-06 02:38:12 +01:00
Siana Gearz
20ae72e5fa CMake needs proper quoting 2013-01-05 23:25:47 +01:00
Siana Gearz
7fc4348f64 Fix build deselect 2013-01-05 22:14:10 +01:00
Lirusaito
5ec116021a Feature request: Alt-R for Region/Estate floater 2013-01-05 01:45:55 -05:00
Lirusaito
a992333744 Zi Ree's Debug Setting Floater awesomeness (Search!!)
Made to work with Singularity, and also be a bit better..
Alphabetizes includes.
Switches settings combobox to a scrolllist, and Boolean combobox to a radiogroup.
Makes floater resizable, aligns a lot of the UI, and prepares it all for proper resize behavior.
Adds Copy button for copying the name of the debug setting.
Yay, verbosity! Also adds FloaterDebugSettingsRect to keep track of the floater's size.

Also somehow the getInstance line snuck out of last commit... tossed it in here.
2013-01-05 01:43:17 -05:00
Siana Gearz
fefe0df922 Merge branch 'master' of git://github.com/AlericInglewood/SingularityViewer 2013-01-03 23:37:00 +01:00
Siana Gearz
509bdcb891 Merge branch 'master' of git://github.com/Lirusaito/SingularityViewer 2013-01-03 23:36:55 +01:00
Aleric Inglewood
2fbd53807c Do not use LLCachedControl as global variables. 2013-01-03 23:25:18 +01:00
Lirusaito
9498375e75 Update LLFloaterSettingsDebug to match up with v-d.
Adds boost::bind and makes the floater a singleton.
2013-01-03 17:20:57 -05:00
Aleric Inglewood
639b264d2d Do not crash upon corrupted HTTP header.
This addresses the reported assertion by luis thibodeaux.
2013-01-03 21:06:20 +01:00
Lirusaito
c3829485e4 Fixed LLCompileQueue messages via update to v-d in parts. Script resets now output properly~ 2013-01-03 14:08:39 -05:00
Lirusaito
88de1b28a2 Add MoyMiniMapCustomColor swatch to Vanity Preferences.
Fixed spacing of MoyMiniMapCustomColor in settings_ascent_coa.xml and removed it from settings_per_account.xml

TODO: Make MoyMiniMapCustomColor more flexible.
-Added ColorCustomChat checkbox, pref code, and setting commented out.
2013-01-03 13:59:14 -05:00
Siana Gearz
17e0c79fe7 Build fix Linux 2013-01-03 03:03:06 +01:00
Siana Gearz
ddef80d2cf Revert "Attempt to fix frame timer on broken mainboards"
This reverts commit 5eb99b7d2f.
2013-01-03 03:02:15 +01:00
Siana Gearz
1872337f5f Merge branch 'master' of git://github.com/AlericInglewood/SingularityViewer 2013-01-03 02:17:20 +01:00
Siana Gearz
6e219f0a4e Merge branch 'master' of https://github.com/Shyotl/SingularityViewer 2013-01-03 02:15:51 +01:00
Shyotl
a408c2211b Workaround for targetomega'd objects turning jittery when zoomed in on. 2013-01-02 18:42:26 -06:00
Siana Gearz
8b2dcb6cb0 We're supposed to use HTTP bake fetch now 2013-01-03 00:10:56 +01:00
Aleric Inglewood
b0fe12f597 Snapshot Freeze Time: add Langolier tag for new (invisible) avatars.
If an avatar TP's in while you are in Freeze Time mode, they now have a
visible tag with the tag 'Langolier' in it. After exiting Freeze Time
mode they become visible. Before they would stay invisible.
2013-01-03 00:02:28 +01:00
Siana Gearz
9a1cc8b9a8 Translation cleanup script fix 2013-01-02 23:47:05 +01:00
Siana Gearz
cce4d50378 Merge branch 'master' of git://github.com/Lirusaito/SingularityViewer 2013-01-02 23:00:46 +01:00
Siana Gearz
e732e62b39 Tiny cleanup 2013-01-02 22:56:04 +01:00
Lirusaito
728056acdb Add support for Aurora's extended land layer codes to llvlmanager.cpp 2013-01-01 20:15:21 -05:00
Lirusaito
b85d282dfb WindLightRefresh added for compliance with Aurora's windlight event system. 2013-01-01 18:09:45 -05:00
Lirusaito
194902798b HippoGridManager and HippoLimits updated with Aurora bits from Voodoo.
Adds isAurora() to HippoGridManager
Adds setAuroraLimits and Aurora case to setLimits() in HippoLimits
2013-01-01 18:04:39 -05:00
Aleric Inglewood
cc276ff232 More snapshot UI tweaks. 2013-01-01 22:34:22 +01:00
Aleric Inglewood
5538fe27e5 Snapshot improvements.
* Warn when it was not possible to make a snapshot because the difference
between the aspect of the required target size and the required target
aspect itself is too large.
* Reset Feed and Postcard Aspect to Default when making a new snapshot.
* Fixed a rounding error that caused one-pixel size error.
2013-01-01 21:30:13 +01:00
Lirusaito
c0ba3e95f3 Ability to change default behavior of Chats being torn off so that all chats appear minimized upon opening, as well, regardless of conditions.
Adds debug setting OtherChatsTornOffAndMinimized
Not added to ui xml because the default behavior is likely fine.
2012-12-31 19:06:23 -05:00
Lirusaito
4ec6f853d8 In-Group feature request: Ability to have chats torn off, by default.
Best viewed without space changes... or maybe it doesn't matter any more.
Debug setting OtherChatsTornOff added.
Added Open new IMs in separate floaters checkbox to  Adv. Chat.
Moved Show group name in chat to the right column on top of Adv. Chat panel.

So how's this work?
Two ways.. 1. The user opens a chat; 2. A chat is started from another party to the user.
In 1, we open the chat in a separate floater and focus the floater.
In 2, we check if there is a floater currently in focus before opening the chat
if so, we minimize the floater, setting focus back to whatever floater the user was focused on;
if not, we leave the new chat floater open and focused.

Note that this will NOT alter the default behavior at all, we can't be having that.
2012-12-31 17:06:30 -05:00
Aleric Inglewood
6dcda3595e Add recovery for randomly closed socket desciptors.
Although it should never happen that a file descriptor is suddenly
closed, it appeared that this happens on linux 64bit when using
FMODex... Not really sure how useful this is, but at least now the
viewer just continues to work, as if -say- the socket was closed
remotely. Before the curl thread would go into a tight loop that it
wouldn't recover from until the watchdog thread terminated the viewer.
2012-12-31 19:24:37 +01:00
Aleric Inglewood
c4a9eb9e44 Work around for 'version `OPENSSL_1.0.0' not found'
When linking against the prebuilt libcrypto.so.1.0.0 and
libssl.so.1.0.0 there is a problem running the viewer in
gdb (on debian) because gdb links with libpython2.7.so
which needs a newer openssl on my system (OPENSSL_1.0.1).

The patch allows to work around this problem by defining
-DUSE_SYSTEM_OPENSSL:BOOL=ON when configuring, which then
causes the viewer to be compiled against the system libs.
(If you already installed the prebuilt, you have to manually
remove them with script/install.py --uninstall openSSL).

The prebuilt libcurl expects a function SSLv2_client_method
however, which is not present in my openssl system libs.
A stub was added which is possible because the function
in question isn't used anyway.
2012-12-31 16:15:36 +01:00
Lirusaito
ba57bb1396 In-group feature request: Allow coloring chat of special people (Friends, Estate Owner, Lindens, Muted Residents)
Added ColorFriendChat, ColorEstateOwnerChat, ColorLindenChat, and ColorMutedChat.
Did some spaces to tabs work, view without space changes.
Add checkboxes beneath corresponding color swatches and "Use colors for chat:" text to Vanity.
Fix Ascent*Color Comments strings.

Also fix the issue where clicking ones name in a group chat would result in it opening a random profile.
2012-12-31 06:24:35 -05:00
Lirusaito
f94f4a1191 Satisfy Issue 100: When timestamp it set to include seconds, the seconds do not get included with IM & chat logs.
Best viewed without space changes.
SecondsInLog debug setting added.
Seconds in Log timestamps checkbox added to Adv. Chat prefs.
2012-12-31 04:54:59 -05:00
Lirusaito
469f76e690 Added "Request New Feature..." to Help->Bug Reporting menu. 2012-12-30 16:21:01 -05:00
Lirusaito
0098466704 Fix for WordFromTheWise's missing lsl strings issue. 2012-12-30 16:09:08 -05:00
Lirusaito
48ddfd25d4 Skins request! Black Red, Black Light Blue, and Black Dark! 2012-12-30 16:07:07 -05:00
Aleric Inglewood
2f3841d7e6 Update of print_diagnostics.
CURLE_COULDNT_CONNECT only happens when we actually get
an error (ie, 'connection refused'). If we time out while the connect
attempt is still running then we get CURLE_OPERATION_TIMEDOUT.
2012-12-30 21:11:10 +01:00
Lirusaito
1cde242f06 Merge branch 'master' of https://github.com/DamianZhaoying/SingularityViewer 2012-12-30 14:05:35 -05:00
Damian Zhaoying
a0b227fdd8 fixes and UI translations tweeks to fit in spanish language 2012-12-30 15:38:11 -03:00
Aleric Inglewood
36a79d7cbe Merge remote-tracking branch 'shyotl/master' 2012-12-30 02:57:11 +01:00
Lirusaito
2c491bc905 Break out LLMakeOutfitDialog.
Added "Make Outfit..." to Edit menu and Create->"New Outfit" to inventory floater menu.
Cleaned up LLMakeOutfitDialog, using boost::bind and less waste.
Moved onMakeOutfitCommit() to LLMakeOutfitDialog as makeOutfit()
Also changes LLFloaterCustomize's callbacks to use boost::bind
Give new outfit dialog a title instead of a heading.

Small fix to mistake with AnnounceSnapshots xmlstuffs.
2012-12-29 19:24:17 -05:00
Aleric Inglewood
a25c405eae Fix assert after failed login.
reset_login(), among others, sets the state back to STATE_LOGIN_SHOW,
which then causes gViewerWindow->initWorldUI() to be called, which
is the (only) function that calls
LLMenuOptionPathfindingRebakeNavmesh::initialize.
In other words, it's perfectly normal to enter that function
a second time and the assert is erroneous.
2012-12-29 18:08:46 +01:00
Aleric Inglewood
e666c60e7d Merge remote-tracking branch 'singu/master' 2012-12-29 17:05:15 +01:00
Aleric Inglewood
6a45e68c73 Merge branch 'master' into llwebprofile 2012-12-29 17:03:46 +01:00
Aleric Inglewood
59b313352b Third time I have to fix this... weird 2012-12-29 17:03:16 +01:00
Aleric Inglewood
9e04f9ba80 Enable/disable upload/send button correctly.
Passes an 'index' magic number to the upload/save functions which
pass that back to the *Done callbacks, so we know if the *raw*
snapshot is still up to date when the upload succeeds or fails.
2012-12-29 16:51:29 +01:00
Lirusaito
cf5838505f In-world feature request: Announce in chat when someone has taken a snapshot.
AnnounceSnapshots debug setting.
"Announce when someone takes a snapshot" added to Vanity Main Preferences.
took_a_snapshot translatable string added to strings.xml

Also in this commit:
Turned PlayTypingSound check into LLCachedControl.
In preparation for the crippling of all old viewers, the Vanity Main tab shall henceforth only be called Main, not Main  (General)
This change has been made in the code comments and the UI itself.
2012-12-29 07:58:06 -05:00
Lirusaito
23469c00de Satisfy Issue 411: Song list in local chat - not a floater
AnnounceStreamMetadata debug setting.
"Announce music stream's metadata in local chat when tuned in" checkbox added to vanity main preferences.
Made the words Title and Artist translatable, as well as the "Now playing" string.
2012-12-29 07:45:05 -05:00
Siana Gearz
66083d6531 Removing leftover dead code 2012-12-28 21:07:19 +01:00
Aleric Inglewood
1c3748e923 Merge remote-tracking branch 'lirusaito/llwebprofile' into llwebprofile 2012-12-28 17:04:29 +01:00
Aleric Inglewood
88bf01fe6f Avoid crashing at exit by joining the curl thread. 2012-12-28 16:59:04 +01:00
Siana Gearz
a969a8f99c UseNewTargetOmegaCode loosely ported from Henri 2012-12-28 16:46:06 +01:00
Aleric Inglewood
ef0e34a278 Do not attach cam to avatar in Freeze Time mode.
We do, and the avatar moves then the cam jumps
away from the frozen avatar to where it really is.

Unfortunately, it's still not possible to attach
the cam to moving objects with this patch.
Also, scripted changes to objects are still visible,
like changes in local lights of texture full brightness.
2012-12-28 16:40:08 +01:00
Lirusaito
50eb45991d "attachments and wearables", not "clothing and wearables" 2012-12-28 02:13:50 -05:00
Lirusaito
ffa405dad9 Comment cleanup. 2012-12-28 01:25:11 -05:00
Lirusaito
1f966eb6c3 Merge branch 'master' of git://github.com/Shyotl/SingularityViewer 2012-12-28 01:21:28 -05:00
Lirusaito
b503540075 Always remember to save after making a change. (Location works now) 2012-12-28 00:33:08 -05:00
Lirusaito
2be305d39e Improvements!
Fix CMakeLists being out of order.
Add setting SnapshotFeedAddLocation to keep track of user's preference whether or not to include location in uploads to profile feed.
Clean up LLFloaterFeed to take only what it needs, also gave it a boost~
Remove saveFeed() from LLFloaterSnapshot, removing the dependency on LLWebProfile.
Compile fixes for LLFloaterSnapshot.
Prettied up the upload to feed floater.

TODO: Does Location even work? I can't get it to appear, never seems to get used right in v-d either.
2012-12-28 00:14:54 -05:00
Shyotl
f6ee966e17 Clean up LLAvatarListEntry creation/destruction and resolve LLAvatarPropertiesProcessor retaining deleted observers. 2012-12-27 21:59:59 -06:00
Drake Arconis
246315c723 This is the Cupcake Commit. Cupcakes. Also may fix linux fmodex64. 2012-12-27 15:15:27 -05:00
Aleric Inglewood
be8f16a8e6 Disable upload/send button immediately.
Immediately disables button and reenables it
again when upload/save was a failure.
The callback is now ignored if the snapshot
was refresh in the meantime.
2012-12-27 19:02:58 +01:00
Aleric Inglewood
32614d3539 Compile bug fix 2012-12-27 17:38:28 +01:00
Aleric Inglewood
aab978c7ea WIP: floater_snapshot_feed.xml and code.
This is just a skeleton, roughly copied from the Postcoard
code, which is very similar. Nothing in indra/newview/llfloaterfeed.cpp
has been changed yet, apart from a few deletions (to make it compile)
and the literal replacement of "Postcard" with "Feed".
indra/newview/llfloatersnapshot.cpp was updated however to
open the new floater when one tries to upload a snapshot to the feed.
It is still needed to make a callback to saveFeed(), or rather to
move that function to the saveFeed that is in llfloatersnapshot.cpp.
2012-12-27 17:13:47 +01:00
Lirusaito
d4b48fae6f Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer 2012-12-26 15:50:38 -05:00
Lirusaito
0433bd8560 Gemini young age color should look more natural for Gemini. 2012-12-26 13:09:05 -05:00
Shyotl
71eb0fedd9 Merge branch 'master' of git://github.com/lkalif/SingularityViewer.git 2012-12-25 06:17:42 -06:00
Latif Khalifa
9056ae72d3 Point library downloads to bitbucket since github is depreciating binary downloads 2012-12-25 11:57:59 +01:00
Latif Khalifa
430a5359ac Merge remote-tracking branch 'upstream/master' 2012-12-25 11:47:32 +01:00
Inusaito Sayori
5468bc8447 Fix compile warning/error in aihttptimeoutpolicy.cpp 2012-12-25 04:53:16 -05:00
Inusaito Sayori
059005a4a7 Fly after teleport, off by default. 2012-12-25 04:47:07 -05:00
Shyotl
3ca39ab3f1 Client-side maturity handling when teleporting. Adds new notification that asks if you want to change maturity settings with a single click and automatically re-fire the teleport request. 2012-12-25 02:30:51 -06:00
Shyotl
f8a6e2e19f Moved region rebake button to 'Tools' menu 2012-12-25 02:27:15 -06:00
Shyotl
1f5c2095a5 Merge branch 'master' of https://github.com/Lirusaito/SingularityViewer.git 2012-12-24 18:26:52 -06:00
Shyotl
afaaba6b3c OSX was choking on transformfeedback shaders. Make failure to load such shaders non-critical to the shader loading process. Also clean up glColorMask state properly in wlsky. 2012-12-24 17:56:32 -06:00
Aleric Inglewood
c85f976ed6 Fix outbox notifications. 2012-12-24 22:08:44 +01:00
Aleric Inglewood
b22832ba54 Fix cookie handling.
Cookies are now collected during redirects, one the last cookie
of a given name is kept. Cookies are then set by looking for
the right cookie name (instead of what viewer 3 does: just
use the last cookie that was set).

This fixes the merchant outbox.
2012-12-24 19:58:54 +01:00
Inusaito Sayori
977f17a893 Add feature to Continue flying upon standing, if the user was flying when they sat down.
A couple users said this could be handy.
Useful for birds, fairies, and otherwise flying critters.
2012-12-24 05:24:57 -05:00
Inusaito Sayori
60621a300c Satisfy in-world feature request: Avatar Count on Radar. 2012-12-24 03:09:09 -05:00
Aleric Inglewood
fac3fc67b6 Add filtering for curl debug output.
Add CURLTR debug channel for libcurl API calls,
and use CURLIO only for libcurl debug output.
Note: need to set gDebugCurlTerse to true for
filtering to take effect, then pass 'debug_on'
to the LLHttpClient methods that require debugging.
2012-12-24 02:54:36 +01:00
Inusaito Sayori
8e3da75c3c Missed a spot for 487. 2012-12-23 15:10:53 -05:00
Inusaito Sayori
c9dc2eaad4 Satisfy Issue 487: Walking Backwards, Turning Around
TurnAroundWhenWalkingBackwards added.
Turn Around When Walking Backwards added to Vanity Main Preferences.
Code borrowed, in part, from Firestorm.
2012-12-23 00:26:49 -05:00
Aleric Inglewood
8095d6c48c Large snapshot update (part 3) 2012-12-22 19:07:08 +01:00
Inusaito Sayori
6f2e192947 Complete Issue 545: OSSL Updates
Updates keywords.ini, lsl_functions_os.xml, and en-us/strings.xml
Thanks WhiteStar, ThiteStar.
2012-12-22 12:25:46 -05:00
Inusaito Sayori
0b9d8c7b47 Satisfy Issue 512: Increase RenderVolume LOD Factor Threshold to 4.000
Phoenix users are used to this.
The setting clamps to the max here, so it must be 4.
2012-12-22 05:29:21 -05:00
Inusaito Sayori
1ecea32933 An hour is not a circle. 2012-12-22 02:07:36 -05:00
Inusaito Sayori
ceae4470f5 Fix a windows compiley thing. 2012-12-21 05:49:14 -05:00
Lirusaito
237455f4b7 Use boost::date_time for displaying avatar age.
llpanelavatar change may be better viewed without space changes.
2012-12-20 23:34:05 -05:00
Lirusaito
3d25f8ee79 Merge branch 'master' of https://github.com/DamianZhaoying/SingularityViewer 2012-12-20 09:25:33 -05:00
Lirusaito
86572462e6 Merge branch 'master' of git://github.com/Shyotl/SingularityViewer 2012-12-20 09:25:21 -05:00
Lirusaito
245eaa1fd9 Satisfy radar issues: 51(Avatar Age), 382(Time duration), 245(Hide columns on command)
Overall:
Extras tab added to radar.
Activities given tool_tip strings, TODO: Get icon entries to have tool_tips.
Added tab_min_width="0" to tab container so tabs take up only as much space as necessary.

Issue 51:
RadarAlertAge, AvatarAgeAlertDays debugs added.
RadarTextYoung color added to colors_base and gemini.
UI bits added to radar.
ALERT_TYPE_AGE, LIST_AGE, and boost::lexical_cast added.
LLAvatarListEntry is now derived from LLAvatarPropertiesObserver for processProperties and all that fun stuff. Also has mAgeAlert and mAge.
processProperties is basically copied directly from LLAvatarPanel, it can probably be bettered.

Issue 382:
mTime, getTime(), LIST_TIME
Time column.

Issue 245:
Hide columns text and checkboxes added to UI.
assessColumns() now used to determine which columns to show. Also once used during postBuild()
col_helper() function added to help decide to hide or resize a column based on given params.
checkboxes all use assessColumns as callback.
RadarColumn* debug settings added.

If you read this all, that's a sign the 'pocalypse is coming.
2012-12-20 08:58:18 -05:00
Damian Zhaoying
e7b712660e update spanish translations 2012-12-19 23:29:36 -03:00
Inusaito Sayori
c35f762826 Satisfy Issue 476: Option to mute gesture sounds
Enable Gesture Sounds checkbox added to Adv. Chat->Spam tab.
2012-12-19 03:35:06 -05:00
Inusaito Sayori
66386d6eec Fix an issue introduced in V2MultiWear in which double-clicking or hitting an enter on a worn wearable would rewear it, not detach it. 2012-12-17 19:32:40 -05:00
Inusaito Sayori
9e8dafc4ca Satisfy Issue 167: Ability to set global "add instead of wear" option in prefs
Adds debug setting LiruAddNotReplace.
Adds "Add clothing and wearables instead of replacing them" to Main (General) tab of Vanity Preferences.
2012-12-17 17:17:12 -05:00
Inusaito Sayori
36a698fee4 Satisfy Issue 271: Fly after teleport feature.
Add debug setting LiruFlyAfterTeleports
Add Always fly after Teleports to General tab of System preferences.
(Also, fixed tabs where spaces should be in settings.xml)
2012-12-16 20:50:40 -05:00
Aleric Inglewood
aab764a6e5 Don't crash when user forgets last name on non-SL grids. 2012-12-16 23:39:58 +01:00
Aleric Inglewood
11f30bc28d Removed gFullName which isn't used anywhere 2012-12-16 23:17:10 +01:00
Inusaito Sayori
46b5595c3f Don't leave Group Copy check enabled unless we have trans and copy perms.
Also some code consistency chages that won't change anything.
2012-12-16 15:32:06 -05:00
Inusaito Sayori
c380f1f399 Don't show Paste As Link when Paste As Copy is shown enabled because it'll just be disabled in these cases. 2012-12-16 15:31:53 -05:00
Aleric Inglewood
a9963bcdb3 In FreezeTime mode, keep avatars that TP away.
If an avatar TP's away (or quits), he will not
disappear anymore from a frozen scene. Unfreezing
makes him disappear of course (and clean up).

Known bug: if during Freeze Time mode someone
TPs away and then back, then he becomes a cloud
after Freeze Time is ended, which can only be
reset by another teleport (or relog) from either
the cloud or the one seeing him as cloud.
I decided not to fix this, cause there are things
with a higher priority and this - if it happens
at all - is rare and easy to recognize and work
around.
2012-12-16 00:13:06 +01:00
Aleric Inglewood
e0c0da7dff In Freeze Time re-show fullscreen preview when clicking thumbnail. 2012-12-15 02:20:53 +01:00
Aleric Inglewood
cfa8df0575 Merge branch 'master' into llwebprofile 2012-12-14 20:43:17 +01:00
Aleric Inglewood
c34f2941aa Merge remote-tracking branch 'github/master' 2012-12-14 20:41:18 +01:00
Aleric Inglewood
555b397067 Install vivox runtime also on standalone when linux64 2012-12-14 20:40:27 +01:00
Aleric Inglewood
65ce7dabe3 Merge remote-tracking branch 'github/master' 2012-12-14 16:42:27 +01:00
Aleric Inglewood
4d7d3ea937 Compile fix for non-standalone with DEBUG_CURLIO
Oops, that option doesn't exist in the prebuilt curl version.
2012-12-14 16:40:03 +01:00
Aleric Inglewood
15b6593143 Large snapshot update (part 2) 2012-12-14 02:31:08 +01:00
Aleric Inglewood
4bb3ed0d85 Login crash bug fix.
XMLRPCResponder constructor was missing.
This fixes the following crash signature:

VIEWER      : 2012-12-12T14:25:13Z INFO("AppInit"): setStartupState: Startup state changing from STATE_LOGIN_NO_DATA_YET to STATE_LOGIN_DOWNLOADING
VIEWER      : 2012-12-12T14:25:14Z INFO("AppInit"): transferRate: Buffer size:   1308 B
VIEWER      : 2012-12-12T14:25:14Z INFO("AppInit"): transferRate: Transfer rate: 11 kb/s

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff33df7f5 in XMLRPC_RequestGetData () from /usr/lib/x86_64-linux-gnu/libxmlrpc-epi.so.0
(gdb) bt

Reason was that if the server replied with some error code then
mResponse was undefined.

I also added code to retry three times in that case;
the http status code that I get was 503, which really
mean "Service *temporarily* unavailable", so a retry
is in order.
2012-12-12 16:27:32 +01:00
Aleric Inglewood
d8bc84adb1 Snapshot fixes and improvements.
* Allow to pass -1 to LLImageBase::reallocateData too (default parameter),
  causing it to allocate what is necessary for the size set (same
  behavior as allocateData).
* Speed up LLImageRaw::scale with factor 2 or 3 by copying the data less
  often and calling LLImageBase::reallocateData instead of destroying
  and recreating always.
* Fix gl_rect_2d to not decrement top and right with one pixel.
* Remove the vague "Constrain Proportions" checkbox and replace it with
  a new combo box and spinner to explicitly set the target aspect ratio,
  allowing to set it also to something different than either the window
  aspect ratio (ie, 1.6) or the target image dimension (1.0 for textures)
  which was totally lacking when, for example, uploading a profile image
  (which needs to be 4:3). This also allows to show snapshots on prims
  of arbitrary aspects.
2012-12-04 00:45:01 +01:00
Drake Arconis
5e71d9578f A bit of cleanup in preperation for VS2012 2012-11-30 11:17:10 -05:00
Aleric Inglewood
e788ee5faf Merge branch 'master' into llwebprofile 2012-11-28 18:50:31 +01:00
Aleric Inglewood
de52eebe7a Allow setting a custom size when uploading a texture. 2012-11-26 23:21:34 +01:00
Aleric Inglewood
d7069a2a66 Fix cancelling "Save" while "Keep open after save" is unchecked.
This causes a failure to save local file, or when clicking
Cancel in the file chooser, to keep the image and keep the
snapshot floater open so a retry to save the image can be
attempted.
2012-11-26 20:41:25 +01:00
Aleric Inglewood
7faa19b297 Large snapshot update (part 1)
This commit concentrates on remembering what parameters
where used for the last snapshot (the actual source, not
the formatted one), thus - the parameters passed to
rawSnapshot() - and then shows this snapshot as if it
was just made whenever the UI parameter selection matches.
The result is that the user can make a snapshot, save
it (for example) to their harddisk and then change the
destination and upload the same thing as snapshot.
The code tries hard to make this possible by automatically
adjusting the UI parameters to match every time the destination
is changed PROVIDED it was already saved or uploaded before.
If a snapshot wasn't saved and one changes destination
then this currently doesn't happen (by you could manually
make the parameters match, and still upload it). Also, if
the resolution is changed for a particular destination then
it won't automatically adjust it again.

Obviously, snapshots are no longer refreshed when changing
destination etc. You have to explicitly click "Refresh
Snapshot" before the last one is deleted / replaced.

The Debug Setting variables reflect the (last) manual choices
in most cases (set in the onCommit functions). If such a choice
is not allowed for a different destination then the UI is
changed to reflect the current behavior and the checkbox is
disabled so the user can't change it anymore. Then, if they
change destination back - the Debug Setting variable is used
to remember their last preference. A new Debug Setting has
been added for this purpose: SnapshotLayerType (colors or depth).

The old mSnapshotUpToDate has been removed and replaced with
mShowFreezeFrameSnapshot. The old getSnapshotUpToDate() now
returns something else (than mShowFreezeFrameSnapshot), namely
whether or not the current raw snapshot was taken with the same
parameters as are currently set in the UI.

The unused functions getImageAspect() and getAspect() were
removed.

mCurImageIndex has been deleted. Index 0 now means "the last
snapshot" and index 1 is temporarily used for the Falling Away
animation.

mDataSize was renamed to mFormattedDataSize.

The size spinner arrows are now disabled too whenever the spinner
edit field is disabled.

A bug in Freeze Time was fixed, where avatars would still
rotate around their axis in place (and without that their
attachments moved!)

Pressing ESC would return keyboard control to "walking"
for the own avatar with the above as result for the own
avatar. We now intercept ESC and use it (in Freeze Time mode)
to return to the cammable preview when a 2D preview was
being shown.
2012-11-26 18:12:41 +01:00
Aleric Inglewood
14c046108e Snapshot floater changes
* Added a radio button for "Post to my.secondlife.com feed"
* Moved the snapshot to the top of the floater.
* Increased the size of the snapshot to match the size used in V3
  (floater is only 4 pixels wider though).
* Disable the "Temporary upload" checkbox when the Destination isn't the
  inventory.
* Update the shown Upload Fee to L$ 0 if temporary is checked.
* Added a size chooser for the Feed destination, using exclusively
  preset sizes with an aspect ratio of 4:3.
* Added two new preset sizes: 1024x1024 for texture uploads, and
  1680x1050 for save to disk.
2012-11-20 22:27:48 +01:00
Aleric Inglewood
b5a8850d65 Fix deinitialization order fiasco. 2012-11-19 08:32:00 +01:00
Aleric Inglewood
3f51bb6e1d Clear the command queue after flushing statemachines
Flushing the state machines can cause remove commands to be added to the
command queue, so clearing it needs to be after.
2012-11-19 08:31:46 +01:00
1573 changed files with 35636 additions and 16638 deletions

View File

@@ -378,6 +378,14 @@
<boolean>true</boolean>
</map>
<key>WindLightRefresh</key>
<map>
<key>flavor</key>
<string>llsd</string>
<key>trusted-sender</key>
<boolean>true</boolean>
</map>
<key>ParcelVoiceInfo</key>
<map>
<key>flavor</key>
@@ -386,7 +394,6 @@
<boolean>true</boolean>
</map>
<key>ParcelNavigateMedia</key>
<map>
<key>flavor</key>
@@ -656,7 +663,7 @@
<boolean>false</boolean>
<key>RequestTextureDownload</key>
<boolean>false</boolean>
<boolean>true</boolean>
<key>EventQueueGet</key>
<boolean>false</boolean>
@@ -708,6 +715,9 @@
<key>FetchLib2</key>
<boolean>true</boolean>
<key>UploadBakedTexture</key>
<boolean>true</boolean>
</map>
<key>messageBans</key>

View File

@@ -30,7 +30,7 @@ include(BuildVersion)
include(UnixInstall)
set (DISABLE_FATAL_WARNINGS TRUE)
set (DISABLE_FATAL_WARNINGS CACHE BOOL TRUE)
if (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING
@@ -53,6 +53,9 @@ add_subdirectory(${LIBS_OPEN_PREFIX}llcharacter)
add_subdirectory(${LIBS_OPEN_PREFIX}llcommon)
add_subdirectory(${LIBS_OPEN_PREFIX}llimage)
add_subdirectory(${LIBS_OPEN_PREFIX}libopenjpeg)
add_subdirectory(${LIBS_OPEN_PREFIX}libhacd)
add_subdirectory(${LIBS_OPEN_PREFIX}libndhacd)
add_subdirectory(${LIBS_OPEN_PREFIX}libpathing)
add_subdirectory(${LIBS_OPEN_PREFIX}llimagej2coj)
add_subdirectory(${LIBS_OPEN_PREFIX}llinventory)
add_subdirectory(${LIBS_OPEN_PREFIX}llmath)

View File

@@ -19,6 +19,7 @@ include_directories(
set(aistatemachine_SOURCE_FILES
aistatemachine.cpp
aistatemachinethread.cpp
aitimer.cpp
)
@@ -26,6 +27,7 @@ set(aistatemachine_HEADER_FILES
CMakeLists.txt
aistatemachine.h
aistatemachinethread.h
aitimer.h
)

View File

@@ -176,7 +176,7 @@ void AIStateMachine::idle(state_type current_run_state)
// About thread safeness:
//
// The main thread initializes a statemachine and calls run, so a statemachine
// runs in the main thread. However, it is allowed that a state calls idle()
// runs in the main thread. However, it is allowed that a state calls idle(current_state)
// and then allows one or more other threads to call cont() upon some
// event (only once, of course, as idle() has to be called before cont()
// can be called again-- and a non-main thread is not allowed to call idle()).

View File

@@ -264,7 +264,7 @@ class AIStateMachine {
//! Halt the state machine until cont() is called (not thread-safe).
void idle(void);
//! Halt the state machine until cont() is called, provided it is still in 'cur_run_state'.
//! Halt the state machine until cont() is called, provided it is still in 'current_run_state'.
void idle(state_type current_run_state);
//! Temporarily halt the state machine.

View File

@@ -0,0 +1,197 @@
/**
* @file aistatemachinethread.cpp
* @brief Implementation of AIStateMachineThread
*
* 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.
*
* 23/01/2013
* Initial version, written by Aleric Inglewood @ SL
*/
#include "linden_common.h"
#include "aistatemachinethread.h"
class AIStateMachineThreadBase::Thread : public LLThread {
private:
LLPointer<AIThreadImpl> mImpl;
bool mNeedCleanup;
public:
Thread(AIThreadImpl* impl) :
#ifdef LL_DEBUG
LLThread(impl->getName()),
#else
LLThread("AIStateMachineThreadBase::Thread"),
#endif
mImpl(impl) { }
protected:
/*virtual*/ void run(void)
{
mNeedCleanup = mImpl->thread_done(mImpl->run());
}
/*virtual*/ void terminated(void)
{
mStatus = STOPPED;
if (mNeedCleanup)
{
// The state machine that started us has disappeared! Clean up ourselves.
// This is OK now because in our case nobody is watching us and having set
// the status to STOPPED didn't change anything really, although it will
// prevent LLThread::shutdown from blocking a whole minute and then calling
// apr_thread_exit to never return! Normally, the LLThread might be deleted
// immediately (by the main thread) after setting mStatus to STOPPED.
Thread::completed(this);
}
}
public:
// TODO: Implement a thread pool. For now, just create a new one every time.
static Thread* allocate(AIThreadImpl* impl) { return new Thread(impl); }
static void completed(Thread* threadp) { delete threadp; }
};
// MAIN THREAD
char const* AIStateMachineThreadBase::state_str_impl(state_type run_state) const
{
switch(run_state)
{
AI_CASE_RETURN(start_thread);
AI_CASE_RETURN(wait_stopped);
}
return "UNKNOWN STATE";
}
void AIStateMachineThreadBase::initialize_impl(void)
{
mThread = NULL;
mAbort = false;
set_state(start_thread);
}
void AIStateMachineThreadBase::multiplex_impl(void)
{
switch(mRunState)
{
case start_thread:
mThread = Thread::allocate(mImpl);
// Set next state.
set_state(wait_stopped);
idle(wait_stopped); // Wait till the thread returns.
mThread->start();
break;
case wait_stopped:
if (!mThread->isStopped())
break;
// We're done!
//
// We can only get here when AIThreadImpl::done called cont(), (very
// shortly after which it will be STOPPED), which means we need to do
// the clean up of the thread.
// Also, the thread has really stopped now, so it's safe to delete it.
//
// Clean up the thread.
Thread::completed(mThread);
mThread = NULL; // Stop abort_impl() from doing anything.
if (mAbort)
abort();
else
finish();
break;
}
}
void AIStateMachineThreadBase::abort_impl(void)
{
if (mThread)
{
// If this AIStateMachineThreadBase still exists then the first base class of
// AIStateMachineThread<THREAD_IMPL>, LLPointer<THREAD_IMPL>, also still exists
// and therefore mImpl is valid.
bool need_cleanup = mImpl->state_machine_done(mThread); // Signal the fact that we aborted.
if (need_cleanup)
{
// This is an unlikely race condition. We have been aborted by our parent,
// but at the same time the thread finished!
// We can only get here when AIThreadImpl::thread_done already returned
// (VERY shortly after the thread will stop (if not already)).
// Just go into a tight loop while waiting for that, when it is safe
// to clean up the thread.
while (!mThread->isStopped())
{
mThread->yield();
}
Thread::completed(mThread);
}
else
{
// The thread is still happily running (and will clean up itself).
// Lets make sure we're not flooded with this situation.
llwarns << "Thread state machine aborted while the thread is still running. That is a waste of CPU and should be avoided." << llendl;
}
}
}
bool AIThreadImpl::state_machine_done(LLThread* threadp)
{
StateMachineThread_wat state_machine_thread_w(mStateMachineThread);
AIStateMachineThreadBase* state_machine_thread = *state_machine_thread_w;
bool need_cleanup = !state_machine_thread;
if (!need_cleanup)
{
// If state_machine_thread is non-NULL, then AIThreadImpl::thread_done wasnt called yet
// (or at least didn't return yet) which means the thread is still running.
// Try telling the thread that it can stop.
threadp->setQuitting();
// Finally, mark that we are NOT going to do the cleanup by setting mStateMachineThread to NULL.
*state_machine_thread_w = NULL;
}
return need_cleanup;
}
// AIStateMachineThread THREAD
bool AIThreadImpl::thread_done(bool result)
{
StateMachineThread_wat state_machine_thread_w(mStateMachineThread);
AIStateMachineThreadBase* state_machine_thread = *state_machine_thread_w;
bool need_cleanup = !state_machine_thread;
if (!need_cleanup)
{
// If state_machine_thread is non-NULL then AIThreadImpl::abort_impl wasn't called,
// which means the state machine still exists. In fact, it should be in the waiting() state.
// It can also happen that the state machine is being aborted right now (but it will still exist).
// (Note that waiting() and running() aren't strictly thread-safe (we should really lock
// mSetStateLock here) but by first calling waiting() and then running(), and assuming that
// changing an int from the value 1 to the value 2 is atomic, this will work since the
// only possible transition is from waiting to not running).
llassert(state_machine_thread->waiting() || !state_machine_thread->running());
state_machine_thread->schedule_abort(!result);
// Note that if the state machine is not running (being aborted, ie - hanging in abort_impl
// waiting for the lock on mStateMachineThread) then this is simply ignored.
state_machine_thread->cont();
// Finally, mark that we are NOT going to do the cleanup by setting mStateMachineThread to NULL.
*state_machine_thread_w = NULL;
}
return need_cleanup;
}

View File

@@ -0,0 +1,229 @@
/**
* @file aistatemachinethread.h
* @brief Run code in a thread.
*
* 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.
*
* 23/01/2013
* Initial version, written by Aleric Inglewood @ SL
*/
#ifndef AISTATEMACHINETHREAD_H
#define AISTATEMACHINETHREAD_H
#include "aistatemachine.h"
#include "llthread.h"
#include "aithreadsafe.h"
#ifdef EXAMPLE_CODE // undefined
class HelloWorldThread : public AIThreadImpl {
private:
bool mStdErr; // input
bool mSuccess; // output
public:
// Constructor.
HelloWorldThread(void) : AIThreadImpl("HelloWorldThread"), // MAIN THREAD
mStdErr(false), mSuccess(false) { }
// Some initialization function (if needed).
void init(bool err) { mStdErr = err; } // MAIN THREAD
// Read back output.
bool successful(void) const { return mSuccess; }
// Mandatory signature.
/*virtual*/ bool run(void) // NEW THREAD
{
if (mStdErr)
std::cerr << "Hello world" << std::endl;
else
std::cout << "Hello world" << std::endl;
mSuccess = true;
return true; // true = finish, false = abort.
}
};
// The states of this state machine.
enum hello_world_state_type {
HelloWorld_start = AIStateMachine::max_state,
HelloWorld_done
};
// The statemachine class (this is almost a template).
class HelloWorld : public AIStateMachine {
private:
AIStateMachineThread<HelloWorldThread> mHelloWorld;
bool mErr;
public:
HelloWorld() : mErr(false) { }
// Print to stderr or stdout?
void init(bool err) { mErr = err; }
protected:
// Call finish() (or abort()), not delete.
/*virtual*/ ~HelloWorld() { }
// Handle initializing the object.
/*virtual*/ void initialize_impl(void);
// Handle mRunState.
/*virtual*/ void multiplex_impl(void);
// Handle aborting from current bs_run state.
/*virtual*/ void abort_impl(void) { }
// Handle cleaning up from initialization (or post abort) state.
/*virtual*/ void finish_impl(void)
{
// Kill object by default.
// This can be overridden by calling run() from the callback function.
kill();
}
// Implemenation of state_str for run states.
/*virtual*/ char const* state_str_impl(state_type run_state) const
{
switch(run_state)
{
AI_CASE_RETURN(HelloWorld_start);
AI_CASE_RETURN(HelloWorld_done);
}
return "UNKNOWN STATE";
}
};
// The actual implementation of this statemachine starts here!
void HelloWorld::initialize_impl(void)
{
mHelloWorld->init(mErr); // Initialize the thread object.
set_state(HelloWorld_start);
}
void HelloWorld::multiplex_impl(void)
{
switch (mRunState)
{
case HelloWorld_start:
{
mHelloWorld.run(this, HelloWorld_done); // Run HelloWorldThread and set the state of 'this' to HelloWorld_done when finished.
idle(HelloWorld_start); // Always go idle after starting a thread!
break;
}
case HelloWorld_done:
{
// We're done. Lets also abort when the thread reported no success.
if (mHelloWorld->successful()) // Read output/result of thread object.
finish();
else
abort();
break;
}
}
}
#endif // EXAMPLE CODE
class AIStateMachineThreadBase;
// Derive from this to implement the code that must run in another thread.
class AIThreadImpl : public LLThreadSafeRefCount {
private:
template<typename THREAD_IMPL> friend struct AIStateMachineThread;
typedef AIAccess<AIStateMachineThreadBase*> StateMachineThread_wat;
AIThreadSafeSimpleDC<AIStateMachineThreadBase*> mStateMachineThread;
public:
virtual bool run(void) = 0;
bool thread_done(bool result);
bool state_machine_done(LLThread* threadp);
#ifdef LL_DEBUG
private:
char const* mName;
protected:
AIThreadImpl(char const* name = "AIStateMachineThreadBase::Thread") : mName(name) { }
public:
char const* getName(void) const { return mName; }
#endif
};
// The base class for statemachine threads.
class AIStateMachineThreadBase : public AIStateMachine {
private:
// The actual thread (derived from LLThread).
class Thread;
// The states of this state machine.
enum thread_state_type {
start_thread = AIStateMachine::max_state, // Start the thread (if necessary create it first).
wait_stopped // Wait till the thread is stopped.
};
protected:
AIStateMachineThreadBase(AIThreadImpl* impl) : mImpl(impl) { }
private:
// Handle initializing the object.
/*virtual*/ void initialize_impl(void);
// Handle mRunState.
/*virtual*/ void multiplex_impl(void);
// Handle aborting from current bs_run state.
/*virtual*/ void abort_impl(void);
// Handle cleaning up from initialization (or post abort) state.
/*virtual*/ void finish_impl(void) { }
// Implemenation of state_str for run states.
/*virtual*/ char const* state_str_impl(state_type run_state) const;
private:
Thread* mThread; // The thread that the code is run in.
AIThreadImpl* mImpl; // Pointer to the implementation code that needs to be run in the thread.
bool mAbort; // (Inverse of) return value of AIThreadImpl::run(). Only valid in state wait_stopped.
public:
void schedule_abort(bool do_abort) { mAbort = do_abort; }
};
// The state machine that runs T::run() in a thread.
// THREAD_IMPL Must be derived from AIThreadImpl.
template<typename THREAD_IMPL>
struct AIStateMachineThread : public LLPointer<THREAD_IMPL>, public AIStateMachineThreadBase {
// Constructor.
AIStateMachineThread(void) :
LLPointer<THREAD_IMPL>(new THREAD_IMPL),
AIStateMachineThreadBase(LLPointer<THREAD_IMPL>::get())
{
*AIThreadImpl::StateMachineThread_wat(static_cast<AIThreadImpl*>(LLPointer<THREAD_IMPL>::get())->mStateMachineThread) = this;
}
};
#endif

View File

@@ -23,27 +23,31 @@ set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Release;Debug" CACHE STRING
# Platform-specific compilation flags.
if (WINDOWS)
# Various libs are compiler specific, generate some variables here we can just use
# when we require them instead of reimplementing the test each time.
if (MSVC10)
set(MSVC_DIR 10.0)
set(MSVC_SUFFIX 100)
endif (MSVC10)
# Remove default /Zm1000 flag that cmake inserts
string (REPLACE "/Zm1000" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
# Don't build DLLs.
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd /arch:SSE2"
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd /MP"
CACHE STRING "C++ compiler debug options" FORCE)
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /MP /arch:SSE2"
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /MP"
CACHE STRING "C++ compiler release-with-debug options" FORCE)
set(CMAKE_CXX_FLAGS_RELEASE
"${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD /MP /arch:SSE2 /fp:fast"
"${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD /MP /fp:fast -D_SECURE_STL=0 -D_HAS_ITERATOR_DEBUGGING=0"
CACHE STRING "C++ compiler release options" FORCE)
set(CMAKE_C_FLAGS_RELEASE
"${CMAKE_C_FLAGS_RELEASE} ${LL_C_FLAGS} /O2 /Zi /MD /MP /arch:SSE2 /fp:fast"
"${CMAKE_C_FLAGS_RELEASE} ${LL_C_FLAGS} /O2 /Zi /MD /MP /fp:fast"
CACHE STRING "C compiler release options" FORCE)
if(NOT CMAKE_EXE_LINKER_FLAGS_RELEASE MATCHES LARGEADDRESSAWARE)
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LARGEADDRESSAWARE")
endif()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE")
set(CMAKE_CXX_STANDARD_LIBRARIES "")
set(CMAKE_C_STANDARD_LIBRARIES "")
@@ -57,53 +61,24 @@ if (WINDOWS)
/W3
/c
/Zc:forScope
/Zc:wchar_t-
/nologo
/Oy-
/arch:SSE2
)
# configure win32 API for windows XP+ compatibility
set(WINVER "0x0501" CACHE STRING "Win32 API Target version (see http://msdn.microsoft.com/en-us/library/aa383745%28v=VS.85%29.aspx)")
add_definitions("/DWINVER=${WINVER}" "/D_WIN32_WINNT=${WINVER}")
if(MSVC80 OR MSVC90 OR MSVC10)
set(CMAKE_CXX_FLAGS_RELEASE
"${CMAKE_CXX_FLAGS_RELEASE} -D_SECURE_STL=0 -D_HAS_ITERATOR_DEBUGGING=0"
CACHE STRING "C++ compiler release options" FORCE)
set(CMAKE_C_FLAGS_RELEASE
"${CMAKE_C_FLAGS_RELEASE}" CACHE STRING "C compiler release options" FORCE)
add_definitions(
/Zc:wchar_t-
)
endif (MSVC80 OR MSVC90 OR MSVC10)
# Are we using the crummy Visual Studio KDU build workaround?
if (NOT DISABLE_FATAL_WARNINGS)
add_definitions(/WX)
endif (NOT DISABLE_FATAL_WARNINGS)
# Various libs are compiler specific, generate some variables here we can just use
# when we require them instead of reimplementing the test each time.
if (MSVC71)
set(MSVC_DIR 7.1)
set(MSVC_SUFFIX 71)
elseif (MSVC80)
set(MSVC_DIR 8.0)
set(MSVC_SUFFIX 80)
elseif (MSVC90)
set(MSVC_DIR 9.0)
set(MSVC_SUFFIX 90)
elseif (MSVC10)
set(MSVC_DIR 10.0)
set(MSVC_SUFFIX 100)
endif (MSVC71)
if (MSVC10)
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /MANIFEST:NO")
SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /MANIFEST:NO")
endif(MSVC10)
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /MANIFEST:NO")
SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /MANIFEST:NO")
endif (WINDOWS)

View File

@@ -36,6 +36,7 @@ set(cmake_SOURCE_FILES
FMOD.cmake
FMODEX.cmake
FreeType.cmake
GLOD.cmake
GStreamer010Plugin.cmake
GooglePerfTools.cmake
Hunspell.cmake
@@ -55,6 +56,7 @@ set(cmake_SOURCE_FILES
LLMessage.cmake
LLPlugin.cmake
LLPrimitive.cmake
LLPhysicsExtensions.cmake
LLQtWebkit.cmake
LLRender.cmake
LLScene.cmake

View File

@@ -0,0 +1,46 @@
# -*- cmake -*-
include(Prebuilt)
set(COLLADADOM_FIND_QUIETLY OFF)
set(COLLADADOM_FIND_REQUIRED ON)
if (STANDALONE)
include (FindColladadom)
else (STANDALONE)
use_prebuilt_binary(colladadom)
if (NOT WINDOWS)
use_prebuilt_binary(pcre)
endif (NOT WINDOWS)
if (NOT DARWIN AND NOT WINDOWS)
use_prebuilt_binary(libxml)
endif (NOT DARWIN AND NOT WINDOWS)
set(COLLADADOM_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/collada
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/collada/1.4
)
if (WINDOWS)
add_definitions(-DDOM_DYNAMIC)
set(COLLADADOM_LIBRARIES
debug libcollada14dom22-d
optimized libcollada14dom22
debug libboost_filesystem-vc100-mt-gd-1_45.lib
optimized libboost_filesystem-vc100-mt-1_45.lib
debug libboost_system-vc100-mt-gd-1_45.lib
optimized libboost_system-vc100-mt-1_45.lib
)
else (WINDOWS)
set(COLLADADOM_LIBRARIES
collada14dom
minizip
xml2
pcrecpp
pcre
)
endif (WINDOWS)
endif (STANDALONE)

View File

@@ -31,6 +31,8 @@ set(debug_files
libapriconv-1.dll
libeay32.dll
ssleay32.dll
libcollada14dom22-d.dll
glod.dll
)
copy_if_different(
@@ -210,6 +212,8 @@ set(release_files
libapriconv-1.dll
libeay32.dll
ssleay32.dll
libcollada14dom22.dll
glod.dll
)
if(FMODEX)

View File

@@ -2,54 +2,52 @@
include(Linking)
if(INSTALL_PROPRIETARY)
include(Prebuilt)
use_prebuilt_binary(fmodex)
endif(INSTALL_PROPRIETARY)
find_library(FMODEX_LIBRARY
NAMES fmodex fmodexL fmodex_vc fmodexL_vc
PATHS
optimized ${ARCH_PREBUILT_DIRS_RELEASE}
debug ${ARCH_PREBUILT_DIRS_DEBUG}
)
if (NOT FMODEX_LIBRARY)
set(FMODEX_SDK_DIR CACHE PATH "Path to the FMOD Ex SDK.")
if (FMODEX_SDK_DIR)
find_library(FMODEX_LIBRARY
fmodex_vc fmodexL_vc fmodex fmodexL fmodex64 fmodexL64
PATHS
${FMODEX_SDK_DIR}/api/lib
${FMODEX_SDK_DIR}/api
${FMODEX_SDK_DIR}/lib
${FMODEX_SDK_DIR}
)
if(WORD_SIZE EQUAL 32)
find_library(FMODEX_LIBRARY
fmodex_vc fmodexL_vc fmodex fmodexL
PATHS
"${FMODEX_SDK_DIR}/api/lib"
"${FMODEX_SDK_DIR}/api"
"${FMODEX_SDK_DIR}/lib"
"${FMODEX_SDK_DIR}"
)
elseif(WORD_SIZE EQUAL 64)
find_library(FMODEX_LIBRARY
fmodex64 fmodexL64
PATHS
"${FMODEX_SDK_DIR}/api/lib"
"${FMODEX_SDK_DIR}/api"
"${FMODEX_SDK_DIR}/lib"
"${FMODEX_SDK_DIR}"
)
endif(WORD_SIZE EQUAL 32)
endif(FMODEX_SDK_DIR)
if(WINDOWS AND NOT FMODEX_LIBRARY)
set(FMODEX_PROG_DIR "$ENV{PROGRAMFILES}/FMOD SoundSystem/FMOD Programmers API Windows")
find_library(FMODEX_LIBRARY
fmodex_vc fmodexL_vc
PATHS
${FMODEX_PROG_DIR}/api/lib
${FMODEX_PROG_DIR}/api
${FMODEX_PROG_DIR}
"${FMODEX_PROG_DIR}/api/lib"
"${FMODEX_PROG_DIR}/api"
"${FMODEX_PROG_DIR}"
)
if(FMODEX_LIBRARY)
message(STATUS "Found fmodex in ${FMODEX_PROG_DIR}")
set(FMODEX_SDK_DIR ${FMODEX_PROG_DIR})
set(FMODEX_SDK_DIR ${FMODEX_PROG_DIR} CACHE PATH "Path to the FMOD Ex SDK." FORCE)
set(FMODEX_SDK_DIR "${FMODEX_PROG_DIR}")
set(FMODEX_SDK_DIR "${FMODEX_PROG_DIR}" CACHE PATH "Path to the FMOD Ex SDK." FORCE)
endif(FMODEX_LIBRARY)
endif(WINDOWS AND NOT FMODEX_LIBRARY)
endif (NOT FMODEX_LIBRARY)
find_path(FMODEX_INCLUDE_DIR fmod.hpp
${LIBS_PREBUILT_DIR}/include/fmodex
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/fmodex
${FMODEX_SDK_DIR}/api/inc
${FMODEX_SDK_DIR}/inc
${FMODEX_SDK_DIR}
"${LIBS_PREBUILT_DIR}/include/fmodex"
"${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/fmodex"
"${FMODEX_SDK_DIR}/api/inc"
"${FMODEX_SDK_DIR}/inc"
"${FMODEX_SDK_DIR}"
)
if(DARWIN)

View File

@@ -0,0 +1,31 @@
# -*- cmake -*-
# - Find collada14dom
# Find the colladadom version 1.4 includes and library
# This module defines
# COLLADADOM_FOUND, System has libcollada14dom.so.
# COLLADADOM_INCLUDE_DIRS - The collada include directories.
# COLLADADOM_LIBRARIES - The libraries needed to use libcollada14dom.
# COLLADADOM_DEFINITIONS - Compiler switches required for using libcollada14dom.
FIND_PACKAGE(PkgConfig)
PKG_CHECK_MODULES(PC_COLLADADOM collada)
SET(COLLADADOM_DEFINITIONS ${PC_COLLADADOM_CFLAGS_OTHER})
FIND_PATH(COLLADADOM_INCLUDE_DIR dae.h
HINTS ${PC_COLLADADOM_INCLUDE_DIR} ${PC_COLLADADOM_INCLUDE_DIRS}
PATH_SUFFIXES collada)
FIND_LIBRARY(COLLADADOM_LIBRARY
NAMES libcollada14dom.so
HINTS ${PC_COLLADADOM_LIBDIR} ${PC_COLLADADOM_LIBRARY_DIRS}
PATHS /usr/lib /usr/local/lib)
SET(COLLADADOM_LIBRARIES ${COLLADADOM_LIBRARY})
SET(COLLADADOM_INCLUDE_DIRS ${COLLADADOM_INCLUDE_DIR} ${COLLADADOM_INCLUDE_DIR}/1.4)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(COLLADADOM DEFAULT_MSG
COLLADADOM_LIBRARY COLLADADOM_INCLUDE_DIR)
MARK_AS_ADVANCED(COLLADADOM_LIBRARY COLLADADOM_INCLUDE_DIR)

View File

@@ -0,0 +1,32 @@
# -*- cmake -*-
# - Find GLOD
# Find the GLOD includes and library
# This module defines
# GLOD_FOUND, System has libglod.so.
# GLOD_INCLUDE_DIRS - The GLOD include directories.
# GLOD_LIBRARIES - The libraries needed to use libglod.
# GLOD_DEFINITIONS - Compiler switches required for using libglod.
FIND_PACKAGE(PkgConfig)
PKG_CHECK_MODULES(PC_GLOD glod)
SET(GLOD_DEFINITIONS ${PC_GLOD_CFLAGS_OTHER})
FIND_PATH(GLOD_INCLUDE_DIR glod/glod.h
HINTS ${PC_GLOD_INCLUDE_DIR} ${PC_GLOD_INCLUDE_DIRS}
)
FIND_LIBRARY(GLOD_LIBRARY
NAMES libGLOD.so
HINTS ${PC_GLOD_LIBDIR} ${PC_GLOD_LIBRARY_DIRS}
PATHS /usr/lib /usr/local/lib)
SET(GLOD_LIBRARIES ${GLOD_LIBRARY})
SET(GLOD_INCLUDE_DIRS ${GLOD_INCLUDE_DIR})
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLOD DEFAULT_MSG
GLOD_LIBRARY GLOD_INCLUDE_DIR)
MARK_AS_ADVANCED(GLOD_LIBRARY GLOD_INCLUDE_DIR)

13
indra/cmake/GLOD.cmake Normal file
View File

@@ -0,0 +1,13 @@
# -*- cmake -*-
include(Prebuilt)
set(GLOD_FIND_QUIETLY OFF)
set(GLOD_FIND_REQUIRED ON)
if (STANDALONE)
include(FindGLOD)
else (STANDALONE)
use_prebuilt_binary(GLOD)
set(GLOD_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
set(GLOD_LIBRARIES glod)
endif (STANDALONE)

View File

@@ -0,0 +1,7 @@
# -*- cmake -*-
set(LLPHYSICSEXTENSIONS_LIBRARIES nd_hacdConvexDecomposition hacd nd_Pathing )
set(LLPHYSICSEXTENSIONS_INCLUDE_DIRS ${LIBS_OPEN_DIR}/libndhacd )

View File

@@ -1,7 +1,22 @@
# -*- cmake -*-
set(LLPRIMITIVE_INCLUDE_DIRS
${LIBS_OPEN_DIR}/llprimitive
)
include(Colladadom)
set(LLPRIMITIVE_INCLUDE_DIRS
${LIBS_OPEN_DIR}/llprimitive
${COLLADADOM_INCLUDE_DIRS}
)
if (WINDOWS)
set(LLPRIMITIVE_LIBRARIES
debug llprimitive
optimized llprimitive
${COLLADADOM_LIBRARIES}
)
else (WINDOWS)
set(LLPRIMITIVE_LIBRARIES
llprimitive
${COLLADADOM_LIBRARIES}
)
endif (WINDOWS)
set(LLPRIMITIVE_LIBRARIES llprimitive)

View File

@@ -4,9 +4,9 @@ include(Prebuilt)
set(OpenSSL_FIND_QUIETLY ON)
set(OpenSSL_FIND_REQUIRED ON)
if (STANDALONE)
if (STANDALONE OR USE_SYSTEM_OPENSSL)
include(FindOpenSSL)
else (STANDALONE)
else (STANDALONE OR USE_SYSTEM_OPENSSL)
use_prebuilt_binary(openSSL)
if (WINDOWS)
set(OPENSSL_LIBRARIES ssleay32 libeay32)
@@ -14,7 +14,7 @@ else (STANDALONE)
set(OPENSSL_LIBRARIES ssl)
endif (WINDOWS)
set(OPENSSL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
endif (STANDALONE)
endif (STANDALONE OR USE_SYSTEM_OPENSSL)
if (LINUX OR DARWIN)
set(CRYPTO_LIBRARIES crypto)

View File

@@ -236,8 +236,10 @@ void stop_recording_backtraces(void)
channel_ct backtrace DDCN("BACKTRACE"); //!< This debug channel is used for backtraces.
channel_ct statemachine DDCN("STATEMACHINE"); //!< This debug channel is used for output related to class AIStateMachine.
channel_ct caps DDCN("CAPS"); //!< This debug channel is used for output related to Capabilities.
channel_ct curl DDCN("CURL"); //!< This debug channel is used for output related to Curl.
channel_ct curlio DDCN("CURLIO"); //!< This debug channel is used to print debug output of libcurl.
channel_ct curl DDCN("CURL"); //!< This debug channel is used for output related to AICurl.
channel_ct curlio DDCN("CURLIO"); //!< This debug channel is used to print debug output of libcurl. This includes all HTTP network traffic.
channel_ct curltr DDCN("CURLTR"); //!< This debug channel is used to print libcurl API calls.
channel_ct snapshot DDCN("SNAPSHOT"); //!< This debug channel is used for output related to snapshots.
} // namespace dc
} // namespace DEBUGCHANNELS

View File

@@ -207,6 +207,8 @@ extern CWD_API channel_ct statemachine;
extern CWD_API channel_ct caps;
extern CWD_API channel_ct curl;
extern CWD_API channel_ct curlio;
extern CWD_API channel_ct curltr;
extern CWD_API channel_ct snapshot;
#endif

View File

@@ -473,26 +473,11 @@ class DarwinSetup(UnixSetup):
class WindowsSetup(PlatformSetup):
gens = {
'vc71' : {
'gen' : r'Visual Studio 7 .NET 2003',
'ver' : r'7.1'
},
'vc80' : {
'gen' : r'Visual Studio 8 2005',
'ver' : r'8.0'
},
'vc90' : {
'gen' : r'Visual Studio 9 2008',
'ver' : r'9.0'
},
'vc100' : {
'gen' : r'Visual Studio 10',
'ver' : r'10.0'
}
}
gens['vs2003'] = gens['vc71']
gens['vs2005'] = gens['vc80']
gens['vs2008'] = gens['vc90']
gens['vs2010'] = gens['vc100']
search_path = r'C:\windows'
@@ -505,21 +490,21 @@ class WindowsSetup(PlatformSetup):
def _get_generator(self):
if self._generator is None:
for version in 'vc80 vc90 vc100 vc71'.split():
for version in 'vc100'.split():
if self.find_visual_studio(version):
self._generator = version
print 'Building with ', self.gens[version]['gen']
break
else:
print >> sys.stderr, 'Cannot find a Visual Studio installation, testing for express editions'
for version in 'vc80 vc90 vc100 vc71'.split():
for version in 'vc100'.split():
if self.find_visual_studio_express(version):
self._generator = version
self.using_express = True
print 'Building with ', self.gens[version]['gen'] , "Express edition"
break
else:
for version in 'vc80 vc90 vc100 vc71'.split():
for version in 'vc100'.split():
if self.find_visual_studio_express_single(version):
self._generator = version
self.using_express = True
@@ -768,8 +753,7 @@ Options:
-m32 | -m64 build architecture (32-bit or 64-bit)
-N | --no-distcc disable use of distcc
-G | --generator=NAME generator name
Windows: VC71 or VS2003 (default), VC80 (VS2005)
VC90 (VS2008), or VC100 (VS2010)
Windows: VC100 (VS2010) (default)
Mac OS X: Xcode (default), Unix Makefiles
Linux: Unix Makefiles (default), KDevelop3
-p | --project=NAME set the root project name. (Doesn't effect makefiles)

View File

@@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 2.6.4)
project(libhacd CXX C)
include(00-Common)
file (GLOB SOURCE_FILES *.cpp )
file (GLOB INCLUDE_FILES *.h )
IF(WINDOWS)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
ENDIF(WINDOWS)
add_library(hacd ${SOURCE_FILES} ${INCLUDE_FILES})

View File

@@ -0,0 +1,85 @@
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#ifndef HACD_CIRCULAR_LIST_H
#define HACD_CIRCULAR_LIST_H
#include <stdlib.h>
#include "hacdVersion.h"
#include "hacdMicroAllocator.h"
namespace HACD
{
//! CircularListElement class.
template < typename T > class CircularListElement
{
public:
T & GetData() { return m_data; }
const T & GetData() const { return m_data; }
CircularListElement<T> * & GetNext() { return m_next; }
CircularListElement<T> * & GetPrev() { return m_prev; }
const CircularListElement<T> * & GetNext() const { return m_next; }
const CircularListElement<T> * & GetPrev() const { return m_prev; }
//! Constructor
CircularListElement(const T & data) {m_data = data;}
CircularListElement(void){}
//! Destructor
~CircularListElement(void){}
private:
T m_data;
CircularListElement<T> * m_next;
CircularListElement<T> * m_prev;
CircularListElement(const CircularListElement & rhs);
};
//! CircularList class.
template < typename T > class CircularList
{
public:
HeapManager * const GetHeapManager() const { return m_heapManager;}
void SetHeapManager(HeapManager * const heapManager) { m_heapManager = heapManager;}
CircularListElement<T> * & GetHead() { return m_head;}
const CircularListElement<T> * GetHead() const { return m_head;}
bool IsEmpty() const { return (m_size == 0);}
size_t GetSize() const { return m_size; }
const T & GetData() const { return m_head->GetData(); }
T & GetData() { return m_head->GetData();}
bool Delete() ;
bool Delete(CircularListElement<T> * element);
CircularListElement<T> * Add(const T * data = 0);
CircularListElement<T> * Add(const T & data);
bool Next();
bool Prev();
void Clear() { while(Delete());};
const CircularList& operator=(const CircularList& rhs);
//! Constructor
CircularList(HeapManager * heapManager)
{
m_head = 0;
m_size = 0;
m_heapManager = heapManager;
}
CircularList(const CircularList& rhs);
//! Destructor
virtual ~CircularList(void) {Clear();};
private:
CircularListElement<T> * m_head; //!< a pointer to the head of the circular list
size_t m_size; //!< number of element in the circular list
HeapManager * m_heapManager;
};
}
#include "hacdCircularList.inl"
#endif

View File

@@ -0,0 +1,230 @@
#pragma once
#ifndef HACD_CIRCULAR_LIST_INL
#define HACD_CIRCULAR_LIST_INL
#include <stdlib.h>
#include "hacdVersion.h"
namespace HACD
{
template < typename T >
inline bool CircularList<T>::Delete(CircularListElement<T> * element)
{
if (!element)
{
return false;
}
if (m_size > 1)
{
CircularListElement<T> * next = element->GetNext();
CircularListElement<T> * prev = element->GetPrev();
if (m_heapManager)
{
element->~CircularListElement<T>();
heap_free(m_heapManager, element);
}
else
{
delete element;
}
m_size--;
if (element == m_head)
{
m_head = next;
}
next->GetPrev() = prev;
prev->GetNext() = next;
return true;
}
else if (m_size == 1)
{
if (m_heapManager)
{
element->~CircularListElement<T>();
heap_free(m_heapManager, m_head);
}
else
{
delete m_head;
}
m_size--;
m_head = 0;
return true;
}
else
{
return false;
}
}
template < typename T >
inline bool CircularList<T>::Delete()
{
if (m_size > 1)
{
CircularListElement<T> * next = m_head->GetNext();
CircularListElement<T> * prev = m_head->GetPrev();
if (m_heapManager)
{
m_head->~CircularListElement<T>();
heap_free(m_heapManager, m_head);
}
else
{
delete m_head;
}
m_size--;
m_head = next;
next->GetPrev() = prev;
prev->GetNext() = next;
return true;
}
else if (m_size == 1)
{
if (m_heapManager)
{
m_head->~CircularListElement<T>();
heap_free(m_heapManager, m_head);
}
else
{
delete m_head;
}
m_size--;
m_head = 0;
return true;
}
else
{
return false;
}
}
template < typename T >
inline CircularListElement<T> * CircularList<T>::Add(const T * data)
{
if (m_size == 0)
{
if (data)
{
if (m_heapManager)
{
m_head = static_cast< CircularListElement<T> * > (heap_malloc(m_heapManager, sizeof(CircularListElement<T>)));
m_head->GetData().Initialize();
m_head->GetData() = (*data);
}
else
{
m_head = new CircularListElement<T>(*data);
}
}
else
{
if (m_heapManager)
{
m_head = static_cast< CircularListElement<T> * > (heap_malloc(m_heapManager, sizeof(CircularListElement<T>)));
m_head->GetData().Initialize();
}
else
{
m_head = new CircularListElement<T>();
}
}
m_head->GetNext() = m_head->GetPrev() = m_head;
}
else
{
CircularListElement<T> * next = m_head->GetNext();
CircularListElement<T> * element = m_head;
if (data)
{
if (m_heapManager)
{
m_head = static_cast< CircularListElement<T> * > (heap_malloc(m_heapManager, sizeof(CircularListElement<T>)));
m_head->GetData().Initialize();
m_head->GetData() = (*data);
}
else
{
m_head = new CircularListElement<T>(*data);
}
}
else
{
if (m_heapManager)
{
m_head = static_cast< CircularListElement<T> * > (heap_malloc(m_heapManager, sizeof(CircularListElement<T>)));
m_head->GetData().Initialize();
}
else
{
m_head = new CircularListElement<T>();
}
}
m_head->GetNext() = next;
m_head->GetPrev() = element;
element->GetNext() = m_head;
next->GetPrev() = m_head;
}
m_size++;
return m_head;
}
template < typename T >
inline CircularListElement<T> * CircularList<T>::Add(const T & data)
{
const T * pData = &data;
return Add(pData);
}
template < typename T >
inline bool CircularList<T>::Next()
{
if (m_size == 0)
{
return false;
}
m_head = m_head->GetNext();
return true;
}
template < typename T >
inline bool CircularList<T>::Prev()
{
if (m_size == 0)
{
return false;
}
m_head = m_head->GetPrev();
return true;
}
template < typename T >
inline CircularList<T>::CircularList(const CircularList& rhs)
{
if (rhs.m_size > 0)
{
CircularListElement<T> * current = rhs.m_head;
do
{
current = current->GetNext();
Add(current->GetData());
}
while ( current != rhs.m_head );
}
}
template < typename T >
inline const CircularList<T>& CircularList<T>::operator=(const CircularList& rhs)
{
if (&rhs != this)
{
Clear();
m_heapManager = rhs.m_heapManager;
if (rhs.m_size > 0)
{
CircularListElement<T> * current = rhs.m_head;
do
{
current = current->GetNext();
Add(current->GetData());
}
while ( current != rhs.m_head );
}
}
return (*this);
}
}
#endif

278
indra/libhacd/hacdGraph.cpp Normal file
View File

@@ -0,0 +1,278 @@
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "hacdGraph.h"
namespace HACD
{
GraphEdge::GraphEdge()
{
m_v1 = -1;
m_v2 = -1;
m_name = -1;
m_error = 0;
m_concavity = 0;
m_deleted = false;
#ifdef HACD_PRECOMPUTE_CHULLS
m_convexHull = 0;
#endif
}
GraphVertex::GraphVertex()
{
m_convexHull = 0;
m_name = -1;
m_cc = -1;
m_concavity = 0;
m_surf = 0;
m_deleted = false;
}
bool GraphVertex::DeleteEdge(long name)
{
return m_edges.Erase(name);
}
Graph::Graph()
{
m_nV = 0;
m_nE = 0;
m_nCCs = 0;
}
Graph::~Graph()
{
}
void Graph::Allocate(size_t nV, size_t nE)
{
m_nV = nV;
m_edges.reserve(nE);
m_vertices.resize(nV);
for(size_t i = 0; i < nV; i++)
{
m_vertices[i].m_name = static_cast<long>(i);
}
}
long Graph::AddVertex()
{
size_t name = m_vertices.size();
m_vertices.resize(name+1);
m_vertices[name].m_name = static_cast<long>(name);
m_nV++;
return static_cast<long>(name);
}
long Graph::AddEdge(long v1, long v2)
{
size_t name = m_edges.size();
m_edges.push_back(GraphEdge());
m_edges[name].m_name = static_cast<long>(name);
m_edges[name].m_v1 = v1;
m_edges[name].m_v2 = v2;
m_vertices[v1].AddEdge(static_cast<long>(name));
m_vertices[v2].AddEdge(static_cast<long>(name));
m_nE++;
return static_cast<long>(name);
}
bool Graph::DeleteEdge(long name)
{
if (name < static_cast<long>(m_edges.size()))
{
long v1 = m_edges[name].m_v1;
long v2 = m_edges[name].m_v2;
m_edges[name].m_deleted = true;
m_vertices[v1].DeleteEdge(name);
m_vertices[v2].DeleteEdge(name);
m_nE--;
return true;
}
return false;
}
bool Graph::DeleteVertex(long name)
{
if (name < static_cast<long>(m_vertices.size()))
{
m_vertices[name].m_deleted = true;
m_vertices[name].m_edges.Clear();
m_vertices[name].m_ancestors = std::vector<long>();
delete m_vertices[name].m_convexHull;
m_vertices[name].m_distPoints.Clear();
m_vertices[name].m_boudaryEdges.Clear();
m_vertices[name].m_convexHull = 0;
m_nV--;
return true;
}
return false;
}
bool Graph::EdgeCollapse(long v1, long v2)
{
long edgeToDelete = GetEdgeID(v1, v2);
if (edgeToDelete >= 0)
{
// delete the edge (v1, v2)
DeleteEdge(edgeToDelete);
// add v2 to v1 ancestors
m_vertices[v1].m_ancestors.push_back(v2);
// add v2's ancestors to v1's ancestors
m_vertices[v1].m_ancestors.insert(m_vertices[v1].m_ancestors.begin(),
m_vertices[v2].m_ancestors.begin(),
m_vertices[v2].m_ancestors.end());
// update adjacency information
SArray<long, SARRAY_DEFAULT_MIN_SIZE> & v1Edges = m_vertices[v1].m_edges;
long b = -1;
long idEdge;
for(size_t ed = 0; ed < m_vertices[v2].m_edges.Size(); ++ed)
{
idEdge = m_vertices[v2].m_edges[ed];
if (m_edges[idEdge].m_v1 == v2)
{
b = m_edges[idEdge].m_v2;
}
else
{
b = m_edges[idEdge].m_v1;
}
if (GetEdgeID(v1, b) >= 0)
{
m_edges[idEdge].m_deleted = true;
m_vertices[b].DeleteEdge(idEdge);
m_nE--;
}
else
{
m_edges[idEdge].m_v1 = v1;
m_edges[idEdge].m_v2 = b;
v1Edges.Insert(idEdge);
}
}
// delete the vertex v2
DeleteVertex(v2);
return true;
}
return false;
}
long Graph::GetEdgeID(long v1, long v2) const
{
if (v1 < static_cast<long>(m_vertices.size()) && !m_vertices[v1].m_deleted)
{
long idEdge;
for(size_t ed = 0; ed < m_vertices[v1].m_edges.Size(); ++ed)
{
idEdge = m_vertices[v1].m_edges[ed];
if ( (m_edges[idEdge].m_v1 == v2) ||
(m_edges[idEdge].m_v2 == v2) )
{
return m_edges[idEdge].m_name;
}
}
}
return -1;
}
void Graph::Print() const
{
std::cout << "-----------------------------" << std::endl;
std::cout << "vertices (" << m_nV << ")" << std::endl;
for (size_t v = 0; v < m_vertices.size(); ++v)
{
const GraphVertex & currentVertex = m_vertices[v];
if (!m_vertices[v].m_deleted)
{
std::cout << currentVertex.m_name << "\t";
long idEdge;
for(size_t ed = 0; ed < currentVertex.m_edges.Size(); ++ed)
{
idEdge = currentVertex.m_edges[ed];
std::cout << "(" << m_edges[idEdge].m_v1 << "," << m_edges[idEdge].m_v2 << ") ";
}
std::cout << std::endl;
}
}
std::cout << "vertices (" << m_nE << ")" << std::endl;
for (size_t e = 0; e < m_edges.size(); ++e)
{
const GraphEdge & currentEdge = m_edges[e];
if (!m_edges[e].m_deleted)
{
std::cout << currentEdge.m_name << "\t("
<< m_edges[e].m_v1 << ","
<< m_edges[e].m_v2 << ") "<< std::endl;
}
}
}
void Graph::Clear()
{
m_vertices.clear();
m_edges.clear();
m_nV = 0;
m_nE = 0;
}
long Graph::ExtractCCs()
{
// all CCs to -1
for (size_t v = 0; v < m_vertices.size(); ++v)
{
if (!m_vertices[v].m_deleted)
{
m_vertices[v].m_cc = -1;
}
}
// we get the CCs
m_nCCs = 0;
long v2 = -1;
long idEdge;
std::vector<long> temp;
for (size_t v = 0; v < m_vertices.size(); ++v)
{
if (!m_vertices[v].m_deleted && m_vertices[v].m_cc == -1)
{
m_vertices[v].m_cc = static_cast<long>(m_nCCs);
temp.clear();
temp.push_back(m_vertices[v].m_name);
while (temp.size())
{
long vertex = temp[temp.size()-1];
temp.pop_back();
for(size_t ed = 0; ed < m_vertices[vertex].m_edges.Size(); ++ed)
{
idEdge = m_vertices[vertex].m_edges[ed];
if (m_edges[idEdge].m_v1 == vertex)
{
v2 = m_edges[idEdge].m_v2;
}
else
{
v2 = m_edges[idEdge].m_v1;
}
if ( !m_vertices[v2].m_deleted && m_vertices[v2].m_cc == -1)
{
m_vertices[v2].m_cc = static_cast<long>(m_nCCs);
temp.push_back(v2);
}
}
}
m_nCCs++;
}
}
return static_cast<long>(m_nCCs);
}
}

118
indra/libhacd/hacdGraph.h Normal file
View File

@@ -0,0 +1,118 @@
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#ifndef HACD_GRAPH_H
#define HACD_GRAPH_H
#include "hacdVersion.h"
#include "hacdVector.h"
#include "hacdICHull.h"
#include <map>
#include <vector>
#include "hacdSArray.h"
//#define HACD_PRECOMPUTE_CHULLS
namespace HACD
{
class GraphVertex;
class GraphEdge;
class Graph;
class HACD;
class GraphVertex
{
public:
bool AddEdge(long name)
{
m_edges.Insert(name);
return true;
}
bool DeleteEdge(long name);
GraphVertex();
~GraphVertex(){ delete m_convexHull;};
private:
long m_name;
long m_cc;
SArray<long, SARRAY_DEFAULT_MIN_SIZE> m_edges;
bool m_deleted;
std::vector<long> m_ancestors;
SArray<DPoint, SARRAY_DEFAULT_MIN_SIZE> m_distPoints;
Real m_concavity;
double m_surf;
ICHull * m_convexHull;
SArray<unsigned long long, SARRAY_DEFAULT_MIN_SIZE> m_boudaryEdges;
friend class GraphEdge;
friend class Graph;
friend class HACD;
};
class GraphEdge
{
public:
GraphEdge();
~GraphEdge()
{
#ifdef HACD_PRECOMPUTE_CHULLS
delete m_convexHull;
#endif
};
private:
long m_name;
long m_v1;
long m_v2;
double m_concavity;
Real m_error;
#ifdef HACD_PRECOMPUTE_CHULLS
ICHull * m_convexHull;
#endif
bool m_deleted;
friend class GraphVertex;
friend class Graph;
friend class HACD;
};
class Graph
{
public:
size_t GetNEdges() const { return m_nE;}
size_t GetNVertices() const { return m_nV;}
bool EdgeCollapse(long v1, long v2);
long AddVertex();
long AddEdge(long v1, long v2);
bool DeleteEdge(long name);
bool DeleteVertex(long name);
long GetEdgeID(long v1, long v2) const;
void Clear();
void Print() const;
long ExtractCCs();
Graph();
virtual ~Graph();
void Allocate(size_t nV, size_t nE);
private:
size_t m_nCCs;
size_t m_nV;
size_t m_nE;
std::vector<GraphEdge> m_edges;
std::vector<GraphVertex> m_vertices;
friend class HACD;
};
}
#endif

1142
indra/libhacd/hacdHACD.cpp Normal file

File diff suppressed because it is too large Load Diff

330
indra/libhacd/hacdHACD.h Normal file
View File

@@ -0,0 +1,330 @@
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#ifndef HACD_HACD_H
#define HACD_HACD_H
#include "hacdVersion.h"
#include "hacdVector.h"
#include "hacdGraph.h"
#include "hacdICHull.h"
#include <set>
#include <vector>
#include <queue>
namespace HACD
{
const double sc_pi = 3.14159265;
class HACD;
// just to be able to set the capcity of the container
template<class _Ty, class _Container = std::vector<_Ty>, class _Pr = std::less<typename _Container::value_type> >
class reservable_priority_queue: public std::priority_queue<_Ty, _Container, _Pr>
{
typedef typename std::priority_queue<_Ty, _Container, _Pr>::size_type size_type;
public:
reservable_priority_queue(size_type capacity = 0) { reserve(capacity); };
void reserve(size_type capacity) { this->c.reserve(capacity); }
size_type capacity() const { return this->c.capacity(); }
};
//! priority queque element
class HACD;
class GraphEdgePriorityQueue
{
public:
//! Constructor
//! @param name edge's id
//! @param priority edge's priority
GraphEdgePriorityQueue(long name, Real priority)
{
m_name = name;
m_priority = priority;
}
//! Destructor
~GraphEdgePriorityQueue(void){}
private:
long m_name; //!< edge name
Real m_priority; //!< priority
//! Operator < for GraphEdgePQ
friend bool operator<(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs);
//! Operator > for GraphEdgePQ
friend bool operator>(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs);
friend class HACD;
};
inline bool operator<(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs)
{
return (lhs.m_priority<rhs.m_priority);
}
inline bool operator>(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs)
{
return lhs.m_priority>rhs.m_priority;
}
class ICallback
{
public:
virtual void operator()( char const *aMsg, double aProgress, double aConcavity, size_t aVertices) = 0;
};
typedef ICallback* CallBackFunction;
//! Provides an implementation of the Hierarchical Approximate Convex Decomposition (HACD) technique described in "A Simple and Efficient Approach for 3D Mesh Approximate Convex Decomposition" Game Programming Gems 8 - Chapter 2.8, p.202. A short version of the chapter was published in ICIP09 and is available at ftp://ftp.elet.polimi.it/users/Stefano.Tubaro/ICIP_USB_Proceedings_v2/pdfs/0003501.pdf
class HACD
{
public:
//! Gives the targeted number of triangles of the decimated mesh
//! @return targeted number of triangles of the decimated mesh
size_t GetTargetNTrianglesDecimatedMesh() const { return m_targetNTrianglesDecimatedMesh;}
//! Sets the targeted number of triangles of the decimated mesh
//! @param targeted number of triangles of the decimated mesh
void SetNTargetTrianglesDecimatedMesh(size_t targetNTrianglesDecimatedMesh) { m_targetNTrianglesDecimatedMesh = targetNTrianglesDecimatedMesh;}
//! Gives the triangles partitionas an array of size m_nTriangles where the i-th element specifies the cluster to which belong the i-th triangle
//! @return triangles partition
const long * const GetPartition() const { return m_partition;}
//! Sets the scale factor
//! @param scale scale factor
void SetScaleFactor(double scale) { m_scale = scale;}
//! Gives the scale factor
//! @return scale factor
const double GetScaleFactor() const { return m_scale;}
//! Sets the threshold to detect small clusters. The threshold is expressed as a percentage of the total mesh surface (default 0.25%)
//! @param smallClusterThreshold threshold to detect small clusters
void SetSmallClusterThreshold(double smallClusterThreshold) { m_smallClusterThreshold = smallClusterThreshold;}
//! Gives the threshold to detect small clusters. The threshold is expressed as a percentage of the total mesh surface (default 0.25%)
//! @return threshold to detect small clusters
const double GetSmallClusterThreshold() const { return m_smallClusterThreshold;}
//! Sets the call-back function
//! @param callBack pointer to the call-back function
void SetCallBack(CallBackFunction callBack) { m_callBack = callBack;}
//! Gives the call-back function
//! @return pointer to the call-back function
const CallBackFunction GetCallBack() const { return m_callBack;}
//! Specifies whether faces points should be added when computing the concavity
//! @param addFacesPoints true = faces points should be added
void SetAddFacesPoints(bool addFacesPoints) { m_addFacesPoints = addFacesPoints;}
//! Specifies wheter faces points should be added when computing the concavity
//! @return true = faces points should be added
const bool GetAddFacesPoints() const { return m_addFacesPoints;}
//! Specifies whether extra points should be added when computing the concavity
//! @param addExteraDistPoints true = extra points should be added
void SetAddExtraDistPoints(bool addExtraDistPoints) { m_addExtraDistPoints = addExtraDistPoints;}
//! Specifies wheter extra points should be added when computing the concavity
//! @return true = extra points should be added
const bool GetAddExtraDistPoints() const { return m_addExtraDistPoints;}
//! Sets the points of the input mesh (Remark: the input points will be scaled and shifted. Use DenormalizeData() to invert those operations)
//! @param points pointer to the input points
void SetPoints(Vec3<Real> * points) { m_points = points;}
//! Gives the points of the input mesh (Remark: the input points will be scaled and shifted. Use DenormalizeData() to invert those operations)
//! @return pointer to the input points
const Vec3<Real> * GetPoints() const { return m_points;}
//! Gives the points of the decimated mesh
//! @return pointer to the decimated mesh points
const Vec3<Real> * GetDecimatedPoints() const { return m_pointsDecimated;}
//! Gives the triangles in the decimated mesh
//! @return pointer to the decimated mesh triangles
const Vec3<long> * GetDecimatedTriangles() const { return m_trianglesDecimated;}
//! Gives the number of points in the decimated mesh.
//! @return number of points the decimated mesh mesh
const size_t GetNDecimatedPoints() const { return m_nPointsDecimated;}
//! Gives the number of triangles in the decimated mesh.
//! @return number of triangles the decimated mesh
const size_t GetNDecimatedTriangles() const { return m_nTrianglesDecimated;}
//! Sets the triangles of the input mesh.
//! @param triangles points pointer to the input points
void SetTriangles(Vec3<long> * triangles) { m_triangles = triangles;}
//! Gives the triangles in the input mesh
//! @return pointer to the input triangles
const Vec3<long> * GetTriangles() const { return m_triangles;}
//! Sets the number of points in the input mesh.
//! @param nPoints number of points the input mesh
void SetNPoints(size_t nPoints) { m_nPoints = nPoints;}
//! Gives the number of points in the input mesh.
//! @return number of points the input mesh
const size_t GetNPoints() const { return m_nPoints;}
//! Sets the number of triangles in the input mesh.
//! @param nTriangles number of triangles in the input mesh
void SetNTriangles(size_t nTriangles) { m_nTriangles = nTriangles;}
//! Gives the number of triangles in the input mesh.
//! @return number of triangles the input mesh
const size_t GetNTriangles() const { return m_nTriangles;}
//! Sets the minimum number of clusters to be generated.
//! @param nClusters minimum number of clusters
void SetNClusters(size_t nClusters) { m_nMinClusters = nClusters;}
//! Gives the number of generated clusters.
//! @return number of generated clusters
const size_t GetNClusters() const { return m_nClusters;}
//! Sets the maximum allowed concavity.
//! @param concavity maximum concavity
void SetConcavity(double concavity) { m_concavity = concavity;}
//! Gives the maximum allowed concavity.
//! @return maximum concavity
double GetConcavity() const { return m_concavity;}
//! Sets the maximum allowed distance to get CCs connected.
//! @param concavity maximum distance to get CCs connected
void SetConnectDist(double ccConnectDist) { m_ccConnectDist = ccConnectDist;}
//! Gives the maximum allowed distance to get CCs connected.
//! @return maximum distance to get CCs connected
double GetConnectDist() const { return m_ccConnectDist;}
//! Sets the volume weight.
//! @param beta volume weight
void SetVolumeWeight(double beta) { m_beta = beta;}
//! Gives the volume weight.
//! @return volume weight
double GetVolumeWeight() const { return m_beta;}
//! Sets the compacity weight (i.e. parameter alpha in ftp://ftp.elet.polimi.it/users/Stefano.Tubaro/ICIP_USB_Proceedings_v2/pdfs/0003501.pdf).
//! @param alpha compacity weight
void SetCompacityWeight(double alpha) { m_alpha = alpha;}
//! Gives the compacity weight (i.e. parameter alpha in ftp://ftp.elet.polimi.it/users/Stefano.Tubaro/ICIP_USB_Proceedings_v2/pdfs/0003501.pdf).
//! @return compacity weight
double GetCompacityWeight() const { return m_alpha;}
//! Sets the maximum number of vertices for each generated convex-hull.
//! @param nVerticesPerCH maximum # vertices per CH
void SetNVerticesPerCH(size_t nVerticesPerCH) { m_nVerticesPerCH = nVerticesPerCH;}
//! Gives the maximum number of vertices for each generated convex-hull.
//! @return maximum # vertices per CH
const size_t GetNVerticesPerCH() const { return m_nVerticesPerCH;}
//! Gives the number of vertices for the cluster number numCH.
//! @return number of vertices
size_t GetNPointsCH(size_t numCH) const;
//! Gives the number of triangles for the cluster number numCH.
//! @param numCH cluster's number
//! @return number of triangles
size_t GetNTrianglesCH(size_t numCH) const;
//! Gives the vertices and the triangles of the cluster number numCH.
//! @param numCH cluster's number
//! @param points pointer to the vector of points to be filled
//! @param triangles pointer to the vector of triangles to be filled
//! @return true if sucess
bool GetCH(size_t numCH, Vec3<Real> * const points, Vec3<long> * const triangles);
//! Computes the HACD decomposition.
//! @param fullCH specifies whether to generate convex-hulls with a full or limited (i.e. < m_nVerticesPerCH) number of vertices
//! @param exportDistPoints specifies wheter distance points should ne exported or not (used only for debugging).
//! @return true if sucess
bool Compute(bool fullCH=false, bool exportDistPoints=false);
#if 0
//! Saves the generated convex-hulls in a VRML 2.0 file.
//! @param fileName the output file name
//! @param uniColor specifies whether the different convex-hulls should have the same color or not
//! @param numCluster specifies the cluster to be saved, if numCluster < 0 export all clusters
//! @return true if sucess
bool Save(const char * fileName, bool uniColor, long numCluster=-1) const;
#endif
//! Shifts and scales to the data to have all the coordinates between 0.0 and 1000.0.
void NormalizeData();
//! Inverse the operations applied by NormalizeData().
void DenormalizeData();
//! Destructor.
~HACD(void);
private:
//! Constructor.
HACD(HeapManager * heapManager = 0);
//! Gives the edge index.
//! @param a first vertex id
//! @param b second vertex id
//! @return edge's index
static unsigned long long GetEdgeIndex(unsigned long long a, unsigned long long b)
{
if (a > b) return (a << 32) + b;
else return (b << 32) + a;
}
//! Computes the concavity of a cluster.
//! @param ch the cluster's convex-hull
//! @param distPoints the cluster's points
//! @return cluster's concavity
double Concavity(ICHull & ch, std::map<long, DPoint> & distPoints);
//! Computes the perimeter of a cluster.
//! @param triIndices the cluster's triangles
//! @param distPoints the cluster's points
//! @return cluster's perimeter
double ComputePerimeter(const std::vector<long> & triIndices) const;
//! Creates the Graph by associating to each mesh triangle a vertex in the graph and to each couple of adjacent triangles an edge in the graph.
void CreateGraph();
//! Initializes the graph costs and computes the vertices normals
void InitializeDualGraph();
//! Computes the cost of an edge
//! @param e edge's id
void ComputeEdgeCost(size_t e);
//! Initializes the priority queue
//! @param fast specifies whether fast mode is used
//! @return true if success
bool InitializePriorityQueue();
//! Cleans the intersection between convex-hulls
void CleanClusters();
//! Computes convex-hulls from partition information
//! @param fullCH specifies whether to generate convex-hulls with a full or limited (i.e. < m_nVerticesPerCH) number of vertices
void ComputeConvexHulls(bool fullCH);
//! Simplifies the graph
//! @param fast specifies whether fast mode is used
void Simplify();
private:
Vec3<long> * m_trianglesDecimated; //>! pointer the triangles array
Vec3<Real> * m_pointsDecimated; //>! pointer the points array
Vec3<long> * m_triangles; //>! pointer the triangles array
Vec3<Real> * m_points; //>! pointer the points array
Vec3<Real> * m_facePoints; //>! pointer to the faces points array
Vec3<Real> * m_faceNormals; //>! pointer to the faces normals array
Vec3<Real> * m_normals; //>! pointer the normals array
Vec3<Real> * m_extraDistPoints; //>! pointer to the faces points array
Vec3<Real> * m_extraDistNormals; //>! pointer to the faces normals array
size_t m_nTrianglesDecimated; //>! number of triangles in the original mesh
size_t m_nPointsDecimated; //>! number of vertices in the original mesh
size_t m_nTriangles; //>! number of triangles in the original mesh
size_t m_nPoints; //>! number of vertices in the original mesh
size_t m_nClusters; //>! number of clusters
size_t m_nMinClusters; //>! minimum number of clusters
double m_ccConnectDist; //>! maximum allowed distance to connect CCs
double m_concavity; //>! maximum concavity
double m_alpha; //>! compacity weigth
double m_beta; //>! volume weigth
double m_gamma; //>! computation cost
double m_diag; //>! length of the BB diagonal
double m_scale; //>! scale factor used for NormalizeData() and DenormalizeData()
double m_flatRegionThreshold; //>! threshhold to control the contirbution of flat regions concavity (default 1% of m_scale)
double m_smallClusterThreshold; //>! threshhold to detect small clusters (default 0.25% of the total mesh surface)
double m_area; //>! surface area
Vec3<Real> m_barycenter; //>! barycenter of the mesh
std::vector< long > m_cVertices; //>! array of vertices each belonging to a different cluster
ICHull * m_convexHulls; //>! convex-hulls associated with the final HACD clusters
Graph m_graph; //>! simplification graph
size_t m_nVerticesPerCH; //>! maximum number of vertices per convex-hull
reservable_priority_queue<GraphEdgePriorityQueue,
std::vector<GraphEdgePriorityQueue>,
std::greater<std::vector<GraphEdgePriorityQueue>::value_type> > m_pqueue; //!> priority queue
HACD(const HACD & rhs);
CallBackFunction m_callBack; //>! call-back function
long * m_partition; //>! array of size m_nTriangles where the i-th element specifies the cluster to which belong the i-th triangle
size_t m_targetNTrianglesDecimatedMesh; //>! specifies the target number of triangles in the decimated mesh. If set to 0 no decimation is applied.
HeapManager * m_heapManager; //>! Heap Manager
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 void DestroyHACD(HACD * const hacd);
};
inline HACD * const CreateHACD(HeapManager * heapManager)
{
return new HACD(heapManager);
}
inline void DestroyHACD(HACD * const hacd)
{
delete hacd;
}
}
#endif

1004
indra/libhacd/hacdICHull.cpp Normal file

File diff suppressed because it is too large Load Diff

133
indra/libhacd/hacdICHull.h Normal file
View File

@@ -0,0 +1,133 @@
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#ifndef HACD_ICHULL_H
#define HACD_ICHULL_H
#include "hacdVersion.h"
#include "hacdManifoldMesh.h"
#include "hacdVector.h"
#include <vector>
#include <map>
#include "hacdMicroAllocator.h"
namespace HACD
{
class DPoint;
class HACD;
//! Incremental Convex Hull algorithm (cf. http://maven.smith.edu/~orourke/books/ftp.html ).
enum ICHullError
{
ICHullErrorOK = 0,
ICHullErrorCoplanarPoints,
ICHullErrorNoVolume,
ICHullErrorInconsistent,
ICHullErrorNotEnoughPoints
};
class ICHull
{
public:
static const double sc_eps;
//!
HeapManager * const GetHeapManager() const { return m_heapManager;}
//!
void SetHeapManager(HeapManager * const heapManager)
{
m_heapManager = heapManager;
m_mesh.SetHeapManager(m_heapManager);
}
//!
bool IsFlat() { return m_isFlat;}
//!
std::map<long, DPoint> * GetDistPoints() const { return m_distPoints;}
//!
void SetDistPoints(std::map<long, DPoint> * distPoints) { m_distPoints = distPoints;}
//! Returns the computed mesh
TMMesh & GetMesh() { return m_mesh;}
//! Add one point to the convex-hull
bool AddPoint(const Vec3<Real> & point) {return AddPoints(&point, 1);}
//! Add one point to the convex-hull
bool AddPoint(const Vec3<Real> & point, long id);
//! Add points to the convex-hull
bool AddPoints(const Vec3<Real> * points, size_t nPoints);
bool AddPoints(std::vector< Vec3<Real> > points);
//!
ICHullError Process();
//!
ICHullError Process(unsigned long nPointsCH);
//!
double ComputeVolume();
//!
double ComputeArea();
//!
bool IsInside(const Vec3<Real> & pt0, const double eps = 0.0);
//!
double ComputeDistance(long name, const Vec3<Real> & pt, const Vec3<Real> & normal, bool & insideHull, bool updateIncidentPoints);
//!
const ICHull & operator=(ICHull & rhs);
//! Constructor
ICHull(HeapManager * const heapManager=0);
//! Destructor
virtual ~ICHull(void) {};
private:
//! DoubleTriangle builds the initial double triangle. It first finds 3 noncollinear points and makes two faces out of them, in opposite order. It then finds a fourth point that is not coplanar with that face. The vertices are stored in the face structure in counterclockwise order so that the volume between the face and the point is negative. Lastly, the 3 newfaces to the fourth point are constructed and the data structures are cleaned up.
ICHullError DoubleTriangle();
//! MakeFace creates a new face structure from three vertices (in ccw order). It returns a pointer to the face.
CircularListElement<TMMTriangle> * MakeFace(CircularListElement<TMMVertex> * v0,
CircularListElement<TMMVertex> * v1,
CircularListElement<TMMVertex> * v2,
CircularListElement<TMMTriangle> * fold);
//!
CircularListElement<TMMTriangle> * MakeConeFace(CircularListElement<TMMEdge> * e, CircularListElement<TMMVertex> * v);
//!
bool ProcessPoint();
//!
bool ComputePointVolume(double &totalVolume, bool markVisibleFaces);
//!
bool FindMaxVolumePoint();
//!
bool CleanEdges();
//!
bool CleanVertices(unsigned long & addedPoints);
//!
bool CleanTriangles();
//!
bool CleanUp(unsigned long & addedPoints);
//!
bool MakeCCW(CircularListElement<TMMTriangle> * f,
CircularListElement<TMMEdge> * e,
CircularListElement<TMMVertex> * v);
void Clear();
private:
static const long sc_dummyIndex;
static const double sc_distMin;
TMMesh m_mesh;
std::vector<CircularListElement<TMMEdge> *> m_edgesToDelete;
std::vector<CircularListElement<TMMEdge> *> m_edgesToUpdate;
std::vector<CircularListElement<TMMTriangle> *> m_trianglesToDelete;
std::map<long, DPoint> * m_distPoints;
// CircularListElement<TMMVertex> * m_dummyVertex;
Vec3<Real> m_normal;
bool m_isFlat;
HeapManager * m_heapManager;
ICHull(const ICHull & rhs);
friend class HACD;
};
}
#endif

View File

@@ -0,0 +1,604 @@
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "hacdManifoldMesh.h"
using namespace std;
namespace HACD
{
Material::Material(void)
{
m_diffuseColor.X() = 0.5;
m_diffuseColor.Y() = 0.5;
m_diffuseColor.Z() = 0.5;
m_specularColor.X() = 0.5;
m_specularColor.Y() = 0.5;
m_specularColor.Z() = 0.5;
m_ambientIntensity = 0.4;
m_emissiveColor.X() = 0.0;
m_emissiveColor.Y() = 0.0;
m_emissiveColor.Z() = 0.0;
m_shininess = 0.4;
m_transparency = 0.0;
}
TMMVertex::TMMVertex(void)
{
Initialize();
}
void TMMVertex::Initialize()
{
m_name = 0;
m_id = 0;
m_duplicate = 0;
m_onHull = false;
m_tag = false;
}
TMMVertex::~TMMVertex(void)
{
}
TMMEdge::TMMEdge(void)
{
Initialize();
}
void TMMEdge::Initialize()
{
m_id = 0;
m_triangles[0] = m_triangles[1] = m_newFace = 0;
m_vertices[0] = m_vertices[1] = 0;
}
TMMEdge::~TMMEdge(void)
{
}
void TMMTriangle::Initialize()
{
m_id = 0;
for(int i = 0; i < 3; i++)
{
m_edges[i] = 0;
m_vertices[0] = 0;
}
m_visible = false;
m_incidentPoints.Initialize();
}
TMMTriangle::TMMTriangle(void)
{
Initialize();
}
TMMTriangle::~TMMTriangle(void)
{
}
TMMesh::TMMesh(HeapManager * const heapManager):
m_vertices(heapManager),
m_edges(heapManager),
m_triangles(heapManager)
{
m_barycenter = Vec3<Real>(0,0,0);
m_diag = 1;
m_heapManager = heapManager;
}
TMMesh::~TMMesh(void)
{
}
void TMMesh::Print()
{
size_t nV = m_vertices.GetSize();
std::cout << "-----------------------------" << std::endl;
std::cout << "vertices (" << nV << ")" << std::endl;
for(size_t v = 0; v < nV; v++)
{
const TMMVertex & currentVertex = m_vertices.GetData();
std::cout << currentVertex.m_id << ", "
<< currentVertex.m_pos.X() << ", "
<< currentVertex.m_pos.Y() << ", "
<< currentVertex.m_pos.Z() << std::endl;
m_vertices.Next();
}
size_t nE = m_edges.GetSize();
std::cout << "edges (" << nE << ")" << std::endl;
for(size_t e = 0; e < nE; e++)
{
const TMMEdge & currentEdge = m_edges.GetData();
const CircularListElement<TMMVertex> * v0 = currentEdge.m_vertices[0];
const CircularListElement<TMMVertex> * v1 = currentEdge.m_vertices[1];
const CircularListElement<TMMTriangle> * f0 = currentEdge.m_triangles[0];
const CircularListElement<TMMTriangle> * f1 = currentEdge.m_triangles[1];
std::cout << "-> (" << v0->GetData().m_name << ", " << v1->GetData().m_name << ")" << std::endl;
std::cout << "-> F0 (" << f0->GetData().m_vertices[0]->GetData().m_name << ", "
<< f0->GetData().m_vertices[1]->GetData().m_name << ", "
<< f0->GetData().m_vertices[2]->GetData().m_name <<")" << std::endl;
std::cout << "-> F1 (" << f1->GetData().m_vertices[0]->GetData().m_name << ", "
<< f1->GetData().m_vertices[1]->GetData().m_name << ", "
<< f1->GetData().m_vertices[2]->GetData().m_name << ")" << std::endl;
m_edges.Next();
}
size_t nT = m_triangles.GetSize();
std::cout << "triangles (" << nT << ")" << std::endl;
for(size_t t = 0; t < nT; t++)
{
const TMMTriangle & currentTriangle = m_triangles.GetData();
const CircularListElement<TMMVertex> * v0 = currentTriangle.m_vertices[0];
const CircularListElement<TMMVertex> * v1 = currentTriangle.m_vertices[1];
const CircularListElement<TMMVertex> * v2 = currentTriangle.m_vertices[2];
const CircularListElement<TMMEdge> * e0 = currentTriangle.m_edges[0];
const CircularListElement<TMMEdge> * e1 = currentTriangle.m_edges[1];
const CircularListElement<TMMEdge> * e2 = currentTriangle.m_edges[2];
std::cout << "-> (" << v0->GetData().m_name << ", " << v1->GetData().m_name << ", "<< v2->GetData().m_name << ")" << std::endl;
std::cout << "-> E0 (" << e0->GetData().m_vertices[0]->GetData().m_name << ", "
<< e0->GetData().m_vertices[1]->GetData().m_name << ")" << std::endl;
std::cout << "-> E1 (" << e1->GetData().m_vertices[0]->GetData().m_name << ", "
<< e1->GetData().m_vertices[1]->GetData().m_name << ")" << std::endl;
std::cout << "-> E2 (" << e2->GetData().m_vertices[0]->GetData().m_name << ", "
<< e2->GetData().m_vertices[1]->GetData().m_name << ")" << std::endl;
m_triangles.Next();
}
}
#if 0
bool TMMesh::Save(const char *fileName)
{
std::ofstream fout(fileName);
std::cout << "Saving " << fileName << std::endl;
if (SaveVRML2(fout))
{
fout.close();
return true;
}
return false;
}
bool TMMesh::SaveVRML2(std::ofstream &fout)
{
return SaveVRML2(fout, Material());
}
bool TMMesh::SaveVRML2(std::ofstream &fout, const Material & material)
{
if (fout.is_open())
{
size_t nV = m_vertices.GetSize();
size_t nT = m_triangles.GetSize();
fout <<"#VRML V2.0 utf8" << std::endl;
fout <<"" << std::endl;
fout <<"# Vertices: " << nV << std::endl;
fout <<"# Triangles: " << nT << std::endl;
fout <<"" << std::endl;
fout <<"Group {" << std::endl;
fout <<" children [" << std::endl;
fout <<" Shape {" << std::endl;
fout <<" appearance Appearance {" << std::endl;
fout <<" material Material {" << std::endl;
fout <<" diffuseColor " << material.m_diffuseColor.X() << " "
<< material.m_diffuseColor.Y() << " "
<< material.m_diffuseColor.Z() << std::endl;
fout <<" ambientIntensity " << material.m_ambientIntensity << std::endl;
fout <<" specularColor " << material.m_specularColor.X() << " "
<< material.m_specularColor.Y() << " "
<< material.m_specularColor.Z() << std::endl;
fout <<" emissiveColor " << material.m_emissiveColor.X() << " "
<< material.m_emissiveColor.Y() << " "
<< material.m_emissiveColor.Z() << std::endl;
fout <<" shininess " << material.m_shininess << std::endl;
fout <<" transparency " << material.m_transparency << std::endl;
fout <<" }" << std::endl;
fout <<" }" << std::endl;
fout <<" geometry IndexedFaceSet {" << std::endl;
fout <<" ccw TRUE" << std::endl;
fout <<" solid TRUE" << std::endl;
fout <<" convex TRUE" << std::endl;
if (GetNVertices() > 0) {
fout <<" coord DEF co Coordinate {" << std::endl;
fout <<" point [" << std::endl;
for(size_t v = 0; v < nV; v++)
{
TMMVertex & currentVertex = m_vertices.GetData();
fout <<" " << currentVertex.m_pos.X() << " "
<< currentVertex.m_pos.Y() << " "
<< currentVertex.m_pos.Z() << "," << std::endl;
currentVertex.m_id = v;
m_vertices.Next();
}
fout <<" ]" << std::endl;
fout <<" }" << std::endl;
}
if (GetNTriangles() > 0) {
fout <<" coordIndex [ " << std::endl;
for(size_t f = 0; f < nT; f++)
{
TMMTriangle & currentTriangle = m_triangles.GetData();
fout <<" " << currentTriangle.m_vertices[0]->GetData().m_id << ", "
<< currentTriangle.m_vertices[1]->GetData().m_id << ", "
<< currentTriangle.m_vertices[2]->GetData().m_id << ", -1," << std::endl;
m_triangles.Next();
}
fout <<" ]" << std::endl;
}
fout <<" }" << std::endl;
fout <<" }" << std::endl;
fout <<" ]" << std::endl;
fout <<"}" << std::endl;
}
return true;
}
#endif
void TMMesh::GetIFS(Vec3<Real> * const points, Vec3<long> * const triangles)
{
size_t nV = m_vertices.GetSize();
size_t nT = m_triangles.GetSize();
for(size_t v = 0; v < nV; v++)
{
points[v] = m_vertices.GetData().m_pos;
m_vertices.GetData().m_id = v;
m_vertices.Next();
}
for(size_t f = 0; f < nT; f++)
{
TMMTriangle & currentTriangle = m_triangles.GetData();
triangles[f].X() = static_cast<long>(currentTriangle.m_vertices[0]->GetData().m_id);
triangles[f].Y() = static_cast<long>(currentTriangle.m_vertices[1]->GetData().m_id);
triangles[f].Z() = static_cast<long>(currentTriangle.m_vertices[2]->GetData().m_id);
m_triangles.Next();
}
}
void TMMesh::Clear()
{
m_vertices.Clear();
m_edges.Clear();
m_triangles.Clear();
}
void TMMesh::Copy(TMMesh & mesh)
{
Clear();
// updating the id's
size_t nV = mesh.m_vertices.GetSize();
size_t nE = mesh. m_edges.GetSize();
size_t nT = mesh.m_triangles.GetSize();
for(size_t v = 0; v < nV; v++)
{
mesh.m_vertices.GetData().m_id = v;
mesh.m_vertices.Next();
}
for(size_t e = 0; e < nE; e++)
{
mesh.m_edges.GetData().m_id = e;
mesh.m_edges.Next();
}
for(size_t f = 0; f < nT; f++)
{
mesh.m_triangles.GetData().m_id = f;
mesh.m_triangles.Next();
}
// copying data
m_vertices = mesh.m_vertices;
m_edges = mesh.m_edges;
m_triangles = mesh.m_triangles;
m_heapManager = mesh.m_heapManager;
// generating mapping
CircularListElement<TMMVertex> ** vertexMap = new CircularListElement<TMMVertex> * [nV];
CircularListElement<TMMEdge> ** edgeMap = new CircularListElement<TMMEdge> * [nE];
CircularListElement<TMMTriangle> ** triangleMap = new CircularListElement<TMMTriangle> * [nT];
for(size_t v = 0; v < nV; v++)
{
vertexMap[v] = m_vertices.GetHead();
m_vertices.Next();
}
for(size_t e = 0; e < nE; e++)
{
edgeMap[e] = m_edges.GetHead();
m_edges.Next();
}
for(size_t f = 0; f < nT; f++)
{
triangleMap[f] = m_triangles.GetHead();
m_triangles.Next();
}
// updating pointers
for(size_t v = 0; v < nV; v++)
{
if (vertexMap[v]->GetData().m_duplicate)
{
vertexMap[v]->GetData().m_duplicate = edgeMap[vertexMap[v]->GetData().m_duplicate->GetData().m_id];
}
}
for(size_t e = 0; e < nE; e++)
{
if (edgeMap[e]->GetData().m_newFace)
{
edgeMap[e]->GetData().m_newFace = triangleMap[edgeMap[e]->GetData().m_newFace->GetData().m_id];
}
if (nT > 0)
{
for(int f = 0; f < 2; f++)
{
if (edgeMap[e]->GetData().m_triangles[f])
{
edgeMap[e]->GetData().m_triangles[f] = triangleMap[edgeMap[e]->GetData().m_triangles[f]->GetData().m_id];
}
}
}
for(int v = 0; v < 2; v++)
{
if (edgeMap[e]->GetData().m_vertices[v])
{
edgeMap[e]->GetData().m_vertices[v] = vertexMap[edgeMap[e]->GetData().m_vertices[v]->GetData().m_id];
}
}
}
for(size_t f = 0; f < nT; f++)
{
if (nE > 0)
{
for(int e = 0; e < 3; e++)
{
if (triangleMap[f]->GetData().m_edges[e])
{
triangleMap[f]->GetData().m_edges[e] = edgeMap[triangleMap[f]->GetData().m_edges[e]->GetData().m_id];
}
}
}
for(int v = 0; v < 3; v++)
{
if (triangleMap[f]->GetData().m_vertices[v])
{
triangleMap[f]->GetData().m_vertices[v] = vertexMap[triangleMap[f]->GetData().m_vertices[v]->GetData().m_id];
}
}
}
delete [] vertexMap;
delete [] edgeMap;
delete [] triangleMap;
}
long IntersectRayTriangle(const Vec3<double> & P0, const Vec3<double> & dir,
const Vec3<double> & V0, const Vec3<double> & V1,
const Vec3<double> & V2, double &t)
{
const double EPS = 1e-9;
const double EPS1 = 1e-6;
t = 0.0;
Vec3<double> edge1, edge2, edge3;
double det;
edge1 = V1 - V2;
edge2 = V2 - V0;
Vec3<double> pvec = dir ^ edge2;
det = edge1 * pvec;
if (det < EPS && det > -EPS)
return 0;
Vec3<double> tvec = P0 - V0;
Vec3<double> qvec = tvec ^ edge1;
t = (edge2 * qvec) / det;
if (t < 0.0)
{
return 0;
}
edge3 = V0 - V1;
Vec3<double> I(P0 + t * dir);
Vec3<double> s0 = (I-V0) ^ edge3;
Vec3<double> s1 = (I-V1) ^ edge1;
Vec3<double> s2 = (I-V2) ^ edge2;
Vec3<double> normal = edge1 ^ edge2;
double diff = normal.GetNorm() - s0.GetNorm() - s1.GetNorm() - s2.GetNorm();
if (diff < EPS1 && diff > -EPS1)
{
return 1;
}
return 0;
}
bool IntersectLineLine(const Vec3<double> & p1, const Vec3<double> & p2,
const Vec3<double> & p3, const Vec3<double> & p4,
Vec3<double> & pa, Vec3<double> & pb,
double & mua, double & mub)
{
Vec3<double> p13,p43,p21;
double d1343,d4321,d1321,d4343,d2121;
double numer,denom;
p13.X() = p1.X() - p3.X();
p13.Y() = p1.Y() - p3.Y();
p13.Z() = p1.Z() - p3.Z();
p43.X() = p4.X() - p3.X();
p43.Y() = p4.Y() - p3.Y();
p43.Z() = p4.Z() - p3.Z();
if (p43.X()==0.0 && p43.Y()==0.0 && p43.Z()==0.0)
return false;
p21.X() = p2.X() - p1.X();
p21.Y() = p2.Y() - p1.Y();
p21.Z() = p2.Z() - p1.Z();
if (p21.X()==0.0 && p21.Y()==0.0 && p21.Z()==0.0)
return false;
d1343 = p13.X() * p43.X() + p13.Y() * p43.Y() + p13.Z() * p43.Z();
d4321 = p43.X() * p21.X() + p43.Y() * p21.Y() + p43.Z() * p21.Z();
d1321 = p13.X() * p21.X() + p13.Y() * p21.Y() + p13.Z() * p21.Z();
d4343 = p43.X() * p43.X() + p43.Y() * p43.Y() + p43.Z() * p43.Z();
d2121 = p21.X() * p21.X() + p21.Y() * p21.Y() + p21.Z() * p21.Z();
denom = d2121 * d4343 - d4321 * d4321;
if (denom==0.0)
return false;
numer = d1343 * d4321 - d1321 * d4343;
mua = numer / denom;
mub = (d1343 + d4321 * (mua)) / d4343;
pa.X() = p1.X() + mua * p21.X();
pa.Y() = p1.Y() + mua * p21.Y();
pa.Z() = p1.Z() + mua * p21.Z();
pb.X() = p3.X() + mub * p43.X();
pb.Y() = p3.Y() + mub * p43.Y();
pb.Z() = p3.Z() + mub * p43.Z();
return true;
}
long IntersectRayTriangle2(const Vec3<double> & P0, const Vec3<double> & dir,
const Vec3<double> & V0, const Vec3<double> & V1,
const Vec3<double> & V2, double &r)
{
Vec3<double> u, v, n; // triangle vectors
Vec3<double> w0, w; // ray vectors
double a, b; // params to calc ray-plane intersect
// get triangle edge vectors and plane normal
u = V1 - V0;
v = V2 - V0;
n = u ^ v; // cross product
if (n.GetNorm() == 0.0) // triangle is degenerate
return -1; // do not deal with this case
w0 = P0 - V0;
a = - n * w0;
b = n * dir;
if (fabs(b) <= 0.0) { // ray is parallel to triangle plane
if (a == 0.0) // ray lies in triangle plane
return 2;
else return 0; // ray disjoint from plane
}
// get intersect point of ray with triangle plane
r = a / b;
if (r < 0.0) // ray goes away from triangle
return 0; // => no intersect
// for a segment, also test if (r > 1.0) => no intersect
Vec3<double> I = P0 + r * dir; // intersect point of ray and plane
// is I inside T?
double uu, uv, vv, wu, wv, D;
uu = u * u;
uv = u * v;
vv = v * v;
w = I - V0;
wu = w * u;
wv = w * v;
D = uv * uv - uu * vv;
// get and test parametric coords
double s, t;
s = (uv * wv - vv * wu) / D;
if (s < 0.0 || s > 1.0) // I is outside T
return 0;
t = (uv * wu - uu * wv) / D;
if (t < 0.0 || (s + t) > 1.0) // I is outside T
return 0;
return 1; // I is in T
}
bool TMMesh::CheckConsistancy()
{
size_t nE = m_edges.GetSize();
size_t nT = m_triangles.GetSize();
for(size_t e = 0; e < nE; e++)
{
for(int f = 0; f < 2; f++)
{
if (!m_edges.GetHead()->GetData().m_triangles[f])
{
return false;
}
}
m_edges.Next();
}
for(size_t f = 0; f < nT; f++)
{
for(int e = 0; e < 3; e++)
{
int found = 0;
for(int k = 0; k < 2; k++)
{
if (m_triangles.GetHead()->GetData().m_edges[e]->GetData().m_triangles[k] == m_triangles.GetHead())
{
found++;
}
}
if (found != 1)
{
return false;
}
}
m_triangles.Next();
}
return true;
}
bool TMMesh::Normalize()
{
size_t nV = m_vertices.GetSize();
if (nV == 0)
{
return false;
}
m_barycenter = m_vertices.GetHead()->GetData().m_pos;
Vec3<Real> min = m_barycenter;
Vec3<Real> max = m_barycenter;
Real x, y, z;
for(size_t v = 1; v < nV; v++)
{
m_barycenter += m_vertices.GetHead()->GetData().m_pos;
x = m_vertices.GetHead()->GetData().m_pos.X();
y = m_vertices.GetHead()->GetData().m_pos.Y();
z = m_vertices.GetHead()->GetData().m_pos.Z();
if ( x < min.X()) min.X() = x;
else if ( x > max.X()) max.X() = x;
if ( y < min.Y()) min.Y() = y;
else if ( y > max.Y()) max.Y() = y;
if ( z < min.Z()) min.Z() = z;
else if ( z > max.Z()) max.Z() = z;
m_vertices.Next();
}
m_barycenter /= static_cast<Real>(nV);
m_diag = static_cast<Real>(0.001 * (max-min).GetNorm());
const Real invDiag = static_cast<Real>(1.0 / m_diag);
if (m_diag != 0.0)
{
for(size_t v = 0; v < nV; v++)
{
m_vertices.GetHead()->GetData().m_pos = (m_vertices.GetHead()->GetData().m_pos - m_barycenter) * invDiag;
m_vertices.Next();
}
}
return true;
}
bool TMMesh::Denormalize()
{
size_t nV = m_vertices.GetSize();
if (nV == 0)
{
return false;
}
if (m_diag != 0.0)
{
for(size_t v = 0; v < nV; v++)
{
m_vertices.GetHead()->GetData().m_pos = m_vertices.GetHead()->GetData().m_pos * m_diag + m_barycenter;
m_vertices.Next();
}
}
return false;
}
}

View File

@@ -0,0 +1,269 @@
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#ifndef HACD_MANIFOLD_MESH_H
#define HACD_MANIFOLD_MESH_H
#include <iostream>
#include <fstream>
#include "hacdVersion.h"
#include "hacdCircularList.h"
#include "hacdVector.h"
#include "hacdSArray.h"
#include <set>
#include "hacdMicroAllocator.h"
namespace HACD
{
class TMMTriangle;
class TMMEdge;
class TMMesh;
class ICHull;
class HACD;
class DPoint
{
public:
DPoint(long name=0, Real dist=0, bool computed=false, bool distOnly=false)
:m_name(name),
m_dist(dist),
m_computed(computed),
m_distOnly(distOnly){};
~DPoint(){};
private:
long m_name;
Real m_dist;
bool m_computed;
bool m_distOnly;
friend class TMMTriangle;
friend class TMMesh;
friend class GraphVertex;
friend class GraphEdge;
friend class Graph;
friend class ICHull;
friend class HACD;
};
//! Vertex data structure used in a triangular manifold mesh (TMM).
class TMMVertex
{
public:
void Initialize();
TMMVertex(void);
~TMMVertex(void);
private:
Vec3<Real> m_pos;
long m_name;
size_t m_id;
CircularListElement<TMMEdge> * m_duplicate; // pointer to incident cone edge (or NULL)
bool m_onHull;
bool m_tag;
TMMVertex(const TMMVertex & rhs);
friend class HACD;
friend class ICHull;
friend class TMMesh;
friend class TMMTriangle;
friend class TMMEdge;
};
//! Edge data structure used in a triangular manifold mesh (TMM).
class TMMEdge
{
public:
void Initialize();
TMMEdge(void);
~TMMEdge(void);
private:
size_t m_id;
CircularListElement<TMMTriangle> * m_triangles[2];
CircularListElement<TMMVertex> * m_vertices[2];
CircularListElement<TMMTriangle> * m_newFace;
TMMEdge(const TMMEdge & rhs);
friend class HACD;
friend class ICHull;
friend class TMMTriangle;
friend class TMMVertex;
friend class TMMesh;
};
//! Triangle data structure used in a triangular manifold mesh (TMM).
class TMMTriangle
{
public:
void Initialize();
TMMTriangle(void);
~TMMTriangle(void);
private:
size_t m_id;
CircularListElement<TMMEdge> * m_edges[3];
CircularListElement<TMMVertex> * m_vertices[3];
SArray<long, SARRAY_DEFAULT_MIN_SIZE> m_incidentPoints;
bool m_visible;
TMMTriangle(const TMMTriangle & rhs);
friend class HACD;
friend class ICHull;
friend class TMMesh;
friend class TMMVertex;
friend class TMMEdge;
};
class Material
{
public:
Material(void);
~Material(void){}
// private:
Vec3<double> m_diffuseColor;
double m_ambientIntensity;
Vec3<double> m_specularColor;
Vec3<double> m_emissiveColor;
double m_shininess;
double m_transparency;
friend class TMMesh;
friend class HACD;
};
//! triangular manifold mesh data structure.
class TMMesh
{
public:
//!
HeapManager * const GetHeapManager() const { return m_heapManager;}
//!
void SetHeapManager(HeapManager * const heapManager)
{
m_heapManager = heapManager;
m_vertices.SetHeapManager(m_heapManager);
m_edges.SetHeapManager(m_heapManager);
m_triangles.SetHeapManager(m_heapManager);
}
//! Returns the number of vertices>
inline size_t GetNVertices() const { return m_vertices.GetSize();}
//! Returns the number of edges
inline size_t GetNEdges() const { return m_edges.GetSize();}
//! Returns the number of triangles
inline size_t GetNTriangles() const { return m_triangles.GetSize();}
//! Returns the vertices circular list
inline const CircularList<TMMVertex> & GetVertices() const { return m_vertices;}
//! Returns the edges circular list
inline const CircularList<TMMEdge> & GetEdges() const { return m_edges;}
//! Returns the triangles circular list
inline const CircularList<TMMTriangle> & GetTriangles() const { return m_triangles;}
//! Returns the vertices circular list
inline CircularList<TMMVertex> & GetVertices() { return m_vertices;}
//! Returns the edges circular list
inline CircularList<TMMEdge> & GetEdges() { return m_edges;}
//! Returns the triangles circular list
inline CircularList<TMMTriangle> & GetTriangles() { return m_triangles;}
//! Add vertex to the mesh
CircularListElement<TMMVertex> * AddVertex() {return m_vertices.Add();}
//! Add vertex to the mesh
CircularListElement<TMMEdge> * AddEdge() {return m_edges.Add();}
//! Add vertex to the mesh
CircularListElement<TMMTriangle> * AddTriangle() {return m_triangles.Add();}
//! Print mesh information
void Print();
//!
void GetIFS(Vec3<Real> * const points, Vec3<long> * const triangles);
#if 0
//! Save mesh
bool Save(const char *fileName);
//! Save mesh to VRML 2.0 format
bool SaveVRML2(std::ofstream &fout);
//! Save mesh to VRML 2.0 format
bool SaveVRML2(std::ofstream &fout, const Material & material);
#endif
//!
void Clear();
//!
void Copy(TMMesh & mesh);
//!
bool CheckConsistancy();
//!
bool Normalize();
//!
bool Denormalize();
//! Constructor
TMMesh(HeapManager * const heapManager);
//! Destructor
virtual ~TMMesh(void);
private:
CircularList<TMMVertex> m_vertices;
CircularList<TMMEdge> m_edges;
CircularList<TMMTriangle> m_triangles;
Real m_diag; //>! length of the BB diagonal
Vec3<Real> m_barycenter; //>! barycenter of the mesh
HeapManager * m_heapManager;
// not defined
TMMesh(const TMMesh & rhs);
friend class ICHull;
friend class HACD;
};
//! IntersectRayTriangle(): intersect a ray with a 3D triangle
//! Input: a ray R, and a triangle T
//! Output: *I = intersection point (when it exists)
//! 0 = disjoint (no intersect)
//! 1 = intersect in unique point I1
long IntersectRayTriangle( const Vec3<double> & P0, const Vec3<double> & dir,
const Vec3<double> & V0, const Vec3<double> & V1,
const Vec3<double> & V2, double &t);
// intersect_RayTriangle(): intersect a ray with a 3D triangle
// Input: a ray R, and a triangle T
// Output: *I = intersection point (when it exists)
// Return: -1 = triangle is degenerate (a segment or point)
// 0 = disjoint (no intersect)
// 1 = intersect in unique point I1
// 2 = are in the same plane
long IntersectRayTriangle2(const Vec3<double> & P0, const Vec3<double> & dir,
const Vec3<double> & V0, const Vec3<double> & V1,
const Vec3<double> & V2, double &r);
/*
Calculate the line segment PaPb that is the shortest route between
two lines P1P2 and P3P4. Calculate also the values of mua and mub where
Pa = P1 + mua (P2 - P1)
Pb = P3 + mub (P4 - P3)
Return FALSE if no solution exists.
*/
bool IntersectLineLine(const Vec3<double> & p1, const Vec3<double> & p2,
const Vec3<double> & p3, const Vec3<double> & p4,
Vec3<double> & pa, Vec3<double> & pb,
double & mua, double &mub);
}
#endif

View File

@@ -0,0 +1,684 @@
#include <sstream>
#include <iostream>
#include <stdlib.h>
#include <algorithm>
#include <vector>
#include "hacdMeshDecimator.h"
namespace HACD
{
MeshDecimator::MeshDecimator(void)
{
m_triangles = 0;
m_points = 0;
m_nPoints = 0;
m_nInitialTriangles = 0;
m_nVertices = 0;
m_nTriangles = 0;
m_nEdges = 0;
m_trianglesTags = 0;
m_ecolManifoldConstraint = true;
m_callBack = 0;
}
MeshDecimator::~MeshDecimator(void)
{
ReleaseMemory();
}
void MeshDecimator::ReleaseMemory()
{
delete [] m_trianglesTags;
std::vector< MDVertex > emptyVertices(0);
m_vertices.swap(emptyVertices);
std::vector<MDEdge> emptyEdges(0);
m_edges.swap(emptyEdges);
m_pqueue = std::priority_queue<
MDEdgePriorityQueue,
std::vector<MDEdgePriorityQueue>,
std::less<MDEdgePriorityQueue> >();
m_triangles = 0;
m_points = 0;
m_nPoints = 0;
m_nInitialTriangles = 0;
m_nVertices = 0;
m_nTriangles = 0;
m_nEdges = 0;
m_trianglesTags = 0;
}
void MeshDecimator::Initialize(size_t nVertices, size_t nTriangles, Vec3<Float> * points, Vec3<long> * triangles)
{
m_nVertices = nVertices;
m_nTriangles = nTriangles;
m_nInitialTriangles = nTriangles;
m_points = points;
m_nPoints = nVertices;
m_triangles = triangles;
m_trianglesTags = new bool[m_nTriangles];
m_edges.reserve(3*m_nTriangles);
m_vertices.resize(m_nVertices);
for(size_t v = 0; v < m_nVertices; ++v)
{
m_vertices[v].m_tag = true;
}
long tri[3];
MDEdge edge;
edge.m_tag = true;
edge.m_onBoundary = true;
long nEdges = 0;
long idEdge;
long nTris = static_cast<long>(m_nTriangles);
for(long t = 0; t < nTris; ++t)
{
tri[0] = m_triangles[t].X();
tri[1] = m_triangles[t].Y();
tri[2] = m_triangles[t].Z();
m_trianglesTags[t] = true;
for(int k = 0; k < 3; ++k)
{
edge.m_v1 = tri[k];
edge.m_v2 = tri[(k+1)%3];
m_vertices[edge.m_v1].m_triangles.Insert(t);
idEdge = GetEdge(edge.m_v1, edge.m_v2);
if (idEdge == -1)
{
m_edges.push_back(edge);
m_vertices[edge.m_v1].m_edges.Insert(nEdges);
m_vertices[edge.m_v2].m_edges.Insert(nEdges);
++nEdges;
}
else
{
m_edges[idEdge].m_onBoundary = false;
}
}
}
m_nEdges = static_cast<size_t>(nEdges);
for(size_t v = 0; v < m_nVertices; ++v)
{
m_vertices[v].m_onBoundary = false;
for(size_t itE = 0; itE < m_vertices[v].m_edges.Size(); ++itE)
{
idEdge = m_vertices[v].m_edges[itE];
if (m_edges[idEdge].m_onBoundary)
{
m_vertices[v].m_onBoundary = true;
break;
}
}
}
}
long MeshDecimator::GetTriangle(long v1, long v2, long v3) const
{
long i, j, k;
long idTriangle;
for(size_t it = 0; it < m_vertices[v1].m_triangles.Size(); ++it)
{
idTriangle = m_vertices[v1].m_triangles[it];
i = m_triangles[idTriangle].X();
j = m_triangles[idTriangle].Y();
k = m_triangles[idTriangle].Z();
if ( (i==v1 && j==v2 && k==v3) || (i==v1 && j==v3 && k==v2) ||
(i==v2 && j==v1 && k==v3) || (i==v2 && j==v3 && k==v1) ||
(i==v3 && j==v2 && k==v1) || (i==v3 && j==v1 && k==v2) )
{
return idTriangle;
}
}
return -1;
}
long MeshDecimator::GetEdge(long v1, long v2) const
{
long idEdge;
for(size_t it = 0; it < m_vertices[v1].m_edges.Size(); ++it)
{
idEdge = m_vertices[v1].m_edges[it];
if ( (m_edges[idEdge].m_v1==v1 && m_edges[idEdge].m_v2==v2) ||
(m_edges[idEdge].m_v1==v2 && m_edges[idEdge].m_v2==v1) )
{
return idEdge;
}
}
return -1;
}
void MeshDecimator::EdgeCollapse(long v1, long v2)
{
long u, w;
int shift;
long idTriangle;
for(size_t itT = 0; itT < m_vertices[v2].m_triangles.Size(); ++itT)
{
idTriangle = m_vertices[v2].m_triangles[itT];
if (m_triangles[idTriangle].X() == v2)
{
shift = 0;
u = m_triangles[idTriangle].Y();
w = m_triangles[idTriangle].Z();
}
else if (m_triangles[idTriangle].Y() == v2)
{
shift = 1;
u = m_triangles[idTriangle].X();
w = m_triangles[idTriangle].Z();
}
else
{
shift = 2;
u = m_triangles[idTriangle].X();
w = m_triangles[idTriangle].Y();
}
if ((u == v1) || (w == v1))
{
m_trianglesTags[idTriangle] = false;
m_vertices[u].m_triangles.Erase(idTriangle);
m_vertices[w].m_triangles.Erase(idTriangle);
m_nTriangles--;
}
else if (GetTriangle(v1, u, w) == -1)
{
m_vertices[v1].m_triangles.Insert(idTriangle);
m_triangles[idTriangle][shift] = v1;
}
else
{
m_trianglesTags[idTriangle] = false;
m_vertices[u].m_triangles.Erase(idTriangle);
m_vertices[w].m_triangles.Erase(idTriangle);
m_nTriangles--;
}
}
long idEdge;
for(size_t itE = 0; itE < m_vertices[v2].m_edges.Size(); ++itE)
{
idEdge = m_vertices[v2].m_edges[itE];
w = (m_edges[idEdge].m_v1 == v2)? m_edges[idEdge].m_v2 : m_edges[idEdge].m_v1;
if (w==v1)
{
m_edges[idEdge].m_tag = false;
m_vertices[w].m_edges.Erase(idEdge);
m_nEdges--;
}
else if ( GetEdge(v1, w) == -1)
{
if (m_edges[idEdge].m_v1 == v2) m_edges[idEdge].m_v1 = v1;
else m_edges[idEdge].m_v2 = v1;
m_vertices[v1].m_edges.Insert(idEdge);
}
else
{
m_edges[idEdge].m_tag = false;
m_vertices[w].m_edges.Erase(idEdge);
m_nEdges--;
}
}
m_vertices[v2].m_tag = false;
m_nVertices--;
// update boundary edges
SArray<long, 64> incidentVertices;
incidentVertices.PushBack(v1);
for(size_t itE = 0; itE < m_vertices[v1].m_edges.Size(); ++itE)
{
incidentVertices.PushBack((m_edges[idEdge].m_v1!= v1)?m_edges[idEdge].m_v1:m_edges[idEdge].m_v2);
idEdge = m_vertices[v1].m_edges[itE];
m_edges[idEdge].m_onBoundary = (IsBoundaryEdge(m_edges[idEdge].m_v1, m_edges[idEdge].m_v2) != -1);
}
// update boundary vertices
long idVertex;
for(size_t itV = 0; itV < incidentVertices.Size(); ++itV)
{
idVertex = incidentVertices[itV];
m_vertices[idVertex].m_onBoundary = false;
for(size_t itE = 0; itE < m_vertices[idVertex].m_edges.Size(); ++itE)
{
idEdge = m_vertices[idVertex].m_edges[itE];
if (m_edges[idEdge].m_onBoundary)
{
m_vertices[idVertex].m_onBoundary = true;
break;
}
}
}
}
long MeshDecimator::IsBoundaryEdge(long v1, long v2) const
{
long commonTri = -1;
long itTriangle1, itTriangle2;
for(size_t itT1 = 0; itT1 < m_vertices[v1].m_triangles.Size(); ++itT1)
{
itTriangle1 = m_vertices[v1].m_triangles[itT1];
for(size_t itT2 = 0; itT2 < m_vertices[v2].m_triangles.Size(); ++itT2)
{
itTriangle2 = m_vertices[v2].m_triangles[itT2];
if (itTriangle1 == itTriangle2)
{
if (commonTri == -1)
{
commonTri = itTriangle1;
}
else
{
return -1;
}
}
}
}
return commonTri;
}
bool MeshDecimator::IsBoundaryVertex(long v) const
{
long idEdge;
for(size_t itE = 0; itE < m_vertices[v].m_edges.Size(); ++itE)
{
idEdge = m_vertices[v].m_edges[itE];
if ( IsBoundaryEdge(m_edges[idEdge].m_v1, m_edges[idEdge].m_v2) != -1) return true;
}
return false;
}
void MeshDecimator::GetMeshData(Vec3<Float> * points, Vec3<long> * triangles) const
{
long * map = new long [m_nPoints];
long counter = 0;
for (size_t v = 0; v < m_nPoints; ++v)
{
if ( m_vertices[v].m_tag )
{
points[counter] = m_points[v];
map[v] = counter++;
}
}
counter = 0;
for (size_t t = 0; t < m_nInitialTriangles; ++t)
{
if ( m_trianglesTags[t] )
{
triangles[counter].X() = map[m_triangles[t].X()];
triangles[counter].Y() = map[m_triangles[t].Y()];
triangles[counter].Z() = map[m_triangles[t].Z()];
counter++;
}
}
delete [] map;
}
void MeshDecimator::InitializeQEM()
{
Vec3<Float> coordMin = m_points[0];
Vec3<Float> coordMax = m_points[0];
Vec3<Float> coord;
for (size_t p = 1; p < m_nPoints ; ++p)
{
coord = m_points[p];
if (coordMin.X() > coord.X()) coordMin.X() = coord.X();
if (coordMin.Y() > coord.Y()) coordMin.Y() = coord.Y();
if (coordMin.Z() > coord.Z()) coordMin.Z() = coord.Z();
if (coordMax.X() < coord.X()) coordMax.X() = coord.X();
if (coordMax.Y() < coord.Y()) coordMax.Y() = coord.Y();
if (coordMax.Z() < coord.Z()) coordMax.Z() = coord.Z();
}
coordMax -= coordMin;
m_diagBB = coordMax.GetNorm();
long i, j, k;
Vec3<Float> n;
Float d = 0;
Float area = 0;
for(size_t v = 0; v < m_nPoints; ++v)
{
memset(m_vertices[v].m_Q, 0, 10 * sizeof(Float));
long idTriangle;
for(size_t itT = 0; itT < m_vertices[v].m_triangles.Size(); ++itT)
{
idTriangle = m_vertices[v].m_triangles[itT];
i = m_triangles[idTriangle].X();
j = m_triangles[idTriangle].Y();
k = m_triangles[idTriangle].Z();
n = (m_points[j] - m_points[i])^(m_points[k] - m_points[i]);
area = n.GetNorm();
n.Normalize();
d = - (m_points[v] * n);
m_vertices[v].m_Q[0] += area * (n.X() * n.X());
m_vertices[v].m_Q[1] += area * (n.X() * n.Y());
m_vertices[v].m_Q[2] += area * (n.X() * n.Z());
m_vertices[v].m_Q[3] += area * (n.X() * d);
m_vertices[v].m_Q[4] += area * (n.Y() * n.Y());
m_vertices[v].m_Q[5] += area * (n.Y() * n.Z());
m_vertices[v].m_Q[6] += area * (n.Y() * d);
m_vertices[v].m_Q[7] += area * (n.Z() * n.Z());
m_vertices[v].m_Q[8] += area * (n.Z() * d);
m_vertices[v].m_Q[9] += area * (d * d);
}
}
Vec3<Float> u1, u2;
const Float w = static_cast<Float>(1000);
long t, v1, v2, v3;
for(size_t e = 0; e < m_edges.size(); ++e)
{
v1 = m_edges[e].m_v1;
v2 = m_edges[e].m_v2;
t = IsBoundaryEdge(v1, v2);
if (t != -1)
{
if (m_triangles[t].X() != v1 && m_triangles[t].X() != v2) v3 = m_triangles[t].X();
else if (m_triangles[t].Y() != v1 && m_triangles[t].Y() != v2) v3 = m_triangles[t].Y();
else v3 = m_triangles[t].Z();
u1 = m_points[v2] - m_points[v1];
u2 = m_points[v3] - m_points[v1];
area = w * (u1^u2).GetNorm();
u1.Normalize();
n = u2 - (u2 * u1) * u1;
n.Normalize();
d = - (m_points[v1] * n);
m_vertices[v1].m_Q[0] += area * (n.X() * n.X());
m_vertices[v1].m_Q[1] += area * (n.X() * n.Y());
m_vertices[v1].m_Q[2] += area * (n.X() * n.Z());
m_vertices[v1].m_Q[3] += area * (n.X() * d);
m_vertices[v1].m_Q[4] += area * (n.Y() * n.Y());
m_vertices[v1].m_Q[5] += area * (n.Y() * n.Z());
m_vertices[v1].m_Q[6] += area * (n.Y() * d);
m_vertices[v1].m_Q[7] += area * (n.Z() * n.Z());
m_vertices[v1].m_Q[8] += area * (n.Z() * d);
m_vertices[v1].m_Q[9] += area * (d * d);
d = - (m_points[v2] * n);
m_vertices[v2].m_Q[0] += area * (n.X() * n.X());
m_vertices[v2].m_Q[1] += area * (n.X() * n.Y());
m_vertices[v2].m_Q[2] += area * (n.X() * n.Z());
m_vertices[v2].m_Q[3] += area * (n.X() * d);
m_vertices[v2].m_Q[4] += area * (n.Y() * n.Y());
m_vertices[v2].m_Q[5] += area * (n.Y() * n.Z());
m_vertices[v2].m_Q[6] += area * (n.Y() * d);
m_vertices[v2].m_Q[7] += area * (n.Z() * n.Z());
m_vertices[v2].m_Q[8] += area * (n.Z() * d);
m_vertices[v2].m_Q[9] += area * (d * d);
}
}
}
void MeshDecimator::InitializePriorityQueue()
{
double progressOld = -1.0;
double progress = 0.0;
char msg[1024];
double ptgStep = 1.0;
long v1, v2;
MDEdgePriorityQueue pqEdge;
size_t nE = m_edges.size();
for(size_t e = 0; e < nE; ++e)
{
progress = e * 100.0 / nE;
if (fabs(progress-progressOld) > ptgStep && m_callBack)
{
sprintf(msg, "%3.2f %% \t \t \r", progress);
(*m_callBack)(msg, progress, 0.0, m_nVertices);
progressOld = progress;
}
if (m_edges[e].m_tag)
{
v1 = m_edges[e].m_v1;
v2 = m_edges[e].m_v2;
if ( (!m_ecolManifoldConstraint) || (ManifoldConstraint(v1, v2)))
{
pqEdge.m_qem = m_edges[e].m_qem = ComputeEdgeCost(v1, v2, m_edges[e].m_pos);
pqEdge.m_name = static_cast<long>(e);
m_pqueue.push(pqEdge);
}
}
}
}
double MeshDecimator::ComputeEdgeCost(long v1, long v2, Vec3<Float> & newPos) const
{
double Q[10];
double M[12];
Vec3<double> pos;
for(int i = 0; i < 10; ++i) Q[i] = m_vertices[v1].m_Q[i] + m_vertices[v2].m_Q[i];
M[0] = Q[0]; // (0, 0)
M[1] = Q[1]; // (0, 1)
M[2] = Q[2]; // (0, 2)
M[3] = Q[3]; // (0, 3)
M[4] = Q[1]; // (1, 0)
M[5] = Q[4]; // (1, 1)
M[6] = Q[5]; // (1, 2)
M[7] = Q[6]; // (1, 3)
M[8] = Q[2]; // (2, 0)
M[9] = Q[5]; // (2, 1)
M[10] = Q[7]; // (2, 2);
M[11] = Q[8]; // (2, 3);
double det = M[0] * M[5] * M[10] + M[1] * M[6] * M[8] + M[2] * M[4] * M[9]
- M[0] * M[6] * M[9] - M[1] * M[4] * M[10]- M[2] * M[5] * M[8];
if (det != 0.0)
{
double d = 1.0 / det;
pos.X() = d * (M[1]*M[7]*M[10] + M[2]*M[5]*M[11] + M[3]*M[6]*M[9]
-M[1]*M[6]*M[11] - M[2]*M[7]*M[9] - M[3]*M[5]*M[10]);
pos.Y() = d * (M[0]*M[6]*M[11] + M[2]*M[7]*M[8] + M[3]*M[4]*M[10]
-M[0]*M[7]*M[10] - M[2]*M[4]*M[11] - M[3]*M[6]*M[8]);
pos.Z() = d * (M[0]*M[7]*M[9] + M[1]*M[4]*M[11] + M[3]*M[5]*M[8]
-M[0]*M[5]*M[11] - M[1]*M[7]*M[8] - M[3]*M[4]*M[9]);
newPos.X() = static_cast<Float>(pos.X());
newPos.Y() = static_cast<Float>(pos.Y());
newPos.Z() = static_cast<Float>(pos.Z());
}
else
{
const Float w = static_cast<Float>(0.5f);
newPos = w * m_points[v1] + w * m_points[v2];
pos.X() = static_cast<double>(newPos.X());
pos.Y() = static_cast<double>(newPos.Y());
pos.Z() = static_cast<double>(newPos.Z());
}
double qem = pos.X() * (Q[0] * pos.X() + Q[1] * pos.Y() + Q[2] * pos.Z() + Q[3]) +
pos.Y() * (Q[1] * pos.X() + Q[4] * pos.Y() + Q[5] * pos.Z() + Q[6]) +
pos.Z() * (Q[2] * pos.X() + Q[5] * pos.Y() + Q[7] * pos.Z() + Q[8]) +
(Q[3] * pos.X() + Q[6] * pos.Y() + Q[8] * pos.Z() + Q[9]) ;
Vec3<Float> d1;
Vec3<Float> d2;
Vec3<Float> n1;
Vec3<Float> n2;
Vec3<Float> oldPosV1 = m_points[v1];
Vec3<Float> oldPosV2 = m_points[v2];
SArray<long, SARRAY_DEFAULT_MIN_SIZE> triangles = m_vertices[v1].m_triangles;
long idTriangle;
for(size_t itT = 0; itT < m_vertices[v2].m_triangles.Size(); ++itT)
{
idTriangle = m_vertices[v2].m_triangles[itT];
triangles.Insert(idTriangle);
}
long a[3];
for(size_t itT = 0; itT != triangles.Size(); ++itT)
{
idTriangle = triangles[itT];
a[0] = m_triangles[idTriangle].X();
a[1] = m_triangles[idTriangle].Y();
a[2] = m_triangles[idTriangle].Z();
d1 = m_points[a[1]] - m_points[a[0]];
d2 = m_points[a[2]] - m_points[a[0]];
n1 = d1^d2;
m_points[v1] = newPos;
m_points[v2] = newPos;
d1 = m_points[a[1]] - m_points[a[0]];
d2 = m_points[a[2]] - m_points[a[0]];
n2 = d1^d2;
m_points[v1] = oldPosV1;
m_points[v2] = oldPosV2;
n1.Normalize();
n2.Normalize();
if (n1*n2 < 0.0)
{
return std::numeric_limits<double>::max();
}
}
if ( m_ecolManifoldConstraint && !ManifoldConstraint(v1, v2))
{
return std::numeric_limits<double>::max();
}
return qem;
}
bool MeshDecimator::ManifoldConstraint(long v1, long v2) const
{
std::set<long> vertices;
long a, b;
long idEdge1;
long idEdge2;
long idEdgeV1V2;
for(size_t itE1 = 0; itE1 < m_vertices[v1].m_edges.Size(); ++itE1)
{
idEdge1 = m_vertices[v1].m_edges[itE1];
a = (m_edges[idEdge1].m_v1 == v1) ? m_edges[idEdge1].m_v2 : m_edges[idEdge1].m_v1;
vertices.insert(a);
if (a != v2)
{
for(size_t itE2 = 0; itE2 < m_vertices[v2].m_edges.Size(); ++itE2)
{
idEdge2 = m_vertices[v2].m_edges[itE2];
b = (m_edges[idEdge2].m_v1 == v2) ? m_edges[idEdge2].m_v2 : m_edges[idEdge2].m_v1;
vertices.insert(b);
if ( a==b )
{
if (GetTriangle(v1, v2, a) == -1)
{
return false;
}
}
}
}
else
{
idEdgeV1V2 = idEdge1;
}
}
if (vertices.size() <= 4 || ( m_vertices[v1].m_onBoundary && m_vertices[v2].m_onBoundary && !m_edges[idEdgeV1V2].m_onBoundary))
{
return false;
}
return true;
}
bool MeshDecimator::EdgeCollapse(double & qem)
{
MDEdgePriorityQueue currentEdge;
long v1, v2;
bool done = false;
do
{
done = false;
if (m_pqueue.size() == 0)
{
done = true;
break;
}
else
{
currentEdge = m_pqueue.top();
m_pqueue.pop();
}
}
while ( (!m_edges[currentEdge.m_name].m_tag) || (m_edges[currentEdge.m_name].m_qem != currentEdge.m_qem));
if (done) return false;
v1 = m_edges[currentEdge.m_name].m_v1;
v2 = m_edges[currentEdge.m_name].m_v2;
qem = currentEdge.m_qem;
EdgeCollapse(v1, v2);
m_points[v1] = m_edges[currentEdge.m_name].m_pos ;
for(int k = 0; k < 10; k++) m_vertices[v1].m_Q[k] += m_vertices[v2].m_Q[k];
// Update priority queue
long idEdge;
long a, b;
SArray<long, SARRAY_DEFAULT_MIN_SIZE> incidentVertices;
for(size_t itE = 0; itE < m_vertices[v1].m_edges.Size(); ++itE)
{
idEdge = m_vertices[v1].m_edges[itE];
a = m_edges[idEdge].m_v1;
b = m_edges[idEdge].m_v2;
incidentVertices.PushBack((a != v1)?a:b);
MDEdgePriorityQueue pqEdge;
pqEdge.m_qem = m_edges[idEdge].m_qem = ComputeEdgeCost(a, b, m_edges[idEdge].m_pos);
pqEdge.m_name = idEdge;
m_pqueue.push(pqEdge);
}
long idVertex;
for(size_t itV = 0; itV< incidentVertices.Size(); ++itV)
{
idVertex = incidentVertices[itV];
for(size_t itE = 0; itE < m_vertices[idVertex].m_edges.Size(); ++itE)
{
idEdge = m_vertices[idVertex].m_edges[itE];
a = m_edges[idEdge].m_v1;
b = m_edges[idEdge].m_v2;
if ( a!=v1 && b!=v1)
{
MDEdgePriorityQueue pqEdge;
pqEdge.m_qem = m_edges[idEdge].m_qem = ComputeEdgeCost(a, b, m_edges[idEdge].m_pos);
pqEdge.m_name = idEdge;
m_pqueue.push(pqEdge);
}
}
}
return true;
}
bool MeshDecimator::Decimate(size_t targetNVertices, size_t targetNTriangles, double targetError)
{
double qem = 0.0;
double progressOld = -1.0;
double progress = 0.0;
char msg[1024];
double ptgStep = 1.0;
if (m_callBack)
{
std::ostringstream msg;
msg << "+ Mesh" << std::endl;
msg << "\t # vertices \t" << m_nPoints << std::endl;
msg << "\t # triangles \t" << m_nTriangles << std::endl;
msg << "+ Parameters" << std::endl;
msg << "\t target # of vertices \t" << targetNVertices << std::endl;
msg << "\t target # of triangles \t" << targetNTriangles << std::endl;
msg << "\t QEM \t" << targetError << std::endl;
(*m_callBack)(msg.str().c_str(), 0.0, 0.0, m_nPoints);
}
if (m_callBack) (*m_callBack)("+ Initialize QEM \n", 0.0, 0.0, m_nPoints);
InitializeQEM();
if (m_callBack) (*m_callBack)("+ Initialize priority queue \n", 0.0, 0.0, m_nPoints);
InitializePriorityQueue();
if (m_callBack) (*m_callBack)("+ Simplification \n", 0.0, 0.0, m_nPoints);
double invDiag2 = 1.0 / (m_diagBB * m_diagBB);
while((m_pqueue.size() > 0) &&
(m_nEdges > 0) &&
(m_nVertices > targetNVertices) &&
(m_nTriangles > targetNTriangles) &&
(qem < targetError))
{
progress = 100.0 - m_nVertices * 100.0 / m_nPoints;
if (fabs(progress-progressOld) > ptgStep && m_callBack)
{
sprintf(msg, "%3.2f %% V = %lu \t QEM = %f \t \t \r", progress, static_cast<unsigned long>(m_nVertices), sqrt(qem));
(*m_callBack)(msg, progress, qem, m_nVertices);
progressOld = progress;
}
if (!EdgeCollapse(qem)) break;
qem *= invDiag2;
}
if (m_callBack)
{
std::ostringstream msg;
msg << "+ Simplification output" << std::endl;
msg << "\t # vertices \t" << m_nVertices << std::endl;
msg << "\t # triangles \t" << m_nTriangles << std::endl;
msg << "\t QEM \t" << qem << std::endl;
(*m_callBack)(msg.str().c_str(), 100.0, qem, m_nVertices);
}
return true;
}
}

View File

@@ -0,0 +1,116 @@
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#ifndef HACD_MESH_DECEMATOR_H
#define HACD_MESH_DECEMATOR_H
#include <queue>
#include <set>
#include <vector>
#include <limits>
#include "hacdVersion.h"
#include "hacdVector.h"
#include "hacdSArray.h"
#include "hacdHACD.h"
namespace HACD
{
typedef double Float;
struct MDVertex
{
SArray<long, SARRAY_DEFAULT_MIN_SIZE> m_edges;
SArray<long, SARRAY_DEFAULT_MIN_SIZE> m_triangles;
Float m_Q[10];
// 0 1 2 3
// 4 5 6
// 7 8
// 9
bool m_tag;
bool m_onBoundary;
};
struct MDEdge
{
long m_v1;
long m_v2;
double m_qem;
Vec3<Float> m_pos;
bool m_onBoundary;
bool m_tag;
};
struct MDEdgePriorityQueue
{
long m_name;
double m_qem;
inline friend bool operator<(const MDEdgePriorityQueue & lhs, const MDEdgePriorityQueue & rhs) { return (lhs.m_qem > rhs.m_qem);}
inline friend bool operator>(const MDEdgePriorityQueue & lhs, const MDEdgePriorityQueue & rhs) { return (lhs.m_qem < rhs.m_qem);}
};
class MeshDecimator
{
public:
//! Sets the call-back function
//! @param callBack pointer to the call-back function
void SetCallBack(CallBackFunction callBack) { m_callBack = callBack;}
//! Gives the call-back function
//! @return pointer to the call-back function
const CallBackFunction GetCallBack() const { return m_callBack;}
inline void SetEColManifoldConstraint(bool ecolManifoldConstraint) { m_ecolManifoldConstraint = ecolManifoldConstraint; }
inline size_t GetNVertices()const {return m_nVertices;};
inline size_t GetNTriangles() const {return m_nTriangles;};
inline size_t GetNEdges() const {return m_nEdges;};
void GetMeshData(Vec3<Float> * points, Vec3<long> * triangles) const;
void ReleaseMemory();
void Initialize(size_t nVertices, size_t nTriangles,
Vec3<Float> * points,
Vec3<long> * triangles);
bool Decimate(size_t targetNVertices = 100,
size_t targetNTriangles = 0,
double targetError = std::numeric_limits<double>::max());
MeshDecimator(void);
~MeshDecimator(void);
private :
void EdgeCollapse(long v1, long v2);
long GetTriangle(long v1, long v2, long v3) const;
long GetEdge(long v1, long v2) const;
long IsBoundaryEdge(long v1, long v2) const;
bool IsBoundaryVertex(long v) const;
void InitializePriorityQueue();
void InitializeQEM();
bool ManifoldConstraint(long v1, long v2) const;
double ComputeEdgeCost(long v1, long v2, Vec3<Float> & pos) const;
bool EdgeCollapse(double & error);
private:
Vec3<long> * m_triangles;
Vec3<Float> * m_points;
size_t m_nPoints;
size_t m_nInitialTriangles;
size_t m_nVertices;
size_t m_nTriangles;
size_t m_nEdges;
double m_diagBB;
std::vector<MDVertex> m_vertices;
std::vector<MDEdge> m_edges;
std::priority_queue<
MDEdgePriorityQueue,
std::vector<MDEdgePriorityQueue>,
std::less<MDEdgePriorityQueue> > m_pqueue;
CallBackFunction m_callBack; //>! call-back function
bool * m_trianglesTags;
bool m_ecolManifoldConstraint;
};
}
#endif

View File

@@ -0,0 +1,993 @@
#include "hacdMicroAllocator.h"
/*!
**
** Copyright (c) 2009 by John W. Ratcliff mailto:jratcliffscarab@gmail.com
**
** If you find this code useful or you are feeling particularily generous I would
** ask that you please go to http://www.amillionpixels.us and make a donation
** to Troy DeMolay.
**
**
** If you wish to contact me you can use the following methods:
**
** Skype ID: jratcliff63367
** email: jratcliffscarab@gmail.com
**
**
** The MIT license:
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
** in the Software without restriction, including without limitation the rights
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
** copies of the Software, and to permit persons to whom the Software is furnished
** to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in all
** copies or substantial portions of the Software.
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <new>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#ifdef WIN32
#include <windows.h>
#endif
#if defined(__APPLE__) || defined(LINUX)
#include <pthread.h>
#endif
#pragma warning(disable:4100)
namespace HACD
{
//==================================================================================
class MemMutex
{
public:
MemMutex(void);
~MemMutex(void);
public:
// Blocking Lock.
void Lock(void);
// Unlock.
void Unlock(void);
private:
#if defined(_WIN32) || defined(_XBOX)
CRITICAL_SECTION m_Mutex;
#elif defined(__APPLE__) || defined(LINUX)
pthread_mutex_t m_Mutex;
#endif
};
//==================================================================================
MemMutex::MemMutex(void)
{
#if defined(_WIN32) || defined(_XBOX)
InitializeCriticalSection(&m_Mutex);
#elif defined(__APPLE__) || defined(LINUX)
pthread_mutexattr_t mta;
pthread_mutexattr_init(&mta);
pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&m_Mutex, &mta);
pthread_mutexattr_destroy(&mta);
#endif
}
//==================================================================================
MemMutex::~MemMutex(void)
{
#if defined(_WIN32) || defined(_XBOX)
DeleteCriticalSection(&m_Mutex);
#elif defined(__APPLE__) || defined(LINUX)
pthread_mutex_destroy(&m_Mutex);
#endif
}
//==================================================================================
// Blocking Lock.
//==================================================================================
void MemMutex::Lock(void)
{
#if defined(_WIN32) || defined(_XBOX)
EnterCriticalSection(&m_Mutex);
#elif defined(__APPLE__) || defined(LINUX)
pthread_mutex_lock(&m_Mutex);
#endif
}
//==================================================================================
// Unlock.
//==================================================================================
void MemMutex::Unlock(void)
{
#if defined(_WIN32) || defined(_XBOX)
LeaveCriticalSection(&m_Mutex);
#elif defined(__APPLE__) || defined(LINUX)
pthread_mutex_unlock(&m_Mutex);
#endif
}
struct ChunkHeader
{
ChunkHeader *mNextChunk;
};
// interface to add and remove new chunks to the master list.
class MicroChunkUpdate
{
public:
virtual void addMicroChunk(NxU8 *memStart,NxU8 *memEnd,MemoryChunk *chunk) = 0;
virtual void removeMicroChunk(MemoryChunk *chunk) = 0;
};
class MemoryHeader
{
public:
MemoryHeader *mNext;
};
// a single fixed size chunk for micro-allocations.
class MemoryChunk
{
public:
MemoryChunk(void)
{
mData = 0;
mDataEnd = 0;
mUsedCount = 0;
mFreeList = 0;
mMyHeap = false;
mChunkSize = 0;
}
NxU8 * init(NxU8 *chunkBase,NxU32 chunkSize,NxU32 maxChunks)
{
mChunkSize = chunkSize;
mData = chunkBase;
mDataEnd = mData+(chunkSize*maxChunks);
mFreeList = (MemoryHeader *) mData;
MemoryHeader *scan = mFreeList;
NxU8 *data = mData;
data+=chunkSize;
for (NxU32 i=0; i<(maxChunks-1); i++)
{
MemoryHeader *next = (MemoryHeader *)data;
scan->mNext = next;
data+=chunkSize;
scan = next;
}
scan->mNext = 0;
return mDataEnd;
}
inline void * allocate(MicroHeap *heap,NxU32 chunkSize,NxU32 maxChunks,MicroChunkUpdate *update)
{
void *ret = 0;
if ( mData == 0 )
{
mMyHeap = true;
mData = (NxU8 *)heap->micro_malloc( chunkSize * maxChunks );
init(mData,chunkSize,maxChunks);
update->addMicroChunk(mData,mDataEnd,this);
}
if ( mFreeList )
{
mUsedCount++;
ret = mFreeList;
mFreeList = mFreeList->mNext;
}
return ret;
}
inline void deallocate(void *p,MicroHeap *heap,MicroChunkUpdate *update)
{
#ifdef _DEBUG
assert(mUsedCount);
NxU8 *s = (NxU8 *)p;
assert( s >= mData && s < mDataEnd );
#endif
MemoryHeader *mh = mFreeList;
mFreeList = (MemoryHeader *)p;
mFreeList->mNext = mh;
mUsedCount--;
if ( mUsedCount == 0 && mMyHeap ) // free the heap back to the application if we are done with this.
{
update->removeMicroChunk(this);
heap->micro_free(mData);
mMyHeap = false;
mData = 0;
mDataEnd = 0;
mFreeList = 0;
}
}
NxU32 getChunkSize(void) const { return mChunkSize; };
bool isInside(const NxU8 *p) const
{
return p>=mData && p < mDataEnd;
}
private:
bool mMyHeap;
NxU8 *mData;
NxU8 *mDataEnd;
NxU32 mUsedCount;
MemoryHeader *mFreeList;
NxU32 mChunkSize;
};
#define DEFAULT_CHUNKS 32
class MemoryChunkChunk
{
public:
MemoryChunkChunk(void)
{
mNext = 0;
mChunkSize = 0;
mMaxChunks = 0;
}
~MemoryChunkChunk(void)
{
}
inline void * allocate(MemoryChunk *&current,MicroChunkUpdate *update)
{
void *ret = 0;
MemoryChunkChunk *scan = this;
while ( scan && ret == 0 )
{
for (NxU32 i=0; i<DEFAULT_CHUNKS; i++)
{
ret = scan->mChunks[i].allocate(mHeap,mChunkSize,mMaxChunks,update);
if ( ret )
{
current = &scan->mChunks[i];
scan = 0;
break;
}
}
if ( scan )
scan = scan->mNext;
}
if ( !ret )
{
MemoryChunkChunk *mcc = (MemoryChunkChunk *)mHeap->micro_malloc( sizeof(MemoryChunkChunk) );
new ( mcc ) MemoryChunkChunk;
MemoryChunkChunk *onext = mNext;
mNext = mcc;
mcc->mNext = onext;
ret = mcc->mChunks[0].allocate(mHeap,mChunkSize,mMaxChunks,update);
current = &mcc->mChunks[0];
}
return ret;
}
NxU8 * init(NxU8 *chunkBase,NxU32 fixedSize,NxU32 chunkSize,MemoryChunk *&current,MicroHeap *heap)
{
mHeap = heap;
mChunkSize = chunkSize;
mMaxChunks = fixedSize/chunkSize;
current = &mChunks[0];
chunkBase = mChunks[0].init(chunkBase,chunkSize,mMaxChunks);
return chunkBase;
}
MicroHeap *mHeap;
NxU32 mChunkSize;
NxU32 mMaxChunks;
MemoryChunkChunk *mNext;
MemoryChunk mChunks[DEFAULT_CHUNKS];
};
class FixedMemory
{
public:
FixedMemory(void)
{
mCurrent = 0;
}
void * allocate(MicroChunkUpdate *update)
{
void *ret = mCurrent->allocate(mChunks.mHeap,mChunks.mChunkSize,mChunks.mMaxChunks,update);
if ( ret == 0 )
{
ret = mChunks.allocate(mCurrent,update);
}
return ret;
}
NxU8 * init(NxU8 *chunkBase,NxU32 chunkSize,NxU32 fixedSize,MicroHeap *heap)
{
mMemBegin = chunkBase;
mMemEnd = chunkBase+fixedSize;
mChunks.init(chunkBase,fixedSize,chunkSize,mCurrent,heap);
return mMemEnd;
}
NxU8 *mMemBegin;
NxU8 *mMemEnd;
MemoryChunk *mCurrent; // the current memory chunk we are operating in.
MemoryChunkChunk mChunks; // the collection of all memory chunks used.
};
class MicroChunk
{
public:
void set(NxU8 *memStart,NxU8 *memEnd,MemoryChunk *mc)
{
mMemStart = memStart;
mMemEnd = memEnd;
mChunk = mc;
mPad = 0;
}
inline bool inside(const NxU8 *p) const
{
return p >= mMemStart && p < mMemEnd;
}
NxU8 *mMemStart;
NxU8 *mMemEnd;
MemoryChunk *mChunk;
NxU8 *mPad; // padding to make it 16 byte aligned.
};
class MyMicroAllocator : public MicroAllocator, public MicroChunkUpdate, public MemMutex
{
public:
MyMicroAllocator(MicroHeap *heap,void *baseMem,NxU32 initialSize,NxU32 chunkSize)
{
mLastMicroChunk = 0;
mMicroChunks = 0;
mMicroChunkCount = 0;
mMaxMicroChunks = 0;
mHeap = heap;
mChunkSize = chunkSize;
// 0 through 8 bytes
for (NxU32 i=0; i<=8; i++)
{
mFixedAllocators[i] = &mAlloc[0];
}
// 9 through 16 bytes
for (NxU32 i=9; i<=16; i++)
{
mFixedAllocators[i] = &mAlloc[1];
}
// 17 through 32 bytes
for (NxU32 i=17; i<=32; i++)
{
mFixedAllocators[i] = &mAlloc[2];
}
// 33 through 64
for (NxU32 i=33; i<=64; i++)
{
mFixedAllocators[i] = &mAlloc[3];
}
// 65 through 128
for (NxU32 i=65; i<=128; i++)
{
mFixedAllocators[i] = &mAlloc[4];
}
// 129 through 255
for (NxU32 i=129; i<257; i++)
{
mFixedAllocators[i] = &mAlloc[5];
}
mBaseMem = (NxU8 *)baseMem;
mBaseMemEnd = mBaseMem+initialSize;
NxU8 *chunkBase = (NxU8 *)baseMem+sizeof(MyMicroAllocator);
chunkBase+=32;
NxU64 ptr = (NxU64)chunkBase;
ptr = ptr>>4;
ptr = ptr<<4; // make sure it is 16 byte aligned.
chunkBase = (NxU8 *)ptr;
mChunkStart = chunkBase;
chunkBase = mAlloc[0].init(chunkBase,8,chunkSize,heap);
chunkBase = mAlloc[1].init(chunkBase,16,chunkSize,heap);
chunkBase = mAlloc[2].init(chunkBase,32,chunkSize,heap);
chunkBase = mAlloc[3].init(chunkBase,64,chunkSize,heap);
chunkBase = mAlloc[4].init(chunkBase,128,chunkSize,heap);
chunkBase = mAlloc[5].init(chunkBase,256,chunkSize,heap);
mChunkEnd = chunkBase;
assert(chunkBase <= mBaseMemEnd );
}
~MyMicroAllocator(void)
{
if ( mMicroChunks )
{
mHeap->micro_free(mMicroChunks);
}
}
virtual NxU32 getChunkSize(MemoryChunk *chunk)
{
return chunk ? chunk->getChunkSize() : 0;
}
// we have to steal one byte out of every allocation to record the size, so we can efficiently de-allocate it later.
virtual void * malloc(size_t size)
{
void *ret = 0;
Lock();
assert( size <= 256 );
if ( size <= 256 )
{
ret = mFixedAllocators[size]->allocate(this);
}
Unlock();
return ret;
}
virtual void free(void *p,MemoryChunk *chunk)
{
Lock();
chunk->deallocate(p,mHeap,this);
Unlock();
}
// perform a binary search on the sorted list of chunks.
MemoryChunk * binarySearchMicroChunks(const NxU8 *p)
{
MemoryChunk *ret = 0;
NxU32 low = 0;
NxU32 high = mMicroChunkCount;
while ( low != high )
{
NxU32 mid = (high-low)/2+low;
MicroChunk &chunk = mMicroChunks[mid];
if ( chunk.inside(p))
{
mLastMicroChunk = &chunk;
ret = chunk.mChunk;
break;
}
else
{
if ( p > chunk.mMemEnd )
{
low = mid+1;
}
else
{
high = mid;
}
}
}
return ret;
}
virtual MemoryChunk * isMicroAlloc(const void *p) // returns true if this pointer is handled by the micro-allocator.
{
MemoryChunk *ret = 0;
Lock();
const NxU8 *s = (const NxU8 *)p;
if ( s >= mChunkStart && s < mChunkEnd )
{
NxU32 index = (NxU32)(s-mChunkStart)/mChunkSize;
assert(index>=0 && index < 6 );
ret = &mAlloc[index].mChunks.mChunks[0];
assert( ret->isInside(s) );
}
else if ( mMicroChunkCount )
{
if ( mLastMicroChunk && mLastMicroChunk->inside(s) )
{
ret = mLastMicroChunk->mChunk;
}
else
{
if ( mMicroChunkCount >= 4 )
{
ret = binarySearchMicroChunks(s);
#ifdef _DEBUG
if (ret )
{
assert( ret->isInside(s) );
}
else
{
for (NxU32 i=0; i<mMicroChunkCount; i++)
{
assert( !mMicroChunks[i].inside(s) );
}
}
#endif
}
else
{
for (NxU32 i=0; i<mMicroChunkCount; i++)
{
if ( mMicroChunks[i].inside(s) )
{
ret = mMicroChunks[i].mChunk;
assert( ret->isInside(s) );
mLastMicroChunk = &mMicroChunks[i];
break;
}
}
}
}
}
#ifdef _DEBUG
if ( ret )
assert( ret->isInside(s) );
#endif
Unlock();
return ret;
}
MicroHeap * getMicroHeap(void) const { return mHeap; };
void allocateMicroChunks(void)
{
if ( mMaxMicroChunks == 0 )
{
mMaxMicroChunks = 64; // initial reserve.
mMicroChunks = (MicroChunk *)mHeap->micro_malloc( sizeof(MicroChunk)*mMaxMicroChunks );
}
else
{
mMaxMicroChunks*=2;
mMicroChunks = (MicroChunk *)mHeap->micro_realloc( mMicroChunks, sizeof(MicroChunk)*mMaxMicroChunks);
}
}
// perform an insertion sort of the new chunk.
virtual void addMicroChunk(NxU8 *memStart,NxU8 *memEnd,MemoryChunk *chunk)
{
if ( mMicroChunkCount >= mMaxMicroChunks )
{
allocateMicroChunks();
}
bool inserted = false;
for (NxU32 i=0; i<mMicroChunkCount; i++)
{
if ( memEnd < mMicroChunks[i].mMemStart )
{
for (NxU32 j=mMicroChunkCount; j>i; j--)
{
mMicroChunks[j] = mMicroChunks[j-1];
}
mMicroChunks[i].set( memStart, memEnd, chunk );
mLastMicroChunk = &mMicroChunks[i];
mMicroChunkCount++;
inserted = true;
break;
}
}
if ( !inserted )
{
mMicroChunks[mMicroChunkCount].set(memStart,memEnd,chunk);
mLastMicroChunk = &mMicroChunks[mMicroChunkCount];
mMicroChunkCount++;
}
}
virtual void removeMicroChunk(MemoryChunk *chunk)
{
mLastMicroChunk = 0;
#ifdef _DEBUG
bool removed = false;
#endif
for (NxU32 i=0; i<mMicroChunkCount; i++)
{
if ( mMicroChunks[i].mChunk == chunk )
{
mMicroChunkCount--;
for (NxU32 j=i; j<mMicroChunkCount; j++)
{
mMicroChunks[j] = mMicroChunks[j+1];
}
#ifdef _DEBUG
removed = true;
#endif
break;
}
}
#ifdef _DEBUG
assert(removed);
#endif
}
inline void * inline_malloc(size_t size)
{
Lock();
void *ret = mFixedAllocators[size]->allocate(this);
Unlock();
return ret;
}
inline void inline_free(void *p,MemoryChunk *chunk) // free relative to previously located MemoryChunk
{
Lock();
chunk->deallocate(p,mHeap,this);
Unlock();
}
inline MemoryChunk * inline_isMicroAlloc(const void *p) // returns pointer to the chunk this memory belongs to, or null if not a micro-allocated block.
{
MemoryChunk *ret = 0;
Lock();
const NxU8 *s = (const NxU8 *)p;
if ( s >= mChunkStart && s < mChunkEnd )
{
NxU32 index = (NxU32)(s-mChunkStart)/mChunkSize;
assert(index>=0 && index < 6 );
ret = &mAlloc[index].mChunks.mChunks[0];
}
else if ( mMicroChunkCount )
{
if ( mLastMicroChunk && mLastMicroChunk->inside(s) )
{
ret = mLastMicroChunk->mChunk;
}
else
{
if ( mMicroChunkCount >= 4 )
{
ret = binarySearchMicroChunks(s);
}
else
{
for (NxU32 i=0; i<mMicroChunkCount; i++)
{
if ( mMicroChunks[i].inside(s) )
{
ret = mMicroChunks[i].mChunk;
mLastMicroChunk = &mMicroChunks[i];
break;
}
}
}
}
}
Unlock();
return ret;
}
private:
MicroHeap *mHeap;
NxU8 *mBaseMem;
NxU8 *mBaseMemEnd;
FixedMemory *mFixedAllocators[257];
NxU32 mChunkSize;
NxU8 *mChunkStart;
NxU8 *mChunkEnd;
NxU32 mMaxMicroChunks;
NxU32 mMicroChunkCount;
MicroChunk *mLastMicroChunk;
MicroChunk *mMicroChunks;
FixedMemory mAlloc[6];
};
MicroAllocator *createMicroAllocator(MicroHeap *heap,NxU32 chunkSize)
{
NxU32 initialSize = chunkSize*6+sizeof(MyMicroAllocator)+32;
void *baseMem = heap->micro_malloc(initialSize);
MyMicroAllocator *mc = (MyMicroAllocator *)baseMem;
new ( mc ) MyMicroAllocator(heap,baseMem,initialSize,chunkSize);
return static_cast< MicroAllocator *>(mc);
}
void releaseMicroAllocator(MicroAllocator *m)
{
MyMicroAllocator *mc = static_cast< MyMicroAllocator *>(m);
MicroHeap *mh = mc->getMicroHeap();
mc->~MyMicroAllocator();
mh->micro_free(mc);
}
class MyHeapManager : public MicroHeap, public HeapManager
{
public:
MyHeapManager(NxU32 defaultChunkSize)
{
mMicro = createMicroAllocator(this,defaultChunkSize);
}
~MyHeapManager(void)
{
releaseMicroAllocator(mMicro);
}
// heap allocations used by the micro allocator.
virtual void * micro_malloc(size_t size)
{
return ::malloc(size);
}
virtual void micro_free(void *p)
{
return ::free(p);
}
virtual void * micro_realloc(void *oldMem,size_t newSize)
{
return ::realloc(oldMem,newSize);
}
virtual void * heap_malloc(size_t size)
{
void *ret;
if ( size <= 256 ) // micro allocator only handles allocations between 0 and 256 bytes in length.
{
ret = mMicro->malloc(size);
}
else
{
ret = ::malloc(size);
}
return ret;
}
virtual void heap_free(void *p)
{
MemoryChunk *chunk = mMicro->isMicroAlloc(p);
if ( chunk )
{
mMicro->free(p,chunk);
}
else
{
::free(p);
}
}
virtual void * heap_realloc(void *oldMem,size_t newSize)
{
void *ret = 0;
MemoryChunk *chunk = mMicro->isMicroAlloc(oldMem);
if ( chunk )
{
ret = heap_malloc(newSize);
NxU32 oldSize = chunk->getChunkSize();
if ( oldSize < newSize )
{
memcpy(ret,oldMem,oldSize);
}
else
{
memcpy(ret,oldMem,newSize);
}
mMicro->free(oldMem,chunk);
}
else
{
ret = ::realloc(oldMem,newSize);
}
return ret;
}
inline void * inline_heap_malloc(size_t size)
{
return size<=256 ? ((MyMicroAllocator *)mMicro)->inline_malloc(size) : ::malloc(size);
}
inline void inline_heap_free(void *p)
{
MemoryChunk *chunk = ((MyMicroAllocator *)mMicro)->inline_isMicroAlloc(p);
if ( chunk )
{
((MyMicroAllocator *)mMicro)->inline_free(p,chunk);
}
else
{
::free(p);
}
}
private:
MicroAllocator *mMicro;
};
HeapManager * createHeapManager(NxU32 defaultChunkSize)
{
MyHeapManager *m = (MyHeapManager *)::malloc(sizeof(MyHeapManager));
new ( m ) MyHeapManager(defaultChunkSize);
return static_cast< HeapManager *>(m);
}
void releaseHeapManager(HeapManager *heap)
{
MyHeapManager *m = static_cast< MyHeapManager *>(heap);
m->~MyHeapManager();
free(m);
}
#define TEST_SIZE 63
#define TEST_ALLOC_COUNT 8192
#define TEST_RUN 40000000
#define TEST_INLINE 1
#ifdef WIN32
#include <windows.h>
#pragma comment(lib,"winmm.lib")
#else
static NxU32 timeGetTime(void)
{
return 0;
}
#endif
#include <stdio.h>
void performUnitTests(void)
{
void *allocs[TEST_ALLOC_COUNT];
for (NxU32 i=0; i<TEST_ALLOC_COUNT; i++)
{
allocs[i] = 0;
}
HeapManager *hm = createHeapManager(65536*32);
{
NxU32 stime = timeGetTime();
srand(0);
for (NxU32 i=0; i<TEST_RUN; i++)
{
NxU32 index = rand()&(TEST_ALLOC_COUNT-1);
if ( allocs[index] )
{
#if TEST_INLINE
heap_free(hm, allocs[index] );
#else
hm->heap_free( allocs[index] );
#endif
allocs[index] = 0;
}
else
{
NxU32 asize = (rand()&TEST_SIZE);
if ( (rand()&127)==0) asize+=256; // one out of every 15 allocs is larger than 256 bytes.
#if TEST_INLINE
allocs[index] = heap_malloc(hm,asize);
#else
allocs[index] = hm->heap_malloc(asize);
#endif
}
}
for (NxU32 i=0; i<TEST_ALLOC_COUNT; i++)
{
if ( allocs[i] )
{
#if TEST_INLINE
heap_free(hm,allocs[i] );
#else
hm->heap_free(allocs[i] );
#endif
allocs[i] = 0;
}
}
NxU32 etime = timeGetTime();
printf("Micro allocation test took %d milliseconds.\r\n", etime - stime );
}
{
NxU32 stime = timeGetTime();
srand(0);
for (NxU32 i=0; i<TEST_RUN; i++)
{
NxU32 index = rand()&(TEST_ALLOC_COUNT-1);
if ( allocs[index] )
{
::free( allocs[index] );
allocs[index] = 0;
}
else
{
NxU32 asize = (rand()&TEST_SIZE);
if ( (rand()&127)==0) asize+=256; // one out of every 15 allocs is larger than 256 bytes.
allocs[index] = ::malloc(asize);
}
}
for (NxU32 i=0; i<TEST_ALLOC_COUNT; i++)
{
if ( allocs[i] )
{
::free(allocs[i] );
allocs[i] = 0;
}
}
NxU32 etime = timeGetTime();
printf("Standard malloc/free test took %d milliseconds.\r\n", etime - stime );
}
releaseHeapManager(hm);
}
void * heap_malloc(HeapManager *hm,size_t size)
{
return ((MyHeapManager *)hm)->inline_heap_malloc(size);
}
void heap_free(HeapManager *hm,void *p)
{
((MyHeapManager *)hm)->inline_heap_free(p);
}
void * heap_realloc(HeapManager *hm,void *oldMem,size_t newSize)
{
return hm->heap_realloc(oldMem,newSize);
}
}; // end of namespace

View File

@@ -0,0 +1,204 @@
#ifndef MICRO_ALLOCATOR_H
#define MICRO_ALLOCATOR_H
/*!
**
** Copyright (c) 2009 by John W. Ratcliff mailto:jratcliffscarab@gmail.com
**
** If you find this code useful or you are feeling particularily generous I would
** ask that you please go to http://www.amillionpixels.us and make a donation
** to Troy DeMolay.
**
** If you wish to contact me you can use the following methods:
**
** Skype ID: jratcliff63367
** email: jratcliffscarab@gmail.com
**
**
** The MIT license:
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
** in the Software without restriction, including without limitation the rights
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
** copies of the Software, and to permit persons to whom the Software is furnished
** to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in all
** copies or substantial portions of the Software.
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
// This code snippet provides a high speed micro-allocator.
//
// The concept is that you reserve an initial bank of memory for small allocations. Ideally a megabyte or two.
// The amount of memory reserved is equal to chunkSize*6
//
// All micro-allocations are split into 6 seperate pools.
// They are: 0-8 bytes
// 9-32 bytes
// 33-64 bytes
// 65-128 bytes
// 129-256 bytes
//
// On creation of the micro-allocation system you preserve a certiain amount of memory for each of these banks.
//
// The user provides a heap interface to callback for additional memory as needed.
//
// In most cases allocations are order-N and frees are order-N as well.
//
// The larger a buffer you provide, the closer to 'order-N' the allocator behaves.
//
// This kind of a micro-allocator is ideal for use with STL as it does many tiny allocations.
// All allocations are 16 byte aligned (with the exception of the 8 byte allocations, which are 8 byte aligned every other one).
//
#include <stdio.h>
#ifdef WIN32
typedef __int64 NxI64;
typedef signed int NxI32;
typedef signed short NxI16;
typedef signed char NxI8;
typedef unsigned __int64 NxU64;
typedef unsigned int NxU32;
typedef unsigned short NxU16;
typedef unsigned char NxU8;
typedef float NxF32;
typedef double NxF64;
#elif __gnu_linux__
typedef long long NxI64;
typedef signed int NxI32;
typedef signed short NxI16;
typedef signed char NxI8;
typedef unsigned long long NxU64;
typedef unsigned int NxU32;
typedef unsigned short NxU16;
typedef unsigned char NxU8;
typedef float NxF32;
typedef double NxF64;
#elif __APPLE__
typedef long long NxI64;
typedef signed int NxI32;
typedef signed short NxI16;
typedef signed char NxI8;
typedef unsigned long long NxU64;
typedef unsigned int NxU32;
typedef unsigned short NxU16;
typedef unsigned char NxU8;
typedef float NxF32;
typedef double NxF64;
#elif __CELLOS_LV2__
typedef long long NxI64;
typedef signed int NxI32;
typedef signed short NxI16;
typedef signed char NxI8;
typedef unsigned long long NxU64;
typedef unsigned int NxU32;
typedef unsigned short NxU16;
typedef unsigned char NxU8;
typedef float NxF32;
typedef double NxF64;
#elif _XBOX
typedef __int64 NxI64;
typedef signed int NxI32;
typedef signed short NxI16;
typedef signed char NxI8;
typedef unsigned __int64 NxU64;
typedef unsigned int NxU32;
typedef unsigned short NxU16;
typedef unsigned char NxU8;
typedef float NxF32;
typedef double NxF64;
#elif defined(__PPCGEKKO__)
typedef long long NxI64;
typedef signed int NxI32;
typedef signed short NxI16;
typedef signed char NxI8;
typedef unsigned long long NxU64;
typedef unsigned int NxU32;
typedef unsigned short NxU16;
typedef float NxF32;
typedef double NxF64;
#else
#error Unknown platform!
#endif
namespace HACD
{
// user provided heap allocator
class MicroHeap
{
public:
virtual void * micro_malloc(size_t size) = 0;
virtual void micro_free(void *p) = 0;
virtual void * micro_realloc(void *oldMen,size_t newSize) = 0;
};
class MemoryChunk;
class MicroAllocator
{
public:
virtual void * malloc(size_t size) = 0;
virtual void free(void *p,MemoryChunk *chunk) = 0; // free relative to previously located MemoryChunk
virtual MemoryChunk * isMicroAlloc(const void *p) = 0; // returns pointer to the chunk this memory belongs to, or null if not a micro-allocated block.
virtual NxU32 getChunkSize(MemoryChunk *chunk) = 0;
};
MicroAllocator *createMicroAllocator(MicroHeap *heap,NxU32 chunkSize=32768); // initial chunk size 32k per block.
void releaseMicroAllocator(MicroAllocator *m);
class HeapManager
{
public:
virtual void * heap_malloc(size_t size) = 0;
virtual void heap_free(void *p) = 0;
virtual void * heap_realloc(void *oldMem,size_t newSize) = 0;
};
// creates a heap manager that uses micro-allocations for all allocations < 256 bytes and standard malloc/free for anything larger.
HeapManager * createHeapManager(NxU32 defaultChunkSize=32768);
void releaseHeapManager(HeapManager *heap);
// about 10% faster than using the virtual interface, inlines the functions as much as possible.
void * heap_malloc(HeapManager *hm,size_t size);
void heap_free(HeapManager *hm,void *p);
void * heap_realloc(HeapManager *hm,void *oldMem,size_t newSize);
void performUnitTests(void);
//
}; // end of namespace
#endif

View File

@@ -0,0 +1,280 @@
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "hacdRaycastMesh.h"
#include <math.h>
#include <assert.h>
#include <limits>
#include "hacdManifoldMesh.h"
namespace HACD
{
bool BBox::Raycast(const Vec3<Float> & origin, const Vec3<Float> & dir, Float & distMin) const
{
Vec3<Float> d = m_max - m_min;
Float r2 = 0.25 * (d.X()*d.X()+d.Y()*d.Y()+d.Z()*d.Z());
Vec3<Float> c = 0.5 * m_max + 0.5 * m_min;
Vec3<Float> u = (c-origin);
Vec3<Float> a = u - (u * dir) * dir;
Float dist2 = (a.X()*a.X()+a.Y()*a.Y()+a.Z()*a.Z());
distMin = (u.X()*u.X()+u.Y()*u.Y()+u.Z()*u.Z());
if ( distMin > r2 ) // origin outside the sphere of center c and radius r
{
distMin = sqrt(distMin) - sqrt(r2); // the distance to any point inside the sphere is higher than |origin - c| - r
}
else
{
distMin = 0.0;
}
if (dist2 > r2) return false;
return true;
}
void RMNode::ComputeBB()
{
if (m_triIDs.Size() == 0)
{
return;
}
Vec3<long> * const triangles = m_rm->m_triangles;
Vec3<Float> * const vertices = m_rm->m_vertices;
const Float minFloat = std::numeric_limits<Float>::min();
const Float maxFloat = std::numeric_limits<Float>::max();
m_bBox.m_max = Vec3<Float>(minFloat, minFloat, minFloat);
m_bBox.m_min = Vec3<Float>(maxFloat, maxFloat, maxFloat);
Float x, y, z;
long v, f;
for(size_t id = 0; id < m_triIDs.Size(); ++id)
{
f = m_triIDs[id];
for(size_t k = 0; k < 3; ++k)
{
v = triangles[f][k];
x = vertices[v].X();
y = vertices[v].Y();
z = vertices[v].Z();
if ( x < m_bBox.m_min.X()) m_bBox.m_min.X() = x;
if ( x > m_bBox.m_max.X()) m_bBox.m_max.X() = x;
if ( y < m_bBox.m_min.Y()) m_bBox.m_min.Y() = y;
if ( y > m_bBox.m_max.Y()) m_bBox.m_max.Y() = y;
if ( z < m_bBox.m_min.Z()) m_bBox.m_min.Z() = z;
if ( z > m_bBox.m_max.Z()) m_bBox.m_max.Z() = z;
}
}
}
void RaycastMesh::ComputeBB()
{
if (m_nVertices == 0)
{
return;
}
m_bBox.m_min = m_vertices[0];
m_bBox.m_max = m_vertices[0];
Float x, y, z;
for (size_t v = 1; v < m_nVertices ; v++)
{
x = m_vertices[v].X();
y = m_vertices[v].Y();
z = m_vertices[v].Z();
if ( x < m_bBox.m_min.X()) m_bBox.m_min.X() = x;
else if ( x > m_bBox.m_max.X()) m_bBox.m_max.X() = x;
if ( y < m_bBox.m_min.Y()) m_bBox.m_min.Y() = y;
else if ( y > m_bBox.m_max.Y()) m_bBox.m_max.Y() = y;
if ( z < m_bBox.m_min.Z()) m_bBox.m_min.Z() = z;
else if ( z > m_bBox.m_max.Z()) m_bBox.m_max.Z() = z;
}
}
void RaycastMesh::Initialize(size_t nVertices, size_t nTriangles,
Vec3<Float> * vertices, Vec3<long> * triangles,
size_t maxDepth, size_t minLeafSize, Float minAxisSize)
{
m_triangles = triangles;
m_vertices = vertices;
m_nVertices = nVertices;
m_nTriangles = nTriangles;
delete [] m_nodes;
m_nNodes = 0;
m_nMaxNodes = 0;
for(size_t k = 0; k < maxDepth; k++)
{
m_nMaxNodes += (1 << maxDepth);
}
m_nodes = new RMNode[m_nMaxNodes];
RMNode & root = m_nodes[AddNode()];
root.m_triIDs.Resize(nTriangles);
for(size_t t = 0; t < m_nTriangles; ++t) root.m_triIDs.PushBack(t);
root.m_rm = this;
root.m_id = 0;
root.Create(0, maxDepth, minLeafSize, minAxisSize);
}
RaycastMesh::RaycastMesh(void)
{
m_triangles = 0;
m_vertices = 0;
m_nVertices = 0;
m_nTriangles = 0;
m_nodes = 0;
m_nNodes = 0;
m_nMaxNodes = 0;
}
RaycastMesh::~RaycastMesh(void)
{
delete [] m_nodes;
}
void RMNode::Create(size_t depth, size_t maxDepth, size_t minLeafSize, Float minAxisSize)
{
ComputeBB();
Vec3<Float> d = m_bBox.m_max - m_bBox.m_min;
Float maxDiff = std::max<Float>(d.X(), std::max<Float>(d.Y(), d.Z()));
RMSplitAxis split;
if (d.X() == maxDiff) split = RMSplitAxis_X;
else if (d.Y() == maxDiff) split = RMSplitAxis_Y;
else split = RMSplitAxis_Z;
if (depth == maxDepth || minLeafSize >= m_triIDs.Size() || maxDiff < minAxisSize)
{
m_leaf = true;
return;
}
m_idLeft = m_rm->AddNode();
m_idRight = m_rm->AddNode();
RMNode & leftNode = m_rm->m_nodes[m_idLeft];
RMNode & rightNode = m_rm->m_nodes[m_idRight];
leftNode.m_id = m_idLeft;
rightNode.m_id = m_idRight;
leftNode.m_bBox = m_bBox;
rightNode.m_bBox = m_bBox;
leftNode.m_rm = m_rm;
rightNode.m_rm = m_rm;
if ( split == RMSplitAxis_X)
{
leftNode.m_bBox.m_max.X() = leftNode.m_bBox.m_max.X() - d.X() * 0.5;
rightNode.m_bBox.m_min.X() = leftNode.m_bBox.m_max.X();
}
else if ( split == RMSplitAxis_Y)
{
leftNode.m_bBox.m_max.Y() = leftNode.m_bBox.m_max.Y() - d.Y() * 0.5;
rightNode.m_bBox.m_min.Y() = leftNode.m_bBox.m_max.Y();
}
else
{
leftNode.m_bBox.m_max.Z() = leftNode.m_bBox.m_max.Z() - d.Z() * 0.5;
rightNode.m_bBox.m_min.Z() = leftNode.m_bBox.m_max.Z();
}
long f;
long pts[3];
long v;
Vec3<long> * const triangles = m_rm->m_triangles;
Vec3<Float> * const vertices = m_rm->m_vertices;
leftNode.m_triIDs.Resize(m_triIDs.Size());
rightNode.m_triIDs.Resize(m_triIDs.Size());
bool found;
for(size_t id = 0; id < m_triIDs.Size(); ++id)
{
f = m_triIDs[id];
pts[0] = triangles[f].X();
pts[1] = triangles[f].Y();
pts[2] = triangles[f].Z();
found = false;
for (int k = 0; k < 3; ++k)
{
v = pts[k];
if ( vertices[v].X() <= leftNode.m_bBox.m_max.X() &&
vertices[v].X() >= leftNode.m_bBox.m_min.X() &&
vertices[v].Y() <= leftNode.m_bBox.m_max.Y() &&
vertices[v].Y() >= leftNode.m_bBox.m_min.Y() &&
vertices[v].Z() <= leftNode.m_bBox.m_max.Z() &&
vertices[v].Z() >= leftNode.m_bBox.m_min.Z() )
{
leftNode.m_triIDs.PushBack(f);
found = true;
break;
}
}
if (!found)
{
for (int k = 0; k < 3; ++k)
{
v = pts[k];
if ( vertices[v].X() <= rightNode.m_bBox.m_max.X() &&
vertices[v].X() >= rightNode.m_bBox.m_min.X() &&
vertices[v].Y() <= rightNode.m_bBox.m_max.Y() &&
vertices[v].Y() >= rightNode.m_bBox.m_min.Y() &&
vertices[v].Z() <= rightNode.m_bBox.m_max.Z() &&
vertices[v].Z() >= rightNode.m_bBox.m_min.Z() )
{
rightNode.m_triIDs.PushBack(f);
break;
}
}
}
}
rightNode.Create(depth+1, maxDepth, minLeafSize, minAxisSize);
leftNode.Create(depth+1, maxDepth, minLeafSize, minAxisSize);
m_triIDs.Clear();
}
bool RaycastMesh::Raycast(const Vec3<Float> & from, const Vec3<Float> & dir, long & triID, Float & distance, Vec3<Real> & hitPoint, Vec3<Real> & hitNormal) const
{
distance = std::numeric_limits<Float>::max();
if (m_nNodes == 0) return false;
return m_nodes[0].Raycast(from, dir, triID, distance, hitPoint, hitNormal);
}
bool RMNode::Raycast(const Vec3<Float> & from, const Vec3<Float> & dir, long & triID, Float & distance, Vec3<Real> & hitPoint, Vec3<Real> & hitNormal) const
{
Float distToSphere;
if (m_bBox.Raycast(from, dir, distToSphere) && (distToSphere < distance))
{
if (m_leaf)
{
long f, i1, j1, k1;
Vec3<long> * const triangles = m_rm->m_triangles;
Vec3<Float> * const vertices = m_rm->m_vertices;
Vec3<Real> u1, v1, normal1;
double dist = 0.0;
long nhit = 0;
bool ret = false;
for(size_t id = 0; id < m_triIDs.Size(); ++id)
{
f = m_triIDs[id];
i1 = triangles[f].X();
j1 = triangles[f].Y();
k1 = triangles[f].Z();
u1 = vertices[j1] - vertices[i1];
v1 = vertices[k1] - vertices[i1];
normal1 = (u1 ^ v1);
if (dir * normal1 > 0.0)
{
nhit = IntersectRayTriangle(from, dir, vertices[i1], vertices[j1], vertices[k1], dist);
if (nhit==1 && distance>dist)
{
normal1.Normalize();
hitNormal = normal1;
hitPoint = from + dist * dir;
distance = dist;
triID = f;
ret = true;
}
}
}
return ret;
}
bool ret1 = false;
bool ret2 = false;
if (m_idRight >= 0) ret1 = m_rm->m_nodes[m_idRight].Raycast(from, dir, triID, distance, hitPoint, hitNormal);
if (m_idLeft >= 0) ret2 = m_rm->m_nodes[m_idLeft].Raycast(from, dir, triID, distance, hitPoint, hitNormal);
return ret1 || ret2;
}
return false;
}
}

View File

@@ -0,0 +1,97 @@
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef RAYCAST_MESH_H
#define RAYCAST_MESH_H
#include "hacdSArray.h"
#include <vector>
#include "hacdVersion.h"
#include "hacdVector.h"
#include "hacdSArray.h"
namespace HACD
{
typedef double Float;
class RaycastMesh;
class RMNode;
class BBox
{
public:
bool Raycast(const Vec3<Float> & origin, const Vec3<Float> & dir, Float & distance) const;
BBox(void){}
~BBox(void){}
private:
Vec3<Float> m_min;
Vec3<Float> m_max;
friend class RMNode;
friend class RaycastMesh;
};
enum RMSplitAxis
{
RMSplitAxis_X,
RMSplitAxis_Y,
RMSplitAxis_Z
};
class RMNode
{
public:
void ComputeBB();
bool Raycast(const Vec3<Float> & from, const Vec3<Float> & dir, long & triID, Float & distance, Vec3<Real> & hitPoint, Vec3<Real> & hitNormal) const;
void Create(size_t depth, size_t maxDepth, size_t minLeafSize, Float minAxisSize);
~RMNode(void){}
RMNode(void)
{
m_idRight = m_idLeft = m_id = -1;
m_rm = 0;
m_leaf = false;
}
long m_id;
long m_idLeft;
long m_idRight;
BBox m_bBox;
SArray<long, SARRAY_DEFAULT_MIN_SIZE> m_triIDs;
RaycastMesh * m_rm;
bool m_leaf;
};
class RaycastMesh
{
public:
size_t GetNNodes() const { return m_nNodes;}
size_t AddNode() { m_nNodes++; return m_nNodes-1; }
void ComputeBB();
bool Raycast(const Vec3<Float> & from, const Vec3<Float> & dir, long & triID, Float & distance, Vec3<Real> & hitPoint, Vec3<Real> & hitNormal) const;
void Initialize(size_t nVertices, size_t nTriangles,
Vec3<Float> * vertices, Vec3<long> * triangles,
size_t maxDepth=15, size_t minLeafSize = 4, Float minAxisSize = 2.0);
RaycastMesh(void);
~RaycastMesh(void);
private :
private:
Vec3<long> * m_triangles;
Vec3<Float> * m_vertices;
size_t m_nVertices;
size_t m_nTriangles;
RMNode * m_nodes;
BBox m_bBox;
size_t m_nNodes;
size_t m_nMaxNodes;
friend class RMNode;
};
}
#endif

154
indra/libhacd/hacdSArray.h Normal file
View File

@@ -0,0 +1,154 @@
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#ifndef HACD_SARRAY_H
#define HACD_SARRAY_H
#include "hacdVersion.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SARRAY_DEFAULT_MIN_SIZE 16
namespace HACD
{
//! SArray.
template < typename T, size_t N > class SArray
{
public:
T & operator[](size_t i)
{
T * const data = Data();
return data[i];
}
const T & operator[](size_t i) const
{
const T * const data = Data();
return data[i];
}
size_t Size() const
{
return m_size;
}
T * const Data()
{
return (m_maxSize == N)? m_data0 : m_data;
}
const T * const Data() const
{
return (m_maxSize == N)? m_data0 : m_data;
}
void Clear()
{
m_size = 0;
delete [] m_data;
m_data = 0;
m_maxSize = N;
}
void PopBack()
{
--m_size;
}
void Resize(size_t size)
{
if (size > m_maxSize)
{
T * temp = new T[size];
memcpy(temp, Data(), m_size*sizeof(T));
delete [] m_data;
m_data = temp;
m_maxSize = size;
}
}
void PushBack(const T & value)
{
if (m_size==m_maxSize)
{
size_t maxSize = (m_maxSize << 1);
T * temp = new T[maxSize];
memcpy(temp, Data(), m_maxSize*sizeof(T));
delete [] m_data;
m_data = temp;
m_maxSize = maxSize;
}
T * const data = Data();
data[m_size++] = value;
}
bool Find(const T & value, size_t & pos)
{
T * const data = Data();
for(pos = 0; pos < m_size; ++pos)
if (value == data[pos]) return true;
return false;
}
bool Insert(const T & value)
{
size_t pos;
if (Find(value, pos)) return false;
PushBack(value);
return true;
}
bool Erase(const T & value)
{
size_t pos;
T * const data = Data();
if (Find(value, pos))
{
for(size_t j = pos+1; j < m_size; ++j)
data[j-1] = data[j];
--m_size;
return true;
}
return false;
}
void operator=(const SArray & rhs)
{
if (m_maxSize < rhs.m_size)
{
delete [] m_data;
m_maxSize = rhs.m_maxSize;
m_data = new T[m_maxSize];
}
m_size = rhs.m_size;
memcpy(Data(), rhs.Data(), m_size*sizeof(T));
}
void Initialize()
{
m_data = 0;
m_size = 0;
m_maxSize = N;
}
SArray(const SArray & rhs)
{
m_data = 0;
m_size = 0;
m_maxSize = N;
*this = rhs;
}
SArray()
{
Initialize();
}
~SArray()
{
delete [] m_data;
}
private:
T m_data0[N];
T * m_data;
size_t m_size;
size_t m_maxSize;
};
}
#endif

View File

@@ -0,0 +1,69 @@
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#ifndef HACD_VECTOR_H
#define HACD_VECTOR_H
#include <math.h>
#include <iostream>
#include "hacdVersion.h"
namespace HACD
{
typedef double Real;
//! Vector dim 3.
template < typename T > class Vec3
{
public:
T & operator[](size_t i) { return m_data[i];}
const T & operator[](size_t i) const { return m_data[i];}
T & X();
T & Y();
T & Z();
const T & X() const;
const T & Y() const;
const T & Z() const;
void Normalize();
T GetNorm() const;
void operator= (const Vec3 & rhs);
void operator+=(const Vec3 & rhs);
void operator-=(const Vec3 & rhs);
void operator-=(T a);
void operator+=(T a);
void operator/=(T a);
void operator*=(T a);
Vec3 operator^ (const Vec3 & rhs) const;
T operator* (const Vec3 & rhs) const;
Vec3 operator+ (const Vec3 & rhs) const;
Vec3 operator- (const Vec3 & rhs) const;
Vec3 operator- () const;
Vec3 operator* (T rhs) const;
Vec3 operator/ (T rhs) const;
Vec3();
Vec3(T a);
Vec3(T x, T y, T z);
Vec3(const Vec3 & rhs);
/*virtual*/ ~Vec3(void);
private:
T m_data[3];
};
template<typename T>
const bool Colinear(const Vec3<T> & a, const Vec3<T> & b, const Vec3<T> & c);
template<typename T>
const T Volume(const Vec3<T> & a, const Vec3<T> & b, const Vec3<T> & c, const Vec3<T> & d);
}
#include "hacdVector.inl" // template implementation
#endif

View File

@@ -0,0 +1,178 @@
#pragma once
#ifndef HACD_VECTOR_INL
#define HACD_VECTOR_INL
namespace HACD
{
template <typename T>
inline Vec3<T> operator*(T lhs, const Vec3<T> & rhs)
{
return Vec3<T>(lhs * rhs.X(), lhs * rhs.Y(), lhs * rhs.Z());
}
template <typename T>
inline T & Vec3<T>::X()
{
return m_data[0];
}
template <typename T>
inline T & Vec3<T>::Y()
{
return m_data[1];
}
template <typename T>
inline T & Vec3<T>::Z()
{
return m_data[2];
}
template <typename T>
inline const T & Vec3<T>::X() const
{
return m_data[0];
}
template <typename T>
inline const T & Vec3<T>::Y() const
{
return m_data[1];
}
template <typename T>
inline const T & Vec3<T>::Z() const
{
return m_data[2];
}
template <typename T>
inline void Vec3<T>::Normalize()
{
T n = sqrt(m_data[0]*m_data[0]+m_data[1]*m_data[1]+m_data[2]*m_data[2]);
if (n != 0.0) (*this) /= n;
}
template <typename T>
inline T Vec3<T>::GetNorm() const
{
return sqrt(m_data[0]*m_data[0]+m_data[1]*m_data[1]+m_data[2]*m_data[2]);
}
template <typename T>
inline void Vec3<T>::operator= (const Vec3 & rhs)
{
this->m_data[0] = rhs.m_data[0];
this->m_data[1] = rhs.m_data[1];
this->m_data[2] = rhs.m_data[2];
}
template <typename T>
inline void Vec3<T>::operator+=(const Vec3 & rhs)
{
this->m_data[0] += rhs.m_data[0];
this->m_data[1] += rhs.m_data[1];
this->m_data[2] += rhs.m_data[2];
}
template <typename T>
inline void Vec3<T>::operator-=(const Vec3 & rhs)
{
this->m_data[0] -= rhs.m_data[0];
this->m_data[1] -= rhs.m_data[1];
this->m_data[2] -= rhs.m_data[2];
}
template <typename T>
inline void Vec3<T>::operator-=(T a)
{
this->m_data[0] -= a;
this->m_data[1] -= a;
this->m_data[2] -= a;
}
template <typename T>
inline void Vec3<T>::operator+=(T a)
{
this->m_data[0] += a;
this->m_data[1] += a;
this->m_data[2] += a;
}
template <typename T>
inline void Vec3<T>::operator/=(T a)
{
this->m_data[0] /= a;
this->m_data[1] /= a;
this->m_data[2] /= a;
}
template <typename T>
inline void Vec3<T>::operator*=(T a)
{
this->m_data[0] *= a;
this->m_data[1] *= a;
this->m_data[2] *= a;
}
template <typename T>
inline Vec3<T> Vec3<T>::operator^ (const Vec3<T> & rhs) const
{
return Vec3<T>(m_data[1] * rhs.m_data[2] - m_data[2] * rhs.m_data[1],
m_data[2] * rhs.m_data[0] - m_data[0] * rhs.m_data[2],
m_data[0] * rhs.m_data[1] - m_data[1] * rhs.m_data[0]);
}
template <typename T>
inline T Vec3<T>::operator*(const Vec3<T> & rhs) const
{
return (m_data[0] * rhs.m_data[0] + m_data[1] * rhs.m_data[1] + m_data[2] * rhs.m_data[2]);
}
template <typename T>
inline Vec3<T> Vec3<T>::operator+(const Vec3<T> & rhs) const
{
return Vec3<T>(m_data[0] + rhs.m_data[0],m_data[1] + rhs.m_data[1],m_data[2] + rhs.m_data[2]);
}
template <typename T>
inline Vec3<T> Vec3<T>::operator-(const Vec3<T> & rhs) const
{
return Vec3<T>(m_data[0] - rhs.m_data[0],m_data[1] - rhs.m_data[1],m_data[2] - rhs.m_data[2]) ;
}
template <typename T>
inline Vec3<T> Vec3<T>::operator-() const
{
return Vec3<T>(-m_data[0],-m_data[1],-m_data[2]) ;
}
template <typename T>
inline Vec3<T> Vec3<T>::operator*(T rhs) const
{
return Vec3<T>(rhs * this->m_data[0], rhs * this->m_data[1], rhs * this->m_data[2]);
}
template <typename T>
inline Vec3<T> Vec3<T>::operator/ (T rhs) const
{
return Vec3<T>(m_data[0] / rhs, m_data[1] / rhs, m_data[2] / rhs);
}
template <typename T>
inline Vec3<T>::Vec3(T a)
{
m_data[0] = m_data[1] = m_data[2] = a;
}
template <typename T>
inline Vec3<T>::Vec3(T x, T y, T z)
{
m_data[0] = x;
m_data[1] = y;
m_data[2] = z;
}
template <typename T>
inline Vec3<T>::Vec3(const Vec3 & rhs)
{
m_data[0] = rhs.m_data[0];
m_data[1] = rhs.m_data[1];
m_data[2] = rhs.m_data[2];
}
template <typename T>
inline Vec3<T>::~Vec3(void){};
template <typename T>
inline Vec3<T>::Vec3() {}
template<typename T>
inline const bool Colinear(const Vec3<T> & a, const Vec3<T> & b, const Vec3<T> & c)
{
return ((c.Z() - a.Z()) * (b.Y() - a.Y()) - (b.Z() - a.Z()) * (c.Y() - a.Y()) == 0.0 /*EPS*/) &&
((b.Z() - a.Z()) * (c.X() - a.X()) - (b.X() - a.X()) * (c.Z() - a.Z()) == 0.0 /*EPS*/) &&
((b.X() - a.X()) * (c.Y() - a.Y()) - (b.Y() - a.Y()) * (c.X() - a.X()) == 0.0 /*EPS*/);
}
template<typename T>
inline const T Volume(const Vec3<T> & a, const Vec3<T> & b, const Vec3<T> & c, const Vec3<T> & d)
{
return (a-d) * ((b-d) ^ (c-d));
}
}
#endif //HACD_VECTOR_INL

View File

@@ -0,0 +1,20 @@
/* Copyright (c) 2011 Khaled Mamou (kmamou at gmail dot com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#ifndef HACD_VERSION_H
#define HACD_VERSION_H
#define HACD_VERSION_MAJOR 0
#define HACD_VERSION_MINOR 0
#endif

View File

@@ -0,0 +1,9 @@
project(libndhacd)
include_directories(${LIBS_OPEN_DIR}/libhacd)
set (SOURCE_FILES LLConvexDecomposition.cpp nd_hacdConvexDecomposition.cpp nd_hacdStructs.cpp nd_hacdUtils.cpp nd_EnterExitTracer.cpp nd_StructTracer.cpp )
file(GLOB HEADER_FILES *.h)
add_library( nd_hacdConvexDecomposition STATIC ${SOURCE_FILES} ${HEADER_FILES})

View File

@@ -0,0 +1,80 @@
/**
* @file LLConvexDecomposition.cpp
* @author falcon@lindenlab.com
* @brief A stub implementation of LLConvexDecomposition interface
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#if defined(_WINDOWS)
# include "windowsincludes.h"
#endif
#ifndef NULL
#define NULL 0
#endif
#include "nd_hacdConvexDecomposition.h"
#include "LLConvexDecomposition.h"
/*static */bool LLConvexDecomposition::s_isInitialized = false;
/*static*/LLConvexDecomposition* LLConvexDecomposition::getInstance()
{
if ( !s_isInitialized )
{
return NULL;
}
else
{
return nd_hacdConvexDecomposition::getInstance();
}
}
/*static */LLCDResult LLConvexDecomposition::initSystem()
{
LLCDResult result = nd_hacdConvexDecomposition::initSystem();
if ( result == LLCD_OK )
{
s_isInitialized = true;
}
return result;
}
/*static */LLCDResult LLConvexDecomposition::initThread()
{
return nd_hacdConvexDecomposition::initThread();
}
/*static */LLCDResult LLConvexDecomposition::quitThread()
{
return nd_hacdConvexDecomposition::quitThread();
}
/*static */LLCDResult LLConvexDecomposition::quitSystem()
{
return nd_hacdConvexDecomposition::quitSystem();
}

View File

@@ -0,0 +1,231 @@
/**
* @file LLConvexDecomposition.cpp
* @brief LLConvexDecomposition interface definition
*
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_CONVEX_DECOMPOSITION
#define LL_CONVEX_DECOMPOSITION
typedef int bool32;
#if defined(_WIN32) || defined(_WIN64)
#define LLCD_CALL __cdecl
#else
#define LLCD_CALL
#endif
struct LLCDParam
{
enum LLCDParamType
{
LLCD_INVALID = 0,
LLCD_INTEGER,
LLCD_FLOAT,
LLCD_BOOLEAN,
LLCD_ENUM
};
struct LLCDEnumItem
{
const char* mName;
int mValue;
};
union LLCDValue
{
float mFloat;
int mIntOrEnumValue;
bool32 mBool;
};
union LLCDParamDetails
{
struct {
LLCDValue mLow;
LLCDValue mHigh;
LLCDValue mDelta;
} mRange;
struct {
int mNumEnums;
LLCDEnumItem* mEnumsArray;
} mEnumValues;
};
const char* mName;
const char* mDescription;
LLCDParamType mType;
LLCDParamDetails mDetails;
LLCDValue mDefault;
int mStage;
// WARNING: Only the LLConvexDecomposition implementation
// should change this value
int mReserved;
};
struct LLCDStageData
{
const char* mName;
const char* mDescription;
bool32 mSupportsCallback;
};
struct LLCDMeshData
{
enum IndexType
{
INT_16,
INT_32
};
const float* mVertexBase;
int mVertexStrideBytes;
int mNumVertices;
const void* mIndexBase;
IndexType mIndexType;
int mIndexStrideBytes;
int mNumTriangles;
};
struct LLCDHull
{
const float* mVertexBase;
int mVertexStrideBytes;
int mNumVertices;
};
enum LLCDResult
{
LLCD_OK = 0,
LLCD_UNKOWN_ERROR,
LLCD_NULL_PTR,
LLCD_INVALID_STAGE,
LLCD_UNKNOWN_PARAM,
LLCD_BAD_VALUE,
LLCD_REQUEST_OUT_OF_RANGE,
LLCD_INVALID_MESH_DATA,
LLCD_INVALID_HULL_DATA,
LLCD_STAGE_NOT_READY,
LLCD_INVALID_THREAD,
LLCD_NOT_IMPLEMENTED
};
// This callback will receive a string describing the current subtask being performed
// as well as a pair of numbers indicating progress. (The values should not be interpreted
// as a completion percentage as 'current' may be greater than 'final'.)
// If the callback returns zero, the decomposition will be terminated
typedef int (LLCD_CALL *llcdCallbackFunc)(const char* description, int current, int final);
class LLConvexDecomposition
{
public:
// Obtain a pointer to the actual implementation
static LLConvexDecomposition* getInstance();
static LLCDResult initSystem();
static LLCDResult initThread();
static LLCDResult quitThread();
static LLCDResult quitSystem();
// Generate a decomposition object handle
virtual void genDecomposition(int& decomp) = 0;
// Delete decomposition object handle
virtual void deleteDecomposition(int decomp) = 0;
// Bind given decomposition handle
// Commands operate on currently bound decomposition
virtual void bindDecomposition(int decomp) = 0;
// Sets *paramsOut to the address of the LLCDParam array and returns
// the number of parameters
virtual int getParameters(const LLCDParam** paramsOut) = 0;
// Sets *stagesOut to the address of the LLCDStageData array and returns
// the number of stages
virtual int getStages(const LLCDStageData** stagesOut) = 0;
// Set a parameter by name. Pass enum values as integers.
virtual LLCDResult setParam(const char* name, float val) = 0;
virtual LLCDResult setParam(const char* name, int val) = 0;
virtual LLCDResult setParam(const char* name, bool val) = 0;
// Set incoming mesh data. Data is copied to local buffers and will
// persist until the next setMeshData call
virtual LLCDResult setMeshData( const LLCDMeshData* data, bool vertex_based ) = 0;
// Register a callback to be called periodically during the specified stage
// See the typedef above for more information
virtual LLCDResult registerCallback( int stage, llcdCallbackFunc callback ) = 0;
// Execute the specified decomposition stage
virtual LLCDResult executeStage(int stage) = 0;
virtual LLCDResult buildSingleHull() = 0 ;
// Gets the number of hulls generated by the specified decompositions stage
virtual int getNumHullsFromStage(int stage) = 0;
// Populates hullOut to reference the internal copy of the requested hull
// The data will persist only until the next executeStage call for that stage.
virtual LLCDResult getHullFromStage( int stage, int hull, LLCDHull* hullOut ) = 0;
virtual LLCDResult getSingleHull( LLCDHull* hullOut ) = 0 ;
// TODO: Implement lock of some kind to disallow this call if data not yet ready
// Populates the meshDataOut to reference the utility's copy of the mesh geometry
// for the hull and stage specified.
// You must copy this data if you want to continue using it after the next executeStage
// call
virtual LLCDResult getMeshFromStage( int stage, int hull, LLCDMeshData* meshDataOut) = 0;
// Creates a mesh from hullIn and temporarily stores it internally in the utility.
// The mesh data persists only until the next call to getMeshFromHull
virtual LLCDResult getMeshFromHull( LLCDHull* hullIn, LLCDMeshData* meshOut ) = 0;
// Takes meshIn, generates a single convex hull from it, converts that to a mesh
// stored internally, and populates meshOut to reference the internally stored data.
// The data is persistent only until the next call to generateSingleHullMeshFromMesh
virtual LLCDResult generateSingleHullMeshFromMesh( LLCDMeshData* meshIn, LLCDMeshData* meshOut) = 0;
//
/// Debug
virtual void loadMeshData(const char* fileIn, LLCDMeshData** meshDataOut) = 0;
virtual bool isFunctional()=0;
private:
static bool s_isInitialized;
};
// Pull in our trace interface
#include "ndConvexDecomposition.h"
#endif //LL_CONVEX_DECOMPOSITION

View File

@@ -0,0 +1,148 @@
/**
* @file LLConvexDecompositionStubImpl.cpp
* @author falcon@lindenlab.com
* @brief A stub implementation of LLConvexDecomposition
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include <string.h>
#include <memory>
#include "LLConvexDecompositionStubImpl.h"
LLConvexDecomposition* LLConvexDecompositionImpl::getInstance()
{
return NULL;
}
LLCDResult LLConvexDecompositionImpl::initSystem()
{
return LLCD_NOT_IMPLEMENTED;
}
LLCDResult LLConvexDecompositionImpl::initThread()
{
return LLCD_NOT_IMPLEMENTED;
}
LLCDResult LLConvexDecompositionImpl::quitThread()
{
return LLCD_NOT_IMPLEMENTED;
}
LLCDResult LLConvexDecompositionImpl::quitSystem()
{
return LLCD_NOT_IMPLEMENTED;
}
void LLConvexDecompositionImpl::genDecomposition(int& decomp)
{
}
void LLConvexDecompositionImpl::deleteDecomposition(int decomp)
{
}
void LLConvexDecompositionImpl::bindDecomposition(int decomp)
{
}
LLCDResult LLConvexDecompositionImpl::setParam(const char* name, float val)
{
return LLCD_NOT_IMPLEMENTED;
}
LLCDResult LLConvexDecompositionImpl::setParam(const char* name, bool val)
{
return LLCD_NOT_IMPLEMENTED;
}
LLCDResult LLConvexDecompositionImpl::setParam(const char* name, int val)
{
return LLCD_NOT_IMPLEMENTED;
}
LLCDResult LLConvexDecompositionImpl::setMeshData( const LLCDMeshData* data, bool vertex_based )
{
return LLCD_NOT_IMPLEMENTED;
}
LLCDResult LLConvexDecompositionImpl::registerCallback(int stage, llcdCallbackFunc callback )
{
return LLCD_NOT_IMPLEMENTED;
}
LLCDResult LLConvexDecompositionImpl::buildSingleHull()
{
return LLCD_NOT_IMPLEMENTED;
}
LLCDResult LLConvexDecompositionImpl::executeStage(int stage)
{
return LLCD_NOT_IMPLEMENTED;
}
int LLConvexDecompositionImpl::getNumHullsFromStage(int stage)
{
return 0;
}
LLCDResult LLConvexDecompositionImpl::getSingleHull( LLCDHull* hullOut )
{
memset( hullOut, 0, sizeof(LLCDHull) );
return LLCD_NOT_IMPLEMENTED;
}
LLCDResult LLConvexDecompositionImpl::getHullFromStage( int stage, int hull, LLCDHull* hullOut )
{
memset( hullOut, 0, sizeof(LLCDHull) );
return LLCD_NOT_IMPLEMENTED;
}
LLCDResult LLConvexDecompositionImpl::getMeshFromStage( int stage, int hull, LLCDMeshData* meshDataOut )
{
memset( meshDataOut, 0, sizeof(LLCDMeshData) );
return LLCD_NOT_IMPLEMENTED;
}
LLCDResult LLConvexDecompositionImpl::getMeshFromHull( LLCDHull* hullIn, LLCDMeshData* meshOut )
{
memset( meshOut, 0, sizeof(LLCDMeshData) );
return LLCD_NOT_IMPLEMENTED;
}
LLCDResult LLConvexDecompositionImpl::generateSingleHullMeshFromMesh(LLCDMeshData* meshIn, LLCDMeshData* meshOut)
{
memset( meshOut, 0, sizeof(LLCDMeshData) );
return LLCD_NOT_IMPLEMENTED;
}
void LLConvexDecompositionImpl::loadMeshData(const char* fileIn, LLCDMeshData** meshDataOut)
{
static LLCDMeshData meshData;
memset( &meshData, 0, sizeof(LLCDMeshData) );
*meshDataOut = &meshData;
}

View File

@@ -0,0 +1,97 @@
/**
* @file LLConvexDecompositionStubImpl.h
* @author falcon@lindenlab.com
* @brief A stub implementation of LLConvexDecomposition
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_CONVEX_DECOMP_UTIL_H
#define LL_CONVEX_DECOMP_UTIL_H
#include "LLConvexDecomposition.h"
class LLConvexDecompositionImpl : public LLConvexDecomposition
{
public:
virtual ~LLConvexDecompositionImpl() {}
static LLConvexDecomposition* getInstance();
static LLCDResult initSystem();
static LLCDResult initThread();
static LLCDResult quitThread();
static LLCDResult quitSystem();
// Generate a decomposition object handle
void genDecomposition(int& decomp);
// Delete decomposition object handle
void deleteDecomposition(int decomp);
// Bind given decomposition handle
// Commands operate on currently bound decomposition
void bindDecomposition(int decomp);
// Sets *paramsOut to the address of the LLCDParam array and returns
// the length of the array
int getParameters(const LLCDParam** paramsOut)
{
*paramsOut = NULL;
return 0;
}
int getStages(const LLCDStageData** stagesOut)
{
*stagesOut = NULL;
return 0;
}
// Set a parameter by name. Returns false if out of bounds or unsupported parameter
LLCDResult setParam(const char* name, float val);
LLCDResult setParam(const char* name, int val);
LLCDResult setParam(const char* name, bool val);
LLCDResult setMeshData( const LLCDMeshData* data, bool vertex_based );
LLCDResult registerCallback(int stage, llcdCallbackFunc callback );
LLCDResult executeStage(int stage);
LLCDResult buildSingleHull() ;
int getNumHullsFromStage(int stage);
LLCDResult getHullFromStage( int stage, int hull, LLCDHull* hullOut );
LLCDResult getSingleHull( LLCDHull* hullOut ) ;
// TODO: Implement lock of some kind to disallow this call if data not yet ready
LLCDResult getMeshFromStage( int stage, int hull, LLCDMeshData* meshDataOut);
LLCDResult getMeshFromHull( LLCDHull* hullIn, LLCDMeshData* meshOut );
// For visualizing convex hull shapes in the viewer physics shape display
LLCDResult generateSingleHullMeshFromMesh( LLCDMeshData* meshIn, LLCDMeshData* meshOut);
/// Debug
void loadMeshData(const char* fileIn, LLCDMeshData** meshDataOut);
private:
LLConvexDecompositionImpl() {}
};
#endif //LL_CONVEX_DECOMP_UTIL_H

View File

@@ -0,0 +1,58 @@
#ifndef ND_CONVEXDECOMPOSITION_H
#define ND_CONVEXDECOMPOSITION_H
/**
* copyright 2011 sl.nicky.ml@googlemail.com
*
* 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
*/
#ifndef ND_HASCONVEXDECOMP_TRACER
#define ND_HASCONVEXDECOMP_TRACER
#endif
class ndConvexDecompositionTracer
{
public:
enum ETraceLevel
{
eNone = 0,
eTraceFunctions = 0x1,
eTraceData = 0x2,
};
virtual ~ndConvexDecompositionTracer()
{ }
virtual void trace( char const *a_strMsg ) = 0;
virtual void startTraceData( char const *a_strWhat) = 0;
virtual void traceData( char const *a_strData ) = 0;
virtual void endTraceData() = 0;
virtual int getLevel() = 0;
virtual void addref() = 0;
virtual void release() = 0;
};
class ndConvexDecompositionTracable
{
public:
virtual void setTracer( ndConvexDecompositionTracer *) = 0;
};
#endif

View File

@@ -0,0 +1,51 @@
/**
* copyright 2011 sl.nicky.ml@googlemail.com
*
* 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
*/
#include "nd_EnterExitTracer.h"
#include <vector>
#include <sstream>
void EnterExitTracer::doTrace( char const *aPrefix )
{
if( !mFunc || !mTracer )
return;
if( ndConvexDecompositionTracer::eTraceFunctions == (mTracer->getLevel() & ndConvexDecompositionTracer::eTraceFunctions ) )
return;
std::stringstream str;
if( aPrefix )
str << aPrefix;
str << mFunc;
mTracer->trace( str.str().c_str() );
}
EnterExitTracer::EnterExitTracer( char const *aFunc, ndConvexDecompositionTracer *aTracer )
: mFunc( aFunc )
, mTracer( aTracer )
{
doTrace( "enter: " );
}
EnterExitTracer::~EnterExitTracer( )
{
doTrace( "exit: " );
}

View File

@@ -0,0 +1,43 @@
#ifndef ND_ENTEREXITTRACER_H
#define ND_ENTEREXITTRACER_H
/**
* copyright 2011 sl.nicky.ml@googlemail.com
*
* 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
*/
#include "ndConvexDecomposition.h"
class EnterExitTracer
{
char const *mFunc;
ndConvexDecompositionTracer *mTracer;
void doTrace( char const *aPrefix );
public:
EnterExitTracer( char const *aFunc, ndConvexDecompositionTracer *aTracer );
~EnterExitTracer( );
};
#ifdef __GNUC__
#define TRACE_FUNC(ATRACER) EnterExitTracer oETTrace( __PRETTY_FUNCTION__, ATRACER );
#else
#define TRACE_FUNC(ATRACER) EnterExitTracer oETTrace( __FUNCTION__, ATRACER );
#endif
#endif

View File

@@ -0,0 +1,188 @@
/**
* copyright 2011 sl.nicky.ml@googlemail.com
*
* 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
*/
#include "nd_StructTracer.h"
#include <sstream>
#include <iomanip>
using namespace std;
namespace ndStructTracer
{
bool doTrace( ndConvexDecompositionTracer *aTracer )
{
if( !aTracer )
return false;
return ndConvexDecompositionTracer::eTraceData == (aTracer->getLevel() & ndConvexDecompositionTracer::eTraceData) ;
}
template<typename T> void traceVecDbl( T const &aValue, ndConvexDecompositionTracer *aTracer )
{
stringstream str;
str << fixed
<< "\tX: " << aValue.X()
<< " Y: " << aValue.Y()
<< " Z: " << aValue.Z();
aTracer->traceData( str.str().c_str() );
}
template< typename T> void traceVecDoubles( vector< T > const &aVertices, ndConvexDecompositionTracer *aTracer )
{
for( size_t i = 0; i < aVertices.size(); ++i )
traceVecDbl( aVertices[i], aTracer );
}
void traceVertices( vector< tVecDbl > const &aVertices, ndConvexDecompositionTracer *aTracer )
{
aTracer->traceData( "Triangles\n" );
traceVecDoubles( aVertices, aTracer );
}
void traceTriangles( vector< tVecLong > const &aTriangles, ndConvexDecompositionTracer *aTracer )
{
aTracer->traceData( "Vertices\n" );
traceVecDoubles( aTriangles, aTracer );
}
void trace( DecompData const &aData, ndConvexDecompositionTracer *aTracer )
{
if( !doTrace( aTracer ) )
return;
aTracer->startTraceData("Hulls");
stringstream str;
str << "Hulls: " << aData.mHulls.size();
aTracer->traceData( str.str().c_str() );
str.seekp(0);
for( size_t i = 0; i < aData.mHulls.size(); ++i )
{
str << "Hull #" << i;
aTracer->traceData( str.str().c_str() );
str.seekp(0);
DecompHull const &oHull( aData.mHulls[i] );
traceVertices( oHull.mVertices, aTracer );
traceTriangles( oHull.mTriangles, aTracer );
}
aTracer->endTraceData();
}
template< typename T> void traceVertex( T aX, T aY, T aZ, ndConvexDecompositionTracer *aTracer )
{
stringstream str;
str << fixed
<< "X: " << aX
<< "Y: " << aY
<< "Z: " << aZ;
aTracer->traceData( str.str().c_str() );
}
template< typename T> void traceTriangle( void *& aPtr, int aStride, ndConvexDecompositionTracer *aTracer )
{
T *pData = reinterpret_cast< T* >(aPtr);
long X( pData[0] ), Y( pData[1] ), Z( pData[2] );
traceVertex( X, Y, Z, aTracer );
pData += aStride;
aPtr = pData;
}
void traceVertices( int aNumVertices, float const *aVertices, int aStride, ndConvexDecompositionTracer *aTracer )
{
for( int i = 0; i < aNumVertices; ++i )
{
float X( aVertices[0] ), Y( aVertices[1] ), Z( aVertices[2] );
traceVertex( X, Y, Z, aTracer );
aVertices += aStride;
}
}
void traceTriangles( LLCDMeshData const *aData, ndConvexDecompositionTracer *aTracer )
{
int nCount = aData->mNumTriangles;
int nStride = aData->mIndexStrideBytes;
void *pData = const_cast<void*>( aData->mIndexBase );
int nIndexType = aData->mIndexType;
if ( LLCDMeshData::INT_16 == nIndexType )
nStride /= 2;
else
nStride /= 4;
for ( int i = 0; i < nCount; ++i )
{
if( LLCDMeshData::INT_16 == nIndexType )
traceTriangle< hacdUINT16 >( pData, nStride, aTracer );
else
traceTriangle< hacdUINT32 >( pData, nStride, aTracer );
}
}
void trace( LLCDMeshData const *aData, bool aVertexBased, ndConvexDecompositionTracer *aTracer )
{
if( !doTrace( aTracer ) )
return;
aTracer->startTraceData("LLCDMeshData");
string strVBased("true");
if( !aVertexBased )
strVBased = "false";
stringstream str;
str << "LLCDMeshData vertex based: " << strVBased
<< "# vertices " << aData->mNumVertices
<< "# triangles " << aData->mNumTriangles;
aTracer->traceData( str.str().c_str() );
traceVertices( aData->mNumVertices, aData->mVertexBase, aData->mVertexStrideBytes/sizeof(float), aTracer );
if( !aVertexBased )
traceTriangles( aData, aTracer );
aTracer->endTraceData();
}
void trace( LLCDHull const *aData, ndConvexDecompositionTracer *aTracer )
{
if( !doTrace( aTracer ) )
return;
aTracer->startTraceData("LLCDHull");
stringstream str;
str << "LLCDHull # vertices " << aData->mNumVertices;
aTracer->traceData( str.str().c_str() );
traceVertices( aData->mNumVertices, aData->mVertexBase, aData->mVertexStrideBytes/sizeof(float), aTracer );
aTracer->endTraceData();
}
};

View File

@@ -0,0 +1,34 @@
#ifndef ND_STRUCTTRACER_H
#define ND_STRUCTTRACER_H
/**
* copyright 2011 sl.nicky.ml@googlemail.com
*
* 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
*/
#include "ndConvexDecomposition.h"
#include "LLConvexDecomposition.h"
#include "nd_hacdStructs.h"
namespace ndStructTracer
{
void trace( DecompData const &aData, ndConvexDecompositionTracer *aTracer );
void trace( LLCDMeshData const *aData, bool aVertexBased, ndConvexDecompositionTracer *aTracer );
void trace( LLCDHull const *aData, ndConvexDecompositionTracer *aTracer );
};
#endif

View File

@@ -0,0 +1,393 @@
/**
* copyright 2011 sl.nicky.ml@googlemail.com
*
* 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
*/
#include <string.h>
#include <memory>
#include "nd_hacdConvexDecomposition.h"
#include "nd_hacdDefines.h"
#include "nd_hacdStructs.h"
#include "nd_hacdUtils.h"
#include "ndConvexDecomposition.h"
#include "nd_EnterExitTracer.h"
#include "nd_StructTracer.h"
LLCDStageData nd_hacdConvexDecomposition::mStages[1];
LLCDParam nd_hacdConvexDecomposition::mParams[4];
LLCDParam::LLCDEnumItem nd_hacdConvexDecomposition::mMethods[1];
LLCDParam::LLCDEnumItem nd_hacdConvexDecomposition::mQuality[1];
LLCDParam::LLCDEnumItem nd_hacdConvexDecomposition::mSimplify[1];
LLConvexDecomposition* nd_hacdConvexDecomposition::getInstance()
{
static nd_hacdConvexDecomposition sImpl;
return &sImpl;
}
nd_hacdConvexDecomposition::nd_hacdConvexDecomposition()
{
mNextId = 0;
mCurrentDecoder = 0;
mSingleHullMeshFromMesh = new HACDDecoder();
mTracer = 0;
}
nd_hacdConvexDecomposition::~nd_hacdConvexDecomposition()
{
if( mTracer )
mTracer->release();
}
LLCDResult nd_hacdConvexDecomposition::initSystem()
{
memset( &mStages[0], 0, sizeof( mStages ) );
memset( &mParams[0], 0, sizeof( mParams ) );
memset( &mMethods[0], 0, sizeof( mMethods ) );
memset( &mQuality[0], 0, sizeof( mQuality ) );
memset( &mSimplify[0], 0, sizeof( mSimplify ) );
mStages[0].mName = "Decompose";
mStages[0].mDescription = NULL;
mMethods[0].mName = "Default";
mMethods[0].mValue = 0;
mQuality[0].mName = "Default";
mQuality[0].mValue = 0;
mSimplify[0].mName = "None";
mSimplify[0].mValue = 0;
mParams[0].mName = "nd_AlwaysNeedTriangles";
mParams[0].mDescription = 0;
mParams[0].mType = LLCDParam::LLCD_BOOLEAN;
mParams[0].mDefault.mBool = true;
mParams[1].mName = "Method";
mParams[1].mType = LLCDParam::LLCD_ENUM;
mParams[1].mDetails.mEnumValues.mNumEnums = sizeof(mMethods)/sizeof(LLCDParam::LLCDEnumItem);
mParams[1].mDetails.mEnumValues.mEnumsArray = mMethods;
mParams[1].mDefault.mIntOrEnumValue = 0;
mParams[2].mName = "Decompose Quality";
mParams[2].mType = LLCDParam::LLCD_ENUM;
mParams[2].mDetails.mEnumValues.mNumEnums = sizeof(mQuality)/sizeof(LLCDParam::LLCDEnumItem);
mParams[2].mDetails.mEnumValues.mEnumsArray = mQuality;
mParams[2].mDefault.mIntOrEnumValue = 0;
mParams[3].mName = "Simplify Method";
mParams[3].mType = LLCDParam::LLCD_ENUM;
mParams[3].mDetails.mEnumValues.mNumEnums = sizeof(mSimplify)/sizeof(LLCDParam::LLCDEnumItem);
mParams[3].mDetails.mEnumValues.mEnumsArray = mSimplify;
mParams[3].mDefault.mIntOrEnumValue = 0;
return LLCD_OK;
}
LLCDResult nd_hacdConvexDecomposition::initThread()
{
return LLCD_OK;
}
LLCDResult nd_hacdConvexDecomposition::quitThread()
{
return LLCD_OK;
}
LLCDResult nd_hacdConvexDecomposition::quitSystem()
{
return LLCD_OK;
}
void nd_hacdConvexDecomposition::genDecomposition( int& decomp )
{
HACDDecoder *pGen = new HACDDecoder();
decomp = mNextId;
++mNextId;
mDecoders[ decomp ] = pGen;
}
void nd_hacdConvexDecomposition::deleteDecomposition( int decomp )
{
delete mDecoders[ decomp ];
mDecoders.erase( decomp );
}
void nd_hacdConvexDecomposition::bindDecomposition( int decomp )
{
TRACE_FUNC( mTracer );
mCurrentDecoder = decomp;
}
LLCDResult nd_hacdConvexDecomposition::setParam( const char* name, float val )
{
TRACE_FUNC( mTracer );
return LLCD_OK;
}
LLCDResult nd_hacdConvexDecomposition::setParam( const char* name, bool val )
{
TRACE_FUNC( mTracer );
return LLCD_OK;
}
LLCDResult nd_hacdConvexDecomposition::setParam( const char* name, int val )
{
TRACE_FUNC( mTracer );
return LLCD_OK;
}
LLCDResult nd_hacdConvexDecomposition::setMeshData( const LLCDMeshData* data, bool vertex_based )
{
TRACE_FUNC( mTracer );
ndStructTracer::trace( data, vertex_based, mTracer );
HACDDecoder *pC = mDecoders[ mCurrentDecoder ];
return ::setMeshData( data, vertex_based, pC );
}
LLCDResult nd_hacdConvexDecomposition::registerCallback( int stage, llcdCallbackFunc callback )
{
TRACE_FUNC( mTracer );
if( mDecoders.end() == mDecoders.find( mCurrentDecoder ) )
return LLCD_STAGE_NOT_READY;
HACDDecoder *pC = mDecoders[ mCurrentDecoder ];
pC->mCallback = callback;
return LLCD_OK;
}
LLCDResult nd_hacdConvexDecomposition::buildSingleHull()
{
TRACE_FUNC( mTracer );
return LLCD_OK;
}
LLCDResult nd_hacdConvexDecomposition::executeStage( int stage )
{
TRACE_FUNC( mTracer );
if ( stage < 0 || stage >= NUM_STAGES )
return LLCD_INVALID_STAGE;
HACDDecoder *pC = mDecoders[ mCurrentDecoder ];
tHACD *pHACD = init( 1, MIN_NUMBER_OF_CLUSTERS, MAX_VERTICES_PER_HULL, CONNECT_DISTS[0], pC );
DecompData oRes = decompose( pHACD );
ndStructTracer::trace( oRes, mTracer );
delete pHACD;
pC->mStages[ stage ] = oRes;
return LLCD_OK;
}
int nd_hacdConvexDecomposition::getNumHullsFromStage( int stage )
{
TRACE_FUNC( mTracer );
HACDDecoder *pC = mDecoders[ mCurrentDecoder ];
if ( !pC )
return 0;
if ( stage < 0 || static_cast<size_t>(stage) >= pC->mStages.size() )
return 0;
return pC->mStages[stage].mHulls.size();
}
DecompData toSingleHull( HACDDecoder *aDecoder, LLCDResult &aRes, ndConvexDecompositionTracer *aTracer )
{
TRACE_FUNC( aTracer );
aRes = LLCD_REQUEST_OUT_OF_RANGE;
for ( int i = 0; i < TO_SINGLE_HULL_TRIES; ++i )
{
tHACD *pHACD = init( CONCAVITY_FOR_SINGLE_HULL[i], 1, MAX_VERTICES_PER_HULL, CONNECT_DISTS[i], aDecoder );
DecompData oRes = decompose( pHACD );
delete pHACD;
ndStructTracer::trace( oRes, aTracer );
if ( oRes.mHulls.size() == 1 )
{
aRes = LLCD_OK;
return oRes;
}
}
return DecompData();
}
LLCDResult nd_hacdConvexDecomposition::getSingleHull( LLCDHull* hullOut )
{
TRACE_FUNC( mTracer );
HACDDecoder *pC = mDecoders[ mCurrentDecoder ];
memset( hullOut, 0, sizeof( LLCDHull ) );
LLCDResult res;
// Will already trace oRes
DecompData oRes = ::toSingleHull( pC, res, mTracer );
if ( LLCD_OK != res || oRes.mHulls.size() != 1 )
return res;
pC->mSingleHull = oRes.mHulls[0];
pC->mSingleHull.toLLHull( hullOut );
return LLCD_OK;
}
LLCDResult nd_hacdConvexDecomposition::getHullFromStage( int stage, int hull, LLCDHull* hullOut )
{
TRACE_FUNC( mTracer );
HACDDecoder *pC = mDecoders[ mCurrentDecoder ];
memset( hullOut, 0, sizeof( LLCDHull ) );
if ( stage < 0 || static_cast<size_t>(stage) >= pC->mStages.size() )
return LLCD_INVALID_STAGE;
DecompData &oData = pC->mStages[ stage ];
if ( hull < 0 ||static_cast<size_t>(hull) >= oData.mHulls.size() )
return LLCD_REQUEST_OUT_OF_RANGE;
oData.mHulls[ hull ].toLLHull( hullOut );
ndStructTracer::trace( hullOut, mTracer );
return LLCD_OK;
}
LLCDResult nd_hacdConvexDecomposition::getMeshFromStage( int stage, int hull, LLCDMeshData* meshDataOut )
{
TRACE_FUNC( mTracer );
HACDDecoder *pC = mDecoders[ mCurrentDecoder ];
memset( meshDataOut, 0, sizeof( LLCDHull ) );
if ( stage < 0 || static_cast<size_t>(stage) >= pC->mStages.size() )
return LLCD_INVALID_STAGE;
DecompData &oData = pC->mStages[ stage ];
if ( hull < 0 || static_cast<size_t>(hull) >= oData.mHulls.size() )
return LLCD_REQUEST_OUT_OF_RANGE;
oData.mHulls[ hull ].toLLMesh( meshDataOut );
ndStructTracer::trace( meshDataOut, true, mTracer );
return LLCD_OK;
}
LLCDResult nd_hacdConvexDecomposition::getMeshFromHull( LLCDHull* hullIn, LLCDMeshData* meshOut )
{
TRACE_FUNC( mTracer );
memset( meshOut, 0, sizeof( LLCDMeshData ) );
mMeshToHullVertices.clear();
mMeshToHullTriangles.clear();
if( !hullIn || !hullIn->mVertexBase || !meshOut )
return LLCD_NULL_PTR;
if( hullIn->mVertexStrideBytes < 3*sizeof(float) || hullIn->mNumVertices < 3 )
return LLCD_INVALID_HULL_DATA;
LLCDResult oRet = convertHullToMesh( hullIn, mMeshToHullVertices, mMeshToHullTriangles );
if( LLCD_OK != oRet )
return oRet;
meshOut->mVertexStrideBytes = sizeof( float )*3;
meshOut->mNumVertices = mMeshToHullVertices.size()/3;
meshOut->mVertexBase = &mMeshToHullVertices[0];
meshOut->mIndexType = LLCDMeshData::INT_32;
meshOut->mIndexStrideBytes = sizeof( hacdUINT32 ) * 3;
meshOut->mNumTriangles = mMeshToHullTriangles.size()/3;
meshOut->mIndexBase = &mMeshToHullTriangles[0];
return LLCD_OK;
}
LLCDResult nd_hacdConvexDecomposition::generateSingleHullMeshFromMesh( LLCDMeshData* meshIn, LLCDMeshData* meshOut )
{
TRACE_FUNC( mTracer );
memset( meshOut, 0, sizeof( LLCDMeshData ) );
mSingleHullMeshFromMesh->clear();
LLCDResult res = ::setMeshData( meshIn, meshIn->mNumVertices > 3, mSingleHullMeshFromMesh );
if ( LLCD_OK != res )
return res;
// Will already trace oRes
DecompData oRes = ::toSingleHull( mSingleHullMeshFromMesh, res, mTracer );
if ( LLCD_OK != res || oRes.mHulls.size() != 1 )
return res;
mSingleHullMeshFromMesh->mSingleHull = oRes.mHulls[0];
mSingleHullMeshFromMesh->mSingleHull.toLLMesh( meshOut );
return LLCD_OK;
}
void nd_hacdConvexDecomposition::loadMeshData( const char* fileIn, LLCDMeshData** meshDataOut )
{
TRACE_FUNC( mTracer );
static LLCDMeshData meshData;
memset( &meshData, 0, sizeof( LLCDMeshData ) );
*meshDataOut = &meshData;
}
int nd_hacdConvexDecomposition::getParameters( const LLCDParam** paramsOut )
{
TRACE_FUNC( mTracer );
*paramsOut = mParams;
return sizeof(mParams)/sizeof(LLCDParam);
}
int nd_hacdConvexDecomposition::getStages( const LLCDStageData** stagesOut )
{
TRACE_FUNC( mTracer );
*stagesOut = mStages;
return sizeof(mStages)/sizeof(LLCDStageData);
}
void nd_hacdConvexDecomposition::setTracer( ndConvexDecompositionTracer * aTracer)
{
if( mTracer )
mTracer->release();
mTracer = aTracer;
if( mTracer )
mTracer->addref();
}
bool nd_hacdConvexDecomposition::isFunctional()
{
return true;
}

View File

@@ -0,0 +1,103 @@
/**
* copyright 2011 sl.nicky.ml@googlemail.com
*
* 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
*/
#ifndef ND_HACD_CONVEXDECOMP_H
#define ND_HACD_CONVEXDECOMP_H
#include "LLConvexDecomposition.h"
#include <map>
#include <vector>
struct HACDDecoder;
class nd_hacdConvexDecomposition : public LLConvexDecomposition, public ndConvexDecompositionTracable
{
int mNextId;
int mCurrentDecoder;
std::map< int, HACDDecoder * > mDecoders;
HACDDecoder *mSingleHullMeshFromMesh;
std::vector< float > mMeshToHullVertices;
std::vector< int > mMeshToHullTriangles;
ndConvexDecompositionTracer *mTracer;
static LLCDStageData mStages[1];
static LLCDParam mParams[4];
static LLCDParam::LLCDEnumItem mMethods[1];
static LLCDParam::LLCDEnumItem mQuality[1];
static LLCDParam::LLCDEnumItem mSimplify[1];
public:
virtual ~nd_hacdConvexDecomposition();
static LLConvexDecomposition* getInstance();
static LLCDResult initSystem();
static LLCDResult initThread();
static LLCDResult quitThread();
static LLCDResult quitSystem();
// Generate a decomposition object handle
void genDecomposition( int& decomp );
// Delete decomposition object handle
void deleteDecomposition( int decomp );
// Bind given decomposition handle
// Commands operate on currently bound decomposition
void bindDecomposition( int decomp );
// Sets *paramsOut to the address of the LLCDParam array and returns
// the length of the array
int getParameters( const LLCDParam** paramsOut );
int getStages( const LLCDStageData** stagesOut ) ;
// Set a parameter by name. Returns false if out of bounds or unsupported parameter
LLCDResult setParam( const char* name, float val );
LLCDResult setParam( const char* name, int val );
LLCDResult setParam( const char* name, bool val );
LLCDResult setMeshData( const LLCDMeshData* data, bool vertex_based );
LLCDResult registerCallback( int stage, llcdCallbackFunc callback );
LLCDResult executeStage( int stage );
LLCDResult buildSingleHull() ;
int getNumHullsFromStage( int stage );
LLCDResult getHullFromStage( int stage, int hull, LLCDHull* hullOut );
LLCDResult getSingleHull( LLCDHull* hullOut ) ;
// TODO: Implement lock of some kind to disallow this call if data not yet ready
LLCDResult getMeshFromStage( int stage, int hull, LLCDMeshData* meshDataOut );
LLCDResult getMeshFromHull( LLCDHull* hullIn, LLCDMeshData* meshOut );
// For visualizing convex hull shapes in the viewer physics shape display
LLCDResult generateSingleHullMeshFromMesh( LLCDMeshData* meshIn, LLCDMeshData* meshOut );
/// Debug
void loadMeshData( const char* fileIn, LLCDMeshData** meshDataOut );
virtual void setTracer( ndConvexDecompositionTracer *);
virtual bool isFunctional();
private:
nd_hacdConvexDecomposition();
};
#endif

View File

@@ -0,0 +1,46 @@
/**
* copyright 2011 sl.nicky.ml@googlemail.com
*
* 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
*/
#ifndef ND_HACD_DEFINES_H
#define ND_HACD_DEFINES_H
#include "hacdHACD.h"
#define NUM_STAGES 1
typedef unsigned short hacdUINT16;
typedef unsigned int hacdUINT32;
typedef HACD::HACD tHACD;
typedef HACD::Vec3< double > tVecDbl;
typedef HACD::Vec3< long > tVecLong;
typedef tVecLong ( *fFromIXX )( void const *&, int );
const int MAX_VERTICES_PER_HULL = 256; // see http://wiki.secondlife.com/wiki/Mesh/Mesh_physics
const int MIN_NUMBER_OF_CLUSTERS = 1;
int const TO_SINGLE_HULL_TRIES = 10;
// Use a high value so HACD will generate just one hull. For now we use the same concavity for each run.
int const CONCAVITY_FOR_SINGLE_HULL[ TO_SINGLE_HULL_TRIES ] = { 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000 };
// Max distance to connect CC. Increase this each run.
double const CONNECT_DISTS[ TO_SINGLE_HULL_TRIES ] = { 30, 60, 120, 240, 480, 960, 1920, 3840, 7680, 10000 };
#endif

View File

@@ -0,0 +1,107 @@
/**
* copyright 2011 sl.nicky.ml@googlemail.com
*
* 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
*/
#include "nd_hacdStructs.h"
#include "LLConvexDecomposition.h"
void DecompHull::clear()
{
mVertices.clear();
mTriangles.clear();
mLLVertices.clear();
mLLTriangles.clear();
}
void DecompHull::computeLLVertices()
{
if ( mLLVertices.size()*3 != mVertices.size() )
{
for ( size_t i = 0; i < mVertices.size(); ++i )
{
mLLVertices.push_back( static_cast<float>( mVertices[i].X() ) );
mLLVertices.push_back( static_cast<float>( mVertices[i].Y() ) );
mLLVertices.push_back( static_cast<float>( mVertices[i].Z() ) );
}
}
}
void DecompHull::computeLLTriangles()
{
if ( mLLTriangles.size()*3 != mTriangles.size() )
{
for ( size_t i = 0; i < mTriangles.size(); ++i )
{
mLLTriangles.push_back( mTriangles[i].X() );
mLLTriangles.push_back( mTriangles[i].Y() );
mLLTriangles.push_back( mTriangles[i].Z() );
}
}
}
void DecompHull::toLLHull( LLCDHull *aHull )
{
computeLLVertices();
aHull->mVertexBase = &mLLVertices[0];
aHull->mVertexStrideBytes = sizeof( float ) * 3;
aHull->mNumVertices = mVertices.size();
}
void DecompHull::toLLMesh( LLCDMeshData *aMesh )
{
computeLLVertices();
computeLLTriangles();
aMesh->mIndexType = LLCDMeshData::INT_32;
aMesh->mVertexBase = &mLLVertices[0];
aMesh->mNumVertices = mVertices.size();
aMesh->mVertexStrideBytes = sizeof( float ) * 3;
aMesh->mIndexBase = &mLLTriangles[0];
aMesh->mIndexStrideBytes = sizeof( hacdUINT32 ) * 3;
aMesh->mNumTriangles = mTriangles.size();
}
void DecompData::clear()
{
mHulls.clear();
}
HACDDecoder::HACDDecoder()
{
mStages.resize( NUM_STAGES );
mCallback = 0;
}
void HACDDecoder::clear()
{
mVertices.clear();
mTriangles.clear();
for ( size_t i = 0; i < mStages.size(); ++i )
mStages[i].clear();
mSingleHull.clear();
mCallback = 0;
}

View File

@@ -0,0 +1,77 @@
/**
* copyright 2011 sl.nicky.ml@googlemail.com
*
* 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
*/
#ifndef ND_HACD_DECOMPSTRUCTS_H
#define ND_HACD_DECOMPSTRUCTS_H
#include "nd_hacdDefines.h"
#include "hacdHACD.h"
#include "LLConvexDecomposition.h"
#include <vector>
struct LLCDHull;
struct LLCDMeshData;
struct DecompHull
{
std::vector< tVecDbl > mVertices;
std::vector< tVecLong > mTriangles;
std::vector< float > mLLVertices;
std::vector< hacdUINT32 > mLLTriangles;
void clear();
void computeLLVertices();
void computeLLTriangles();
void toLLHull( LLCDHull *aHull );
void toLLMesh( LLCDMeshData *aMesh );
};
struct DecompData
{
std::vector< DecompHull > mHulls;
void clear();
};
struct HACDDecoder: public HACD::ICallback
{
std::vector< tVecDbl > mVertices;
std::vector< tVecLong > mTriangles;
std::vector< DecompData > mStages;
DecompHull mSingleHull;
llcdCallbackFunc mCallback;
HACDDecoder();
void clear();
virtual void operator()( char const *aMsg, double aProgress, double aConcavity, size_t aVertices)
{
if( mCallback )
(*mCallback)(aMsg, static_cast<int>(aProgress), aVertices );
}
};
#endif

View File

@@ -0,0 +1,183 @@
/**
* copyright 2011 sl.nicky.ml@googlemail.com
*
* 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
*/
#include "nd_hacdUtils.h"
tHACD* init( int nConcavity, int nClusters, int nMaxVerticesPerHull, double dMaxConnectDist, HACDDecoder *aData )
{
tHACD *pDec = HACD::CreateHACD(0);
pDec->SetPoints( &aData->mVertices[0] );
pDec->SetNPoints( aData->mVertices.size() );
if ( aData->mTriangles.size() )
{
pDec->SetTriangles( &aData->mTriangles[0] );
pDec->SetNTriangles( aData->mTriangles.size() );
}
pDec->SetCompacityWeight( 0.1f );
pDec->SetVolumeWeight( 0 );
pDec->SetNClusters( nClusters );
pDec->SetAddExtraDistPoints( true );
pDec->SetAddFacesPoints( true );
pDec->SetNVerticesPerCH( nMaxVerticesPerHull );
pDec->SetConcavity( nConcavity );
pDec->SetConnectDist( dMaxConnectDist );
pDec->SetCallBack( aData );
return pDec;
}
DecompData decompose( tHACD *aHACD )
{
aHACD->Compute();
DecompData oRet;
int nClusters = aHACD->GetNClusters();
for ( int i = 0; i < nClusters; ++i )
{
int nVertices = aHACD->GetNPointsCH( i );
int nTriangles = aHACD->GetNTrianglesCH( i );
DecompHull oHull;
oHull.mVertices.resize( nVertices );
oHull.mTriangles.resize( nTriangles );
aHACD->GetCH( i, &oHull.mVertices[0], &oHull.mTriangles[0] );
oRet.mHulls.push_back( oHull );
}
return oRet;
}
tVecLong fromI16( void const *& pPtr, int aStride )
{
hacdUINT16 const *pVal = reinterpret_cast< hacdUINT16 const * >( pPtr );
tVecLong oRet( pVal[0], pVal[1], pVal[2] );
pVal += aStride / 2;
pPtr = pVal;
return oRet;
}
tVecLong fromI32( void const *& pPtr, int aStride )
{
hacdUINT32 const *pVal = reinterpret_cast< hacdUINT32 const * >( pPtr );
tVecLong oRet( pVal[0], pVal[1], pVal[2] );
pVal += aStride / 4;
pPtr = pVal;
return oRet;
}
LLCDResult setMeshData( const LLCDMeshData* data, bool vertex_based, HACDDecoder *aDec )
{
if ( !data || !data->mVertexBase || ( data->mNumVertices < 3 ) || ( data->mVertexStrideBytes != 12 && data->mVertexStrideBytes != 16 ) )
return LLCD_INVALID_MESH_DATA;
if ( !vertex_based && ( ( data->mNumTriangles < 1 ) || ! data->mIndexBase ) )
return LLCD_INVALID_MESH_DATA;
aDec->clear();
int nCount = data->mNumVertices;
float const* pVertex = data->mVertexBase;
int nStride = data->mVertexStrideBytes / sizeof( float );
for ( int i = 0; i < nCount; ++i )
{
tVecDbl oPt( pVertex[0], pVertex[1], pVertex[2] );
aDec->mVertices.push_back( oPt );
pVertex += nStride;
}
if ( !vertex_based )
{
fFromIXX pFunc = 0;
nCount = data->mNumTriangles;
nStride = data->mIndexStrideBytes;
void const *pData = data->mIndexBase;
if ( data->mIndexType == LLCDMeshData::INT_16 )
pFunc = fromI16;
else
pFunc = fromI32;
for ( int i = 0; i < nCount; ++i )
{
tVecLong oVal( ( *pFunc )( pData, nStride ) );
aDec->mTriangles.push_back( oVal );
}
}
return LLCD_OK;
}
LLCDResult convertHullToMesh( const LLCDHull* aHull, std::vector< float > &aVerticesOut, std::vector< int > &aTrianglesOut )
{
if( !aHull || !aHull->mVertexBase )
return LLCD_NULL_PTR;
if( aHull->mVertexStrideBytes < 3*sizeof(float) || aHull->mNumVertices < 3 )
return LLCD_INVALID_HULL_DATA;
HACD::ICHull oHull;
int nCount = aHull->mNumVertices;
float const *pVertex = aHull->mVertexBase;
int nStride = aHull->mVertexStrideBytes / sizeof( float );
std::vector< tVecDbl > vcPoints;
for ( int i = 0; i < nCount; ++i )
{
vcPoints.push_back( tVecDbl( pVertex[0], pVertex[1], pVertex[2] ) );
pVertex += nStride;
}
oHull.AddPoints( &vcPoints[0], vcPoints.size() );
HACD::ICHullError eErr = oHull.Process( MAX_VERTICES_PER_HULL );
if( HACD::ICHullErrorOK != eErr )
return LLCD_INVALID_HULL_DATA;
HACD::TMMesh &oMesh = oHull.GetMesh();
std::vector< tVecDbl > vPoints;
std::vector< tVecLong > vTriangles;
vPoints.resize( oMesh.GetNVertices() );
vTriangles.resize( oMesh.GetNTriangles() );
oMesh.GetIFS( &vPoints[0], &vTriangles[0] );
for( size_t i = 0; i < vPoints.size(); ++i )
{
aVerticesOut.push_back( static_cast<float>( vPoints[i].X() ) );
aVerticesOut.push_back( static_cast<float>( vPoints[i].Y() ) );
aVerticesOut.push_back( static_cast<float>( vPoints[i].Z() ) );
}
for( size_t i = 0; i < vTriangles.size(); ++i )
{
aTrianglesOut.push_back( vTriangles[i].X() );
aTrianglesOut.push_back( vTriangles[i].Y() );
aTrianglesOut.push_back( vTriangles[i].Z() );
}
return LLCD_OK;
}

View File

@@ -0,0 +1,34 @@
/**
* copyright 2011 sl.nicky.ml@googlemail.com
*
* 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
*/
#ifndef ND_HACD_UTILS_H
#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 );
tVecLong fromI16( void *& pPtr, int aStride );
tVecLong fromI32( void *& pPtr, int aStride );
LLCDResult setMeshData( const LLCDMeshData* data, bool vertex_based, HACDDecoder *aDec );
LLCDResult convertHullToMesh( const LLCDHull* aHull, std::vector< float > &aVerticesOut, std::vector< int > &aTrianglesOut );
#endif

View File

@@ -0,0 +1,59 @@
/**
* @file windowsincludes.h
* @brief includes that need to be involved in the windows version of llconvexdecompositionstub
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER // Allow use of features specific to Windows XP or later.
#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
#endif
#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later.
#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE.
#endif
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
// TODO: reference additional headers your program requires here

View File

@@ -703,15 +703,15 @@ static void j2k_read_cox(opj_j2k_t *j2k, int compno) {
/* If user wants to remove more resolutions than the codestream contains, return error*/
if (cp->reduce >= tccp->numresolutions) {
opj_event_msg(j2k->cinfo, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions to remove is higher than the number "
"of resolutions of this component\nModify the cp_reduce parameter.\n\n", compno);
"of resolutions of this component\nModify the cp_reduce parameter.\n\n", compno);
j2k->state |= J2K_STATE_ERR;
}
if( tccp->numresolutions > J2K_MAXRLVLS ) {
opj_event_msg(j2k->cinfo, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions is too big: %d vs max= %d. Truncating.\n\n",
compno, tccp->numresolutions, J2K_MAXRLVLS);
if( tccp->numresolutions > J2K_MAXRLVLS ) {
opj_event_msg(j2k->cinfo, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions is too big: %d vs max= %d. Truncating.\n\n",
compno, tccp->numresolutions, J2K_MAXRLVLS);
j2k->state |= J2K_STATE_ERR;
tccp->numresolutions = J2K_MAXRLVLS;
}
tccp->numresolutions = J2K_MAXRLVLS;
}
tccp->cblkw = cio_read(cio, 1) + 2; /* SPcox (E) */
tccp->cblkh = cio_read(cio, 1) + 2; /* SPcox (F) */
@@ -1518,24 +1518,6 @@ static void j2k_read_sod(opj_j2k_t *j2k) {
truncate = 1; /* Case of a truncate codestream */
}
{/* chop padding bytes: */
unsigned char *s, *e;
s = cio_getbp(cio);
e = s + len;
if(len > 8) s = e - 8;
if(e[-2] == 0x00 && e[-1] == 0x00) /* padding bytes */
{
while(e > s)
{
if(e[-2] == 0xff && e[-1] == 0xd9) break;
--len; --e; truncate = 1;
}
}
}
data = j2k->tile_data[curtileno];
data = (unsigned char*) opj_realloc(data, (j2k->tile_len[curtileno] + len) * sizeof(unsigned char));
@@ -1935,15 +1917,9 @@ opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *c
#endif /* USE_JPWL */
if (id >> 8 != 0xff) {
if(cio_numbytesleft(cio) != 0) /* not end of file reached and no EOC */
{
opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
opj_image_destroy(image);
return 0;
}
opj_event_msg(cinfo, EVT_WARNING, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
j2k->state = J2K_STATE_NEOC;
break;
opj_image_destroy(image);
opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
return 0;
}
e = j2k_dec_mstab_lookup(id);
/* Check if the marker is known*/
@@ -2037,15 +2013,9 @@ opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestre
id = cio_read(cio, 2);
if (id >> 8 != 0xff) {
if(cio_numbytesleft(cio) != 0) /* no end of file reached and no EOC */
{
opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
opj_image_destroy(image);
return 0;
}
opj_event_msg(cinfo, EVT_WARNING, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
j2k->state = J2K_STATE_NEOC;
break;
opj_image_destroy(image);
opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id);
return 0;
}
e = j2k_dec_mstab_lookup(id);
if (!(j2k->state & e->states)) {

View File

@@ -1091,14 +1091,27 @@ static double t1_getwmsedec(
int numcomps,
int mct)
{
double w1, w2, wmsedec;
double w1 = 1, w2, wmsedec;
// Prevent running an MCT on more than 3 components. NB openjpeg v2.0 will support this via
// custom MCT tables that can be passed as encode parameters, 1.3 cannot support this as it
// uses a static table of 3 entries and there for can only cope with 3 components with out an
// array overflow
if(numcomps==3) {
if (qmfbid == 1) {
w1 = (numcomps > 1) ? mct_getnorm(compno) : 1.0;
} else {
w1 = (numcomps > 1) ? mct_getnorm_real(compno) : 1.0;
}
}
if (qmfbid == 1) {
w1 = (mct && numcomps==3) ? mct_getnorm(compno) : 1.0;
w2 = dwt_getnorm(level, orient);
} else { /* if (qmfbid == 0) */
w1 = (mct && numcomps==3) ? mct_getnorm_real(compno) : 1.0;
w2 = dwt_getnorm_real(level, orient);
}
wmsedec = w1 * w2 * stepsize * (1 << bpno);
wmsedec *= wmsedec * nmsedec / 8192.0;

View File

@@ -1420,13 +1420,18 @@ opj_bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno
if (tcd->cp->reduce != 0) {
if ( tile->comps[compno].numresolutions < ( tcd->cp->reduce - 1 ) ) {
opj_event_msg(tcd->cinfo, EVT_ERROR, "Error decoding tile. The number of resolutions to remove [%d+1] is higher than the number "
" of resolutions in the original codestream [%d]\nModify the cp_reduce parameter.\n", tcd->cp->reduce, tile->comps[compno].numresolutions);
" of resolutions in the original codestream [%d]\nModify the cp_reduce parameter.\n", tcd->cp->reduce, tile->comps[compno].numresolutions);
return OPJ_FALSE;
}
else {
tcd->image->comps[compno].resno_decoded =
tile->comps[compno].numresolutions - tcd->cp->reduce - 1;
}
else {
tcd->image->comps[compno].resno_decoded =
tile->comps[compno].numresolutions - tcd->cp->reduce - 1;
}
}
if(!tilec->data) {
opj_event_msg(tcd->cinfo, EVT_ERROR, "Error decoding tile. null data\n");
return OPJ_FALSE;
}
numres2decode = tcd->image->comps[compno].resno_decoded + 1;

View File

@@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 2.6.4)
project(ndPathingLib CXX C)
if( MSVC )
add_definitions(-D_HAS_ITERATOR_DEBUGGING=0 -D_SECURE_SCL=0 -D_CRT_SECURE_NO_WARNINGS=1)
endif( MSVC )
file (GLOB SOURCE_FILES *.cpp )
file (GLOB INCLUDE_FILES *.h )
add_library(nd_Pathing STATIC ${SOURCE_FILES} ${INCLUDE_FILES} )

View File

@@ -0,0 +1,89 @@
#include "llpathinglib.h"
void LLPathingLib::initSystem()
{
}
void LLPathingLib::quitSystem()
{
}
LLPathingLib* LLPathingLib::getInstance()
{
static LLPathingLib sObj;
return &sObj;
}
bool LLPathingLib::isFunctional()
{
return false;
}
void LLPathingLib::extractNavMeshSrcFromLLSD( std::vector< unsigned char > const &aMeshData, int aNavigation )
{
}
LLPathingLib::LLPLResult LLPathingLib::generatePath( PathingPacket const& )
{
return LLPL_NO_PATH;
}
void LLPathingLib::cleanupResidual()
{
}
void LLPathingLib::stitchNavMeshes( )
{
}
void LLPathingLib::renderNavMesh( void )
{
}
void LLPathingLib::renderNavMeshShapesVBO( unsigned int aShapeTypeBitmask )
{
}
void LLPathingLib::renderPath()
{
}
void LLPathingLib::cleanupVBOManager()
{
}
void LLPathingLib::setNavMeshColors( NavMeshColors const &aColors )
{
}
void LLPathingLib::setNavMeshMaterialType( LLPLCharacterType aType )
{
}
void LLPathingLib::renderNavMeshEdges()
{
}
void LLPathingLib::renderPathBookend( LLRender&, LLPLRenderType )
{
}
void LLPathingLib::renderSimpleShapes( LLRender&, float )
{
}
void LLPathingLib::createPhysicsCapsuleRep( float, float, bool, LLUUID const& )
{
}
void LLPathingLib::cleanupPhysicsCapsuleRepResiduals()
{
}
void LLPathingLib::processNavMeshData()
{
}
void LLPathingLib::renderSimpleShapeCapsuleID( LLRender&, LLUUID const&, LLVector3 const&, LLQuaternion const& )
{
}

View File

@@ -0,0 +1,181 @@
#ifndef LL_PATHINGLIB_H
#define LL_PATHINGLIB_H
#include <vector>
#ifndef LL_V3MATH_H
class LLVector3
{
public:
float mV[3];
};
#endif
#ifndef LL_V4COLORU_H
class LLColor4U
{
public:
unsigned char mV[4];
};
#endif
#ifndef LL_LLUUID_H
class LLUUID
{
public:
unsigned char mData[16];
};
#endif
#ifndef LLQUATERNION_H
class LLQuaternion
{
public:
double mQ[4];
};
#endif
class LLRender;
class LLPathingLib
{
public:
enum LLPLResult
{
LLPL_NO_PATH,
LLPL_PATH_GENERATED_OK,
};
enum LLPLCharacterType
{
LLPL_CHARACTER_TYPE_NONE,
LLPL_CHARACTER_TYPE_A,
LLPL_CHARACTER_TYPE_B,
LLPL_CHARACTER_TYPE_C,
LLPL_CHARACTER_TYPE_D,
};
enum LLShapeType
{
LLST_WalkableObjects = 1,
LLST_ObstacleObjects = 2,
LLST_MaterialPhantoms = 3,
LLST_ExclusionPhantoms = 4,
};
enum LLPLRenderType
{
LLPL_START,
LLPL_END,
};
struct Vector
{
double mX;
double mY;
double mZ;
Vector& operator=( LLVector3 const &aRHS )
{
mX = aRHS.mV[0];
mY = aRHS.mV[1];
mZ = aRHS.mV[2];
return *this;
}
operator LLVector3() const
{
LLVector3 ret;
ret.mV[0] = mX;
ret.mV[1] = mY;
ret.mV[2] = mZ;
return ret;
}
};
struct PathingPacket
{
Vector mStartPointA;
Vector mEndPointA;
Vector mStartPointB;
Vector mEndPointB;
bool mHasPointA;
bool mHasPointB;
double mCharacterWidth;
LLPLCharacterType mCharacterType;
};
struct NavMeshColor
{
unsigned char mR;
unsigned char mG;
unsigned char mB;
unsigned char mAlpha;
NavMeshColor& operator=( LLColor4U const &aRHS )
{
mR = aRHS.mV[0];
mG = aRHS.mV[1];
mB = aRHS.mV[2];
mAlpha = aRHS.mV[3];
return *this;
}
};
struct NavMeshColors
{
NavMeshColor mWalkable;
NavMeshColor mObstacle;
NavMeshColor mMaterial;
NavMeshColor mExclusion;
NavMeshColor mConnectedEdge;
NavMeshColor mBoundaryEdge;
NavMeshColor mHeatColorBase;
NavMeshColor mHeatColorMax;
NavMeshColor mFaceColor;
NavMeshColor mStarValid;
NavMeshColor mStarInvalid;
NavMeshColor mTestPath;
NavMeshColor mWaterColor;
};
static void initSystem();
static void quitSystem();
static LLPathingLib* getInstance();
bool isFunctional();
void extractNavMeshSrcFromLLSD( std::vector< unsigned char> const &aMeshData, int aNavigation );
LLPLResult generatePath( PathingPacket const& );
void cleanupResidual();
void stitchNavMeshes( );
void renderNavMesh( void );
void renderNavMeshShapesVBO( unsigned int aShapeTypeBitmask );
void renderPath();
void cleanupVBOManager();
void renderNavMeshEdges();
void renderPathBookend( LLRender&, LLPLRenderType );
void setNavMeshColors( NavMeshColors const& );
void setNavMeshMaterialType( LLPLCharacterType );
void renderSimpleShapes( LLRender&, float );
void createPhysicsCapsuleRep( float, float, bool, LLUUID const& );
void cleanupPhysicsCapsuleRepResiduals();
void processNavMeshData();
void renderSimpleShapeCapsuleID( LLRender&, LLUUID const&, LLVector3 const&, LLQuaternion const& );
};
#endif

View File

@@ -0,0 +1,10 @@
#include "llphysicsextensions.h"
void LLPhysicsExtensions::quitSystem()
{
}
bool LLPhysicsExtensions::isFunctional()
{
return false;
}

View File

@@ -0,0 +1,12 @@
#ifndef LLPYHSICS_EXTENSIONS_H
#define LLPYHSICS_EXTENSIONS_H
class LLPhysicsExtensions
{
public:
static void quitSystem();
bool isFunctional();
};
#endif

View File

@@ -112,11 +112,9 @@ public:
public:
virtual bool isSelf() const { return false; } // True if this avatar is for this viewer's agent
virtual BOOL isValid() const;
//virtual BOOL isUsingServerBakes() const = 0;
//virtual BOOL isUsingLocalAppearance() const = 0;
//virtual BOOL isEditingAppearance() const = 0;
BOOL isUsingLocalAppearance() const {return isEditingAppearance();}
virtual BOOL isEditingAppearance() const {return FALSE;}
virtual BOOL isUsingServerBakes() const = 0;
virtual BOOL isUsingLocalAppearance() const = 0;
virtual BOOL isEditingAppearance() const = 0;
bool isBuilt() const { return mIsBuilt; }

View File

@@ -37,7 +37,7 @@
//#include "llviewercontrol.h"
//#include "llxmltree.h"
//#include "llvoavatar.h"
//#include "llwearable.h"
#include "llwearable.h"
//#include "lldir.h"
//#include "llvolume.h"
//#include "llendianswizzle.h"

View File

@@ -38,7 +38,7 @@
#include "llvfs.h"
#include "lltexlayerparams.h"
#include "lltexturemanagerbridge.h"
//#include "llrender2dutils.h"
#include "llrender2dutils.h"
#include "llwearable.h"
#include "llwearabledata.h"
#include "llvertexbuffer.h"

View File

@@ -33,6 +33,7 @@
#include "llquantize.h"
#include "lltexlayer.h"
#include "lltexturemanagerbridge.h"
#include "llrender2dutils.h"
#include "llwearable.h"
//-----------------------------------------------------------------------------

View File

@@ -39,10 +39,6 @@ class LLTexLayerInterface;
class LLGLTexture;
class LLWearable;
//Temporary externs
void gl_rect_2d_simple_tex( S32 width, S32 height );
void gl_rect_2d_simple( S32 width, S32 height );
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// LLTexLayerParam
//

View File

@@ -35,6 +35,7 @@
class LLTextureManagerBridge
{
public:
virtual ~LLTextureManagerBridge(){};
virtual LLPointer<LLGLTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE) = 0;
virtual LLPointer<LLGLTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) = 0;
virtual LLGLTexture* getFetchedTexture(const LLUUID &image_id) = 0;

View File

@@ -35,6 +35,7 @@
class LLTranslationBridge
{
public:
virtual ~LLTranslationBridge(){};
virtual std::string getString(const std::string &xml_desc) = 0;
};

View File

@@ -1,31 +1,25 @@
/**
* @file llaudiodecodemgr.h
*
* $LicenseInfo:firstyear=2003&license=viewergpl$
*
* Copyright (c) 2003-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2003&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

@@ -3,31 +3,25 @@
* @brief implementation of LLAudioEngine class abstracting the Open
* AL audio support
*
* $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

@@ -2,31 +2,25 @@
* @file audioengine.h
* @brief Definition of LLAudioEngine base class abstracting the audio support
*
* $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

@@ -2,31 +2,25 @@
* @file audioengine_fmod.cpp
* @brief Implementation of LLAudioEngine class abstracting the audio support as a FMOD 3D implementation
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2002&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

@@ -3,31 +3,25 @@
* @brief Definition of LLAudioEngine class abstracting the audio
* support as a FMOD 3D implementation
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2002&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

@@ -2,31 +2,25 @@
* @file listener.cpp
* @brief Implementation of LISTENER class abstracting the audio support
*
* $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

@@ -2,31 +2,25 @@
* @file listener.h
* @brief Description of LISTENER base class abstracting the audio support.
*
* $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

@@ -3,31 +3,25 @@
* @brief Description of LISTENER class abstracting the audio support
* as a DirectSound 3D implementation (windows only)
*
* $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

@@ -3,31 +3,25 @@
* @brief implementation of LISTENER class abstracting the audio
* support as a FMOD 3D implementation (windows only)
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2002&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

@@ -3,31 +3,25 @@
* @brief Description of LISTENER class abstracting the audio support
* as an FMOD 3D implementation (windows and Linux)
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2002&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

@@ -3,31 +3,25 @@
* @brief implementation of audio engine using OpenAL
* support as a OpenAL 3D implementation
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2002&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

@@ -3,31 +3,25 @@
* @brief Description of LISTENER class abstracting the audio support
* as an OpenAL 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.
*
* 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

@@ -3,31 +3,25 @@
* @author Tofu Linden
* @brief Definition of LLStreamingAudioInterface base class abstracting the streaming audio interface
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2009&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

@@ -2,31 +2,25 @@
* @file streamingaudio_fmod.cpp
* @brief LLStreamingAudio_FMOD implementation
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2009&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$
*/
@@ -206,6 +200,7 @@ void LLStreamingAudio_FMOD::update()
// buffering
break;
}
}
void LLStreamingAudio_FMOD::stop()

View File

@@ -3,31 +3,25 @@
* @author Tofu Linden
* @brief Definition of LLStreamingAudio_FMOD implementation
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2009&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

@@ -2,31 +2,25 @@
* @file vorbisencode.cpp
* @brief Vorbis encoding routine routine for Indra.
*
* $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

@@ -2,31 +2,25 @@
* @file vorbisencode.h
* @brief Vorbis encoding routine routine for Indra.
*
* $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

@@ -2,31 +2,25 @@
* @file llanimationstates.cpp
* @brief Implementation of animation state related functions.
*
* $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$
*/
@@ -39,57 +33,57 @@
#include "llanimationstates.h"
#include "llstring.h"
LLUUID const ANIM_AGENT_AFRAID ("6b61c8e8-4747-0d75-12d7-e49ff207a4ca");
LLUUID const ANIM_AGENT_AIM_BAZOOKA_R ("b5b4a67d-0aee-30d2-72cd-77b333e932ef");
LLUUID const ANIM_AGENT_AIM_BOW_L ("46bb4359-de38-4ed8-6a22-f1f52fe8f506");
LLUUID const ANIM_AGENT_AIM_HANDGUN_R ("3147d815-6338-b932-f011-16b56d9ac18b");
LLUUID const ANIM_AGENT_AIM_RIFLE_R ("ea633413-8006-180a-c3ba-96dd1d756720");
LLUUID const ANIM_AGENT_ANGRY ("5747a48e-073e-c331-f6f3-7c2149613d3e");
LLUUID const ANIM_AGENT_AWAY ("fd037134-85d4-f241-72c6-4f42164fedee");
LLUUID const ANIM_AGENT_BACKFLIP ("c4ca6188-9127-4f31-0158-23c4e2f93304");
LLUUID const ANIM_AGENT_BELLY_LAUGH ("18b3a4b5-b463-bd48-e4b6-71eaac76c515");
LLUUID const ANIM_AGENT_BLOW_KISS ("db84829b-462c-ee83-1e27-9bbee66bd624");
LLUUID const ANIM_AGENT_BORED ("b906c4ba-703b-1940-32a3-0c7f7d791510");
LLUUID const ANIM_AGENT_BOW ("82e99230-c906-1403-4d9c-3889dd98daba");
LLUUID const ANIM_AGENT_BRUSH ("349a3801-54f9-bf2c-3bd0-1ac89772af01");
LLUUID const ANIM_AGENT_BUSY ("efcf670c-2d18-8128-973a-034ebc806b67");
LLUUID const ANIM_AGENT_CLAP ("9b0c1c4e-8ac7-7969-1494-28c874c4f668");
LLUUID const ANIM_AGENT_COURTBOW ("9ba1c942-08be-e43a-fb29-16ad440efc50");
LLUUID const ANIM_AGENT_CROUCH ("201f3fdf-cb1f-dbec-201f-7333e328ae7c");
LLUUID const ANIM_AGENT_CROUCHWALK ("47f5f6fb-22e5-ae44-f871-73aaaf4a6022");
LLUUID const ANIM_AGENT_CRY ("92624d3e-1068-f1aa-a5ec-8244585193ed");
LLUUID const ANIM_AGENT_CUSTOMIZE ("038fcec9-5ebd-8a8e-0e2e-6e71a0a1ac53");
LLUUID const ANIM_AGENT_CUSTOMIZE_DONE ("6883a61a-b27b-5914-a61e-dda118a9ee2c");
LLUUID const ANIM_AGENT_DANCE1 ("b68a3d7c-de9e-fc87-eec8-543d787e5b0d");
LLUUID const ANIM_AGENT_DANCE2 ("928cae18-e31d-76fd-9cc9-2f55160ff818");
LLUUID const ANIM_AGENT_DANCE3 ("30047778-10ea-1af7-6881-4db7a3a5a114");
LLUUID const ANIM_AGENT_DANCE4 ("951469f4-c7b2-c818-9dee-ad7eea8c30b7");
LLUUID const ANIM_AGENT_DANCE5 ("4bd69a1d-1114-a0b4-625f-84e0a5237155");
LLUUID const ANIM_AGENT_DANCE6 ("cd28b69b-9c95-bb78-3f94-8d605ff1bb12");
LLUUID const ANIM_AGENT_DANCE7 ("a54d8ee2-28bb-80a9-7f0c-7afbbe24a5d6");
LLUUID const ANIM_AGENT_DANCE8 ("b0dc417c-1f11-af36-2e80-7e7489fa7cdc");
LLUUID const ANIM_AGENT_DEAD ("57abaae6-1d17-7b1b-5f98-6d11a6411276");
LLUUID const ANIM_AGENT_DRINK ("0f86e355-dd31-a61c-fdb0-3a96b9aad05f");
LLUUID const ANIM_AGENT_EMBARRASSED ("514af488-9051-044a-b3fc-d4dbf76377c6");
LLUUID const ANIM_AGENT_EXPRESS_AFRAID ("aa2df84d-cf8f-7218-527b-424a52de766e");
LLUUID const ANIM_AGENT_EXPRESS_ANGER ("1a03b575-9634-b62a-5767-3a679e81f4de");
LLUUID const ANIM_AGENT_EXPRESS_BORED ("214aa6c1-ba6a-4578-f27c-ce7688f61d0d");
LLUUID const ANIM_AGENT_EXPRESS_CRY ("d535471b-85bf-3b4d-a542-93bea4f59d33");
LLUUID const ANIM_AGENT_EXPRESS_DISDAIN ("d4416ff1-09d3-300f-4183-1b68a19b9fc1");
LLUUID const ANIM_AGENT_EXPRESS_EMBARRASSED ("0b8c8211-d78c-33e8-fa28-c51a9594e424");
LLUUID const ANIM_AGENT_EXPRESS_FROWN ("fee3df48-fa3d-1015-1e26-a205810e3001");
LLUUID const ANIM_AGENT_EXPRESS_KISS ("1e8d90cc-a84e-e135-884c-7c82c8b03a14");
LLUUID const ANIM_AGENT_EXPRESS_LAUGH ("62570842-0950-96f8-341c-809e65110823");
LLUUID const ANIM_AGENT_EXPRESS_OPEN_MOUTH ("d63bc1f9-fc81-9625-a0c6-007176d82eb7");
LLUUID const ANIM_AGENT_EXPRESS_REPULSED ("f76cda94-41d4-a229-2872-e0296e58afe1");
LLUUID const ANIM_AGENT_EXPRESS_SAD ("eb6ebfb2-a4b3-a19c-d388-4dd5c03823f7");
LLUUID const ANIM_AGENT_EXPRESS_SHRUG ("a351b1bc-cc94-aac2-7bea-a7e6ebad15ef");
LLUUID const ANIM_AGENT_EXPRESS_SMILE ("b7c7c833-e3d3-c4e3-9fc0-131237446312");
LLUUID const ANIM_AGENT_EXPRESS_SURPRISE ("728646d9-cc79-08b2-32d6-937f0a835c24");
LLUUID const ANIM_AGENT_EXPRESS_TONGUE_OUT ("835965c6-7f2f-bda2-5deb-2478737f91bf");
LLUUID const ANIM_AGENT_EXPRESS_TOOTHSMILE ("b92ec1a5-e7ce-a76b-2b05-bcdb9311417e");
LLUUID const ANIM_AGENT_EXPRESS_WINK ("da020525-4d94-59d6-23d7-81fdebf33148");
LLUUID const ANIM_AGENT_EXPRESS_WORRY ("9c05e5c7-6f07-6ca4-ed5a-b230390c3950");
LLUUID const ANIM_AGENT_AFRAID ("6b61c8e8-4747-0d75-12d7-e49ff207a4ca");
LLUUID const ANIM_AGENT_AIM_BAZOOKA_R ("b5b4a67d-0aee-30d2-72cd-77b333e932ef");
LLUUID const ANIM_AGENT_AIM_BOW_L ("46bb4359-de38-4ed8-6a22-f1f52fe8f506");
LLUUID const ANIM_AGENT_AIM_HANDGUN_R ("3147d815-6338-b932-f011-16b56d9ac18b");
LLUUID const ANIM_AGENT_AIM_RIFLE_R ("ea633413-8006-180a-c3ba-96dd1d756720");
LLUUID const ANIM_AGENT_ANGRY ("5747a48e-073e-c331-f6f3-7c2149613d3e");
LLUUID const ANIM_AGENT_AWAY ("fd037134-85d4-f241-72c6-4f42164fedee");
LLUUID const ANIM_AGENT_BACKFLIP ("c4ca6188-9127-4f31-0158-23c4e2f93304");
LLUUID const ANIM_AGENT_BELLY_LAUGH ("18b3a4b5-b463-bd48-e4b6-71eaac76c515");
LLUUID const ANIM_AGENT_BLOW_KISS ("db84829b-462c-ee83-1e27-9bbee66bd624");
LLUUID const ANIM_AGENT_BORED ("b906c4ba-703b-1940-32a3-0c7f7d791510");
LLUUID const ANIM_AGENT_BOW ("82e99230-c906-1403-4d9c-3889dd98daba");
LLUUID const ANIM_AGENT_BRUSH ("349a3801-54f9-bf2c-3bd0-1ac89772af01");
LLUUID const ANIM_AGENT_BUSY ("efcf670c-2d18-8128-973a-034ebc806b67");
LLUUID const ANIM_AGENT_CLAP ("9b0c1c4e-8ac7-7969-1494-28c874c4f668");
LLUUID const ANIM_AGENT_COURTBOW ("9ba1c942-08be-e43a-fb29-16ad440efc50");
LLUUID const ANIM_AGENT_CROUCH ("201f3fdf-cb1f-dbec-201f-7333e328ae7c");
LLUUID const ANIM_AGENT_CROUCHWALK ("47f5f6fb-22e5-ae44-f871-73aaaf4a6022");
LLUUID const ANIM_AGENT_CRY ("92624d3e-1068-f1aa-a5ec-8244585193ed");
LLUUID const ANIM_AGENT_CUSTOMIZE ("038fcec9-5ebd-8a8e-0e2e-6e71a0a1ac53");
LLUUID const ANIM_AGENT_CUSTOMIZE_DONE ("6883a61a-b27b-5914-a61e-dda118a9ee2c");
LLUUID const ANIM_AGENT_DANCE1 ("b68a3d7c-de9e-fc87-eec8-543d787e5b0d");
LLUUID const ANIM_AGENT_DANCE2 ("928cae18-e31d-76fd-9cc9-2f55160ff818");
LLUUID const ANIM_AGENT_DANCE3 ("30047778-10ea-1af7-6881-4db7a3a5a114");
LLUUID const ANIM_AGENT_DANCE4 ("951469f4-c7b2-c818-9dee-ad7eea8c30b7");
LLUUID const ANIM_AGENT_DANCE5 ("4bd69a1d-1114-a0b4-625f-84e0a5237155");
LLUUID const ANIM_AGENT_DANCE6 ("cd28b69b-9c95-bb78-3f94-8d605ff1bb12");
LLUUID const ANIM_AGENT_DANCE7 ("a54d8ee2-28bb-80a9-7f0c-7afbbe24a5d6");
LLUUID const ANIM_AGENT_DANCE8 ("b0dc417c-1f11-af36-2e80-7e7489fa7cdc");
LLUUID const ANIM_AGENT_DEAD ("57abaae6-1d17-7b1b-5f98-6d11a6411276");
LLUUID const ANIM_AGENT_DRINK ("0f86e355-dd31-a61c-fdb0-3a96b9aad05f");
LLUUID const ANIM_AGENT_EMBARRASSED ("514af488-9051-044a-b3fc-d4dbf76377c6");
LLUUID const ANIM_AGENT_EXPRESS_AFRAID ("aa2df84d-cf8f-7218-527b-424a52de766e");
LLUUID const ANIM_AGENT_EXPRESS_ANGER ("1a03b575-9634-b62a-5767-3a679e81f4de");
LLUUID const ANIM_AGENT_EXPRESS_BORED ("214aa6c1-ba6a-4578-f27c-ce7688f61d0d");
LLUUID const ANIM_AGENT_EXPRESS_CRY ("d535471b-85bf-3b4d-a542-93bea4f59d33");
LLUUID const ANIM_AGENT_EXPRESS_DISDAIN ("d4416ff1-09d3-300f-4183-1b68a19b9fc1");
LLUUID const ANIM_AGENT_EXPRESS_EMBARRASSED ("0b8c8211-d78c-33e8-fa28-c51a9594e424");
LLUUID const ANIM_AGENT_EXPRESS_FROWN ("fee3df48-fa3d-1015-1e26-a205810e3001");
LLUUID const ANIM_AGENT_EXPRESS_KISS ("1e8d90cc-a84e-e135-884c-7c82c8b03a14");
LLUUID const ANIM_AGENT_EXPRESS_LAUGH ("62570842-0950-96f8-341c-809e65110823");
LLUUID const ANIM_AGENT_EXPRESS_OPEN_MOUTH ("d63bc1f9-fc81-9625-a0c6-007176d82eb7");
LLUUID const ANIM_AGENT_EXPRESS_REPULSED ("f76cda94-41d4-a229-2872-e0296e58afe1");
LLUUID const ANIM_AGENT_EXPRESS_SAD ("eb6ebfb2-a4b3-a19c-d388-4dd5c03823f7");
LLUUID const ANIM_AGENT_EXPRESS_SHRUG ("a351b1bc-cc94-aac2-7bea-a7e6ebad15ef");
LLUUID const ANIM_AGENT_EXPRESS_SMILE ("b7c7c833-e3d3-c4e3-9fc0-131237446312");
LLUUID const ANIM_AGENT_EXPRESS_SURPRISE ("728646d9-cc79-08b2-32d6-937f0a835c24");
LLUUID const ANIM_AGENT_EXPRESS_TONGUE_OUT ("835965c6-7f2f-bda2-5deb-2478737f91bf");
LLUUID const ANIM_AGENT_EXPRESS_TOOTHSMILE ("b92ec1a5-e7ce-a76b-2b05-bcdb9311417e");
LLUUID const ANIM_AGENT_EXPRESS_WINK ("da020525-4d94-59d6-23d7-81fdebf33148");
LLUUID const ANIM_AGENT_EXPRESS_WORRY ("9c05e5c7-6f07-6ca4-ed5a-b230390c3950");
LLUUID const ANIM_AGENT_FALLDOWN ("666307d9-a860-572d-6fd4-c3ab8865c094");
LLUUID const ANIM_AGENT_FEMALE_RUN_NEW ("85995026-eade-5d78-d364-94a64512cb66");
LLUUID const ANIM_AGENT_FEMALE_WALK ("f5fc7433-043d-e819-8298-f519a119b688");
@@ -97,33 +91,33 @@ LLUUID const ANIM_AGENT_FEMALE_WALK_NEW ("d60c41d2-7c24-7074-d3fa-6101cea2
LLUUID const ANIM_AGENT_FINGER_WAG ("c1bc7f36-3ba0-d844-f93c-93be945d644f");
LLUUID const ANIM_AGENT_FIST_PUMP ("7db00ccd-f380-f3ee-439d-61968ec69c8a");
LLUUID const ANIM_AGENT_FLY ("aec4610c-757f-bc4e-c092-c6e9caf18daf");
LLUUID const ANIM_AGENT_FLYSLOW ("2b5a38b2-5e00-3a97-a495-4c826bc443e6");
LLUUID const ANIM_AGENT_HELLO ("9b29cd61-c45b-5689-ded2-91756b8d76a9");
LLUUID const ANIM_AGENT_HOLD_BAZOOKA_R ("ef62d355-c815-4816-2474-b1acc21094a6");
LLUUID const ANIM_AGENT_HOLD_BOW_L ("8b102617-bcba-037b-86c1-b76219f90c88");
LLUUID const ANIM_AGENT_HOLD_HANDGUN_R ("efdc1727-8b8a-c800-4077-975fc27ee2f2");
LLUUID const ANIM_AGENT_HOLD_RIFLE_R ("3d94bad0-c55b-7dcc-8763-033c59405d33");
LLUUID const ANIM_AGENT_HOLD_THROW_R ("7570c7b5-1f22-56dd-56ef-a9168241bbb6");
LLUUID const ANIM_AGENT_HOVER ("4ae8016b-31b9-03bb-c401-b1ea941db41d");
LLUUID const ANIM_AGENT_HOVER_DOWN ("20f063ea-8306-2562-0b07-5c853b37b31e");
LLUUID const ANIM_AGENT_HOVER_UP ("62c5de58-cb33-5743-3d07-9e4cd4352864");
LLUUID const ANIM_AGENT_IMPATIENT ("5ea3991f-c293-392e-6860-91dfa01278a3");
LLUUID const ANIM_AGENT_JUMP ("2305bd75-1ca9-b03b-1faa-b176b8a8c49e");
LLUUID const ANIM_AGENT_JUMP_FOR_JOY ("709ea28e-1573-c023-8bf8-520c8bc637fa");
LLUUID const ANIM_AGENT_KISS_MY_BUTT ("19999406-3a3a-d58c-a2ac-d72e555dcf51");
LLUUID const ANIM_AGENT_LAND ("7a17b059-12b2-41b1-570a-186368b6aa6f");
LLUUID const ANIM_AGENT_LAUGH_SHORT ("ca5b3f14-3194-7a2b-c894-aa699b718d1f");
LLUUID const ANIM_AGENT_MEDIUM_LAND ("f4f00d6e-b9fe-9292-f4cb-0ae06ea58d57");
LLUUID const ANIM_AGENT_MOTORCYCLE_SIT ("08464f78-3a8e-2944-cba5-0c94aff3af29");
LLUUID const ANIM_AGENT_MUSCLE_BEACH ("315c3a41-a5f3-0ba4-27da-f893f769e69b");
LLUUID const ANIM_AGENT_NO ("5a977ed9-7f72-44e9-4c4c-6e913df8ae74");
LLUUID const ANIM_AGENT_NO_UNHAPPY ("d83fa0e5-97ed-7eb2-e798-7bd006215cb4");
LLUUID const ANIM_AGENT_NYAH_NYAH ("f061723d-0a18-754f-66ee-29a44795a32f");
LLUUID const ANIM_AGENT_ONETWO_PUNCH ("eefc79be-daae-a239-8c04-890f5d23654a");
LLUUID const ANIM_AGENT_PEACE ("b312b10e-65ab-a0a4-8b3c-1326ea8e3ed9");
LLUUID const ANIM_AGENT_POINT_ME ("17c024cc-eef2-f6a0-3527-9869876d7752");
LLUUID const ANIM_AGENT_POINT_YOU ("ec952cca-61ef-aa3b-2789-4d1344f016de");
LLUUID const ANIM_AGENT_PRE_JUMP ("7a4e87fe-de39-6fcb-6223-024b00893244");
LLUUID const ANIM_AGENT_FLYSLOW ("2b5a38b2-5e00-3a97-a495-4c826bc443e6");
LLUUID const ANIM_AGENT_HELLO ("9b29cd61-c45b-5689-ded2-91756b8d76a9");
LLUUID const ANIM_AGENT_HOLD_BAZOOKA_R ("ef62d355-c815-4816-2474-b1acc21094a6");
LLUUID const ANIM_AGENT_HOLD_BOW_L ("8b102617-bcba-037b-86c1-b76219f90c88");
LLUUID const ANIM_AGENT_HOLD_HANDGUN_R ("efdc1727-8b8a-c800-4077-975fc27ee2f2");
LLUUID const ANIM_AGENT_HOLD_RIFLE_R ("3d94bad0-c55b-7dcc-8763-033c59405d33");
LLUUID const ANIM_AGENT_HOLD_THROW_R ("7570c7b5-1f22-56dd-56ef-a9168241bbb6");
LLUUID const ANIM_AGENT_HOVER ("4ae8016b-31b9-03bb-c401-b1ea941db41d");
LLUUID const ANIM_AGENT_HOVER_DOWN ("20f063ea-8306-2562-0b07-5c853b37b31e");
LLUUID const ANIM_AGENT_HOVER_UP ("62c5de58-cb33-5743-3d07-9e4cd4352864");
LLUUID const ANIM_AGENT_IMPATIENT ("5ea3991f-c293-392e-6860-91dfa01278a3");
LLUUID const ANIM_AGENT_JUMP ("2305bd75-1ca9-b03b-1faa-b176b8a8c49e");
LLUUID const ANIM_AGENT_JUMP_FOR_JOY ("709ea28e-1573-c023-8bf8-520c8bc637fa");
LLUUID const ANIM_AGENT_KISS_MY_BUTT ("19999406-3a3a-d58c-a2ac-d72e555dcf51");
LLUUID const ANIM_AGENT_LAND ("7a17b059-12b2-41b1-570a-186368b6aa6f");
LLUUID const ANIM_AGENT_LAUGH_SHORT ("ca5b3f14-3194-7a2b-c894-aa699b718d1f");
LLUUID const ANIM_AGENT_MEDIUM_LAND ("f4f00d6e-b9fe-9292-f4cb-0ae06ea58d57");
LLUUID const ANIM_AGENT_MOTORCYCLE_SIT ("08464f78-3a8e-2944-cba5-0c94aff3af29");
LLUUID const ANIM_AGENT_MUSCLE_BEACH ("315c3a41-a5f3-0ba4-27da-f893f769e69b");
LLUUID const ANIM_AGENT_NO ("5a977ed9-7f72-44e9-4c4c-6e913df8ae74");
LLUUID const ANIM_AGENT_NO_UNHAPPY ("d83fa0e5-97ed-7eb2-e798-7bd006215cb4");
LLUUID const ANIM_AGENT_NYAH_NYAH ("f061723d-0a18-754f-66ee-29a44795a32f");
LLUUID const ANIM_AGENT_ONETWO_PUNCH ("eefc79be-daae-a239-8c04-890f5d23654a");
LLUUID const ANIM_AGENT_PEACE ("b312b10e-65ab-a0a4-8b3c-1326ea8e3ed9");
LLUUID const ANIM_AGENT_POINT_ME ("17c024cc-eef2-f6a0-3527-9869876d7752");
LLUUID const ANIM_AGENT_POINT_YOU ("ec952cca-61ef-aa3b-2789-4d1344f016de");
LLUUID const ANIM_AGENT_PRE_JUMP ("7a4e87fe-de39-6fcb-6223-024b00893244");
LLUUID const ANIM_AGENT_PUNCH_LEFT ("f3300ad9-3462-1d07-2044-0fef80062da0");
LLUUID const ANIM_AGENT_PUNCH_RIGHT ("c8e42d32-7310-6906-c903-cab5d4a34656");
LLUUID const ANIM_AGENT_REPULSED ("36f81a92-f076-5893-dc4b-7c3795e487cf");
@@ -140,44 +134,44 @@ LLUUID const ANIM_AGENT_SHOOT_BOW_L ("e04d450d-fdb5-0432-fd68-818aaf59
LLUUID const ANIM_AGENT_SHOUT ("6bd01860-4ebd-127a-bb3d-d1427e8e0c42");
LLUUID const ANIM_AGENT_SHRUG ("70ea714f-3a97-d742-1b01-590a8fcd1db5");
LLUUID const ANIM_AGENT_SIT ("1a5fe8ac-a804-8a5d-7cbd-56bd83184568");
LLUUID const ANIM_AGENT_SIT_FEMALE ("b1709c8d-ecd3-54a1-4f28-d55ac0840782");
LLUUID const ANIM_AGENT_SIT_GENERIC ("245f3c54-f1c0-bf2e-811f-46d8eeb386e7");
LLUUID const ANIM_AGENT_SIT_GROUND ("1c7600d6-661f-b87b-efe2-d7421eb93c86");
LLUUID const ANIM_AGENT_SIT_FEMALE ("b1709c8d-ecd3-54a1-4f28-d55ac0840782");
LLUUID const ANIM_AGENT_SIT_GENERIC ("245f3c54-f1c0-bf2e-811f-46d8eeb386e7");
LLUUID const ANIM_AGENT_SIT_GROUND ("1c7600d6-661f-b87b-efe2-d7421eb93c86");
LLUUID const ANIM_AGENT_SIT_GROUND_CONSTRAINED("1a2bd58e-87ff-0df8-0b4c-53e047b0bb6e");
LLUUID const ANIM_AGENT_SIT_TO_STAND ("a8dee56f-2eae-9e7a-05a2-6fb92b97e21e");
LLUUID const ANIM_AGENT_SLEEP ("f2bed5f9-9d44-39af-b0cd-257b2a17fe40");
LLUUID const ANIM_AGENT_SMOKE_IDLE ("d2f2ee58-8ad1-06c9-d8d3-3827ba31567a");
LLUUID const ANIM_AGENT_SMOKE_INHALE ("6802d553-49da-0778-9f85-1599a2266526");
LLUUID const ANIM_AGENT_SMOKE_THROW_DOWN ("0a9fb970-8b44-9114-d3a9-bf69cfe804d6");
LLUUID const ANIM_AGENT_SNAPSHOT ("eae8905b-271a-99e2-4c0e-31106afd100c");
LLUUID const ANIM_AGENT_STAND ("2408fe9e-df1d-1d7d-f4ff-1384fa7b350f");
LLUUID const ANIM_AGENT_STANDUP ("3da1d753-028a-5446-24f3-9c9b856d9422");
LLUUID const ANIM_AGENT_STAND_1 ("15468e00-3400-bb66-cecc-646d7c14458e");
LLUUID const ANIM_AGENT_STAND_2 ("370f3a20-6ca6-9971-848c-9a01bc42ae3c");
LLUUID const ANIM_AGENT_STAND_3 ("42b46214-4b44-79ae-deb8-0df61424ff4b");
LLUUID const ANIM_AGENT_STAND_4 ("f22fed8b-a5ed-2c93-64d5-bdd8b93c889f");
LLUUID const ANIM_AGENT_STRETCH ("80700431-74ec-a008-14f8-77575e73693f");
LLUUID const ANIM_AGENT_STRIDE ("1cb562b0-ba21-2202-efb3-30f82cdf9595");
LLUUID const ANIM_AGENT_SURF ("41426836-7437-7e89-025d-0aa4d10f1d69");
LLUUID const ANIM_AGENT_SURPRISE ("313b9881-4302-73c0-c7d0-0e7a36b6c224");
LLUUID const ANIM_AGENT_SWORD_STRIKE ("85428680-6bf9-3e64-b489-6f81087c24bd");
LLUUID const ANIM_AGENT_TALK ("5c682a95-6da4-a463-0bf6-0f5b7be129d1");
LLUUID const ANIM_AGENT_TANTRUM ("11000694-3f41-adc2-606b-eee1d66f3724");
LLUUID const ANIM_AGENT_THROW_R ("aa134404-7dac-7aca-2cba-435f9db875ca");
LLUUID const ANIM_AGENT_TRYON_SHIRT ("83ff59fe-2346-f236-9009-4e3608af64c1");
LLUUID const ANIM_AGENT_TURNLEFT ("56e0ba0d-4a9f-7f27-6117-32f2ebbf6135");
LLUUID const ANIM_AGENT_TURNRIGHT ("2d6daa51-3192-6794-8e2e-a15f8338ec30");
LLUUID const ANIM_AGENT_SIT_TO_STAND ("a8dee56f-2eae-9e7a-05a2-6fb92b97e21e");
LLUUID const ANIM_AGENT_SLEEP ("f2bed5f9-9d44-39af-b0cd-257b2a17fe40");
LLUUID const ANIM_AGENT_SMOKE_IDLE ("d2f2ee58-8ad1-06c9-d8d3-3827ba31567a");
LLUUID const ANIM_AGENT_SMOKE_INHALE ("6802d553-49da-0778-9f85-1599a2266526");
LLUUID const ANIM_AGENT_SMOKE_THROW_DOWN ("0a9fb970-8b44-9114-d3a9-bf69cfe804d6");
LLUUID const ANIM_AGENT_SNAPSHOT ("eae8905b-271a-99e2-4c0e-31106afd100c");
LLUUID const ANIM_AGENT_STAND ("2408fe9e-df1d-1d7d-f4ff-1384fa7b350f");
LLUUID const ANIM_AGENT_STANDUP ("3da1d753-028a-5446-24f3-9c9b856d9422");
LLUUID const ANIM_AGENT_STAND_1 ("15468e00-3400-bb66-cecc-646d7c14458e");
LLUUID const ANIM_AGENT_STAND_2 ("370f3a20-6ca6-9971-848c-9a01bc42ae3c");
LLUUID const ANIM_AGENT_STAND_3 ("42b46214-4b44-79ae-deb8-0df61424ff4b");
LLUUID const ANIM_AGENT_STAND_4 ("f22fed8b-a5ed-2c93-64d5-bdd8b93c889f");
LLUUID const ANIM_AGENT_STRETCH ("80700431-74ec-a008-14f8-77575e73693f");
LLUUID const ANIM_AGENT_STRIDE ("1cb562b0-ba21-2202-efb3-30f82cdf9595");
LLUUID const ANIM_AGENT_SURF ("41426836-7437-7e89-025d-0aa4d10f1d69");
LLUUID const ANIM_AGENT_SURPRISE ("313b9881-4302-73c0-c7d0-0e7a36b6c224");
LLUUID const ANIM_AGENT_SWORD_STRIKE ("85428680-6bf9-3e64-b489-6f81087c24bd");
LLUUID const ANIM_AGENT_TALK ("5c682a95-6da4-a463-0bf6-0f5b7be129d1");
LLUUID const ANIM_AGENT_TANTRUM ("11000694-3f41-adc2-606b-eee1d66f3724");
LLUUID const ANIM_AGENT_THROW_R ("aa134404-7dac-7aca-2cba-435f9db875ca");
LLUUID const ANIM_AGENT_TRYON_SHIRT ("83ff59fe-2346-f236-9009-4e3608af64c1");
LLUUID const ANIM_AGENT_TURNLEFT ("56e0ba0d-4a9f-7f27-6117-32f2ebbf6135");
LLUUID const ANIM_AGENT_TURNRIGHT ("2d6daa51-3192-6794-8e2e-a15f8338ec30");
LLUUID const ANIM_AGENT_TYPE ("c541c47f-e0c0-058b-ad1a-d6ae3a4584d9");
LLUUID const ANIM_AGENT_WALK ("6ed24bd8-91aa-4b12-ccc7-c97c857ab4e0");
LLUUID const ANIM_AGENT_WALK_NEW ("33339176-7ddc-9397-94a4-bf3403cbc8f5");
LLUUID const ANIM_AGENT_WHISPER ("7693f268-06c7-ea71-fa21-2b30d6533f8f");
LLUUID const ANIM_AGENT_WHISTLE ("b1ed7982-c68e-a982-7561-52a88a5298c0");
LLUUID const ANIM_AGENT_WINK ("869ecdad-a44b-671e-3266-56aef2e3ac2e");
LLUUID const ANIM_AGENT_WINK_HOLLYWOOD ("c0c4030f-c02b-49de-24ba-2331f43fe41c");
LLUUID const ANIM_AGENT_WORRY ("9f496bd2-589a-709f-16cc-69bf7df1d36c");
LLUUID const ANIM_AGENT_YES ("15dd911d-be82-2856-26db-27659b142875");
LLUUID const ANIM_AGENT_YES_HAPPY ("b8c8b2a3-9008-1771-3bfc-90924955ab2d");
LLUUID const ANIM_AGENT_YOGA_FLOAT ("42ecd00b-9947-a97c-400a-bbc9174c7aeb");
LLUUID const ANIM_AGENT_WINK ("869ecdad-a44b-671e-3266-56aef2e3ac2e");
LLUUID const ANIM_AGENT_WINK_HOLLYWOOD ("c0c4030f-c02b-49de-24ba-2331f43fe41c");
LLUUID const ANIM_AGENT_WORRY ("9f496bd2-589a-709f-16cc-69bf7df1d36c");
LLUUID const ANIM_AGENT_YES ("15dd911d-be82-2856-26db-27659b142875");
LLUUID const ANIM_AGENT_YES_HAPPY ("b8c8b2a3-9008-1771-3bfc-90924955ab2d");
LLUUID const ANIM_AGENT_YOGA_FLOAT ("42ecd00b-9947-a97c-400a-bbc9174c7aeb");
LLUUID AGENT_WALK_ANIMS[] = {ANIM_AGENT_WALK, ANIM_AGENT_RUN, ANIM_AGENT_CROUCHWALK, ANIM_AGENT_TURNLEFT, ANIM_AGENT_TURNRIGHT};
S32 NUM_AGENT_WALK_ANIMS = LL_ARRAY_SIZE(AGENT_WALK_ANIMS);
@@ -498,6 +492,5 @@ const LLAnimStateEntry gUserAnimStates[] = {
const S32 gUserAnimStatesCount = LL_ARRAY_SIZE(gUserAnimStates);
// End

View File

@@ -2,31 +2,25 @@
* @file llanimationstates.h
* @brief Implementation of animation state support.
*
* $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$
*/
@@ -262,7 +256,6 @@ extern const LLAnimStateEntry gUserAnimStates[];
extern const S32 gUserAnimStatesCount;
extern LLAnimationLibrary gAnimLibrary;
#endif // LL_LLANIMATIONSTATES_H

View File

@@ -33,7 +33,7 @@
#ifndef LL_LLBVHCONSTS_H
#define LL_LLBVHCONSTS_H
const F32 MAX_ANIM_DURATION = 30.f;
const F32 MAX_ANIM_DURATION = 60.f;
typedef enum e_constraint_type
{

View File

@@ -2,31 +2,25 @@
* @file llbvhloader.cpp
* @brief Translates a BVH files to LindenLabAnimation format.
*
* $LicenseInfo:firstyear=2004&license=viewergpl$
*
* Copyright (c) 2004-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2004&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

@@ -2,31 +2,25 @@
* @file llcharacter.cpp
* @brief Implementation of LLCharacter 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.
*
* 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

@@ -2,31 +2,25 @@
* @file llcharacter.h
* @brief Implementation of LLCharacter 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.
*
* 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$
*/
@@ -99,13 +93,6 @@ public:
// get the height & normal of the ground under a point
virtual void getGround(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm) = 0;
// allocate an array of joints for the character skeleton
// this must be overloaded to support joint subclasses,
// and is called implicitly from buildSkeleton().
// Note this must handle reallocation as it will be called
// each time buildSkeleton() is called.
virtual BOOL allocateCharacterJoints( U32 num ) = 0;
// skeleton joint accessor to support joint subclasses
virtual LLJoint *getCharacterJoint( U32 i ) = 0;

View File

@@ -2,31 +2,25 @@
* @file lleditingmotion.cpp
* @brief Implementation of LLEditingMotion 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.
*
* 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

@@ -2,31 +2,25 @@
* @file llhandmotion.cpp
* @brief Implementation of LLHandMotion 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.
*
* 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$
*/

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