Compare commits

...

176 Commits

Author SHA1 Message Date
UbitUmarov 5145980c74 Merge branch 'master' of ssh://3dhosting.de/var/git/careminster into ubitwork 2012-02-24 02:13:43 +00:00
Melanie e74bf46007 Prevent a nullref when nonphysical motion objects cross sim boundaries 2012-02-23 23:18:01 +01:00
Melanie 7c520cf531 Merge branch 'master' of ssh://3dhosting.de/var/git/careminster 2012-02-23 22:27:20 +01:00
Melanie daf58575f8 Partially apply the core banlines fix 2012-02-23 23:05:04 +00:00
Melanie e7cebaa4bd Merge branch 'master' into careminster 2012-02-23 22:50:31 +00:00
Justin Clark-Casey (justincc) 90ea00a109 Try to resolve some problems with viewers crashing after hitting parcel banlines or freezing on the banline.
This involves
1) On forcible teleport, call m_scene.RequestTeleportLocation() rather than ScenePresence.Teleport() - only EntityTransferModule now should call SP.Teleport()
2) When avatar is being forcibly moved due to banlines, use a 'stop movement' tolerance of 0.2 to requested position rather than 1
This prevents the avatar sometimes being stuck to banlines until they teleport somewhere else.
This aims to fix some problems in http://opensimulator.org/mantis/view.php?id=5822
2012-02-23 22:56:42 +00:00
Melanie 1c0adfa6e0 Correct sit position calculations 2012-02-23 22:26:17 +01:00
Melanie f3ea2bde61 Fix preserving the animation state of a crossing seated avatar 2012-02-23 20:32:35 +01:00
UbitUmarov 8994ab1336 Merge branch 'master' of ssh://3dhosting.de/var/git/careminster into ubitwork 2012-02-23 14:50:49 +00:00
Melanie dc835717d6 Properly sequence updates of avatars and attachments so that we don't
update attachments on child avatars or intermingle agent and attachment
updates, which would render the root prim of huds invisible
2012-02-23 14:08:35 +01:00
Melanie f266c54f82 Merge branch 'ubitwork' 2012-02-23 13:10:02 +01:00
Melanie 56cc573d2f Show avatars as sitting on proot prims only to avoid motion jitter
for passengers
2012-02-23 12:20:20 +01:00
UbitUmarov e827bcaf2b Merge branch 'master' of ssh://3dhosting.de/var/git/careminster into ubitwork 2012-02-23 02:04:16 +00:00
Melanie f1a76195ea Merge branch 'master' into careminster
Conflicts:
	OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
2012-02-23 01:49:14 +00:00
Melanie 9ed4245d9e Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim 2012-02-23 01:42:08 +00:00
Melanie 1dfc990264 Add a position parameter to region crossing of objects. This avoids the
potential bad update that places an object at the opposite side of the
origin sim for a moment before actually crossing it. Especially important in
grids like OSG where lag between sims is high.
2012-02-23 01:40:30 +00:00
UbitUmarov 15bc539bd4 fix the last fix. Regions are square but... Also remove the 0.5 offset in map position. It was apparently needed to fix we having nsamples = size and not size + 1. 2012-02-23 00:50:07 +00:00
UbitUmarov aa77d1d486 fix my bug on ChODE terrain heightmap build 2012-02-23 00:22:44 +00:00
Melanie c0b8f3d0bc Add permission checks to scripted object movements, which didn't respect bans
and parcel settings until now. Add llSetRegionPos() function according to
LL spec
2012-02-23 00:08:31 +01:00
Melanie 3796e08b59 Count agents for LSL instead of relying on SceneGraph to have the correct
value. Fixes a reported glitch.
2012-02-22 23:14:29 +01:00
Melanie 1e1270166f Adjust sit target and the llSetLinkPrimitiveParams sit position hack
to match SL.
2012-02-22 20:40:44 +01:00
Justin Clark-Casey (justincc) 5d31267185 Remove two spurious m_sceneGraph != null checks in Scene.cs. It's set in constructor and never subsequent set to null. 2012-02-22 00:55:16 +00:00
Melanie 65f5f60317 Merge branch 'master' into careminster 2012-02-21 23:43:39 +00:00
Justin Clark-Casey (justincc) cf9b3e7708 Restore the taskItem null check that I accidentally blatted in 5397a6d
This is a valid check because the caller could supply an invalid uuid.
2012-02-21 23:41:48 +00:00
Melanie 1273ec6c7d Merge branch 'master' into careminster 2012-02-21 23:17:39 +00:00
PixelTomsen 1c533eb520 Fix:LINK_ROOT flag for llGetLinkName() by SinglePrim 2012-02-21 23:15:33 +00:00
Justin Clark-Casey (justincc) 5397a6d4c6 Fix problem with dragging child part inventory item to user inventory.
This fixes the problem by fixing the permissions module to look at root part permissions rather than having to do this for every caller.
Resolves http://opensimulator.org/mantis/view.php?id=5569
2012-02-21 22:54:30 +00:00
Melanie 24a49011cb Merge branch 'master' into careminster 2012-02-21 22:54:00 +00:00
Justin Clark-Casey (justincc) 76f411147d Revert "Fix:Cannot drag inventory from child prim into inventory http://opensimulator.org/mantis/view.php?id=5569"
This reverts commit 15ce73caca.

As per the COMMENTS in http://opensimulator.org/mantis/view.php?id=5569, I was going to fix this in a more general way.
2012-02-21 22:49:06 +00:00
PixelTomsen 15ce73caca Fix:Cannot drag inventory from child prim into inventory http://opensimulator.org/mantis/view.php?id=5569 2012-02-21 22:07:12 +00:00
Melanie cb4509f3b8 Reverse the changed to ODE heightmap. It results in SERIOUS issues like an
irreversible y-flip and holes in the map.
2012-02-21 21:34:02 +01:00
Melanie dede31174e Merge branch 'master' into careminster 2012-02-21 22:08:34 +00:00
Melanie 0e4d5a4d3c Also preserve angular velocity on crossing. 2012-02-21 10:10:04 +01:00
Melanie 03e7bc1526 Merge branch 'master' into careminster
Conflicts:
2012-02-21 10:20:56 +00:00
Justin Clark-Casey (justincc) a27e5a9c95 Both 32-bit and 64-bit BulletSim.dll must have the same name. Rename the 64 bit one in lib64 2012-02-21 04:12:17 +00:00
Justin Clark-Casey (justincc) daee2eda93 Load 32-bit or 64-bit BulletSim Windows library automatically as appropriate.
This uses the same approach as ODE.
radams, if this doesn't work for you please feel free to revert.
2012-02-21 04:10:39 +00:00
Justin Clark-Casey (justincc) a15b00d3ef Replace previous windows 64-bit sqlite3.dll with one from http://system.data.sqlite.org/downloads/1.0.79.0/sqlite-netFx35-binary-bundle-x64-2008-1.0.79.0.zip
In this zip, it's called System.Data.SQLite.dll.  We rename it to lib64/sqlite3.dll
This is a little unexpected but it works.  For some reason my hand-rolled one in Visual Studio 2008 did not.
This is sqlite 3.7.10.  Other libraries are still currently 3.7.6 but this should make no difference.
This should make it possible to use OpenSim.exe on 64-bit Windows now, though currently the bullet physics plugin will still complain (can be ignored if you are not using bullet).
2012-02-21 04:01:27 +00:00
Justin Clark-Casey (justincc) 1b906ef2ad Replace win 64-bit sqlite3.dll with another version, though I suspect this one won't work either. 2012-02-21 03:24:01 +00:00
Justin Clark-Casey (justincc) 68a4ef5ef6 Add 64 bit Windows sqlite3.dll and use this if running a 64-bit windows process. 2012-02-21 02:52:20 +00:00
Justin Clark-Casey (justincc) 90dc5f47e7 Fix bug where NPCs would establish child agents on other neighbour regions that had come up after the NPC was created. 2012-02-21 01:57:19 +00:00
Justin Clark-Casey (justincc) 19d271d3fc Remove PhysXPlugin and wrappers.
In over 4 years this never progressed beyond an unimplemented stub.
This doesn't mean that it can't come back if someone is interested in implementing PhysX support.
2012-02-21 01:45:17 +00:00
Melanie ee62bf3c69 Merge branch 'master' of ssh://3dhosting.de/var/git/careminster 2012-02-20 20:23:14 +01:00
Melanie 3b2900e884 Merge branch 'master' into careminster 2012-02-20 19:48:28 +00:00
Diva Canto 4a329098e8 Amend to last commit: synchronize access to queues. 2012-02-20 11:12:02 -08:00
Diva Canto 99b9c1a9d5 More improvements on agent position updates: if the target sims fail, blacklist them for 2 min, so that we don't keep doing remote calls that fail. 2012-02-20 10:58:07 -08:00
Melanie d6b8febbf4 Make vehicles retain velocity when crossing between regions. 2012-02-20 19:49:01 +01:00
Melanie 8f8206f478 Add an override to make SOG.Velocity work as expected 2012-02-20 16:55:12 +01:00
Diva Canto 1c3ee5d1ce One more tweak related to the previous 2 commits. 2012-02-19 16:42:01 -08:00
Diva Canto b489c85226 Amend to last commit. This should have been committed too. 2012-02-19 15:37:37 -08:00
Diva Canto dcea23906b Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-02-19 12:28:47 -08:00
Diva Canto 20c65ac438 A few more tweaks on position updates and create child agents. Mono hates concurrent uses of the same TCP connection, and even of the connections to the same server. So let's stop doing it. This patch makes movement much smoother when there are lots of neighbours. 2012-02-19 12:28:07 -08:00
Melanie 77575ec51b Merge branch 'master' of ssh://3dhosting.de/var/git/careminster 2012-02-19 20:36:26 +01:00
Melanie 756baff86a Merge branch 'master' into careminster
Conflicts:
	OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
2012-02-19 21:14:18 +00:00
Melanie 4bc3a0ecf4 Uncomment serialization 2012-02-19 20:25:20 +01:00
Melanie 433d5f1d3e Merge branch 'ubitwork' 2012-02-19 20:24:00 +01:00
UbitUmarov 3c9b7f2c0c simplified vehicle fromXml. Use still comented on SceneObjectSerialized.cs 2012-02-19 19:27:01 +00:00
Melanie d6f212059e Fix merge issues in prebuild 2012-02-19 20:17:47 +01:00
Melanie 96409cc2ee Merge branch 'ubitwork'
Conflicts:
	OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
	OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs
2012-02-19 20:08:01 +01:00
UbitUmarov 60d68ee312 Vehicle XML serialization more complete. Inactived by coments in SceneObjectSerializar.cs until proper testing 2012-02-19 18:10:00 +00:00
BlueWall bcb9577495 Use localy defined name, TPFlags, for Constants.TeleportFlags 2012-02-19 12:09:57 -05:00
Melanie 488ec59408 Merge branch 'master' into careminster 2012-02-19 14:57:51 +00:00
UbitUmarov b77d354e6d moved vehicle from SOG to SOP 2012-02-19 13:21:01 +00:00
Melanie 185bf55804 Merge branch 'master' of ssh://3dhosting.de/var/git/careminster 2012-02-19 14:20:53 +01:00
PixelTomsen d22715126c Fix:Fly setting for Parcel dosen't work http://opensimulator.org/mantis/view.php?id=5887
Signed-off-by: nebadon <michael@osgrid.org>
2012-02-19 01:58:28 -07:00
PixelTomsen a114367b9b Fix:OmegaX, OmegaY and OmegaZ not saved for child prims http://opensimulator.org/mantis/view.php?id=5893
Signed-off-by: nebadon <michael@osgrid.org>
2012-02-19 01:00:01 -07:00
Diva Canto 2ffc055f7e This should smooth movement in heteregeneous networks by a lot: cache the region by position instead of looking it up all the time -- this was being done during the main update loop! 2012-02-18 21:59:42 -08:00
UbitUmarov 736fb0b41d minor fix to chODE terrain heighmap scale 2012-02-19 02:07:43 +00:00
Melanie 985526b662 Merge branch 'master' into careminster
Conflicts:
	OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
	OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
2012-02-18 22:21:10 +00:00
UbitUmarov 7a1ab03b75 missing paramenters init plus some cleaning 2012-02-18 19:31:36 +00:00
UbitUmarov a62baf8ea4 added a EnUsCulture whatever that is.. 2012-02-18 18:37:29 +00:00
UbitUmarov 028dc1f4ed a bit less human readable xml 2012-02-18 18:33:41 +00:00
UbitUmarov 70b3b599bc added some ToXml2 to SOGVehicle ( unused untested ) 2012-02-18 18:25:48 +00:00
UbitUmarov 3aee642190 changed how vehicle data is stored and passed to physics. use unsafe in serializer, tried to control m_dupeInProgress 2012-02-18 17:42:14 +00:00
UbitUmarov 91a326331f vehicle parameters do cross (i hope) on regions in same instance ( others need xml) 2012-02-18 16:16:48 +00:00
UbitUmarov 5351ff925c let SOG know about vehicles. Still needs serialization and applyphyscis on deserialize, etc 2012-02-18 14:08:42 +00:00
BlueWall 14e9bf894c Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-02-18 00:51:23 -05:00
BlueWall f4cd35322f Route logins according to Estate, Telehub and TeleportFlags 2012-02-18 00:45:43 -05:00
BlueWall 7bdcf9eb26 Propagate our teleport flags on logins 2012-02-18 00:32:09 -05:00
Justin Clark-Casey (justincc) 9846a1e56e Report an error if the required native Windows ODE library can't be found. 2012-02-18 02:52:29 +00:00
Justin Clark-Casey (justincc) 4cc97df8f3 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-02-18 02:46:44 +00:00
Justin Clark-Casey (justincc) 0ef64fbe03 Actually add the Windows 64-bit ode.dll file.
This might be why it didn't work.
2012-02-18 02:46:07 +00:00
BlueWall fbccff4994 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-02-17 21:15:18 -05:00
Justin Clark-Casey (justincc) 84184708de Fix a bug where changing shape parameters of a child prim in a linkset would not persist.
Resolves http://opensimulator.org/mantis/view.php?id=5819
2012-02-18 01:15:43 +00:00
BlueWall 8f8b478d36 Parcel sales support to SQLite 2012-02-17 20:04:38 -05:00
Justin Clark-Casey (justincc) b817c337dc On Windows automatically load the correct native ODE library depending on whether the process is 32-bit or 64-bit
In theory, this means that a 64-bit Windows OS user can now run OpenSim.exe with ODE and use more than 2 (or 3) GB of memory.
However, this is completely untested since I don't currently own a 64-bit Windows box.  Feedback appreciated.
Using OpenSim.32BitLaunch.exe should continue to work.  Other platforms are unaffected.
This will currently not work with sqlite - I will add that too if this works.
2012-02-18 00:33:52 +00:00
BlueWall d03e878d53 Fillin missing SQLite support for Telehubs 2012-02-17 17:31:20 -05:00
Dan Lake b313d16493 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-02-17 13:51:54 -08:00
Dan Lake 784263f5e3 Added the TriggerAvatarAppearanceChanged to EventManager. It's triggered by AvatarFactoryModule after an avatar's appearance has been succesfully changed and persisted (if the persist option is set). 2012-02-17 13:45:45 -08:00
UbitUmarov 7d77ccc659 Added simple binary serializer/deserializer to chODE. 100% untested and most like still broken 2012-02-17 21:09:00 +00:00
Robert Adams 6baa13ab7a Add new and updated script events 2012-02-17 09:12:41 -08:00
BlueWall 0e16e0fb6a Merge branch 'master' of /home/opensim/src/opensim 2012-02-17 08:21:33 -05:00
BlueWall ba98d6fffe Fix missing telehub handling on login 2012-02-17 08:03:53 -05:00
Justin Clark-Casey (justincc) 972f73ed2b Make osNpcStopAnimation() call AvatarStopAnimation() rather than AvatarPlayAnimation() 2012-02-17 02:53:12 +00:00
BlueWall c5ff37bf3e Merge branch 'master' of /home/opensim/src/opensim 2012-02-16 09:01:02 -05:00
BlueWall 6b867773a8 Remove some debugging output form the logger 2012-02-16 08:59:34 -05:00
Justin Clark-Casey (justincc) 912aac3447 minor formatting changes from last commit (4486n7d) 2012-02-16 03:37:40 +00:00
PixelTomsen 4486b7d8e8 Fix: Object owned by the group does not return to the last owner http://opensimulator.org/mantis/view.php?id=5404 2012-02-16 03:35:18 +00:00
Justin Clark-Casey (justincc) 1267094a51 Turn off logging on test in last commit (2b84295). 2012-02-16 03:02:11 +00:00
Justin Clark-Casey (justincc) 2b842958cc If shape properties fail SOP parsing (e.g. due to commas instead of decimal points) print out one short message listing the failing node names rather than lots of exceptions.
Adds skeleton bad float values deserialization test
2012-02-16 02:58:00 +00:00
Justin Clark-Casey (justincc) 80ec2ac167 Correct a bug introduced in 1f402fdf (Feb 7 2012) where the delete friends grid call would try and contact the wrong uri. Also fixes the build from df960d5 2012-02-16 01:39:12 +00:00
Justin Clark-Casey (justincc) df960d5767 Add known identity informatio nto log message if an exception is thrown during LLUDPServer.HandleUseCircuitCode() 2012-02-16 01:25:54 +00:00
Melanie 0c1074537b Merge branch 'master' into careminster
Conflicts:
	OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
2012-02-16 00:38:04 +00:00
Justin Clark-Casey (justincc) c0760f9f91 Comment out "experimental" log message printed out whenever a physics mesh was generated for a mesh
Also adds prim name to the "no asset data" error log message
2012-02-16 00:28:57 +00:00
Justin Clark-Casey (justincc) c906128191 Fix some logic mistakes where firstly osNpcCreate() without options was creating npcs sensed as agents and secondly the OS_NPC_SENSE_AS_AGENT option was having the opposite effect.
Hopefully makes progress on addressing http://opensimulator.org/mantis/view.php?id=5872
2012-02-16 00:22:39 +00:00
UbitUmarov 819fcdaee1 Now if chode prim.cs detects out of bounds it requests a update and blocks movement and colisions. Base code must do a PhysActor.CrossingFailure() to make it move again inside sim or delete it. 2012-02-15 22:04:26 +01:00
UbitUmarov 3bffdddc9d don't freeze with a sitted avatar in a border without other sim. Still messy :( 2012-02-15 22:04:17 +01:00
UbitUmarov f6c35cf26f Now if chode prim.cs detects out of bounds it requests a update and blocks movement and colisions. Base code must do a PhysActor.CrossingFailure() to make it move again inside sim or delete it. 2012-02-15 20:33:31 +00:00
UbitUmarov b59275355e don't freeze with a sitted avatar in a border without other sim. Still messy :( 2012-02-15 19:44:54 +00:00
UbitUmarov a758abaa9f try to make crossings work better. chode no longer prevents crossings i hope 2012-02-15 17:08:33 +00:00
UbitUmarov f6f0d884bd try to make crossings work better. chode no longer prevents crossings i hope 2012-02-15 16:44:15 +01:00
UbitUmarov 04279e36d1 Merge branch 'master' of ssh://3dhosting.de/var/git/careminster into ubitwork 2012-02-15 03:51:30 +00:00
Justin Clark-Casey (justincc) f574d3c8fc Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-02-15 01:50:57 +00:00
Justin Clark-Casey (justincc) ebe5e1731d In ObjectTortureTests, run garbage collector on Teardown and run scene loop update when scene objects have been deleted.
At least on mono 2.6.4, running GC.Collect() is not guaranteed to force gc of all objects when run in the same method where those objects had references.
Therefore, GC.Collect() is now being done in the per-script teardown of ObjectTortureTests.
In addition, scene loop update is being run after garbage collection in order to clean out the viewer update list of scene objects in the SceneGraph.
These measures mean that scene objects/parts are now garbage collected after a test run if deleted from the scene, resulting in a much better memory usage report (though probably still not very accurate).
However, deletion takes a very long time - what's really needed is to find out now why the entire scene isn't being GC'd by this measure.
This change hasn't yet been applied to the other stress tests.
2012-02-15 01:45:25 +00:00
Dan Lake 2ebb421331 Refactor appearance saving for NPC to use AvatarFactoryModule interface. 2012-02-14 17:20:34 -08:00
Melanie 7be9ba5564 Merge branch 'master' of ssh://melanie@3dhosting.de/var/git/careminster into careminster 2012-02-15 01:11:35 +00:00
Melanie 272ba5a741 Merge branch 'master' into careminster 2012-02-15 01:11:17 +00:00
Melanie 2d3381b795 Implement region crossing of sitting avatars. Edit mode and llSetPos work
but unscripted default sit anim is lost. Still some Gfx glitching. Physical
crossing doesn't work yet.
2012-02-14 23:16:20 +01:00
Mic Bowman a9e8bd59a3 Fix a race condition in the simian groups connector. When requests were
too slow they would circumvent the cache (piling up on the network service
and making the problem even worse). This condition happens frequently
during permission checks.
2012-02-13 19:38:22 -08:00
PixelTomsen 4589ce61bc Fix: get embedded objects from Notecard fails with activated FreeSwitchVoiceModul
http://opensimulator.org/mantis/view.php?id=2607
2012-02-14 02:12:12 +00:00
PixelTomsen 33e66107be Fix: Lightshare Module(Windlight)-Region settings are not applicable for database sqlite mantis: http://opensimulator.org/mantis/view.php?id=5888 2012-02-14 02:06:42 +00:00
PixelTomsen db90dea9bd Fix: MSSQLDB Grid - unable to register region http://opensimulator.org/mantis/view.php?id=5886 2012-02-14 02:04:02 +00:00
Justin Clark-Casey (justincc) 04544b4510 Revert "Add GridStore migration for MSSQL."
This reverts commit 0b17a66e68.
2012-02-14 02:03:23 +00:00
Justin Clark-Casey (justincc) 0b17a66e68 Add GridStore migration for MSSQL.
This is done blind since I don't use MSSQL.  If this doesn't work, then one will have to wait for it to be updated for the 0.7.3 opensim release.
2012-02-14 02:02:11 +00:00
Justin Clark-Casey (justincc) 04986bbb15 Add some more data to the new user connection logging for debug purposes. 2012-02-14 01:50:51 +00:00
Justin Clark-Casey (justincc) b0d02adeee Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-02-14 00:01:24 +00:00
Justin Clark-Casey (justincc) 48b962c401 Update [XEngine] AppDomainLoading advice in OpenSim.ini.example 2012-02-14 00:00:49 +00:00
Melanie e321306517 Prevent object loss and positioning outside the region with failed object sim
crossings
2012-02-14 00:02:53 +01:00
Mic Bowman 04a195266b short circuit the expensive parts of the permission checking code
if the current user is the owner of an object. none of the later
checks can reverse the outcome.
2012-02-13 13:21:42 -08:00
Justin Clark-Casey (justincc) 21393af631 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-02-13 20:48:50 +00:00
Justin Clark-Casey (justincc) 189c67db95 On object deserialization, go back to logging errors at DEBUG level rather than ERROR. Restore extra log message if shape processing fails.
Logging level was DEBUG before 312e145 (Fri Feb 3 2012).
312e145 also accidentally removed the 'general error' log message if any shape deserialization failed.
This commit restores it, though this has no functional impact.
2012-02-13 20:43:26 +00:00
UbitUmarov 6fd6919a0b remove drawstuff from ubitode 2012-02-11 19:25:41 +00:00
UbitUmarov f168fefb79 removed outdated coments. 2012-02-11 19:14:27 +00:00
UbitUmarov bcf59a574f remove forgotten taints code 2012-02-11 19:12:04 +00:00
UbitUmarov 09f6647aa3 scenepresence change! in standup() give avatar a physical actor after deciding the new position. This reduces a bit the odds of it being still coliding with object. 2012-02-11 17:48:49 +00:00
UbitUmarov 022ae33ed5 UbitODE: replace 'taints' by 'changes' for avatars also. This provides better time order with changes in prims. 2012-02-11 17:35:38 +00:00
UbitUmarov d4e28ed113 vehicle changes done by simulation thread and not calling one 2012-02-11 15:18:13 +00:00
UbitUmarov 3f9c390b4d changes to vehicle banking 2012-02-11 14:29:36 +00:00
UbitUmarov 33a9f0f1c5 a bit better vertical attractor and banking 2012-02-11 04:42:45 +00:00
UbitUmarov f415256e0b Use mesh to estimate real center of prims if avaiable. Let sculpt map textures with alpha channel work. On linux J2DecodeCache folder must be deleted to remove bad entries. Corrently this can't be cached on linux (mono/ cairo/? problem) 2012-02-11 03:25:17 +00:00
UbitUmarov b617411b97 scale avatar push force with avatar density 2012-02-11 02:48:38 +00:00
Justin Clark-Casey (justincc) b92b9228ef correct the default avatar_terminal_velocity value that I accidentally left in whilst testing 2012-02-11 02:29:07 +00:00
Justin Clark-Casey (justincc) f49897a419 Clamp ODE character velocity. Make ODE falling character 54m/s by default.
If velocity reaches 256 in any vector then bad things happen with ODE, so we now clamp this value.
In addition, a falling avatar is clamped by default at 54 m/s, which is the same as a falling skydiver.
This also appears to be the value used on the linden lab grid.
This should resolve http://opensimulator.org/mantis/view.php?id=5882
2012-02-11 02:28:40 +00:00
UbitUmarov 83868c0387 revert project name to OpenSim and not Careminster 2012-02-11 01:07:57 +00:00
Justin Clark-Casey (justincc) aab30f5e67 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-02-11 00:11:28 +00:00
Justin Clark-Casey (justincc) e7fd732209 Make ScenePresence.MovementFlag a private only settable value to reduce complexity of code analysis 2012-02-11 00:10:59 +00:00
Melanie acfe7e555e Merge branch 'master' into careminster 2012-02-10 23:59:10 +00:00
Melanie 5023cc86f0 Change parser to leave embedded quotes alone if the pattern is recognized
as an OptionSet long option
2012-02-10 23:58:39 +00:00
Melanie 4455140f30 Change parser to leave embedded quotes alone if the pattern is recognized
as an OptionSet long option
2012-02-10 23:52:06 +00:00
UbitUmarov 43a74d8481 test on git 2012-02-10 23:51:55 +00:00
Justin Clark-Casey (justincc) 71e484516a minor: Remove warning from RegionInfo due to repeated config.GetString() call where the first was unused. 2012-02-10 23:41:14 +00:00
Justin Clark-Casey (justincc) 38f878952c Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-02-10 23:39:59 +00:00
Justin Clark-Casey (justincc) d80422eba7 Add line numbers to Util.PrintCallStack() 2012-02-10 23:39:32 +00:00
UbitUmarov e3f5fd81f1 Merge branch 'master' of ssh://3dhosting.de/var/git/careminster into ubitwork
Conflicts:
	prebuild.xml
2012-02-10 23:03:30 +00:00
UbitUmarov 7cf73cb92a Changes to vehicles code etc. Includes some debug aids to remove later. 2012-02-10 22:43:51 +00:00
BlueWall ee078f717a Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-02-10 16:28:11 -05:00
BlueWall 73f34de1f9 Merge branch 'master' of /home/opensim/var/repo/opensim 2012-02-10 16:27:14 -05:00
Justin Clark-Casey (justincc) b3d152f3ba Fix an npc delete race condition with LSL sensors where an initial presence check could succeed but then the npc removed before the subequent npc check.
The resulting null would cause an exception.  We now check for null before looking at SenseAsAgent.
Hopefully fixes http://opensimulator.org/mantis/view.php?id=5872
2012-02-10 21:26:05 +00:00
PixelTomsen a7dc7e636e Fix: Covenant view fails after updates or cache-clean see mantis http://opensimulator.org/mantis/view.php?id=2879
Signed-off-by: BlueWall <jamesh@bluewallgroup.com>
2012-02-10 15:45:03 -05:00
Justin Clark-Casey (justincc) 44d84bc277 Fix bug where somebody taking a copy of an object they didn't own that was rezzed before the region was restarted would wrongly place the copy in the object owner's inventory.
Addresses http://opensimulator.org/mantis/view.php?id=5825
2012-02-10 19:58:34 +00:00
Melanie 215acbcc96 Merge branch 'master' into careminster
Conflicts:
	OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
	OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
2012-02-10 10:20:51 +00:00
PixelTomsen 7273e05995 Fix: Unable to remove AV from friend list (sqldb-bug) http://opensimulator.org/mantis/view.php?id=3731 2012-02-10 02:30:55 +00:00
Justin Clark-Casey (justincc) ddca5347c3 When an asset is uploaded (e.g. a mesh) set individual copy/move/transfer permissions, not PermissionMask.All
Setting PermissionMask.All will cause next permissions to replace current permissions when the object is rezzed, since bit 4 will be set.
This is not correct behaviour for a freshly uploaded mesh.  Freshly rezzed in-world prims also do not have bit 4 set (don't yet know exactly what this is).
Should resolve http://opensimulator.org/mantis/view.php?id=5651
2012-02-10 02:13:15 +00:00
Justin Clark-Casey (justincc) e8cc1bd329 Fix another Torture test build break on Windows. 2012-02-09 20:12:29 +00:00
Justin Clark-Casey (justincc) 9c84a8162f If NPCModule.CreateNPC() fails to create the required ScenePresence (which should in theory never happen), don't add the NPC to the npc list but return UUID.Zero instead. 2012-02-09 01:17:59 +00:00
Justin Clark-Casey (justincc) 16c4636048 Add NPC torture tests for 100, 1000 and 2000 create and delete NPC calls. 2012-02-09 00:38:09 +00:00
Melanie 7c888f6af1 Merge branch 'master' into careminster
Conflicts:
	OpenSim/Region/Framework/Scenes/SceneGraph.cs
2012-02-09 00:19:37 +00:00
Justin Clark-Casey (justincc) dbe32a1f6d minor: put in commented out logging statements for future reuse 2012-02-09 00:10:45 +00:00
UbitUmarov 6af01f6767 initial introdution of physics actor building control. 2012-02-08 23:14:53 +00:00
Justin Clark-Casey (justincc) 3fa61c4a39 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-02-08 22:21:15 +00:00
Justin Clark-Casey (justincc) dfa19e23f0 Stop a scene object from attempting to link with itself (which results in an exception and constant complaints in v3 viewers).
Aims to address http://opensimulator.org/mantis/view.php?id=5878
2012-02-08 22:19:34 +00:00
UbitUmarov 6cc9aa30ac first change in SOP. in AddPrimShape(..) give physics the world rotation and not local offset. Currently physics interface only knows about world frame 2012-02-08 15:45:44 +00:00
UbitUmarov 754129b903 files need to run UbitODE in linux ( untested ) 2012-02-08 15:33:51 +00:00
UbitUmarov 12c3239666 changes needed to compile UbitODE, also changes project name to "Careminter". untested on linux 2012-02-08 15:29:48 +00:00
UbitUmarov c75fa8b8a1 changes in physics manager, needed for UbitODE 2012-02-08 15:28:13 +00:00
Robert Adams d5c08c44bf Add missing reference to prebuild.xml for torture tests 2012-02-07 16:40:09 -08:00
Justin Clark-Casey (justincc) bef2a368f4 Make WebStats logging report consistently as WEB STATS MODULE instead of VC, VS and WEBSTATS 2012-02-07 23:38:53 +00:00
111 changed files with 6375 additions and 4435 deletions
@@ -235,4 +235,11 @@ CREATE NONCLUSTERED INDEX IX_regions_name ON dbo.regions
regionName
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
COMMIT
COMMIT
:VERSION 9
BEGIN TRANSACTION
ALTER TABLE regions ADD parcelMapTexture uniqueidentifier NULL;
COMMIT
@@ -472,3 +472,95 @@ COMMIT;
BEGIN;
ALTER TABLE regionsettings ADD COLUMN covenant_datetime INTEGER NOT NULL default 0;
COMMIT;
:VERSION 23
BEGIN;
CREATE TABLE regionwindlight (
region_id VARCHAR(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000' PRIMARY KEY,
water_color_r FLOAT NOT NULL DEFAULT '4.000000',
water_color_g FLOAT NOT NULL DEFAULT '38.000000',
water_color_b FLOAT NOT NULL DEFAULT '64.000000',
water_color_i FLOAT NOT NULL DEFAULT '1.000000',
water_fog_density_exponent FLOAT NOT NULL DEFAULT '4.0',
underwater_fog_modifier FLOAT NOT NULL DEFAULT '0.25',
reflection_wavelet_scale_1 FLOAT NOT NULL DEFAULT '2.0',
reflection_wavelet_scale_2 FLOAT NOT NULL DEFAULT '2.0',
reflection_wavelet_scale_3 FLOAT NOT NULL DEFAULT '2.0',
fresnel_scale FLOAT NOT NULL DEFAULT '0.40',
fresnel_offset FLOAT NOT NULL DEFAULT '0.50',
refract_scale_above FLOAT NOT NULL DEFAULT '0.03',
refract_scale_below FLOAT NOT NULL DEFAULT '0.20',
blur_multiplier FLOAT NOT NULL DEFAULT '0.040',
big_wave_direction_x FLOAT NOT NULL DEFAULT '1.05',
big_wave_direction_y FLOAT NOT NULL DEFAULT '-0.42',
little_wave_direction_x FLOAT NOT NULL DEFAULT '1.11',
little_wave_direction_y FLOAT NOT NULL DEFAULT '-1.16',
normal_map_texture VARCHAR(36) NOT NULL DEFAULT '822ded49-9a6c-f61c-cb89-6df54f42cdf4',
horizon_r FLOAT NOT NULL DEFAULT '0.25',
horizon_g FLOAT NOT NULL DEFAULT '0.25',
horizon_b FLOAT NOT NULL DEFAULT '0.32',
horizon_i FLOAT NOT NULL DEFAULT '0.32',
haze_horizon FLOAT NOT NULL DEFAULT '0.19',
blue_density_r FLOAT NOT NULL DEFAULT '0.12',
blue_density_g FLOAT NOT NULL DEFAULT '0.22',
blue_density_b FLOAT NOT NULL DEFAULT '0.38',
blue_density_i FLOAT NOT NULL DEFAULT '0.38',
haze_density FLOAT NOT NULL DEFAULT '0.70',
density_multiplier FLOAT NOT NULL DEFAULT '0.18',
distance_multiplier FLOAT NOT NULL DEFAULT '0.8',
max_altitude INTEGER NOT NULL DEFAULT '1605',
sun_moon_color_r FLOAT NOT NULL DEFAULT '0.24',
sun_moon_color_g FLOAT NOT NULL DEFAULT '0.26',
sun_moon_color_b FLOAT NOT NULL DEFAULT '0.30',
sun_moon_color_i FLOAT NOT NULL DEFAULT '0.30',
sun_moon_position FLOAT NOT NULL DEFAULT '0.317',
ambient_r FLOAT NOT NULL DEFAULT '0.35',
ambient_g FLOAT NOT NULL DEFAULT '0.35',
ambient_b FLOAT NOT NULL DEFAULT '0.35',
ambient_i FLOAT NOT NULL DEFAULT '0.35',
east_angle FLOAT NOT NULL DEFAULT '0.00',
sun_glow_focus FLOAT NOT NULL DEFAULT '0.10',
sun_glow_size FLOAT NOT NULL DEFAULT '1.75',
scene_gamma FLOAT NOT NULL DEFAULT '1.00',
star_brightness FLOAT NOT NULL DEFAULT '0.00',
cloud_color_r FLOAT NOT NULL DEFAULT '0.41',
cloud_color_g FLOAT NOT NULL DEFAULT '0.41',
cloud_color_b FLOAT NOT NULL DEFAULT '0.41',
cloud_color_i FLOAT NOT NULL DEFAULT '0.41',
cloud_x FLOAT NOT NULL DEFAULT '1.00',
cloud_y FLOAT NOT NULL DEFAULT '0.53',
cloud_density FLOAT NOT NULL DEFAULT '1.00',
cloud_coverage FLOAT NOT NULL DEFAULT '0.27',
cloud_scale FLOAT NOT NULL DEFAULT '0.42',
cloud_detail_x FLOAT NOT NULL DEFAULT '1.00',
cloud_detail_y FLOAT NOT NULL DEFAULT '0.53',
cloud_detail_density FLOAT NOT NULL DEFAULT '0.12',
cloud_scroll_x FLOAT NOT NULL DEFAULT '0.20',
cloud_scroll_x_lock INTEGER NOT NULL DEFAULT '0',
cloud_scroll_y FLOAT NOT NULL DEFAULT '0.01',
cloud_scroll_y_lock INTEGER NOT NULL DEFAULT '0',
draw_classic_clouds INTEGER NOT NULL DEFAULT '1');
COMMIT;
:VERSION 24
BEGIN;
CREATE TABLE IF NOT EXISTS `spawn_points` (
`RegionID` varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000',
`Yaw` float NOT NULL,
`Pitch` float NOT NULL,
`Distance` float NOT NULL
);
ALTER TABLE `regionsettings` ADD COLUMN `TelehubObject` varchar(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
COMMIT;
:VERSION 25
BEGIN;
ALTER TABLE `regionsettings` ADD COLUMN `parcel_tile_ID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
COMMIT;
+3
View File
@@ -81,6 +81,9 @@ namespace OpenSim.Data.SQLite
/// <param name="dbconnect">connect string</param>
override public void Initialise(string dbconnect)
{
if (Util.IsWindows())
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
if (dbconnect == string.Empty)
{
dbconnect = "URI=file:Asset.db,version=3";
@@ -65,6 +65,9 @@ namespace OpenSim.Data.SQLite
if (!m_initialized)
{
if (Util.IsWindows())
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
m_Connection = new SqliteConnection(connectionString);
m_Connection.Open();
+3
View File
@@ -69,6 +69,9 @@ namespace OpenSim.Data.SQLite
public void Initialise(string connectionString)
{
if (Util.IsWindows())
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
m_connectionString = connectionString;
m_log.Info("[ESTATE DB]: Sqlite - connecting: "+m_connectionString);
+2
View File
@@ -48,6 +48,8 @@ namespace OpenSim.Data.SQLite
protected SQLiteFramework(string connectionString)
{
if (Util.IsWindows())
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
}
//////////////////////////////////////////////////////////////
+1 -1
View File
@@ -75,7 +75,7 @@ namespace OpenSim.Data.SQLite
cmd.Parameters.AddWithValue(":PrincipalID", principalID.ToString());
cmd.Parameters.AddWithValue(":Friend", friend);
ExecuteNonQuery(cmd, cmd.Connection);
ExecuteNonQuery(cmd, m_Connection);
return true;
}
@@ -77,6 +77,9 @@ namespace OpenSim.Data.SQLite
{
m_Initialized = true;
if (Util.IsWindows())
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
if (dbconnect == string.Empty)
{
dbconnect = "URI=file:inventoryStore.db,version=3";
File diff suppressed because it is too large Load Diff
@@ -52,6 +52,9 @@ namespace OpenSim.Data.SQLite
public SQLiteXInventoryData(string conn, string realm)
{
if (Util.IsWindows())
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
m_Folders = new SQLiteGenericTableHandler<XInventoryFolder>(
conn, "inventoryfolders", "XInventoryStore");
m_Items = new SqliteItemHandler(
+11
View File
@@ -308,6 +308,8 @@ namespace OpenSim.Framework
public Animation[] Anims;
public UUID GranterID;
public UUID ParentPart;
public Vector3 SitOffset;
// Appearance
public AvatarAppearance Appearance;
@@ -468,6 +470,10 @@ namespace OpenSim.Framework
}
args["attach_objects"] = attObjs;
}
args["parent_part"] = OSD.FromUUID(ParentPart);
args["sit_offset"] = OSD.FromString(SitOffset.ToString());
return args;
}
@@ -675,6 +681,11 @@ namespace OpenSim.Framework
}
}
}
if (args["parent_part"] != null)
ParentPart = args["parent_part"].AsUUID();
if (args["sit_offset"] != null)
Vector3.TryParse(args["sit_offset"].AsString(), out SitOffset);
}
public AgentData()
@@ -31,6 +31,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using log4net;
using OpenSim.Framework;
@@ -531,6 +532,11 @@ namespace OpenSim.Framework.Console
public class Parser
{
// If an unquoted portion ends with an element matching this regex
// and the next element contains a space, then we have stripped
// embedded quotes that should not have been stripped
private static Regex optionRegex = new Regex("^--[a-zA-Z0-9-]+=$");
public static string[] Parse(string text)
{
List<string> result = new List<string>();
@@ -544,10 +550,38 @@ namespace OpenSim.Framework.Console
if (index % 2 == 0)
{
string[] words = unquoted[index].Split(new char[] {' '});
bool option = false;
foreach (string w in words)
{
if (w != String.Empty)
{
if (optionRegex.Match(w) == Match.Empty)
option = false;
else
option = true;
result.Add(w);
}
}
// The last item matched the regex, put the quotes back
if (option)
{
// If the line ended with it, don't do anything
if (index < (unquoted.Length - 1))
{
// Get and remove the option name
string optionText = result[result.Count - 1];
result.RemoveAt(result.Count - 1);
// Add the quoted value back
optionText += "\"" + unquoted[index + 1] + "\"";
// Push the result into our return array
result.Add(optionText);
// Skip the already used value
index++;
}
}
}
else
-1
View File
@@ -627,7 +627,6 @@ namespace OpenSim.Framework
foreach (String s in allKeys)
{
string val = config.GetString(s);
SetOtherSetting(s, config.GetString(s));
}
}
@@ -49,15 +49,16 @@ namespace OpenSim.Framework.Serialization.External
/// <param name="nodeToFill"></param>
/// <param name="processors">/param>
/// <param name="xtr"></param>
public static void ExecuteReadProcessors<NodeType>(
/// <returns>true on successful, false if there were any processing failures</returns>
public static bool ExecuteReadProcessors<NodeType>(
NodeType nodeToFill, Dictionary<string, Action<NodeType, XmlTextReader>> processors, XmlTextReader xtr)
{
ExecuteReadProcessors(
return ExecuteReadProcessors(
nodeToFill,
processors,
xtr,
(o, name, e)
=> m_log.ErrorFormat(
=> m_log.DebugFormat(
"[ExternalRepresentationUtils]: Exception while parsing element {0}, continuing. Exception {1}{2}",
name, e.Message, e.StackTrace));
}
@@ -71,12 +72,15 @@ namespace OpenSim.Framework.Serialization.External
/// <param name="parseExceptionAction">
/// Action to take if there is a parsing problem. This will usually just be to log the exception
/// </param>
public static void ExecuteReadProcessors<NodeType>(
/// <returns>true on successful, false if there were any processing failures</returns>
public static bool ExecuteReadProcessors<NodeType>(
NodeType nodeToFill,
Dictionary<string, Action<NodeType, XmlTextReader>> processors,
XmlTextReader xtr,
Action<NodeType, string, Exception> parseExceptionAction)
{
bool errors = false;
string nodeName = string.Empty;
while (xtr.NodeType != XmlNodeType.EndElement)
{
@@ -95,6 +99,7 @@ namespace OpenSim.Framework.Serialization.External
}
catch (Exception e)
{
errors = true;
parseExceptionAction(nodeToFill, nodeName, e);
if (xtr.NodeType == XmlNodeType.EndElement)
@@ -107,6 +112,8 @@ namespace OpenSim.Framework.Serialization.External
xtr.ReadOuterXml(); // ignore
}
}
return errors;
}
/// <summary>
@@ -140,6 +147,7 @@ namespace OpenSim.Framework.Serialization.External
UUID.TryParse(node.InnerText, out uuid);
creator = userService.GetUserAccount(scopeID, uuid);
}
if (node.Name == "CreatorData" && node.InnerText != null && node.InnerText != string.Empty)
hasCreatorData = true;
@@ -163,7 +171,6 @@ namespace OpenSim.Framework.Serialization.External
doc.Save(wr);
return wr.ToString();
}
}
}
}
}
@@ -308,7 +308,9 @@ namespace OpenSim.Framework.Servers
// clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and
// the clr version number doesn't match the project version number under Mono.
//m_log.Info("[STARTUP]: Virtual machine runtime version: " + Environment.Version + Environment.NewLine);
m_log.Info("[STARTUP]: Operating system version: " + Environment.OSVersion + Environment.NewLine);
m_log.InfoFormat(
"[STARTUP]: Operating system version: {0}, .NET platform {1}, {2}-bit\n",
Environment.OSVersion, Environment.OSVersion.Platform, Util.Is64BitProcess() ? "64" : "32");
StartupSpecific();
+70 -3
View File
@@ -35,7 +35,8 @@ using System.IO;
using System.IO.Compression;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security.Cryptography;
@@ -375,6 +376,50 @@ namespace OpenSim.Framework
}
return sb.ToString();
}
/// <summary>
/// Is the platform Windows?
/// </summary>
/// <returns>true if so, false otherwise</returns>
public static bool IsWindows()
{
PlatformID platformId = Environment.OSVersion.Platform;
return (platformId == PlatformID.Win32NT
|| platformId == PlatformID.Win32S
|| platformId == PlatformID.Win32Windows
|| platformId == PlatformID.WinCE);
}
public static bool LoadArchSpecificWindowsDll(string libraryName)
{
// We do this so that OpenSimulator on Windows loads the correct native library depending on whether
// it's running as a 32-bit process or a 64-bit one. By invoking LoadLibary here, later DLLImports
// will find it already loaded later on.
//
// This isn't necessary for other platforms (e.g. Mac OSX and Linux) since the DLL used can be
// controlled in config files.
string nativeLibraryPath;
if (Util.Is64BitProcess())
nativeLibraryPath = "lib64/" + libraryName;
else
nativeLibraryPath = "lib32/" + libraryName;
m_log.DebugFormat("[UTIL]: Loading native Windows library at {0}", nativeLibraryPath);
if (Util.LoadLibrary(nativeLibraryPath) == IntPtr.Zero)
{
m_log.ErrorFormat(
"[UTIL]: Couldn't find native Windows library at {0}", nativeLibraryPath);
return false;
}
else
{
return true;
}
}
public static bool IsEnvironmentSupported(ref string reason)
@@ -1469,6 +1514,27 @@ namespace OpenSim.Framework
}
return data;
}
/// <summary>
/// Used to trigger an early library load on Windows systems.
/// </summary>
/// <remarks>
/// Required to get 32-bit and 64-bit processes to automatically use the
/// appropriate native library.
/// </remarks>
/// <param name="dllToLoad"></param>
/// <returns></returns>
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);
/// <summary>
/// Determine whether the current process is 64 bit
/// </summary>
/// <returns>true if so, false if not</returns>
public static bool Is64BitProcess()
{
return IntPtr.Size == 8;
}
#region FireAndForget Threading Pattern
@@ -1676,13 +1742,14 @@ namespace OpenSim.Framework
/// </summary>
public static void PrintCallStack()
{
StackTrace stackTrace = new StackTrace(); // get call stack
StackTrace stackTrace = new StackTrace(true); // get call stack
StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
// write call stack method names
foreach (StackFrame stackFrame in stackFrames)
{
m_log.Debug(stackFrame.GetMethod().DeclaringType + "." + stackFrame.GetMethod().Name); // write method name
MethodBase mb = stackFrame.GetMethod();
m_log.DebugFormat("{0}.{1}:{2}", mb.DeclaringType, mb.Name, stackFrame.GetFileLineNumber()); // write method name
}
}
@@ -422,7 +422,7 @@ namespace OpenSim.Region.ClientStack.Linden
string assetType)
{
m_log.DebugFormat(
"Uploaded asset {0} for inventory item {1}, inv type {2}, asset type {3}",
"[BUNCH OF CAPS]: Uploaded asset {0} for inventory item {1}, inv type {2}, asset type {3}",
assetID, inventoryItem, inventoryType, assetType);
sbyte assType = 0;
@@ -625,7 +625,12 @@ namespace OpenSim.Region.ClientStack.Linden
item.AssetType = assType;
item.InvType = inType;
item.Folder = parentFolder;
item.CurrentPermissions = (uint)PermissionMask.All;
// If we set PermissionMask.All then when we rez the item the next permissions will replace the current
// (owner) permissions. This becomes a problem if next permissions are changed.
item.CurrentPermissions
= (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
item.BasePermissions = (uint)PermissionMask.All;
item.EveryOnePermissions = 0;
item.NextPermissions = (uint)PermissionMask.All;
@@ -50,8 +50,7 @@ namespace OpenSim.Region.ClientStack.Linden
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class NewFileAgentInventoryVariablePriceModule : INonSharedRegionModule
{
// private static readonly ILog m_log =
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene;
// private IAssetService m_assetService;
@@ -210,6 +209,9 @@ namespace OpenSim.Region.ClientStack.Linden
UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
string assetType,UUID AgentID)
{
// m_log.DebugFormat(
// "[NEW FILE AGENT INVENTORY VARIABLE PRICE MODULE]: Upload complete for {0}", inventoryItem);
sbyte assType = 0;
sbyte inType = 0;
@@ -259,13 +261,13 @@ namespace OpenSim.Region.ClientStack.Linden
item.AssetType = assType;
item.InvType = inType;
item.Folder = parentFolder;
item.CurrentPermissions = (uint)PermissionMask.All;
item.CurrentPermissions
= (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
item.BasePermissions = (uint)PermissionMask.All;
item.EveryOnePermissions = 0;
item.NextPermissions = (uint)PermissionMask.All;
item.CreationDate = Util.UnixTimeSinceEpoch();
m_scene.AddInventoryItem(item);
}
}
}
@@ -339,7 +339,7 @@ namespace OpenSim.Region.ClientStack.Linden
m_scene.AddSceneObject(grp);
grp.AbsolutePosition = obj.Position;
}
allparts[i] = grp;
}
@@ -1549,7 +1549,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void SendKillObject(ulong regionHandle, List<uint> localIDs)
{
// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle);
// foreach (uint id in localIDs)
// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
// TODO: don't create new blocks if recycling an old packet
@@ -3773,6 +3774,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// doesn't seem to be attached, skip
if (!found)
continue;
// On vehicle crossing, the attachments are received
// while the avatar is still a child. Don't send
// updates here because the LocalId has not yet
// been updated and the viewer will derender the
// attachments until the avatar becomes root.
if (sp.IsChildAgent)
continue;
}
if (part.ParentGroup.IsAttachment && m_disableFacelights)
{
@@ -4827,9 +4836,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
ScenePresence presence = (ScenePresence)entity;
position = presence.OffsetPosition;
rotation = presence.Rotation;
if (presence.ParentID != 0)
{
SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
if (part != null && part != part.ParentGroup.RootPart)
{
position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
rotation = part.RotationOffset * presence.Rotation;
}
}
attachPoint = 0;
collisionPlane = presence.CollisionPlane;
position = presence.OffsetPosition;
velocity = presence.Velocity;
acceleration = Vector3.Zero;
@@ -4839,7 +4860,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// acceleration = new Vector3(1, 0, 0);
angularVelocity = Vector3.Zero;
rotation = presence.Rotation;
if (sendTexture)
textureEntry = presence.Appearance.Texture.GetBytes();
@@ -4944,13 +4964,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
{
Vector3 offsetPosition = data.OffsetPosition;
Quaternion rotation = data.Rotation;
uint parentID = data.ParentID;
if (parentID != 0)
{
SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
if (part != null && part != part.ParentGroup.RootPart)
{
offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
rotation = part.RotationOffset * data.Rotation;
parentID = part.ParentGroup.RootPart.LocalId;
}
}
byte[] objectData = new byte[76];
data.CollisionPlane.ToBytes(objectData, 0);
data.OffsetPosition.ToBytes(objectData, 16);
offsetPosition.ToBytes(objectData, 16);
// data.Velocity.ToBytes(objectData, 28);
// data.Acceleration.ToBytes(objectData, 40);
data.Rotation.ToBytes(objectData, 52);
rotation.ToBytes(objectData, 52);
//data.AngularVelocity.ToBytes(objectData, 64);
ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -4964,7 +4999,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
update.ObjectData = objectData;
update.ParentID = data.ParentID;
update.ParentID = parentID;
update.PathCurve = 16;
update.PathScaleX = 100;
update.PathScaleY = 100;
@@ -5168,7 +5203,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage, false);
AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship);
AddLocalPacketHandler(PacketType.DeclineFriendship, HandlerDeclineFriendship);
AddLocalPacketHandler(PacketType.TerminateFriendship, HandlerTerminateFrendship);
AddLocalPacketHandler(PacketType.TerminateFriendship, HandlerTerminateFriendship);
AddLocalPacketHandler(PacketType.RezObject, HandlerRezObject);
AddLocalPacketHandler(PacketType.DeRezObject, HandlerDeRezObject);
AddLocalPacketHandler(PacketType.ModifyLand, HandlerModifyLand);
@@ -5891,7 +5926,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return true;
}
private bool HandlerTerminateFrendship(IClientAPI sender, Packet Pack)
private bool HandlerTerminateFriendship(IClientAPI sender, Packet Pack)
{
TerminateFriendshipPacket tfriendpack = (TerminateFriendshipPacket)Pack;
@@ -5906,13 +5941,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
UUID listOwnerAgentID = tfriendpack.AgentData.AgentID;
UUID exFriendID = tfriendpack.ExBlock.OtherID;
FriendshipTermination handlerTerminateFriendship = OnTerminateFriendship;
if (handlerTerminateFriendship != null)
FriendshipTermination TerminateFriendshipHandler = OnTerminateFriendship;
if (TerminateFriendshipHandler != null)
{
handlerTerminateFriendship(this, listOwnerAgentID, exFriendID);
TerminateFriendshipHandler(this, listOwnerAgentID, exFriendID);
return true;
}
return true;
return false;
}
private bool HandleFindAgent(IClientAPI client, Packet Packet)
@@ -7689,6 +7724,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
}
}
else
if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate)
{
//TransferRequestPacket does not include covenant uuid?
//get scene covenant uuid
taskID = m_scene.RegionInfo.RegionSettings.Covenant;
}
MakeAssetRequest(transfer, taskID);
@@ -12113,6 +12155,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
requestID = new UUID(transferRequest.TransferInfo.Params, 80);
}
else if (transferRequest.TransferInfo.SourceType == (int)SourceType.SimEstate)
{
requestID = taskID;
}
// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
@@ -903,47 +903,64 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private void HandleUseCircuitCode(object o)
{
// DateTime startTime = DateTime.Now;
object[] array = (object[])o;
UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
IPEndPoint remoteEndPoint = null;
IClientAPI client = null;
try
{
// DateTime startTime = DateTime.Now;
object[] array = (object[])o;
UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
m_log.DebugFormat("[LLUDPSERVER]: Handling UseCircuitCode request from {0}", buffer.RemoteEndPoint);
remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
AuthenticateResponse sessionInfo;
if (IsClientAuthorized(uccp, out sessionInfo))
{
// Begin the process of adding the client to the simulator
client
= AddClient(
uccp.CircuitCode.Code,
uccp.CircuitCode.ID,
uccp.CircuitCode.SessionID,
remoteEndPoint,
sessionInfo);
m_log.DebugFormat("[LLUDPSERVER]: Handling UseCircuitCode request from {0}", buffer.RemoteEndPoint);
// Send ack straight away to let the viewer know that the connection is active.
// The client will be null if it already exists (e.g. if on a region crossing the client sends a use
// circuit code to the existing child agent. This is not particularly obvious.
SendAckImmediate(remoteEndPoint, uccp.Header.Sequence);
// We only want to send initial data to new clients, not ones which are being converted from child to root.
if (client != null)
client.SceneAgent.SendInitialDataToMe();
}
else
{
// Don't create clients for unauthorized requesters.
m_log.WarnFormat(
"[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
uccp.CircuitCode.ID, uccp.CircuitCode.Code, remoteEndPoint);
}
// m_log.DebugFormat(
// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds);
IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
AuthenticateResponse sessionInfo;
if (IsClientAuthorized(uccp, out sessionInfo))
{
// Begin the process of adding the client to the simulator
IClientAPI client
= AddClient(
uccp.CircuitCode.Code,
uccp.CircuitCode.ID,
uccp.CircuitCode.SessionID,
remoteEndPoint,
sessionInfo);
// Send ack straight away to let the viewer know that the connection is active.
// The client will be null if it already exists (e.g. if on a region crossing the client sends a use
// circuit code to the existing child agent. This is not particularly obvious.
SendAckImmediate(remoteEndPoint, uccp.Header.Sequence);
// We only want to send initial data to new clients, not ones which are being converted from child to root.
if (client != null)
client.SceneAgent.SendInitialDataToMe();
}
else
catch (Exception e)
{
// Don't create clients for unauthorized requesters.
m_log.WarnFormat(
"[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
uccp.CircuitCode.ID, uccp.CircuitCode.Code, remoteEndPoint);
m_log.ErrorFormat(
"[LLUDPSERVER]: UseCircuitCode handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}",
remoteEndPoint != null ? remoteEndPoint.ToString() : "n/a",
client != null ? client.Name : "unknown",
client != null ? client.AgentId.ToString() : "unknown",
e.Message,
e.StackTrace);
}
// m_log.DebugFormat(
// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds);
}
/// <summary>
@@ -417,7 +417,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
so.AttachedAvatar = UUID.Zero;
rootPart.SetParentLocalId(0);
so.ClearPartAttachmentData();
rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive);
rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive,false);
so.HasGroupChanged = true;
rootPart.Rezzed = DateTime.Now;
rootPart.RemFlag(PrimFlags.TemporaryOnRez);
@@ -111,6 +111,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
#region IAvatarFactoryModule
/// </summary>
/// <param name="sp"></param>
/// <param name="texture"></param>
/// <param name="visualParam"></param>
public void SetAppearance(IScenePresence sp, AvatarAppearance appearance)
{
SetAppearance(sp, appearance.Texture, appearance.VisualParams);
}
/// <summary>
/// Set appearance data (texture asset IDs and slider settings)
/// </summary>
@@ -156,14 +165,23 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
// WriteBakedTexturesReport(sp, m_log.DebugFormat);
if (!ValidateBakedTextureCache(sp))
// If bake textures are missing and this is not an NPC, request a rebake from client
if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc))
RequestRebake(sp, true);
// This appears to be set only in the final stage of the appearance
// update transaction. In theory, we should be able to do an immediate
// appearance send and save here.
}
// NPC should send to clients immediately and skip saving appearance
if (((ScenePresence)sp).PresenceType == PresenceType.Npc)
{
SendAppearance((ScenePresence)sp);
return;
}
// save only if there were changes, send no matter what (doesn't hurt to send twice)
if (changed)
QueueAppearanceSave(sp.ControllingClient.AgentId);
@@ -174,6 +192,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
// m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString());
}
private void SendAppearance(ScenePresence sp)
{
// Send the appearance to everyone in the scene
sp.SendAppearanceToAllOtherAgents();
// Send animations back to the avatar as well
sp.Animator.SendAnimPack();
}
public bool SendAppearance(UUID agentId)
{
// m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId);
@@ -185,12 +212,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
return false;
}
// Send the appearance to everyone in the scene
sp.SendAppearanceToAllOtherAgents();
// Send animations back to the avatar as well
sp.Animator.SendAnimPack();
SendAppearance(sp);
return true;
}
@@ -474,6 +496,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
SetAppearanceAssets(sp.UUID, sp.Appearance);
m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
// Trigger this here because it's the final step in the set/queue/save process for appearance setting.
// Everything has been updated and stored. Ensures bakes have been persisted (if option is set to persist bakes).
m_scene.EventManager.TriggerAvatarAppearanceChanged(sp);
}
private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
@@ -626,4 +652,4 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
outputAction("{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt");
}
}
}
}
@@ -681,11 +681,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
#region Agent Crossings
public bool Cross(ScenePresence agent, bool isFlying)
public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos)
{
Scene scene = agent.Scene;
Vector3 pos = agent.AbsolutePosition;
Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
version = String.Empty;
newpos = new Vector3(pos.X, pos.Y, pos.Z);
uint neighbourx = scene.RegionInfo.RegionLocX;
uint neighboury = scene.RegionInfo.RegionLocY;
const float boundaryDistance = 1.7f;
@@ -706,53 +705,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
{
Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0)
{
neighboury--;
newpos.Y = Constants.RegionSize - enterDistance;
}
else
{
agent.IsInTransit = true;
neighboury = b.TriggerRegionY;
neighbourx = b.TriggerRegionX;
Vector3 newposition = pos;
newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
agent.ControllingClient.SendAgentAlertMessage(
String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
return true;
}
neighboury--;
newpos.Y = Constants.RegionSize - enterDistance;
}
Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W);
if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0)
{
neighbourx--;
newpos.X = Constants.RegionSize - enterDistance;
}
else
{
agent.IsInTransit = true;
neighboury = ba.TriggerRegionY;
neighbourx = ba.TriggerRegionX;
Vector3 newposition = pos;
newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
agent.ControllingClient.SendAgentAlertMessage(
String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
return true;
}
neighbourx--;
newpos.X = Constants.RegionSize - enterDistance;
}
else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
@@ -763,26 +721,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (scene.TestBorderCross(pos + southCross, Cardinals.S))
{
Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0)
{
neighboury--;
newpos.Y = Constants.RegionSize - enterDistance;
}
else
{
agent.IsInTransit = true;
neighboury = ba.TriggerRegionY;
neighbourx = ba.TriggerRegionX;
Vector3 newposition = pos;
newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
agent.ControllingClient.SendAgentAlertMessage(
String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
return true;
}
neighboury--;
newpos.Y = Constants.RegionSize - enterDistance;
}
else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
{
@@ -790,35 +730,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize);
newpos.Y = enterDistance;
}
}
else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
{
Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0)
{
neighboury--;
newpos.Y = Constants.RegionSize - enterDistance;
}
else
{
agent.IsInTransit = true;
neighboury = b.TriggerRegionY;
neighbourx = b.TriggerRegionX;
Vector3 newposition = pos;
newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
agent.ControllingClient.SendAgentAlertMessage(
String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
return true;
}
neighboury--;
newpos.Y = Constants.RegionSize - enterDistance;
}
else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
{
Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
newpos.Y = enterDistance;
@@ -849,19 +769,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
*/
ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
xDest = neighbourx;
yDest = neighboury;
int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);
ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);
ExpiringCache<ulong, DateTime> r;
DateTime banUntil;
if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r))
if (m_bannedRegions.TryGetValue(agentID, out r))
{
if (r.TryGetValue(neighbourHandle, out banUntil))
{
if (DateTime.Now < banUntil)
return false;
return null;
r.Remove(neighbourHandle);
}
}
@@ -873,28 +796,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
string reason;
string version;
if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason))
if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
{
agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
if (r == null)
{
r = new ExpiringCache<ulong, DateTime>();
r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45));
m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45));
}
else
{
r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
}
return null;
}
return neighbourRegion;
}
public bool Cross(ScenePresence agent, bool isFlying)
{
uint x;
uint y;
Vector3 newpos;
string version;
GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos);
if (neighbourRegion == null)
{
agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
return false;
}
agent.IsInTransit = true;
CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
d.BeginInvoke(agent, newpos, x, y, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
return true;
}
@@ -951,13 +889,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
icon.EndInvoke(iar);
}
public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version);
/// <summary>
/// This Closes child agents on neighbouring regions
/// Calls an asynchronous method to do so.. so it doesn't lag the sim.
/// </summary>
protected ScenePresence CrossAgentToNewRegionAsync(
public ScenePresence CrossAgentToNewRegionAsync(
ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion,
bool isFlying, string version)
{
@@ -1013,6 +949,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
neighbourRegion.RegionHandle);
return agent;
}
// No turning back
agent.IsChildAgent = true;
string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
@@ -1161,7 +1100,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// <summary>
/// This informs all neighbouring regions about agent "avatar".
/// Calls an asynchronous method to do so.. so it doesn't lag the sim.
/// </summary>
/// <param name="sp"></param>
public void EnableChildAgents(ScenePresence sp)
@@ -1281,13 +1219,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle)
{
InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
try
{
//neighbour.ExternalEndPoint may return null, which will be caught
d.BeginInvoke(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent,
InformClientOfNeighbourCompleted,
d);
// Let's put this back at sync, so that it doesn't clog
// the network, especially for regions in the same physical server.
// We're really not in a hurry here.
InformClientOfNeighbourAsync(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent);
//InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
//d.BeginInvoke(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent,
// InformClientOfNeighbourCompleted,
// d);
}
catch (ArgumentOutOfRangeException)
@@ -1720,34 +1661,34 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// Offset the positions for the new region across the border
Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
grp.RootPart.GroupPosition = pos;
// If we fail to cross the border, then reset the position of the scene object on that border.
uint x = 0, y = 0;
Utils.LongToUInts(newRegionHandle, out x, out y);
GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
if (destination == null || !CrossPrimGroupIntoNewRegion(destination, grp, silent))
if (destination != null)
{
m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID);
// We are going to move the object back to the old position so long as the old position
// is in the region
oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1);
oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1);
oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f);
grp.RootPart.GroupPosition = oldGroupPosition;
// Need to turn off the physics flags, otherwise the object will continue to attempt to
// move out of the region creating an infinite loop of failed attempts to cross
grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false);
grp.ScheduleGroupForFullUpdate();
if (CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
return; // we did it
}
// no one or failed lets go back and tell physics to go on
oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 0.5f, (float)Constants.RegionSize - 0.5f);
oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 0.5f, 4096.0f);
grp.AbsolutePosition = oldGroupPosition;
grp.Velocity = Vector3.Zero;
if (grp.RootPart.PhysActor != null)
grp.RootPart.PhysActor.CrossingFailure();
grp.ScheduleGroupForFullUpdate();
}
/// <summary>
/// Move the given scene object into a new region
/// </summary>
@@ -1757,7 +1698,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
/// true if the crossing itself was successful, false on failure
/// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region
/// </returns>
protected bool CrossPrimGroupIntoNewRegion(GridRegion destination, SceneObjectGroup grp, bool silent)
protected bool CrossPrimGroupIntoNewRegion(GridRegion destination, Vector3 newPosition, SceneObjectGroup grp, bool silent)
{
//m_log.Debug(" >>> CrossPrimGroupIntoNewRegion <<<");
@@ -1782,7 +1723,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
//if (m_interregionCommsOut != null)
// successYN = m_interregionCommsOut.SendCreateObject(newRegionHandle, grp, true);
if (m_aScene.SimulationService != null)
successYN = m_aScene.SimulationService.CreateObject(destination, grp, true);
successYN = m_aScene.SimulationService.CreateObject(destination, newPosition, grp, true);
if (successYN)
{
@@ -1841,7 +1782,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
gobj.IsAttachment = false;
//gobj.RootPart.LastOwnerID = gobj.GetFromAssetID();
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", gobj.UUID, destination.RegionName);
CrossPrimGroupIntoNewRegion(destination, gobj, silent);
CrossPrimGroupIntoNewRegion(destination, Vector3.Zero, gobj, silent);
}
}
@@ -560,12 +560,25 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
return null;
userID = remoteClient.AgentId;
// m_log.DebugFormat(
// "[INVENTORY ACCESS MODULE]: Target of {0} in CreateItemForObject() is {1} {2}",
// action, remoteClient.Name, userID);
}
else if (so.RootPart.OwnerID == so.RootPart.GroupID)
{
// Group owned objects go to the last owner before the object was transferred.
userID = so.RootPart.LastOwnerID;
}
else
{
// All returns / deletes go to the object owner
// Other returns / deletes go to the object owner
//
userID = so.RootPart.OwnerID;
// m_log.DebugFormat(
// "[INVENTORY ACCESS MODULE]: Target of {0} in CreateItemForObject() is object owner {1}",
// action, userID);
}
if (userID == UUID.Zero) // Can't proceed
@@ -651,11 +664,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
}
// Override and put into where it came from, if it came
// from anywhere in inventory
// from anywhere in inventory and the owner is taking it back.
//
if (action == DeRezAction.Take || action == DeRezAction.TakeCopy)
{
if (so.RootPart.FromFolderID != UUID.Zero)
if (so.RootPart.FromFolderID != UUID.Zero && userID == remoteClient.AgentId)
{
InventoryFolderBase f = new InventoryFolderBase(so.RootPart.FromFolderID, userID);
if (f != null)
@@ -830,6 +843,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
group = objlist[i];
SceneObjectPart rootPart = group.RootPart;
// m_log.DebugFormat(
// "[InventoryAccessModule]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
// group.Name, group.LocalId, group.UUID,
// group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask,
// remoteClient.Name);
// Vector3 storedPosition = group.AbsolutePosition;
if (group.UUID == UUID.Zero)
{
@@ -892,6 +911,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
rootPart.ScheduleFullUpdate();
}
// m_log.DebugFormat(
// "[InventoryAccessModule]: Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
// group.Name, group.LocalId, group.UUID,
// group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask,
// remoteClient.Name);
}
group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
@@ -958,7 +983,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
}
rootPart.FromFolderID = item.Folder;
// Console.WriteLine("rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}",
// rootPart.OwnerID, item.Owner, item.CurrentPermissions);
if ((rootPart.OwnerID != item.Owner) ||
(item.CurrentPermissions & 16) != 0 ||
(item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)
@@ -65,13 +65,26 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
}
}
internal struct ScopedRegionPosition
{
public UUID m_scopeID;
public ulong m_regionHandle;
public ScopedRegionPosition(UUID scopeID, ulong handle)
{
m_scopeID = scopeID;
m_regionHandle = handle;
}
}
private ExpiringCache<ScopedRegionUUID, GridRegion> m_UUIDCache;
private ExpiringCache<ScopedRegionName, ScopedRegionUUID> m_NameCache;
private ExpiringCache<ScopedRegionPosition, GridRegion> m_PositionCache;
public RegionInfoCache()
{
m_UUIDCache = new ExpiringCache<ScopedRegionUUID, GridRegion>();
m_NameCache = new ExpiringCache<ScopedRegionName, ScopedRegionUUID>();
m_NameCache = new ExpiringCache<ScopedRegionName, ScopedRegionUUID>();
m_PositionCache = new ExpiringCache<ScopedRegionPosition, GridRegion>();
}
public void Cache(GridRegion rinfo)
@@ -96,6 +109,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
{
ScopedRegionName name = new ScopedRegionName(scopeID,rinfo.RegionName);
m_NameCache.AddOrUpdate(name, id, CACHE_EXPIRATION_SECONDS);
ScopedRegionPosition pos = new ScopedRegionPosition(scopeID, rinfo.RegionHandle);
m_PositionCache.AddOrUpdate(pos, rinfo, CACHE_EXPIRATION_SECONDS);
}
}
@@ -114,6 +130,22 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
return null;
}
public GridRegion Get(UUID scopeID, ulong handle, out bool inCache)
{
inCache = false;
GridRegion rinfo = null;
ScopedRegionPosition pos = new ScopedRegionPosition(scopeID, handle);
if (m_PositionCache.TryGetValue(pos, out rinfo))
{
inCache = true;
return rinfo;
}
return null;
}
public GridRegion Get(UUID scopeID, string name, out bool inCache)
{
inCache = false;
@@ -186,10 +186,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
{
GridRegion rinfo = m_LocalGridService.GetRegionByPosition(scopeID, x, y);
bool inCache = false;
GridRegion rinfo = m_RegionInfoCache.Get(scopeID, Util.UIntsToLong((uint)x, (uint)y), out inCache);
if (inCache)
return rinfo;
rinfo = m_LocalGridService.GetRegionByPosition(scopeID, x, y);
if (rinfo == null)
rinfo = m_RemoteGridService.GetRegionByPosition(scopeID, x, y);
m_RegionInfoCache.Cache(rinfo);
return rinfo;
}
@@ -328,7 +328,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
* Object-related communications
*/
public bool CreateObject(GridRegion destination, ISceneObject sog, bool isLocalCall)
public bool CreateObject(GridRegion destination, Vector3 newPosition, ISceneObject sog, bool isLocalCall)
{
if (destination == null)
return false;
@@ -343,12 +343,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
// We need to make a local copy of the object
ISceneObject sogClone = sog.CloneForNewScene();
sogClone.SetState(sog.GetStateSnapshot(), s);
return s.IncomingCreateObject(sogClone);
return s.IncomingCreateObject(newPosition, sogClone);
}
else
{
// Use the object as it came through the wire
return s.IncomingCreateObject(sog);
return s.IncomingCreateObject(newPosition, sog);
}
}
}
@@ -297,13 +297,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
* Object-related communications
*/
public bool CreateObject(GridRegion destination, ISceneObject sog, bool isLocalCall)
public bool CreateObject(GridRegion destination, Vector3 newPosition, ISceneObject sog, bool isLocalCall)
{
if (destination == null)
return false;
// Try local first
if (m_localBackend.CreateObject(destination, sog, isLocalCall))
if (m_localBackend.CreateObject(destination, newPosition, sog, isLocalCall))
{
//m_log.Debug("[REST COMMS]: LocalBackEnd SendCreateObject succeeded");
return true;
@@ -311,7 +311,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
// else do the remote thing
if (!m_localBackend.IsLocalRegion(destination.RegionHandle))
return m_remoteConnector.CreateObject(destination, sog, isLocalCall);
return m_remoteConnector.CreateObject(destination, newPosition, sog, isLocalCall);
return false;
}
@@ -290,7 +290,8 @@ namespace OpenSim.Region.CoreModules.World.Land
ParcelFlags.AllowGroupScripts |
ParcelFlags.CreateGroupObjects |
ParcelFlags.AllowAPrimitiveEntry |
ParcelFlags.AllowGroupObjectEntry);
ParcelFlags.AllowGroupObjectEntry |
ParcelFlags.AllowFly);
}
if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandSetSale))
@@ -677,18 +677,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions
bool permission = false;
bool locked = false;
if (!m_scene.Entities.ContainsKey(objId))
{
return false;
}
SceneObjectPart part = m_scene.GetSceneObjectPart(objId);
// If it's not an object, we cant edit it.
if ((!(m_scene.Entities[objId] is SceneObjectGroup)))
{
if (part == null)
return false;
}
SceneObjectGroup group = (SceneObjectGroup)m_scene.Entities[objId];
SceneObjectGroup group = part.ParentGroup;
UUID objectOwner = group.OwnerID;
locked = ((group.RootPart.OwnerMask & PERM_LOCKED) == 0);
@@ -707,7 +701,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions
// Object owners should be able to edit their own content
if (currentUser == objectOwner)
{
permission = true;
// there is no way that later code can change this back to false
// so just return true immediately and short circuit the more
// expensive group checks
return true;
//permission = true;
}
else if (group.IsAttachment)
{
@@ -972,16 +971,6 @@ namespace OpenSim.Region.CoreModules.World.Permissions
DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name);
if (m_bypassPermissions) return m_bypassPermissionsValue;
SceneObjectPart part = m_scene.GetSceneObjectPart(objectID);
// If we selected a sub-prim to edit, the objectID won't represent the object, but only a part.
// We have to check the permissions of the group, though.
if (part.ParentID != 0)
{
objectID = part.ParentUUID;
part = m_scene.GetSceneObjectPart(objectID);
}
return GenericObjectPermission(editorID, objectID, false);
}
@@ -148,6 +148,113 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
<OtherParts />
</SceneObjectGroup>";
private string badFloatsXml = @"
<SceneObjectGroup>
<RootPart>
<SceneObjectPart xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
<AllowedDrop>false</AllowedDrop>
<CreatorID><Guid>a6dacf01-4636-4bb9-8a97-30609438af9d</Guid></CreatorID>
<FolderID><Guid>e6a5a05e-e8cc-4816-8701-04165e335790</Guid></FolderID>
<InventorySerial>1</InventorySerial>
<TaskInventory />
<ObjectFlags>0</ObjectFlags>
<UUID><Guid>e6a5a05e-e8cc-4816-8701-04165e335790</Guid></UUID>
<LocalId>2698615125</LocalId>
<Name>NaughtyPrim</Name>
<Material>0</Material>
<PassTouches>false</PassTouches>
<RegionHandle>1099511628032000</RegionHandle>
<ScriptAccessPin>0</ScriptAccessPin>
<GroupPosition><X>147.23</X><Y>92.698</Y><Z>22.78084</Z></GroupPosition>
<OffsetPosition><X>0</X><Y>0</Y><Z>0</Z></OffsetPosition>
<RotationOffset><X>-4.371139E-08</X><Y>-1</Y><Z>-4.371139E-08</Z><W>0</W></RotationOffset>
<Velocity><X>0</X><Y>0</Y><Z>0</Z></Velocity>
<RotationalVelocity><X>0</X><Y>0</Y><Z>0</Z></RotationalVelocity>
<AngularVelocity><X>0</X><Y>0</Y><Z>0</Z></AngularVelocity>
<Acceleration><X>0</X><Y>0</Y><Z>0</Z></Acceleration>
<Description />
<Color />
<Text />
<SitName />
<TouchName />
<LinkNum>0</LinkNum>
<ClickAction>0</ClickAction>
<Shape>
<ProfileCurve>1</ProfileCurve>
<TextureEntry>AAAAAAAAERGZmQAAAAAABQCVlZUAAAAAQEAAAABAQAAAAAAAAAAAAAAAAAAAAA==</TextureEntry>
<ExtraParams>AA==</ExtraParams>
<PathBegin>0</PathBegin>
<PathCurve>16</PathCurve>
<PathEnd>0</PathEnd>
<PathRadiusOffset>0</PathRadiusOffset>
<PathRevolutions>0</PathRevolutions>
<PathScaleX>100</PathScaleX>
<PathScaleY>100</PathScaleY>
<PathShearX>0</PathShearX>
<PathShearY>0</PathShearY>
<PathSkew>0</PathSkew>
<PathTaperX>0</PathTaperX>
<PathTaperY>0</PathTaperY>
<PathTwist>0</PathTwist>
<PathTwistBegin>0</PathTwistBegin>
<PCode>9</PCode>
<ProfileBegin>0</ProfileBegin>
<ProfileEnd>0</ProfileEnd>
<ProfileHollow>0</ProfileHollow>
<Scale><X>10</X><Y>10</Y><Z>0.5</Z></Scale>
<State>0</State>
<ProfileShape>Square</ProfileShape>
<HollowShape>Same</HollowShape>
<SculptTexture><Guid>00000000-0000-0000-0000-000000000000</Guid></SculptTexture>
<SculptType>0</SculptType><SculptData />
<FlexiSoftness>0</FlexiSoftness>
<FlexiTension>0,5</FlexiTension>
<FlexiDrag>yo mamma</FlexiDrag>
<FlexiGravity>0</FlexiGravity>
<FlexiWind>0</FlexiWind>
<FlexiForceX>0</FlexiForceX>
<FlexiForceY>0</FlexiForceY>
<FlexiForceZ>0</FlexiForceZ>
<LightColorR>0</LightColorR>
<LightColorG>0</LightColorG>
<LightColorB>0</LightColorB>
<LightColorA>1</LightColorA>
<LightRadius>0</LightRadius>
<LightCutoff>0</LightCutoff>
<LightFalloff>0</LightFalloff>
<LightIntensity>1</LightIntensity>
<FlexiEntry>false</FlexiEntry>
<LightEntry>false</LightEntry>
<SculptEntry>false</SculptEntry>
</Shape>
<Scale><X>10</X><Y>10</Y><Z>0.5</Z></Scale>
<UpdateFlag>0</UpdateFlag>
<SitTargetOrientation><X>0</X><Y>0</Y><Z>0</Z><W>1</W></SitTargetOrientation>
<SitTargetPosition><X>0</X><Y>0</Y><Z>0</Z></SitTargetPosition>
<SitTargetPositionLL><X>0</X><Y>0</Y><Z>0</Z></SitTargetPositionLL>
<SitTargetOrientationLL><X>0</X><Y>0</Y><Z>0</Z><W>1</W></SitTargetOrientationLL>
<ParentID>0</ParentID>
<CreationDate>1211330445</CreationDate>
<Category>0</Category>
<SalePrice>0</SalePrice>
<ObjectSaleType>0</ObjectSaleType>
<OwnershipCost>0</OwnershipCost>
<GroupID><Guid>00000000-0000-0000-0000-000000000000</Guid></GroupID>
<OwnerID><Guid>a6dacf01-4636-4bb9-8a97-30609438af9d</Guid></OwnerID>
<LastOwnerID><Guid>a6dacf01-4636-4bb9-8a97-30609438af9d</Guid></LastOwnerID>
<BaseMask>2147483647</BaseMask>
<OwnerMask>2147483647</OwnerMask>
<GroupMask>0</GroupMask>
<EveryoneMask>0</EveryoneMask>
<NextOwnerMask>2147483647</NextOwnerMask>
<Flags>None</Flags>
<CollisionSound><Guid>00000000-0000-0000-0000-000000000000</Guid></CollisionSound>
<CollisionSoundVolume>0</CollisionSoundVolume>
</SceneObjectPart>
</RootPart>
<OtherParts />
</SceneObjectGroup>";
private string xml2 = @"
<SceneObjectGroup>
<SceneObjectPart xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
@@ -256,6 +363,32 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
// TODO: Check other properties
}
[Test]
public void TestDeserializeBadFloatsXml()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(badFloatsXml);
SceneObjectPart rootPart = so.RootPart;
Assert.That(rootPart.UUID, Is.EqualTo(new UUID("e6a5a05e-e8cc-4816-8701-04165e335790")));
Assert.That(rootPart.CreatorID, Is.EqualTo(new UUID("a6dacf01-4636-4bb9-8a97-30609438af9d")));
Assert.That(rootPart.Name, Is.EqualTo("NaughtyPrim"));
// This terminates the deserialization earlier if couldn't be parsed.
// TODO: Need to address this
Assert.That(rootPart.GroupPosition.X, Is.EqualTo(147.23f));
Assert.That(rootPart.Shape.PathCurve, Is.EqualTo(16));
// Defaults for bad parses
Assert.That(rootPart.Shape.FlexiTension, Is.EqualTo(0));
Assert.That(rootPart.Shape.FlexiDrag, Is.EqualTo(0));
// TODO: Check other properties
}
[Test]
public void TestSerializeXml()
{
@@ -35,6 +35,7 @@ namespace OpenSim.Region.Framework.Interfaces
public interface IAvatarFactoryModule
{
void SetAppearance(IScenePresence sp, AvatarAppearance appearance);
void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams);
/// <summary>
@@ -35,6 +35,8 @@ using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.Framework.Interfaces
{
public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version);
public interface IEntityTransferModule
{
void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position,
@@ -53,7 +55,12 @@ namespace OpenSim.Region.Framework.Interfaces
void EnableChildAgent(ScenePresence agent, GridRegion region);
GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos);
void Cross(SceneObjectGroup sog, Vector3 position, bool silent);
ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version);
}
public interface IUserAgentVerificationModule
@@ -58,7 +58,7 @@ namespace OpenSim.Region.Framework.Interfaces
/// </param>
/// <param name="scene"></param>
/// <param name="appearance">The avatar appearance to use for the new NPC.</param>
/// <returns>The UUID of the ScenePresence created.</returns>
/// <returns>The UUID of the ScenePresence created. UUID.Zero if there was a failure.</returns>
UUID CreateNPC(
string firstname,
string lastname,
@@ -148,7 +148,8 @@ namespace OpenSim.Region.Framework.Scenes
x = m_inventoryDeletes.Dequeue();
m_log.DebugFormat(
"[ASYNC DELETER]: Sending object to user's inventory, action {1}, count {2}, {0} item(s) remaining.", left, x.action, x.objectGroups.Count);
"[ASYNC DELETER]: Sending object to user's inventory, action {1}, count {2}, {0} item(s) remaining.",
left, x.action, x.objectGroups.Count);
try
{
@@ -177,6 +177,9 @@ namespace OpenSim.Region.Framework.Scenes
public delegate void AvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID);
public event AvatarEnteringNewParcel OnAvatarEnteringNewParcel;
public delegate void AvatarAppearanceChange(ScenePresence avatar);
public event AvatarAppearanceChange OnAvatarAppearanceChange;
public event Action<ScenePresence> OnSignificantClientMovement;
public delegate void IncomingInstantMessage(GridInstantMessage message);
@@ -188,10 +191,62 @@ namespace OpenSim.Region.Framework.Scenes
public event ClientClosed OnClientClosed;
// Fired when a script is created
// The indication that a new script exists in this region.
public delegate void NewScript(UUID clientID, SceneObjectPart part, UUID itemID);
public event NewScript OnNewScript;
public virtual void TriggerNewScript(UUID clientID, SceneObjectPart part, UUID itemID)
{
NewScript handlerNewScript = OnNewScript;
if (handlerNewScript != null)
{
foreach (NewScript d in handlerNewScript.GetInvocationList())
{
try
{
d(clientID, part, itemID);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[EVENT MANAGER]: Delegate for TriggerNewScript failed - continuing. {0} {1}",
e.Message, e.StackTrace);
}
}
}
}
//TriggerUpdateScript: triggered after Scene receives client's upload of updated script and stores it as asset
// An indication that the script has changed.
public delegate void UpdateScript(UUID clientID, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID);
public event UpdateScript OnUpdateScript;
public virtual void TriggerUpdateScript(UUID clientId, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID)
{
UpdateScript handlerUpdateScript = OnUpdateScript;
if (handlerUpdateScript != null)
{
foreach (UpdateScript d in handlerUpdateScript.GetInvocationList())
{
try
{
d(clientId, itemId, primId, isScriptRunning, newAssetID);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[EVENT MANAGER]: Delegate for TriggerUpdateScript failed - continuing. {0} {1}",
e.Message, e.StackTrace);
}
}
}
}
/// <summary>
/// This is fired when a scene object property that a script might be interested in (such as color, scale or
/// inventory) changes. Only enough information is sent for the LSL changed event
/// (see http://lslwiki.net/lslwiki/wakka.php?wakka=changed)
/// ScriptChangedEvent is fired when a scene object property that a script might be interested
/// in (such as color, scale or inventory) changes. Only enough information sent is for the LSL changed event.
/// This is not an indication that the script has changed (see OnUpdateScript for that).
/// This event is sent to a script to tell it that some property changed on
/// the object the script is in. See http://lslwiki.net/lslwiki/wakka.php?wakka=changed .
/// </summary>
public event ScriptChangedEvent OnScriptChangedEvent;
public delegate void ScriptChangedEvent(uint localID, uint change);
@@ -1262,6 +1317,27 @@ namespace OpenSim.Region.Framework.Scenes
}
}
public void TriggerAvatarAppearanceChanged(ScenePresence avatar)
{
AvatarAppearanceChange handler = OnAvatarAppearanceChange;
if (handler != null)
{
foreach (AvatarAppearanceChange d in handler.GetInvocationList())
{
try
{
d(avatar);
}
catch (Exception e)
{
m_log.ErrorFormat(
"[EVENT MANAGER]: Delegate for TriggerAvatarAppearanceChanged failed - continuing. {0} {1}",
e.Message, e.StackTrace);
}
}
}
}
public void TriggerIncomingInstantMessage(GridInstantMessage message)
{
IncomingInstantMessage handlerIncomingInstantMessage = OnIncomingInstantMessage;
@@ -0,0 +1,742 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 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.
*/
using System;
using System.Collections.Generic;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Physics.Manager;
using System.Xml;
using OpenSim.Framework.Serialization;
using OpenSim.Framework.Serialization.External;
using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Region.Framework.Scenes.Serialization;
namespace OpenSim.Region.Framework.Scenes
{
public class SOPVehicle
{
public VehicleData vd;
public Vehicle Type
{
get { return vd.m_type; }
}
public SOPVehicle()
{
vd = new VehicleData();
ProcessTypeChange(Vehicle.TYPE_NONE); // is needed?
}
public void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
{
float len;
float timestep = 0.01f;
switch (pParam)
{
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
if (pValue < 0f) pValue = 0f;
if (pValue > 1f) pValue = 1f;
vd.m_angularDeflectionEfficiency = pValue;
break;
case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
if (pValue < timestep) pValue = timestep;
vd.m_angularDeflectionTimescale = pValue;
break;
case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
if (pValue < timestep) pValue = timestep;
else if (pValue > 120) pValue = 120;
vd.m_angularMotorDecayTimescale = pValue;
break;
case Vehicle.ANGULAR_MOTOR_TIMESCALE:
if (pValue < timestep) pValue = timestep;
vd.m_angularMotorTimescale = pValue;
break;
case Vehicle.BANKING_EFFICIENCY:
if (pValue < -1f) pValue = -1f;
if (pValue > 1f) pValue = 1f;
vd.m_bankingEfficiency = pValue;
break;
case Vehicle.BANKING_MIX:
if (pValue < 0f) pValue = 0f;
if (pValue > 1f) pValue = 1f;
vd.m_bankingMix = pValue;
break;
case Vehicle.BANKING_TIMESCALE:
if (pValue < timestep) pValue = timestep;
vd.m_bankingTimescale = pValue;
break;
case Vehicle.BUOYANCY:
if (pValue < -1f) pValue = -1f;
if (pValue > 1f) pValue = 1f;
vd.m_VehicleBuoyancy = pValue;
break;
case Vehicle.HOVER_EFFICIENCY:
if (pValue < 0f) pValue = 0f;
if (pValue > 1f) pValue = 1f;
vd.m_VhoverEfficiency = pValue;
break;
case Vehicle.HOVER_HEIGHT:
vd.m_VhoverHeight = pValue;
break;
case Vehicle.HOVER_TIMESCALE:
if (pValue < timestep) pValue = timestep;
vd.m_VhoverTimescale = pValue;
break;
case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
if (pValue < 0f) pValue = 0f;
if (pValue > 1f) pValue = 1f;
vd.m_linearDeflectionEfficiency = pValue;
break;
case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
if (pValue < timestep) pValue = timestep;
vd.m_linearDeflectionTimescale = pValue;
break;
case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
if (pValue < timestep) pValue = timestep;
else if (pValue > 120) pValue = 120;
vd.m_linearMotorDecayTimescale = pValue;
break;
case Vehicle.LINEAR_MOTOR_TIMESCALE:
if (pValue < timestep) pValue = timestep;
vd.m_linearMotorTimescale = pValue;
break;
case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
if (pValue < 0f) pValue = 0f;
if (pValue > 1f) pValue = 1f;
vd.m_verticalAttractionEfficiency = pValue;
break;
case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
if (pValue < timestep) pValue = timestep;
vd.m_verticalAttractionTimescale = pValue;
break;
// These are vector properties but the engine lets you use a single float value to
// set all of the components to the same value
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
if (pValue < timestep) pValue = timestep;
vd.m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
break;
case Vehicle.ANGULAR_MOTOR_DIRECTION:
vd.m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
len = vd.m_angularMotorDirection.Length();
if (len > 12.566f)
vd.m_angularMotorDirection *= (12.566f / len);
break;
case Vehicle.LINEAR_FRICTION_TIMESCALE:
if (pValue < timestep) pValue = timestep;
vd.m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
break;
case Vehicle.LINEAR_MOTOR_DIRECTION:
vd.m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
len = vd.m_linearMotorDirection.Length();
if (len > 30.0f)
vd.m_linearMotorDirection *= (30.0f / len);
break;
case Vehicle.LINEAR_MOTOR_OFFSET:
vd.m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
len = vd.m_linearMotorOffset.Length();
if (len > 100.0f)
vd.m_linearMotorOffset *= (100.0f / len);
break;
}
}//end ProcessFloatVehicleParam
public void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue)
{
float len;
float timestep = 0.01f;
switch (pParam)
{
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
if (pValue.X < timestep) pValue.X = timestep;
if (pValue.Y < timestep) pValue.Y = timestep;
if (pValue.Z < timestep) pValue.Z = timestep;
vd.m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
break;
case Vehicle.ANGULAR_MOTOR_DIRECTION:
vd.m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
// Limit requested angular speed to 2 rps= 4 pi rads/sec
len = vd.m_angularMotorDirection.Length();
if (len > 12.566f)
vd.m_angularMotorDirection *= (12.566f / len);
break;
case Vehicle.LINEAR_FRICTION_TIMESCALE:
if (pValue.X < timestep) pValue.X = timestep;
if (pValue.Y < timestep) pValue.Y = timestep;
if (pValue.Z < timestep) pValue.Z = timestep;
vd.m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
break;
case Vehicle.LINEAR_MOTOR_DIRECTION:
vd.m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
len = vd.m_linearMotorDirection.Length();
if (len > 30.0f)
vd.m_linearMotorDirection *= (30.0f / len);
break;
case Vehicle.LINEAR_MOTOR_OFFSET:
vd.m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
len = vd.m_linearMotorOffset.Length();
if (len > 100.0f)
vd.m_linearMotorOffset *= (100.0f / len);
break;
}
}//end ProcessVectorVehicleParam
public void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
{
switch (pParam)
{
case Vehicle.REFERENCE_FRAME:
vd.m_referenceFrame = Quaternion.Inverse(pValue);
break;
}
}//end ProcessRotationVehicleParam
public void ProcessVehicleFlags(int pParam, bool remove)
{
if (remove)
{
vd.m_flags &= ~((VehicleFlag)pParam);
}
else
{
vd.m_flags |= (VehicleFlag)pParam;
}
}//end ProcessVehicleFlags
public void ProcessTypeChange(Vehicle pType)
{
vd.m_linearMotorDirection = Vector3.Zero;
vd.m_angularMotorDirection = Vector3.Zero;
vd.m_linearMotorOffset = Vector3.Zero;
vd.m_referenceFrame = Quaternion.Identity;
// Set Defaults For Type
vd.m_type = pType;
switch (pType)
{
case Vehicle.TYPE_NONE:
vd.m_linearFrictionTimescale = new Vector3(1000, 1000, 1000);
vd.m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
vd.m_linearMotorTimescale = 1000;
vd.m_linearMotorDecayTimescale = 120;
vd.m_angularMotorTimescale = 1000;
vd.m_angularMotorDecayTimescale = 1000;
vd.m_VhoverHeight = 0;
vd.m_VhoverEfficiency = 1;
vd.m_VhoverTimescale = 1000;
vd.m_VehicleBuoyancy = 0;
vd.m_linearDeflectionEfficiency = 0;
vd.m_linearDeflectionTimescale = 1000;
vd.m_angularDeflectionEfficiency = 0;
vd.m_angularDeflectionTimescale = 1000;
vd.m_bankingEfficiency = 0;
vd.m_bankingMix = 1;
vd.m_bankingTimescale = 1000;
vd.m_verticalAttractionEfficiency = 0;
vd.m_verticalAttractionTimescale = 1000;
vd.m_flags = (VehicleFlag)0;
break;
case Vehicle.TYPE_SLED:
vd.m_linearFrictionTimescale = new Vector3(30, 1, 1000);
vd.m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
vd.m_linearMotorTimescale = 1000;
vd.m_linearMotorDecayTimescale = 120;
vd.m_angularMotorTimescale = 1000;
vd.m_angularMotorDecayTimescale = 120;
vd.m_VhoverHeight = 0;
vd.m_VhoverEfficiency = 1;
vd.m_VhoverTimescale = 10;
vd.m_VehicleBuoyancy = 0;
vd.m_linearDeflectionEfficiency = 1;
vd.m_linearDeflectionTimescale = 1;
vd.m_angularDeflectionEfficiency = 0;
vd.m_angularDeflectionTimescale = 1000;
vd.m_bankingEfficiency = 0;
vd.m_bankingMix = 1;
vd.m_bankingTimescale = 10;
vd.m_flags &=
~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
vd.m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
break;
case Vehicle.TYPE_CAR:
vd.m_linearFrictionTimescale = new Vector3(100, 2, 1000);
vd.m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
vd.m_linearMotorTimescale = 1;
vd.m_linearMotorDecayTimescale = 60;
vd.m_angularMotorTimescale = 1;
vd.m_angularMotorDecayTimescale = 0.8f;
vd.m_VhoverHeight = 0;
vd.m_VhoverEfficiency = 0;
vd.m_VhoverTimescale = 1000;
vd.m_VehicleBuoyancy = 0;
vd.m_linearDeflectionEfficiency = 1;
vd.m_linearDeflectionTimescale = 2;
vd.m_angularDeflectionEfficiency = 0;
vd.m_angularDeflectionTimescale = 10;
vd.m_verticalAttractionEfficiency = 1f;
vd.m_verticalAttractionTimescale = 10f;
vd.m_bankingEfficiency = -0.2f;
vd.m_bankingMix = 1;
vd.m_bankingTimescale = 1;
vd.m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
vd.m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY |
VehicleFlag.LIMIT_MOTOR_UP | VehicleFlag.HOVER_UP_ONLY);
break;
case Vehicle.TYPE_BOAT:
vd.m_linearFrictionTimescale = new Vector3(10, 3, 2);
vd.m_angularFrictionTimescale = new Vector3(10, 10, 10);
vd.m_linearMotorTimescale = 5;
vd.m_linearMotorDecayTimescale = 60;
vd.m_angularMotorTimescale = 4;
vd.m_angularMotorDecayTimescale = 4;
vd.m_VhoverHeight = 0;
vd.m_VhoverEfficiency = 0.5f;
vd.m_VhoverTimescale = 2;
vd.m_VehicleBuoyancy = 1;
vd.m_linearDeflectionEfficiency = 0.5f;
vd.m_linearDeflectionTimescale = 3;
vd.m_angularDeflectionEfficiency = 0.5f;
vd.m_angularDeflectionTimescale = 5;
vd.m_verticalAttractionEfficiency = 0.5f;
vd.m_verticalAttractionTimescale = 5f;
vd.m_bankingEfficiency = -0.3f;
vd.m_bankingMix = 0.8f;
vd.m_bankingTimescale = 1;
vd.m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
VehicleFlag.HOVER_GLOBAL_HEIGHT |
VehicleFlag.HOVER_UP_ONLY |
VehicleFlag.LIMIT_ROLL_ONLY);
vd.m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
VehicleFlag.LIMIT_MOTOR_UP |
VehicleFlag.HOVER_WATER_ONLY);
break;
case Vehicle.TYPE_AIRPLANE:
vd.m_linearFrictionTimescale = new Vector3(200, 10, 5);
vd.m_angularFrictionTimescale = new Vector3(20, 20, 20);
vd.m_linearMotorTimescale = 2;
vd.m_linearMotorDecayTimescale = 60;
vd.m_angularMotorTimescale = 4;
vd.m_angularMotorDecayTimescale = 8;
vd.m_VhoverHeight = 0;
vd.m_VhoverEfficiency = 0.5f;
vd.m_VhoverTimescale = 1000;
vd.m_VehicleBuoyancy = 0;
vd.m_linearDeflectionEfficiency = 0.5f;
vd.m_linearDeflectionTimescale = 0.5f;
vd.m_angularDeflectionEfficiency = 1;
vd.m_angularDeflectionTimescale = 2;
vd.m_verticalAttractionEfficiency = 0.9f;
vd.m_verticalAttractionTimescale = 2f;
vd.m_bankingEfficiency = 1;
vd.m_bankingMix = 0.7f;
vd.m_bankingTimescale = 2;
vd.m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY |
VehicleFlag.HOVER_TERRAIN_ONLY |
VehicleFlag.HOVER_GLOBAL_HEIGHT |
VehicleFlag.HOVER_UP_ONLY |
VehicleFlag.NO_DEFLECTION_UP |
VehicleFlag.LIMIT_MOTOR_UP);
vd.m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
break;
case Vehicle.TYPE_BALLOON:
vd.m_linearFrictionTimescale = new Vector3(5, 5, 5);
vd.m_angularFrictionTimescale = new Vector3(10, 10, 10);
vd.m_linearMotorTimescale = 5;
vd.m_linearMotorDecayTimescale = 60;
vd.m_angularMotorTimescale = 6;
vd.m_angularMotorDecayTimescale = 10;
vd.m_VhoverHeight = 5;
vd.m_VhoverEfficiency = 0.8f;
vd.m_VhoverTimescale = 10;
vd.m_VehicleBuoyancy = 1;
vd.m_linearDeflectionEfficiency = 0;
vd.m_linearDeflectionTimescale = 5;
vd.m_angularDeflectionEfficiency = 0;
vd.m_angularDeflectionTimescale = 5;
vd.m_verticalAttractionEfficiency = 0f;
vd.m_verticalAttractionTimescale = 1000f;
vd.m_bankingEfficiency = 0;
vd.m_bankingMix = 0.7f;
vd.m_bankingTimescale = 5;
vd.m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY |
VehicleFlag.HOVER_TERRAIN_ONLY |
VehicleFlag.HOVER_UP_ONLY |
VehicleFlag.NO_DEFLECTION_UP |
VehicleFlag.LIMIT_MOTOR_UP);
vd.m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY |
VehicleFlag.HOVER_GLOBAL_HEIGHT);
break;
}
}
public void SetVehicle(PhysicsActor ph)
{
if (ph == null)
return;
ph.SetVehicle(vd);
}
private XmlTextWriter writer;
private void XWint(string name, int i)
{
writer.WriteElementString(name, i.ToString());
}
private void XWfloat(string name, float f)
{
writer.WriteElementString(name, f.ToString(Utils.EnUsCulture));
}
private void XWVector(string name, Vector3 vec)
{
writer.WriteStartElement(name);
writer.WriteElementString("X", vec.X.ToString(Utils.EnUsCulture));
writer.WriteElementString("Y", vec.Y.ToString(Utils.EnUsCulture));
writer.WriteElementString("Z", vec.Z.ToString(Utils.EnUsCulture));
writer.WriteEndElement();
}
private void XWQuat(string name, Quaternion quat)
{
writer.WriteStartElement(name);
writer.WriteElementString("X", quat.X.ToString(Utils.EnUsCulture));
writer.WriteElementString("Y", quat.Y.ToString(Utils.EnUsCulture));
writer.WriteElementString("Z", quat.Z.ToString(Utils.EnUsCulture));
writer.WriteElementString("W", quat.W.ToString(Utils.EnUsCulture));
writer.WriteEndElement();
}
public void ToXml2(XmlTextWriter twriter)
{
writer = twriter;
writer.WriteStartElement("Vehicle");
XWint("TYPE", (int)vd.m_type);
XWint("FLAGS", (int)vd.m_flags);
// Linear properties
XWVector("LMDIR", vd.m_linearMotorDirection);
XWVector("LMFTIME", vd.m_linearFrictionTimescale);
XWfloat("LMDTIME", vd.m_linearMotorDecayTimescale);
XWfloat("LMTIME", vd.m_linearMotorTimescale);
XWVector("LMOFF", vd.m_linearMotorOffset);
//Angular properties
XWVector("AMDIR", vd.m_angularMotorDirection);
XWfloat("AMTIME", vd.m_angularMotorTimescale);
XWfloat("AMDTIME", vd.m_angularMotorDecayTimescale);
XWVector("AMFTIME", vd.m_angularFrictionTimescale);
//Deflection properties
XWfloat("ADEFF", vd.m_angularDeflectionEfficiency);
XWfloat("ADTIME", vd.m_angularDeflectionTimescale);
XWfloat("LDEFF", vd.m_linearDeflectionEfficiency);
XWfloat("LDTIME", vd.m_linearDeflectionTimescale);
//Banking properties
XWfloat("BEFF", vd.m_bankingEfficiency);
XWfloat("BMIX", vd.m_bankingMix);
XWfloat("BTIME", vd.m_bankingTimescale);
//Hover and Buoyancy properties
XWfloat("HHEI", vd.m_VhoverHeight);
XWfloat("HEFF", vd.m_VhoverEfficiency);
XWfloat("HTIME", vd.m_VhoverTimescale);
XWfloat("VBUO", vd.m_VehicleBuoyancy);
//Attractor properties
XWfloat("VAEFF", vd.m_verticalAttractionEfficiency);
XWfloat("VATIME", vd.m_verticalAttractionTimescale);
XWQuat("REF_FRAME", vd.m_referenceFrame);
writer.WriteEndElement();
writer = null;
}
XmlTextReader reader;
private int XRint()
{
return reader.ReadElementContentAsInt();
}
private float XRfloat()
{
return reader.ReadElementContentAsFloat();
}
public Vector3 XRvector()
{
Vector3 vec;
reader.ReadStartElement();
vec.X = reader.ReadElementContentAsFloat();
vec.Y = reader.ReadElementContentAsFloat();
vec.Z = reader.ReadElementContentAsFloat();
reader.ReadEndElement();
return vec;
}
public Quaternion XRquat()
{
Quaternion q;
reader.ReadStartElement();
q.X = reader.ReadElementContentAsFloat();
q.Y = reader.ReadElementContentAsFloat();
q.Z = reader.ReadElementContentAsFloat();
q.W = reader.ReadElementContentAsFloat();
reader.ReadEndElement();
return q;
}
public static bool EReadProcessors(
Dictionary<string, Action> processors,
XmlTextReader xtr)
{
bool errors = false;
string nodeName = string.Empty;
while (xtr.NodeType != XmlNodeType.EndElement)
{
nodeName = xtr.Name;
// m_log.DebugFormat("[ExternalRepresentationUtils]: Processing: {0}", nodeName);
Action p = null;
if (processors.TryGetValue(xtr.Name, out p))
{
// m_log.DebugFormat("[ExternalRepresentationUtils]: Found {0} processor, nodeName);
try
{
p();
}
catch (Exception e)
{
errors = true;
if (xtr.NodeType == XmlNodeType.EndElement)
xtr.Read();
}
}
else
{
// m_log.DebugFormat("[LandDataSerializer]: caught unknown element {0}", nodeName);
xtr.ReadOuterXml(); // ignore
}
}
return errors;
}
public void FromXml2(XmlTextReader _reader, out bool errors)
{
errors = false;
reader = _reader;
Dictionary<string, Action> m_VehicleXmlProcessors
= new Dictionary<string, Action>();
m_VehicleXmlProcessors.Add("TYPE", ProcessXR_type);
m_VehicleXmlProcessors.Add("FLAGS", ProcessXR_flags);
// Linear properties
m_VehicleXmlProcessors.Add("LMDIR", ProcessXR_linearMotorDirection);
m_VehicleXmlProcessors.Add("LMFTIME", ProcessXR_linearFrictionTimescale);
m_VehicleXmlProcessors.Add("LMDTIME", ProcessXR_linearMotorDecayTimescale);
m_VehicleXmlProcessors.Add("LMTIME", ProcessXR_linearMotorTimescale);
m_VehicleXmlProcessors.Add("LMOFF", ProcessXR_linearMotorOffset);
//Angular properties
m_VehicleXmlProcessors.Add("AMDIR", ProcessXR_angularMotorDirection);
m_VehicleXmlProcessors.Add("AMTIME", ProcessXR_angularMotorTimescale);
m_VehicleXmlProcessors.Add("AMDTIME", ProcessXR_angularMotorDecayTimescale);
m_VehicleXmlProcessors.Add("AMFTIME", ProcessXR_angularFrictionTimescale);
//Deflection properties
m_VehicleXmlProcessors.Add("ADEFF", ProcessXR_angularDeflectionEfficiency);
m_VehicleXmlProcessors.Add("ADTIME", ProcessXR_angularDeflectionTimescale);
m_VehicleXmlProcessors.Add("LDEFF", ProcessXR_linearDeflectionEfficiency);
m_VehicleXmlProcessors.Add("LDTIME", ProcessXR_linearDeflectionTimescale);
//Banking properties
m_VehicleXmlProcessors.Add("BEFF", ProcessXR_bankingEfficiency);
m_VehicleXmlProcessors.Add("BMIX", ProcessXR_bankingMix);
m_VehicleXmlProcessors.Add("BTIME", ProcessXR_bankingTimescale);
//Hover and Buoyancy properties
m_VehicleXmlProcessors.Add("HHEI", ProcessXR_VhoverHeight);
m_VehicleXmlProcessors.Add("HEFF", ProcessXR_VhoverEfficiency);
m_VehicleXmlProcessors.Add("HTIME", ProcessXR_VhoverTimescale);
m_VehicleXmlProcessors.Add("VBUO", ProcessXR_VehicleBuoyancy);
//Attractor properties
m_VehicleXmlProcessors.Add("VAEFF", ProcessXR_verticalAttractionEfficiency);
m_VehicleXmlProcessors.Add("VATIME", ProcessXR_verticalAttractionTimescale);
m_VehicleXmlProcessors.Add("REF_FRAME", ProcessXR_referenceFrame);
vd = new VehicleData();
reader.ReadStartElement("Vehicle", String.Empty);
errors = EReadProcessors(
m_VehicleXmlProcessors,
reader);
reader.ReadEndElement();
reader = null;
}
private void ProcessXR_type()
{
vd.m_type = (Vehicle)XRint();
}
private void ProcessXR_flags()
{
vd.m_flags = (VehicleFlag)XRint();
}
// Linear properties
private void ProcessXR_linearMotorDirection()
{
vd.m_linearMotorDirection = XRvector();
}
private void ProcessXR_linearFrictionTimescale()
{
vd.m_linearFrictionTimescale = XRvector();
}
private void ProcessXR_linearMotorDecayTimescale()
{
vd.m_linearMotorDecayTimescale = XRfloat();
}
private void ProcessXR_linearMotorTimescale()
{
vd.m_linearMotorTimescale = XRfloat();
}
private void ProcessXR_linearMotorOffset()
{
vd.m_linearMotorOffset = XRvector();
}
//Angular properties
private void ProcessXR_angularMotorDirection()
{
vd.m_angularMotorDirection = XRvector();
}
private void ProcessXR_angularMotorTimescale()
{
vd.m_angularMotorTimescale = XRfloat();
}
private void ProcessXR_angularMotorDecayTimescale()
{
vd.m_angularMotorDecayTimescale = XRfloat();
}
private void ProcessXR_angularFrictionTimescale()
{
vd.m_angularFrictionTimescale = XRvector();
}
//Deflection properties
private void ProcessXR_angularDeflectionEfficiency()
{
vd.m_angularDeflectionEfficiency = XRfloat();
}
private void ProcessXR_angularDeflectionTimescale()
{
vd.m_angularDeflectionTimescale = XRfloat();
}
private void ProcessXR_linearDeflectionEfficiency()
{
vd.m_linearDeflectionEfficiency = XRfloat();
}
private void ProcessXR_linearDeflectionTimescale()
{
vd.m_linearDeflectionTimescale = XRfloat();
}
//Banking properties
private void ProcessXR_bankingEfficiency()
{
vd.m_bankingEfficiency = XRfloat();
}
private void ProcessXR_bankingMix()
{
vd.m_bankingMix = XRfloat();
}
private void ProcessXR_bankingTimescale()
{
vd.m_bankingTimescale = XRfloat();
}
//Hover and Buoyancy properties
private void ProcessXR_VhoverHeight()
{
vd.m_VhoverHeight = XRfloat();
}
private void ProcessXR_VhoverEfficiency()
{
vd.m_VhoverEfficiency = XRfloat();
}
private void ProcessXR_VhoverTimescale()
{
vd.m_VhoverTimescale = XRfloat();
}
private void ProcessXR_VehicleBuoyancy()
{
vd.m_VehicleBuoyancy = XRfloat();
}
//Attractor properties
private void ProcessXR_verticalAttractionEfficiency()
{
vd.m_verticalAttractionEfficiency = XRfloat();
}
private void ProcessXR_verticalAttractionTimescale()
{
vd.m_verticalAttractionTimescale = XRfloat();
}
private void ProcessXR_referenceFrame()
{
vd.m_referenceFrame = XRquat();
}
}
}
@@ -265,6 +265,10 @@ namespace OpenSim.Region.Framework.Scenes
//
errors = part.Inventory.CreateScriptInstanceEr(item.ItemID, 0, false, DefaultScriptEngine, 0);
}
// Tell anyone managing scripts that a script has been reloaded/changed
EventManager.TriggerUpdateScript(remoteClient.AgentId, itemId, primId, isScriptRunning, item.AssetID);
part.ParentGroup.ResumeScripts();
return errors;
}
@@ -330,6 +334,12 @@ namespace OpenSim.Region.Framework.Scenes
item.Flags = (item.Flags & ~(uint)255) | (itemUpd.Flags & (uint)255);
item.Name = itemUpd.Name;
item.Description = itemUpd.Description;
// m_log.DebugFormat(
// "[USER INVENTORY]: itemUpd {0} {1} {2} {3}, item {4} {5} {6} {7}",
// itemUpd.NextPermissions, itemUpd.GroupPermissions, itemUpd.EveryOnePermissions, item.Flags,
// item.NextPermissions, item.GroupPermissions, item.EveryOnePermissions, item.CurrentPermissions);
if (item.NextPermissions != (itemUpd.NextPermissions & item.BasePermissions))
item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner;
item.NextPermissions = itemUpd.NextPermissions & item.BasePermissions;
@@ -338,6 +348,9 @@ namespace OpenSim.Region.Framework.Scenes
item.EveryOnePermissions = itemUpd.EveryOnePermissions & item.BasePermissions;
if (item.GroupPermissions != (itemUpd.GroupPermissions & item.BasePermissions))
item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteGroup;
// m_log.DebugFormat("[USER INVENTORY]: item.Flags {0}", item.Flags);
item.GroupPermissions = itemUpd.GroupPermissions & item.BasePermissions;
item.GroupID = itemUpd.GroupID;
item.GroupOwned = itemUpd.GroupOwned;
@@ -1149,8 +1162,7 @@ namespace OpenSim.Region.Framework.Scenes
return;
}
TaskInventoryItem item = part.Inventory.GetInventoryItem(itemId);
if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
if ((taskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
{
// If the item to be moved is no copy, we need to be able to
// edit the prim.
@@ -1634,9 +1646,13 @@ namespace OpenSim.Region.Framework.Scenes
// have state in inventory
part.Inventory.CreateScriptInstance(copyID, 0, false, DefaultScriptEngine, 0);
// tell anyone watching that there is a new script in town
EventManager.TriggerNewScript(agentID, part, copyID);
// m_log.InfoFormat("[PRIMINVENTORY]: " +
// "Rezzed script {0} into prim local ID {1} for user {2}",
// item.inventoryName, localID, remoteClient.Name);
part.ParentGroup.ResumeScripts();
return part;
@@ -1717,6 +1733,10 @@ namespace OpenSim.Region.Framework.Scenes
part.Inventory.AddInventoryItem(taskItem, false);
part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0);
// tell anyone managing scripts that a new script exists
EventManager.TriggerNewScript(agentID, part, taskItem.ItemID);
part.ParentGroup.ResumeScripts();
return part;
@@ -1945,7 +1965,7 @@ namespace OpenSim.Region.Framework.Scenes
permissionToTake = true;
permissionToDelete = true;
AddReturn(grp.OwnerID, grp.Name, grp.AbsolutePosition, "parcel owner return");
AddReturn(grp.OwnerID == grp.GroupID ? grp.LastOwnerID : grp.OwnerID, grp.Name, grp.AbsolutePosition, "parcel owner return");
}
}
else // Auto return passes through here with null agent
@@ -2310,7 +2330,24 @@ namespace OpenSim.Region.Framework.Scenes
m_sceneGraph.DelinkObjects(parts);
}
/// <summary>
/// Link the scene objects containing the indicated parts to a root object.
/// </summary>
/// <param name="client"></param>
/// <param name="parentPrimId">A root prim id of the object which will be the root prim of the resulting linkset.</param>
/// <param name="childPrimIds">A list of child prims for the objects that should be linked in.</param>
public void LinkObjects(IClientAPI client, uint parentPrimId, List<uint> childPrimIds)
{
LinkObjects(client.AgentId, parentPrimId, childPrimIds);
}
/// <summary>
/// Link the scene objects containing the indicated parts to a root object.
/// </summary>
/// <param name="agentId">The ID of the user linking.</param>
/// <param name="parentPrimId">A root prim id of the object which will be the root prim of the resulting linkset.</param>
/// <param name="childPrimIds">A list of child prims for the objects that should be linked in.</param>
public void LinkObjects(UUID agentId, uint parentPrimId, List<uint> childPrimIds)
{
List<UUID> owners = new List<UUID>();
@@ -2323,7 +2360,7 @@ namespace OpenSim.Region.Framework.Scenes
return;
}
if (!Permissions.CanLinkObject(client.AgentId, root.ParentGroup.RootPart.UUID))
if (!Permissions.CanLinkObject(agentId, root.ParentGroup.RootPart.UUID))
{
m_log.DebugFormat("[LINK]: Refusing link. No permissions on root prim");
return;
@@ -2339,7 +2376,7 @@ namespace OpenSim.Region.Framework.Scenes
if (!owners.Contains(part.OwnerID))
owners.Add(part.OwnerID);
if (Permissions.CanLinkObject(client.AgentId, part.ParentGroup.RootPart.UUID))
if (Permissions.CanLinkObject(agentId, part.ParentGroup.RootPart.UUID))
children.Add(part);
}
+52 -30
View File
@@ -890,16 +890,16 @@ namespace OpenSim.Region.Framework.Scenes
try
{
ForEachRootScenePresence(delegate(ScenePresence agent)
{
//agent.ControllingClient.new
//this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo());
{
//agent.ControllingClient.new
//this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo());
List<ulong> old = new List<ulong>();
old.Add(otherRegion.RegionHandle);
agent.DropOldNeighbours(old);
if (m_teleportModule != null)
m_teleportModule.EnableChildAgent(agent, otherRegion);
});
List<ulong> old = new List<ulong>();
old.Add(otherRegion.RegionHandle);
agent.DropOldNeighbours(old);
if (m_teleportModule != null && agent.PresenceType != PresenceType.Npc)
m_teleportModule.EnableChildAgent(agent, otherRegion);
});
}
catch (NullReferenceException)
{
@@ -907,7 +907,6 @@ namespace OpenSim.Region.Framework.Scenes
// This shouldn't happen too often anymore.
m_log.Error("[SCENE]: Couldn't inform client of regionup because we got a null reference exception");
}
}
else
{
@@ -1035,10 +1034,10 @@ namespace OpenSim.Region.Framework.Scenes
try
{
ForEachRootScenePresence(delegate(ScenePresence agent)
{
if (m_teleportModule != null)
m_teleportModule.EnableChildAgent(agent, r);
});
{
if (m_teleportModule != null && agent.PresenceType != PresenceType.Npc)
m_teleportModule.EnableChildAgent(agent, r);
});
}
catch (NullReferenceException)
{
@@ -2404,7 +2403,7 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
/// <param name="sog"></param>
/// <returns></returns>
public bool IncomingCreateObject(ISceneObject sog)
public bool IncomingCreateObject(Vector3 newPosition, ISceneObject sog)
{
//m_log.DebugFormat(" >>> IncomingCreateObject(sog) <<< {0} deleted? {1} isAttach? {2}", ((SceneObjectGroup)sog).AbsolutePosition,
// ((SceneObjectGroup)sog).IsDeleted, ((SceneObjectGroup)sog).RootPart.IsAttachment);
@@ -2420,6 +2419,9 @@ namespace OpenSim.Region.Framework.Scenes
return false;
}
if (newPosition != Vector3.Zero)
newObject.RootPart.GroupPosition = newPosition;
if (!AddSceneObject(newObject))
{
m_log.DebugFormat("[SCENE]: Problem adding scene object {0} in {1} ", sog.UUID, RegionInfo.RegionName);
@@ -3395,8 +3397,11 @@ namespace OpenSim.Region.Framework.Scenes
/// also return a reason.</returns>
public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason, bool requirePresenceLookup)
{
bool vialogin = ((teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0 ||
(teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0);
bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 ||
(teleportFlags & (uint)TPFlags.ViaHGLogin) != 0);
bool viahome = ((teleportFlags & (uint)TPFlags.ViaHome) != 0);
bool godlike = ((teleportFlags & (uint)TPFlags.Godlike) != 0);
reason = String.Empty;
//Teleport flags:
@@ -3408,9 +3413,9 @@ namespace OpenSim.Region.Framework.Scenes
// Don't disable this log message - it's too helpful
m_log.DebugFormat(
"[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, teleportflags {6}, position {7})",
RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
agent.AgentID, agent.circuitcode, teleportFlags, agent.startpos);
"[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags ({8}), position {9})",
RegionInfo.RegionName, (agent.child ? "child" : "root"),agent.firstname, agent.lastname,
agent.AgentID, agent.circuitcode, agent.IPAddress, agent.Viewer, ((TPFlags)teleportFlags).ToString(), agent.startpos);
if (LoginsDisabled)
{
@@ -3571,6 +3576,29 @@ namespace OpenSim.Region.Framework.Scenes
agent.startpos.Z = 720;
}
}
// Honor Estate teleport routing via Telehubs excluding ViaHome and GodLike TeleportFlags
if (RegionInfo.RegionSettings.TelehubObject != UUID.Zero &&
RegionInfo.EstateSettings.AllowDirectTeleport == false &&
!viahome && !godlike)
{
SceneObjectGroup telehub = GetSceneObjectGroup(RegionInfo.RegionSettings.TelehubObject);
// Can have multiple SpawnPoints
List<SpawnPoint> spawnpoints = RegionInfo.RegionSettings.SpawnPoints();
if ( spawnpoints.Count > 1)
{
// We have multiple SpawnPoints, Route the agent to a random one
agent.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count)].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
}
else
{
// We have a single SpawnPoint and will route the agent to it
agent.startpos = spawnpoints[0].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
}
return true;
}
// Honor parcel landing type and position.
/*
ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
@@ -4406,10 +4434,7 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="action"></param>
public void ForEachRootScenePresence(Action<ScenePresence> action)
{
if (m_sceneGraph != null)
{
m_sceneGraph.ForEachAvatar(action);
}
m_sceneGraph.ForEachAvatar(action);
}
/// <summary>
@@ -4418,10 +4443,7 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="action"></param>
public void ForEachScenePresence(Action<ScenePresence> action)
{
if (m_sceneGraph != null)
{
m_sceneGraph.ForEachScenePresence(action);
}
m_sceneGraph.ForEachScenePresence(action);
}
/// <summary>
@@ -4766,7 +4788,7 @@ Environment.Exit(1);
bool wasUsingPhysics = ((jointProxyObject.Flags & PrimFlags.Physics) != 0);
if (wasUsingPhysics)
{
jointProxyObject.UpdatePrimFlags(false, false, true, false); // FIXME: possible deadlock here; check to make sure all the scene alterations set into motion here won't deadlock
jointProxyObject.UpdatePrimFlags(false, false, true, false,false); // FIXME: possible deadlock here; check to make sure all the scene alterations set into motion here won't deadlock
}
}
@@ -5450,7 +5472,7 @@ Environment.Exit(1);
// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget);
Vector3 agent_control_v3 = new Vector3();
presence.HandleMoveToTargetUpdate(ref agent_control_v3);
presence.HandleMoveToTargetUpdate(1, ref agent_control_v3);
presence.AddNewMovement(agent_control_v3);
}
}
@@ -156,16 +156,20 @@ namespace OpenSim.Region.Framework.Scenes
// that the region position is cached or performance will degrade
Utils.LongToUInts(regionHandle, out x, out y);
GridRegion dest = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y);
bool v = true;
if (! simulatorList.Contains(dest.ServerURI))
{
// we havent seen this simulator before, add it to the list
// and send it an update
simulatorList.Add(dest.ServerURI);
// Let move this to sync. Mono definitely does not like async networking.
m_scene.SimulationService.UpdateAgent(dest, cAgentData);
SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync;
d.BeginInvoke(cAgentData, m_regionInfo.ScopeID, dest,
SendChildAgentDataUpdateCompleted,
d);
// Leaving this here as a reminder that we tried, and it sucks.
//SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync;
//d.BeginInvoke(cAgentData, m_regionInfo.ScopeID, dest,
// SendChildAgentDataUpdateCompleted,
// d);
}
}
}
+18 -9
View File
@@ -406,7 +406,7 @@ namespace OpenSim.Region.Framework.Scenes
m_log.ErrorFormat(
"[SCENEGRAPH]: Tried to add scene object {0} to {1} with illegal UUID of {2}",
sceneObject.Name, m_parentScene.RegionInfo.RegionName, UUID.Zero);
return false;
}
@@ -415,12 +415,12 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.DebugFormat(
// "[SCENEGRAPH]: Scene graph for {0} already contains object {1} in AddSceneObject()",
// m_parentScene.RegionInfo.RegionName, sceneObject.UUID);
return false;
}
// m_log.DebugFormat(
// "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}",
// "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}",
// sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName);
SceneObjectPart[] parts = sceneObject.Parts;
@@ -456,7 +456,7 @@ namespace OpenSim.Region.Framework.Scenes
lock (SceneObjectGroupsByFullID)
SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
lock (SceneObjectGroupsByFullPartID)
{
foreach (SceneObjectPart part in parts)
@@ -1678,7 +1678,7 @@ namespace OpenSim.Region.Framework.Scenes
if (group != null)
{
if (m_parentScene.Permissions.CanEditObject(group.UUID,agentID))
if (m_parentScene.Permissions.CanEditObject(group.UUID, agentID))
{
group.UpdateExtraParam(primLocalID, type, inUse, data);
}
@@ -1695,7 +1695,7 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectGroup group = GetGroupByPrim(primLocalID);
if (group != null)
{
if (m_parentScene.Permissions.CanEditObject(group.GetPartsFullID(primLocalID), agentID))
if (m_parentScene.Permissions.CanEditObject(group.UUID, agentID))
{
ObjectShapePacket.ObjectDataBlock shapeData = new ObjectShapePacket.ObjectDataBlock();
shapeData.ObjectLocalID = shapeBlock.ObjectLocalID;
@@ -1751,6 +1751,10 @@ namespace OpenSim.Region.Framework.Scenes
{
SceneObjectGroup child = children[i].ParentGroup;
// Don't try and add a group to itself - this will only cause severe problems later on.
if (child == parentGroup)
continue;
// Make sure no child prim is set for sale
// So that, on delink, no prims are unwittingly
// left for sale and sold off
@@ -1777,8 +1781,13 @@ namespace OpenSim.Region.Framework.Scenes
// We need to explicitly resend the newly link prim's object properties since no other actions
// occur on link to invoke this elsewhere (such as object selection)
parentGroup.RootPart.CreateSelected = true;
parentGroup.TriggerScriptChangedEvent(Changed.LINK);
if (childGroups.Count > 0)
{
parentGroup.RootPart.CreateSelected = true;
parentGroup.TriggerScriptChangedEvent(Changed.LINK);
parentGroup.HasGroupChanged = true;
parentGroup.ScheduleGroupForFullUpdate();
}
}
finally
{
@@ -269,6 +269,8 @@ namespace OpenSim.Region.Framework.Scenes
public void ApplyNextOwnerPermissions()
{
// m_log.DebugFormat("[PRIM INVENTORY]: Applying next owner permissions to {0} {1}", Name, UUID);
SceneObjectPart[] parts = m_parts.GetArray();
for (int i = 0; i < parts.Length; i++)
parts[i].ApplyNextOwnerPermissions();
@@ -43,6 +43,7 @@ using OpenSim.Region.Framework.Scenes.Serialization;
namespace OpenSim.Region.Framework.Scenes
{
[Flags]
public enum scriptEvents
{
@@ -461,11 +462,91 @@ namespace OpenSim.Region.Framework.Scenes
if (Scene != null)
{
if ((Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) || Scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W)
|| Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S))
// if ((Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) || Scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W)
// || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S))
// && !IsAttachmentCheckFull() && (!Scene.LoadingPrims))
if ((Scene.TestBorderCross(val, Cardinals.E) || Scene.TestBorderCross(val, Cardinals.W)
|| Scene.TestBorderCross(val, Cardinals.N) || Scene.TestBorderCross(val, Cardinals.S))
&& !IsAttachmentCheckFull() && (!Scene.LoadingPrims))
{
m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
uint x = 0;
uint y = 0;
string version = String.Empty;
Vector3 newpos = Vector3.Zero;
OpenSim.Services.Interfaces.GridRegion destination = null;
bool canCross = true;
foreach (ScenePresence av in m_linkedAvatars)
{
// We need to cross these agents. First, let's find
// out if any of them can't cross for some reason.
// We have to deny the crossing entirely if any
// of them are banned. Alternatively, we could
// unsit banned agents....
// We set the avatar position as being the object
// position to get the region to send to
if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out x, out y, out version, out newpos)) == null)
{
canCross = false;
break;
}
m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName);
}
if (canCross)
{
// We unparent the SP quietly so that it won't
// be made to stand up
foreach (ScenePresence av in m_linkedAvatars)
{
SceneObjectPart parentPart = m_scene.GetSceneObjectPart(av.ParentID);
if (parentPart != null)
av.ParentUUID = parentPart.UUID;
av.ParentID = 0;
}
m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
// Normalize
if (val.X >= Constants.RegionSize)
val.X -= Constants.RegionSize;
if (val.Y >= Constants.RegionSize)
val.Y -= Constants.RegionSize;
if (val.X < 0)
val.X += Constants.RegionSize;
if (val.Y < 0)
val.Y += Constants.RegionSize;
// If it's deleted, crossing was successful
if (IsDeleted)
{
foreach (ScenePresence av in m_linkedAvatars)
{
m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val);
av.IsInTransit = true;
CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync;
d.BeginInvoke(av, val, x, y, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d);
}
return;
}
}
else if (RootPart.PhysActor != null)
{
RootPart.PhysActor.CrossingFailure();
}
Vector3 oldp = AbsolutePosition;
val.X = Util.Clamp<float>(oldp.X, 0.5f, (float)Constants.RegionSize - 0.5f);
val.Y = Util.Clamp<float>(oldp.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
val.Z = Util.Clamp<float>(oldp.Z, 0.5f, 4096.0f);
}
}
@@ -501,7 +582,7 @@ namespace OpenSim.Region.Framework.Scenes
foreach (ScenePresence av in m_linkedAvatars)
{
SceneObjectPart p = m_scene.GetSceneObjectPart(av.ParentID);
if (m_parts.TryGetValue(p.UUID, out p))
if (p != null && m_parts.TryGetValue(p.UUID, out p))
{
Vector3 offset = p.GetWorldPosition() - av.ParentPosition;
av.AbsolutePosition += offset;
@@ -524,6 +605,29 @@ namespace OpenSim.Region.Framework.Scenes
}
}
public override Vector3 Velocity
{
get { return RootPart.Velocity; }
set { RootPart.Velocity = value; }
}
private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
{
CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState;
ScenePresence agent = icon.EndInvoke(iar);
//// If the cross was successful, this agent is a child agent
//if (agent.IsChildAgent)
// agent.Reset();
//else // Not successful
// agent.RestoreInCurrentScene();
// In any case
agent.IsInTransit = false;
m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname);
}
public override uint LocalId
{
get { return m_rootPart.LocalId; }
@@ -1281,7 +1385,8 @@ namespace OpenSim.Region.Framework.Scenes
m_rootPart.SetParentLocalId(0);
AttachmentPoint = (byte)0;
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive);
// must check if buildind should be true or false here
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive,false);
HasGroupChanged = true;
RootPart.Rezzed = DateTime.Now;
RootPart.RemFlag(PrimFlags.TemporaryOnRez);
@@ -1580,22 +1685,32 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
public void ApplyPhysics()
{
// Apply physics to the root prim
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive);
// Apply physics to child prims
SceneObjectPart[] parts = m_parts.GetArray();
if (parts.Length > 1)
{
ResetChildPrimPhysicsPositions();
// Apply physics to the root prim
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, true);
for (int i = 0; i < parts.Length; i++)
{
SceneObjectPart part = parts[i];
if (part.LocalId != m_rootPart.LocalId)
part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive);
part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, true);
}
// Hack to get the physics scene geometries in the right spot
ResetChildPrimPhysicsPositions();
// ResetChildPrimPhysicsPositions();
if (m_rootPart.PhysActor != null)
{
m_rootPart.PhysActor.Building = false;
}
}
else
{
// Apply physics to the root prim
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, false);
}
}
@@ -1667,7 +1782,7 @@ namespace OpenSim.Region.Framework.Scenes
m_log.DebugFormat(
"[SCENE OBJECT GROUP]: Returning object {0} due to parcel autoreturn",
RootPart.UUID);
m_scene.AddReturn(OwnerID, Name, AbsolutePosition, "parcel autoreturn");
m_scene.AddReturn(OwnerID == GroupID ? LastOwnerID : OwnerID, Name, AbsolutePosition, "parcel autoreturn");
m_scene.DeRezObjects(null, new List<uint>() { RootPart.LocalId }, UUID.Zero,
DeRezAction.Return, UUID.Zero);
@@ -1766,6 +1881,7 @@ namespace OpenSim.Region.Framework.Scenes
/// <returns></returns>
public SceneObjectGroup Copy(bool userExposed)
{
m_dupeInProgress = true;
SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone();
dupe.m_isBackedUp = false;
dupe.m_parts = new MapAndArray<OpenMetaverse.UUID, SceneObjectPart>();
@@ -1829,13 +1945,16 @@ namespace OpenSim.Region.Framework.Scenes
pbs,
newPart.AbsolutePosition,
newPart.Scale,
newPart.RotationOffset,
//newPart.RotationOffset,
newPart.GetWorldRotation(),
part.PhysActor.IsPhysical,
newPart.LocalId);
newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true);
}
}
if (dupe.m_rootPart.PhysActor != null && userExposed)
dupe.m_rootPart.PhysActor.Building = false; // tell physics to finish building
if (userExposed)
{
@@ -1846,6 +1965,7 @@ namespace OpenSim.Region.Framework.Scenes
ScheduleGroupForFullUpdate();
}
m_dupeInProgress = false;
return dupe;
}
@@ -2361,6 +2481,10 @@ namespace OpenSim.Region.Framework.Scenes
// "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}",
// objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID);
// Linking to ourselves is not a valid operation.
if (objectGroup == this)
return;
SceneObjectPart linkPart = objectGroup.m_rootPart;
Vector3 oldGroupPosition = linkPart.GroupPosition;
@@ -2849,12 +2973,31 @@ namespace OpenSim.Region.Framework.Scenes
}
}
/*
RootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect);
for (int i = 0; i < parts.Length; i++)
{
if (parts[i] != RootPart)
parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect);
}
*/
if (parts.Length > 1)
{
m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
for (int i = 0; i < parts.Length; i++)
{
if (parts[i].UUID != m_rootPart.UUID)
parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
}
if (m_rootPart.PhysActor != null)
m_rootPart.PhysActor.Building = false;
}
else
m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, false);
}
}
@@ -310,10 +310,16 @@ namespace OpenSim.Region.Framework.Scenes
private UUID m_collisionSound;
private float m_collisionSoundVolume;
private SOPVehicle m_vehicle = null;
#endregion Fields
// ~SceneObjectPart()
// {
// Console.WriteLine(
// "[SCENE OBJECT PART]: Destructor called for {0}, local id {1}, parent {2} {3}",
// Name, LocalId, ParentGroup.Name, ParentGroup.LocalId);
// m_log.DebugFormat(
// "[SCENE OBJECT PART]: Destructor called for {0}, local id {1}, parent {2} {3}",
// Name, LocalId, ParentGroup.Name, ParentGroup.LocalId);
@@ -1503,7 +1509,8 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
/// <param name="rootObjectFlags"></param>
/// <param name="VolumeDetectActive"></param>
public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive)
// public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive)
public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive, bool building)
{
if (!ParentGroup.Scene.CollidablePrims)
return;
@@ -1532,6 +1539,8 @@ namespace OpenSim.Region.Framework.Scenes
// or flexible
if (!isPhantom && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible))
{
Vector3 velocity = Velocity;
Vector3 rotationalVelocity = AngularVelocity;
try
{
PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape(
@@ -1539,7 +1548,8 @@ namespace OpenSim.Region.Framework.Scenes
Shape,
AbsolutePosition,
Scale,
RotationOffset,
// RotationOffset,
GetWorldRotation(), // physics wants world rotation
RigidBody,
m_localId);
}
@@ -1554,8 +1564,21 @@ namespace OpenSim.Region.Framework.Scenes
{
PhysActor.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
PhysActor.SetMaterial(Material);
// if root part apply vehicle
if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
m_vehicle.SetVehicle(PhysActor);
DoPhysicsPropertyUpdate(RigidBody, true);
PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
Velocity = velocity;
AngularVelocity = rotationalVelocity;
PhysActor.Velocity = velocity;
PhysActor.RotationalVelocity = rotationalVelocity;
if (!building)
PhysActor.Building = false;
}
}
}
@@ -1601,9 +1624,9 @@ namespace OpenSim.Region.Framework.Scenes
dupe.GroupPosition = GroupPosition;
dupe.OffsetPosition = OffsetPosition;
dupe.RotationOffset = RotationOffset;
dupe.Velocity = new Vector3(0, 0, 0);
dupe.Acceleration = new Vector3(0, 0, 0);
dupe.AngularVelocity = new Vector3(0, 0, 0);
dupe.Velocity = Velocity;
dupe.Acceleration = Acceleration;
dupe.AngularVelocity = AngularVelocity;
dupe.Flags = Flags;
dupe.OwnershipCost = OwnershipCost;
@@ -1791,6 +1814,10 @@ namespace OpenSim.Region.Framework.Scenes
if (!isNew)
ParentGroup.Scene.RemovePhysicalPrim(1);
Velocity = new Vector3(0, 0, 0);
Acceleration = new Vector3(0, 0, 0);
AngularVelocity = new Vector3(0, 0, 0);
PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
PhysActor.OnOutOfBounds -= PhysicsOutOfBounds;
PhysActor.delink();
@@ -2612,9 +2639,9 @@ namespace OpenSim.Region.Framework.Scenes
Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0);
if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
| ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
| ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
| ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
|| ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
|| ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
|| ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
{
ParentGroup.AbsolutePosition = newpos;
return;
@@ -3160,17 +3187,74 @@ namespace OpenSim.Region.Framework.Scenes
}
}
public SOPVehicle sopVehicle
{
get
{
return m_vehicle;
}
set
{
m_vehicle = value;
}
}
public int VehicleType
{
get
{
if (m_vehicle == null)
return (int)Vehicle.TYPE_NONE;
else
return (int)m_vehicle.Type;
}
set
{
SetVehicleType(value);
}
}
public void SetVehicleType(int type)
{
if (PhysActor != null)
m_vehicle = null;
if (type == (int)Vehicle.TYPE_NONE)
{
if (_parentID ==0 && PhysActor != null)
PhysActor.VehicleType = (int)Vehicle.TYPE_NONE;
return;
}
m_vehicle = new SOPVehicle();
m_vehicle.ProcessTypeChange((Vehicle)type);
{
if (_parentID ==0 && PhysActor != null)
PhysActor.VehicleType = type;
return;
}
}
public void SetVehicleFlags(int param, bool remove)
{
if (m_vehicle == null)
return;
m_vehicle.ProcessVehicleFlags(param, remove);
if (_parentID ==0 && PhysActor != null)
{
PhysActor.VehicleType = type;
PhysActor.VehicleFlags(param, remove);
}
}
public void SetVehicleFloatParam(int param, float value)
{
if (PhysActor != null)
if (m_vehicle == null)
return;
m_vehicle.ProcessFloatVehicleParam((Vehicle)param, value);
if (_parentID == 0 && PhysActor != null)
{
PhysActor.VehicleFloatParam(param, value);
}
@@ -3178,7 +3262,12 @@ namespace OpenSim.Region.Framework.Scenes
public void SetVehicleVectorParam(int param, Vector3 value)
{
if (PhysActor != null)
if (m_vehicle == null)
return;
m_vehicle.ProcessVectorVehicleParam((Vehicle)param, value);
if (_parentID == 0 && PhysActor != null)
{
PhysActor.VehicleVectorParam(param, value);
}
@@ -3186,7 +3275,12 @@ namespace OpenSim.Region.Framework.Scenes
public void SetVehicleRotationParam(int param, Quaternion rotation)
{
if (PhysActor != null)
if (m_vehicle == null)
return;
m_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
if (_parentID == 0 && PhysActor != null)
{
PhysActor.VehicleRotationParam(param, rotation);
}
@@ -3373,13 +3467,6 @@ namespace OpenSim.Region.Framework.Scenes
hasProfileCut = hasDimple; // is it the same thing?
}
public void SetVehicleFlags(int param, bool remove)
{
if (PhysActor != null)
{
PhysActor.VehicleFlags(param, remove);
}
}
public void SetGroup(UUID groupID, IClientAPI client)
{
@@ -4267,7 +4354,8 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="SetTemporary"></param>
/// <param name="SetPhantom"></param>
/// <param name="SetVD"></param>
public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD)
// public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD)
public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
{
bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
@@ -4285,6 +4373,9 @@ namespace OpenSim.Region.Framework.Scenes
// that...
// ... if VD is changed, all others are not.
// ... if one of the others is changed, VD is not.
// do this first
if (building && PhysActor != null && PhysActor.Building != building)
PhysActor.Building = building;
if (SetVD) // VD is active, special logic applies
{
// State machine logic for VolumeDetect
@@ -4366,11 +4457,17 @@ namespace OpenSim.Region.Framework.Scenes
Shape,
AbsolutePosition,
Scale,
RotationOffset,
// RotationOffset,
GetWorldRotation(), //physics wants world rotation like all other functions send
UsePhysics,
m_localId);
PhysActor.SetMaterial(Material);
// if root part apply vehicle
if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
m_vehicle.SetVehicle(PhysActor);
DoPhysicsPropertyUpdate(UsePhysics, true);
if (!ParentGroup.IsDeleted)
@@ -4446,6 +4543,9 @@ namespace OpenSim.Region.Framework.Scenes
}
// m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
// and last in case we have a new actor and not building
if (PhysActor != null && PhysActor.Building != building)
PhysActor.Building = building;
if (ParentGroup != null)
{
ParentGroup.HasGroupChanged = true;
+158 -79
View File
@@ -91,7 +91,7 @@ namespace OpenSim.Region.Framework.Scenes
/// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
/// issue #1716
/// </summary>
public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.4f);
/// <summary>
/// Movement updates for agents in neighboring regions are sent directly to clients.
@@ -233,6 +233,8 @@ namespace OpenSim.Region.Framework.Scenes
private bool m_collisionEventFlag = false;
private object m_collisionEventLock = new Object();
private Vector3 m_prevSitOffset;
protected AvatarAppearance m_appearance;
public AvatarAppearance Appearance
@@ -295,13 +297,10 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
public PhysicsActor PhysicsActor { get; private set; }
private byte m_movementflag;
public byte MovementFlag
{
set { m_movementflag = value; }
get { return m_movementflag; }
}
/// <summary>
/// Record user movement inputs.
/// </summary>
public byte MovementFlag { get; private set; }
private bool m_updateflag;
@@ -647,6 +646,13 @@ namespace OpenSim.Region.Framework.Scenes
}
private uint m_parentID;
public UUID ParentUUID
{
get { return m_parentUUID; }
set { m_parentUUID = value; }
}
private UUID m_parentUUID = UUID.Zero;
public float Health
{
get { return m_health; }
@@ -868,10 +874,37 @@ namespace OpenSim.Region.Framework.Scenes
"[SCENE]: Upgrading child to root agent for {0} in {1}",
Name, m_scene.RegionInfo.RegionName);
//m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
bool wasChild = IsChildAgent;
IsChildAgent = false;
if (ParentUUID != UUID.Zero)
{
m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
if (part == null)
{
m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
}
else
{
part.ParentGroup.AddAvatar(UUID);
if (part.SitTargetPosition != Vector3.Zero)
part.SitTargetAvatar = UUID;
ParentPosition = part.GetWorldPosition();
ParentID = part.LocalId;
m_pos = m_prevSitOffset;
pos = ParentPosition;
}
ParentUUID = UUID.Zero;
IsChildAgent = false;
Animator.TrySetMovementAnimation("SIT");
}
else
{
IsChildAgent = false;
}
IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
if (gm != null)
@@ -881,62 +914,64 @@ namespace OpenSim.Region.Framework.Scenes
m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
// Moved this from SendInitialData to ensure that Appearance is initialized
// before the inventory is processed in MakeRootAgent. This fixes a race condition
// related to the handling of attachments
//m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
if (m_scene.TestBorderCross(pos, Cardinals.E))
if (ParentID == 0)
{
Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
pos.X = crossedBorder.BorderLine.Z - 1;
// Moved this from SendInitialData to ensure that Appearance is initialized
// before the inventory is processed in MakeRootAgent. This fixes a race condition
// related to the handling of attachments
//m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
if (m_scene.TestBorderCross(pos, Cardinals.E))
{
Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
pos.X = crossedBorder.BorderLine.Z - 1;
}
if (m_scene.TestBorderCross(pos, Cardinals.N))
{
Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
pos.Y = crossedBorder.BorderLine.Z - 1;
}
CheckAndAdjustLandingPoint(ref pos);
if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
{
m_log.WarnFormat(
"[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
pos, Name, UUID);
if (pos.X < 0f) pos.X = 0f;
if (pos.Y < 0f) pos.Y = 0f;
if (pos.Z < 0f) pos.Z = 0f;
}
float localAVHeight = 1.56f;
if (Appearance.AvatarHeight > 0)
localAVHeight = Appearance.AvatarHeight;
float posZLimit = 0;
if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
float newPosZ = posZLimit + localAVHeight / 2;
if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
{
pos.Z = newPosZ;
}
AbsolutePosition = pos;
AddToPhysicalScene(isFlying);
if (ForceFly)
{
Flying = true;
}
else if (FlyDisabled)
{
Flying = false;
}
}
if (m_scene.TestBorderCross(pos, Cardinals.N))
{
Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
pos.Y = crossedBorder.BorderLine.Z - 1;
}
CheckAndAdjustLandingPoint(ref pos);
if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
{
m_log.WarnFormat(
"[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
pos, Name, UUID);
if (pos.X < 0f) pos.X = 0f;
if (pos.Y < 0f) pos.Y = 0f;
if (pos.Z < 0f) pos.Z = 0f;
}
float localAVHeight = 1.56f;
if (Appearance.AvatarHeight > 0)
localAVHeight = Appearance.AvatarHeight;
float posZLimit = 0;
if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
float newPosZ = posZLimit + localAVHeight / 2;
if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
{
pos.Z = newPosZ;
}
AbsolutePosition = pos;
AddToPhysicalScene(isFlying);
if (ForceFly)
{
Flying = true;
}
else if (FlyDisabled)
{
Flying = false;
}
// Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
// avatar to return to the standing position in mid-air. On login it looks like this is being sent
// elsewhere anyway
@@ -954,14 +989,19 @@ namespace OpenSim.Region.Framework.Scenes
{
m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments...");
// Resume scripts
foreach (SceneObjectGroup sog in m_attachments)
{
sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
sog.ResumeScripts();
}
Util.FireAndForget(delegate(object x) {
foreach (SceneObjectGroup sog in m_attachments)
{
sog.ScheduleGroupForFullUpdate();
sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
sog.ResumeScripts();
}
});
}
}
SendAvatarDataToAllAgents();
// send the animations of the other presences to me
m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
{
@@ -1055,7 +1095,7 @@ namespace OpenSim.Region.Framework.Scenes
}
/// <summary>
///
/// Do not call this directly. Call Scene.RequestTeleportLocation() instead.
/// </summary>
/// <param name="pos"></param>
public void Teleport(Vector3 pos)
@@ -1226,7 +1266,7 @@ namespace OpenSim.Region.Framework.Scenes
{
IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
if (m_agentTransfer != null)
m_agentTransfer.EnableChildAgents(this);
Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); });
IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
if (friendsModule != null)
@@ -1529,7 +1569,10 @@ namespace OpenSim.Region.Framework.Scenes
}
else if (bAllowUpdateMoveToPosition)
{
if (HandleMoveToTargetUpdate(ref agent_control_v3))
// The UseClientAgentPosition is set if parcel ban is forcing the avatar to move to a
// certain position. It's only check for tolerance on returning to that position is 0.2
// rather than 1, at which point it removes its force target.
if (HandleMoveToTargetUpdate(agentData.UseClientAgentPosition ? 0.2 : 1, ref agent_control_v3))
update_movementflag = true;
}
}
@@ -1591,7 +1634,7 @@ namespace OpenSim.Region.Framework.Scenes
/// </remarks>
/// <param value="agent_control_v3">Cumulative agent movement that this method will update.</param>
/// <returns>True if movement has been updated in some way. False otherwise.</returns>
public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3)
public bool HandleMoveToTargetUpdate(double tolerance, ref Vector3 agent_control_v3)
{
// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
@@ -1608,7 +1651,7 @@ namespace OpenSim.Region.Framework.Scenes
// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
// Check the error term of the current position in relation to the target position
if (distanceToTarget <= 1)
if (distanceToTarget <= tolerance)
{
// We are close enough to the target
AbsolutePosition = MoveToPositionTarget;
@@ -1784,7 +1827,7 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, Rotation);
Vector3 agent_control_v3 = new Vector3();
HandleMoveToTargetUpdate(ref agent_control_v3);
HandleMoveToTargetUpdate(1, ref agent_control_v3);
AddNewMovement(agent_control_v3);
}
@@ -1814,8 +1857,11 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name);
SitGround = false;
/* move this down so avatar gets physical in the new position and not where it is siting
if (PhysicsActor == null)
AddToPhysicalScene(false);
*/
if (ParentID != 0)
{
@@ -1850,6 +1896,10 @@ namespace OpenSim.Region.Framework.Scenes
ParentPosition = Vector3.Zero;
ParentID = 0;
if (PhysicsActor == null)
AddToPhysicalScene(false);
SendAvatarDataToAllAgents();
m_requestedSitTargetID = 0;
@@ -1857,6 +1907,9 @@ namespace OpenSim.Region.Framework.Scenes
part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
}
else if (PhysicsActor == null)
AddToPhysicalScene(false);
Animator.TrySetMovementAnimation("STAND");
}
@@ -2262,7 +2315,27 @@ namespace OpenSim.Region.Framework.Scenes
//Quaternion result = (sitTargetOrient * vq) * nq;
m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT;
double x, y, z, m;
Quaternion r = sitTargetOrient;
m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
if (Math.Abs(1.0 - m) > 0.000001)
{
m = 1.0 / Math.Sqrt(m);
r.X *= (float)m;
r.Y *= (float)m;
r.Z *= (float)m;
r.W *= (float)m;
}
x = 2 * (r.X * r.Z + r.Y * r.W);
y = 2 * (-r.X * r.W + r.Y * r.Z);
z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
Vector3 up = new Vector3((float)x, (float)y, (float)z);
Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f;
m_pos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
Rotation = sitTargetOrient;
ParentPosition = part.AbsolutePosition;
part.ParentGroup.AddAvatar(UUID);
@@ -2748,7 +2821,8 @@ namespace OpenSim.Region.Framework.Scenes
AgentPosition agentpos = new AgentPosition();
agentpos.CopyFrom(cadu);
m_scene.SendOutChildAgentUpdates(agentpos, this);
// Let's get this out of the update loop
Util.FireAndForget(delegate { m_scene.SendOutChildAgentUpdates(agentpos, this); });
}
}
@@ -3112,6 +3186,9 @@ namespace OpenSim.Region.Framework.Scenes
cAgent.AlwaysRun = SetAlwaysRun;
cAgent.Appearance = new AvatarAppearance(Appearance);
cAgent.ParentPart = ParentUUID;
cAgent.SitOffset = m_pos;
lock (scriptedcontrols)
{
@@ -3171,6 +3248,8 @@ namespace OpenSim.Region.Framework.Scenes
CameraAtAxis = cAgent.AtAxis;
CameraLeftAxis = cAgent.LeftAxis;
m_CameraUpAxis = cAgent.UpAxis;
ParentUUID = cAgent.ParentPart;
m_prevSitOffset = cAgent.SitOffset;
// When we get to the point of re-computing neighbors everytime this
// changes, then start using the agent's drawdistance rather than the
@@ -3232,7 +3311,7 @@ namespace OpenSim.Region.Framework.Scenes
((SceneObjectGroup)so).LocalId = 0;
((SceneObjectGroup)so).RootPart.ClearUpdateSchedule();
so.SetState(cAgent.AttachmentObjectStates[i++], m_scene);
m_scene.IncomingCreateObject(so);
m_scene.IncomingCreateObject(Vector3.Zero, so);
}
}
}
@@ -29,6 +29,7 @@ using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml;
using log4net;
@@ -349,6 +350,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
m_SOPXmlProcessors.Add("Buoyancy", ProcessBuoyancy);
m_SOPXmlProcessors.Add("VolumeDetectActive", ProcessVolumeDetectActive);
//Ubit comented until proper testing
m_SOPXmlProcessors.Add("Vehicle", ProcessVehicle);
#endregion
#region TaskInventoryXmlProcessors initialization
@@ -571,15 +577,36 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
obj.ClickAction = (byte)reader.ReadElementContentAsInt("ClickAction", String.Empty);
}
private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader)
private static void ProcessVehicle(SceneObjectPart obj, XmlTextReader reader)
{
bool errors = false;
obj.Shape = ReadShape(reader, "Shape", out errors);
SOPVehicle _vehicle = new SOPVehicle();
_vehicle.FromXml2(reader, out errors);
if (errors)
{
obj.sopVehicle = null;
m_log.DebugFormat(
"[SceneObjectSerializer]: Parsing PrimitiveBaseShape for object part {0} {1} encountered errors. Please see earlier log entries.",
"[SceneObjectSerializer]: Parsing Vehicle for object part {0} {1} encountered errors. Please see earlier log entries.",
obj.Name, obj.UUID);
}
else
obj.sopVehicle = _vehicle;
}
private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader)
{
List<string> errorNodeNames;
obj.Shape = ReadShape(reader, "Shape", out errorNodeNames);
if (errorNodeNames != null)
{
m_log.DebugFormat(
"[SceneObjectSerializer]: Parsing PrimitiveBaseShape for object part {0} {1} encountered errors in properties {2}.",
obj.Name, obj.UUID, string.Join(", ", errorNodeNames.ToArray()));
}
}
private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader)
@@ -1231,6 +1258,10 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
writer.WriteElementString("Buoyancy", sop.Buoyancy.ToString());
writer.WriteElementString("VolumeDetectActive", sop.VolumeDetectActive.ToString().ToLower());
//Ubit comented until proper testing
if (sop.sopVehicle != null)
sop.sopVehicle.ToXml2(writer);
writer.WriteEndElement();
}
@@ -1486,7 +1517,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
m_SOPXmlProcessors,
reader,
(o, nodeName, e)
=> m_log.ErrorFormat(
=> m_log.DebugFormat(
"[SceneObjectSerializer]: Exception while parsing {0} in object {1} {2}: {3}{4}",
((SceneObjectPart)o).Name, ((SceneObjectPart)o).UUID, nodeName, e.Message, e.StackTrace));
@@ -1529,14 +1560,21 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
/// </summary>
/// <param name="reader"></param>
/// <param name="name">The name of the xml element containing the shape</param>
/// <param name="errors">true if any errors were encountered during parsing, false otherwise</param>
/// <param name="errors">a list containing the failing node names. If no failures then null.</param>
/// <returns>The shape parsed</returns>
public static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name, out bool errors)
public static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name, out List<string> errorNodeNames)
{
errors = false;
List<string> internalErrorNodeNames = null;
PrimitiveBaseShape shape = new PrimitiveBaseShape();
if (reader.IsEmptyElement)
{
reader.Read();
errorNodeNames = null;
return shape;
}
reader.ReadStartElement(name, String.Empty); // Shape
ExternalRepresentationUtils.ExecuteReadProcessors(
@@ -1544,12 +1582,22 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
m_ShapeXmlProcessors,
reader,
(o, nodeName, e)
=> m_log.ErrorFormat(
"[SceneObjectSerializer]: Exception while parsing Shape property {0}: {1}{2}",
nodeName, e.Message, e.StackTrace));
=>
{
// m_log.DebugFormat(
// "[SceneObjectSerializer]: Exception while parsing Shape property {0}: {1}{2}",
// nodeName, e.Message, e.StackTrace);
if (internalErrorNodeNames == null)
internalErrorNodeNames = new List<string>();
internalErrorNodeNames.Add(nodeName);
}
);
reader.ReadEndElement(); // Shape
errorNodeNames = internalErrorNodeNames;
return shape;
}
@@ -27,6 +27,7 @@
using System;
using System.Reflection;
using System.Threading;
using NUnit.Framework;
using OpenMetaverse;
using OpenSim.Framework;
@@ -43,6 +44,42 @@ namespace OpenSim.Region.Framework.Scenes.Tests
[TestFixture]
public class SceneObjectBasicTests
{
// [TearDown]
// public void TearDown()
// {
// Console.WriteLine("TearDown");
// GC.Collect();
// Thread.Sleep(3000);
// }
// public class GcNotify
// {
// public static AutoResetEvent gcEvent = new AutoResetEvent(false);
// private static bool _initialized = false;
//
// public static void Initialize()
// {
// if (!_initialized)
// {
// _initialized = true;
// new GcNotify();
// }
// }
//
// private GcNotify(){}
//
// ~GcNotify()
// {
// if (!Environment.HasShutdownStarted &&
// !AppDomain.CurrentDomain.IsFinalizingForUnload())
// {
// Console.WriteLine("GcNotify called");
// gcEvent.Set();
// new GcNotify();
// }
// }
// }
/// <summary>
/// Test adding an object to a scene.
/// </summary>
@@ -147,11 +184,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests
public void TestDeleteSceneObject()
{
TestHelpers.InMethod();
TestScene scene = SceneHelpers.SetupScene();
SceneObjectPart part = SceneHelpers.AddSceneObject(scene);
scene.DeleteSceneObject(part.ParentGroup, false);
SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId);
Assert.That(retrievedPart, Is.Null);
}
@@ -39,14 +39,31 @@ using log4net;
namespace OpenSim.Region.Framework.Scenes.Tests
{
/// <summary>
/// Linking tests
/// </summary>
[TestFixture]
public class SceneObjectLinkingTests
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Links to self should be ignored.
/// </summary>
[Test]
public void TestLinkToSelf()
{
TestHelpers.InMethod();
UUID ownerId = TestHelpers.ParseTail(0x1);
int nParts = 3;
TestScene scene = SceneHelpers.SetupScene();
SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(nParts, ownerId, "TestLinkToSelf_", 0x10);
scene.AddSceneObject(sog1);
scene.LinkObjects(ownerId, sog1.LocalId, new List<uint>() { sog1.Parts[1].LocalId });
// sog1.LinkToGroup(sog1);
Assert.That(sog1.Parts.Length, Is.EqualTo(nParts));
}
[Test]
public void TestLinkDelink2SceneObjects()
{
@@ -63,9 +63,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// Capability string prefixes
private static readonly string m_parcelVoiceInfoRequestPath = "0007/";
private static readonly string m_provisionVoiceAccountRequestPath = "0008/";
private static readonly string m_chatSessionRequestPath = "0009/";
private static readonly string m_parcelVoiceInfoRequestPath = "0207/";
private static readonly string m_provisionVoiceAccountRequestPath = "0208/";
private static readonly string m_chatSessionRequestPath = "0209/";
// Control info
private static bool m_Enabled = false;
@@ -30,6 +30,7 @@ using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reflection;
using System.Threading;
using Nwc.XmlRpc;
@@ -167,6 +168,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
private bool m_debugEnabled = false;
private Dictionary<string, bool> m_pendingRequests = new Dictionary<string,bool>();
private ExpiringCache<string, OSDMap> m_memoryCache;
private int m_cacheTimeout = 30;
@@ -1348,6 +1351,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
// Immediately forward the request if the cache is disabled.
if (m_cacheTimeout == 0)
{
m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: cache is disabled");
return WebUtil.PostToService(m_groupsServerURI, requestArgs);
}
@@ -1355,6 +1359,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
if (requestArgs["RequestMethod"] == "RemoveGeneric"
|| requestArgs["RequestMethod"] == "AddGeneric")
{
m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: clearing generics cache");
// Any and all updates cause the cache to clear
m_memoryCache.Clear();
@@ -1366,18 +1372,67 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
// Create the cache key for the request and see if we have it cached
string CacheKey = WebUtil.BuildQueryString(requestArgs);
OSDMap response = null;
if (!m_memoryCache.TryGetValue(CacheKey, out response))
{
// if it wasn't in the cache, pass the request to the Simian Grid Services
response = WebUtil.PostToService(m_groupsServerURI, requestArgs);
// and cache the response
m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout));
// This code uses a leader/follower pattern. On a cache miss, the request is added
// to a queue; the first thread to add it to the queue completes the request while
// follow on threads busy wait for the results, this situation seems to happen
// often when checking permissions
while (true)
{
OSDMap response = null;
bool firstRequest = false;
lock (m_memoryCache)
{
if (m_memoryCache.TryGetValue(CacheKey, out response))
return response;
if (! m_pendingRequests.ContainsKey(CacheKey))
{
m_pendingRequests.Add(CacheKey,true);
firstRequest = true;
}
}
if (firstRequest)
{
// if it wasn't in the cache, pass the request to the Simian Grid Services
try
{
response = WebUtil.PostToService(m_groupsServerURI, requestArgs);
}
catch (Exception e)
{
m_log.InfoFormat("[SIMIAN GROUPS CONNECTOR] request failed {0}",CacheKey);
}
// and cache the response
lock (m_memoryCache)
{
m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout));
m_pendingRequests.Remove(CacheKey);
}
return response;
}
Thread.Sleep(50); // waiting for a web request to complete, 50msecs is reasonable
}
// return cached response
return response;
// if (!m_memoryCache.TryGetValue(CacheKey, out response))
// {
// m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: query not in the cache");
// Util.PrintCallStack();
// // if it wasn't in the cache, pass the request to the Simian Grid Services
// response = WebUtil.PostToService(m_groupsServerURI, requestArgs);
// // and cache the response
// m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout));
// }
// // return cached response
// return response;
}
#endregion
@@ -230,8 +230,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
m_scene.EventManager.OnEmptyScriptCompileQueue -= OnEmptyScriptCompileQueue;
m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}",
m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString());
// m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}",
// m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString());
m_log.InfoFormat("[RegionReady]: Logins enabled for {0}", m_scene.RegionInfo.RegionName);
if ( m_uri != string.Empty )
{
@@ -44,7 +44,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
private readonly string m_firstname;
private readonly string m_lastname;
private readonly Vector3 m_startPos;
private readonly UUID m_uuid = UUID.Random();
private UUID m_uuid = UUID.Random();
private readonly Scene m_scene;
private readonly UUID m_ownerID;
@@ -444,6 +444,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
public virtual UUID AgentId
{
get { return m_uuid; }
set { m_uuid = value; }
}
public UUID SessionId
@@ -96,15 +96,15 @@ namespace OpenSim.Region.OptionalModules.World.NPC
if (!m_avatars.ContainsKey(agentId))
return false;
// Delete existing sp attachments
scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, false);
AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true);
sp.Appearance = npcAppearance;
// Set new sp appearance. Also sends to clients.
scene.RequestModuleInterface<IAvatarFactoryModule>().SetAppearance(sp, new AvatarAppearance(appearance, true));
// Rez needed sp attachments
scene.AttachmentsModule.RezAttachments(sp);
IAvatarFactoryModule module = scene.RequestModuleInterface<IAvatarFactoryModule>();
module.SendAppearance(sp.UUID);
return true;
}
@@ -121,8 +121,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC
npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0, int.MaxValue);
m_log.DebugFormat(
"[NPC MODULE]: Creating NPC {0} {1} {2} at {3} in {4}",
firstname, lastname, npcAvatar.AgentId, position, scene.RegionInfo.RegionName);
"[NPC MODULE]: Creating NPC {0} {1} {2}, owner={3}, senseAsAgent={4} at {5} in {6}",
firstname, lastname, npcAvatar.AgentId, owner, senseAsAgent, position, scene.RegionInfo.RegionName);
AgentCircuitData acd = new AgentCircuitData();
acd.AgentID = npcAvatar.AgentId;
@@ -155,20 +155,21 @@ namespace OpenSim.Region.OptionalModules.World.NPC
"[NPC MODULE]: Successfully retrieved scene presence for NPC {0} {1}", sp.Name, sp.UUID);
sp.CompleteMovement(npcAvatar, false);
m_avatars.Add(npcAvatar.AgentId, npcAvatar);
}
else
{
m_log.WarnFormat("[NPC MODULE]: Could not find scene presence for NPC {0} {1}", sp.Name, sp.UUID);
npcAvatar.AgentId = UUID.Zero;
}
m_avatars.Add(npcAvatar.AgentId, npcAvatar);
}
ev.Set();
});
ev.WaitOne();
m_log.DebugFormat("[NPC MODULE]: Created NPC with id {0}", npcAvatar.AgentId);
// m_log.DebugFormat("[NPC MODULE]: Created NPC with id {0}", npcAvatar.AgentId);
return npcAvatar.AgentId;
}
@@ -299,13 +300,16 @@ namespace OpenSim.Region.OptionalModules.World.NPC
NPCAvatar av;
if (m_avatars.TryGetValue(agentID, out av))
{
// m_log.DebugFormat("[NPC MODULE]: Found {0} {1} to remove", agentID, av.Name);
scene.RemoveClient(agentID, false);
m_avatars.Remove(agentID);
// m_log.DebugFormat("[NPC MODULE]: Removed {0} {1}", agentID, av.Name);
return true;
}
}
// m_log.DebugFormat("[NPC MODULE]: Could not find {0} to remove", agentID);
return false;
}
@@ -51,6 +51,9 @@ public class BSPlugin : IPhysicsPlugin
{
if (_mScene == null)
{
if (Util.IsWindows())
Util.LoadArchSpecificWindowsDll("BulletSim.dll");
_mScene = new BSScene(sceneIdentifier);
}
return (_mScene);
File diff suppressed because it is too large Load Diff
+41 -11
View File
@@ -1536,7 +1536,7 @@ namespace OpenSim.Region.Physics.OdePlugin
List<OdePrim> removeprims = null;
foreach (OdePrim chr in _activeprims)
{
if (chr.Body != IntPtr.Zero && d.BodyIsEnabled(chr.Body) && (!chr.m_disabled))
if (chr.Body != IntPtr.Zero && d.BodyIsEnabled(chr.Body) && (!chr.m_disabled) && !chr.m_outofBounds)
{
try
{
@@ -1736,6 +1736,23 @@ namespace OpenSim.Region.Physics.OdePlugin
return newPrim;
}
private PhysicsActor AddPrim(String name, Vector3 position, PhysicsActor parent,
PrimitiveBaseShape pbs, uint localid, byte[] sdata)
{
Vector3 pos = position;
OdePrim newPrim;
lock (OdeLock)
{
newPrim = new OdePrim(name, this, pos, parent, pbs, ode, localid, sdata);
lock (_prims)
_prims.Add(newPrim);
}
return newPrim;
}
public void addActivePrim(OdePrim activatePrim)
{
// adds active prim.. (ones that should be iterated over in collisions_optimized
@@ -1762,6 +1779,17 @@ namespace OpenSim.Region.Physics.OdePlugin
return result;
}
public override PhysicsActor AddPrimShape(string primName, PhysicsActor parent, PrimitiveBaseShape pbs, Vector3 position,
uint localid, byte[] sdata)
{
PhysicsActor result;
result = AddPrim(primName, position, parent,
pbs, localid, sdata);
return result;
}
public override float TimeDilation
{
get { return m_timeDilation; }
@@ -3410,13 +3438,13 @@ namespace OpenSim.Region.Physics.OdePlugin
public void SetTerrain(float[] heightMap, Vector3 pOffset)
{
uint regionsize = (uint) Constants.RegionSize; // visible region size eg. 256(M)
int regionsize = (int) Constants.RegionSize; // visible region size eg. 256(M)
uint heightmapWidth = regionsize + 1; // ODE map size 257 x 257 (Meters) (1 extra
uint heightmapHeight = regionsize + 1;
int heightmapWidth = regionsize + 2; // ODE map size 257 x 257 (Meters) (1 extra
int heightmapHeight = regionsize + 2;
uint heightmapWidthSamples = (uint)regionsize + 2; // Sample file size, 258 x 258 samples
uint heightmapHeightSamples = (uint)regionsize + 2;
int heightmapWidthSamples = (int)regionsize + 3; // Sample file size, 258 x 258 samples
int heightmapHeightSamples = (int)regionsize + 3;
// Array of height samples for ODE
float[] _heightmap;
@@ -3432,10 +3460,10 @@ namespace OpenSim.Region.Physics.OdePlugin
float hfmax = -2000f;
float minele = 0.0f; // Dont allow -ve heights
uint x = 0;
uint y = 0;
uint xx = 0;
uint yy = 0;
int x = 0;
int y = 0;
int xx = 0;
int yy = 0;
// load the height samples array from the heightMap
for ( x = 0; x < heightmapWidthSamples; x++) // 0 to 257
@@ -3453,7 +3481,7 @@ namespace OpenSim.Region.Physics.OdePlugin
// Output x = 0 1 2 3 ..... 255 256 257 258 total out
float val= heightMap[(yy * regionsize) + xx]; // input from heightMap, <0-255 * 256> <0-255>
if (val < minele) val = minele;
_heightmap[x * (regionsize + 2) + y] = val; // samples output to _heightmap, <0-257 * 258> <0-257>
_heightmap[x * (heightmapHeightSamples) + y] = val; // samples output to _heightmap, <0-257 * 258> <0-257>
hfmin = (val < hfmin) ? val : hfmin;
hfmax = (val > hfmax) ? val : hfmax;
}
@@ -3503,6 +3531,8 @@ namespace OpenSim.Region.Physics.OdePlugin
d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
d.GeomSetRotation(GroundGeom, ref R);
d.GeomSetPosition(GroundGeom, (pOffset.X + (regionsize * 0.5f)) - 0.5f, (pOffset.Y + (regionsize * 0.5f)) - 0.5f, 0);
// having nsamples = size + 1 center is actually at size/2
d.GeomSetPosition(GroundGeom, (pOffset.X + (regionsize * 0.5f)), (pOffset.Y + (regionsize * 0.5f)), 0);
IntPtr testGround = IntPtr.Zero;
if (RegionTerrain.TryGetValue(pOffset, out testGround))
{
@@ -0,0 +1,353 @@
/* Ubit 2012
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 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.
*/
// no endian conversion. So can't be use to pass information around diferent cpus with diferent endian
using System;
using System.IO;
using OpenMetaverse;
namespace OpenSim.Region.Physics.OdePlugin
{
unsafe public class wstreamer
{
byte[] buf;
int index;
byte* src;
public wstreamer()
{
buf = new byte[1024];
index = 0;
}
public wstreamer(int size)
{
buf = new byte[size];
index = 0;
}
public byte[] close()
{
byte[] data = new byte[index];
Buffer.BlockCopy(buf, 0, data, 0, index);
return data;
}
public void Seek(int pos)
{
index = pos;
}
public void Seekrel(int pos)
{
index += pos;
}
public void Wbyte(byte value)
{
buf[index++] = value;
}
public void Wshort(short value)
{
src = (byte*)&value;
buf[index++] = *src++;
buf[index++] = *src;
}
public void Wushort(ushort value)
{
src = (byte*)&value;
buf[index++] = *src++;
buf[index++] = *src;
}
public void Wint(int value)
{
src = (byte*)&value;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src;
}
public void Wuint(uint value)
{
src = (byte*)&value;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src;
}
public void Wlong(long value)
{
src = (byte*)&value;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src;
}
public void Wulong(ulong value)
{
src = (byte*)&value;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src;
}
public void Wfloat(float value)
{
src = (byte*)&value;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src;
}
public void Wdouble(double value)
{
src = (byte*)&value;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src;
}
public void Wvector3(Vector3 value)
{
src = (byte*)&value.X;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src;
src = (byte*)&value.Y; // it may have padding ??
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src;
src = (byte*)&value.Z;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src;
}
public void Wquat(Quaternion value)
{
src = (byte*)&value.X;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src;
src = (byte*)&value.Y; // it may have padding ??
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src;
src = (byte*)&value.Z;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src;
src = (byte*)&value.W;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src++;
buf[index++] = *src;
}
}
unsafe public class rstreamer
{
private byte[] rbuf;
private int ptr;
private byte* dst;
public rstreamer(byte[] data)
{
rbuf = data;
ptr = 0;
}
public void close()
{
}
public void Seek(int pos)
{
ptr = pos;
}
public void Seekrel(int pos)
{
ptr += pos;
}
public byte Rbyte()
{
return (byte)rbuf[ptr++];
}
public short Rshort()
{
short v;
dst = (byte*)&v;
*dst++ = rbuf[ptr++];
*dst = rbuf[ptr++];
return v;
}
public ushort Rushort()
{
ushort v;
dst = (byte*)&v;
*dst++ = rbuf[ptr++];
*dst = rbuf[ptr++];
return v;
}
public int Rint()
{
int v;
dst = (byte*)&v;
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst = rbuf[ptr++];
return v;
}
public uint Ruint()
{
uint v;
dst = (byte*)&v;
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst = rbuf[ptr++];
return v;
}
public long Rlong()
{
long v;
dst = (byte*)&v;
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst = rbuf[ptr++];
return v;
}
public ulong Rulong()
{
ulong v;
dst = (byte*)&v;
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst = rbuf[ptr++];
return v;
}
public float Rfloat()
{
float v;
dst = (byte*)&v;
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst = rbuf[ptr++];
return v;
}
public double Rdouble()
{
double v;
dst = (byte*)&v;
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst = rbuf[ptr++];
return v;
}
public Vector3 Rvector3()
{
Vector3 v;
dst = (byte*)&v.X;
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst = rbuf[ptr++];
dst = (byte*)&v.Y;
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst = rbuf[ptr++];
dst = (byte*)&v.Z;
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst = rbuf[ptr++];
return v;
}
public Quaternion Rquat()
{
Quaternion v;
dst = (byte*)&v.X;
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst = rbuf[ptr++];
dst = (byte*)&v.Y;
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst = rbuf[ptr++];
dst = (byte*)&v.Z;
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst = rbuf[ptr++];
dst = (byte*)&v.W;
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst++ = rbuf[ptr++];
*dst = rbuf[ptr++];
return v;
}
}
}
@@ -65,5 +65,6 @@ namespace OpenSim.Region.Physics.Manager
void releasePinned();
void Append(IMesh newMesh);
void TransformLinear(float[,] matrix, float[] offset);
Vector3 GetCentroid();
}
}
@@ -68,6 +68,17 @@ namespace OpenSim.Region.Physics.Manager
}
}
public struct ContactData
{
public float mu;
public float bounce;
public ContactData(float _mu, float _bounce)
{
mu = _mu;
bounce = _bounce;
}
}
/// <summary>
/// Used to pass collision information to OnCollisionUpdate listeners.
/// </summary>
@@ -135,6 +146,8 @@ namespace OpenSim.Region.Physics.Manager
/// </summary>
public event CollisionUpdate OnCollisionUpdate;
public virtual void SetVehicle(object vdata) { }
public event OutOfBounds OnOutOfBounds;
#pragma warning restore 67
@@ -142,6 +155,13 @@ namespace OpenSim.Region.Physics.Manager
{
get { return new NullPhysicsActor(); }
}
public virtual bool Building { get; set; }
public virtual ContactData ContactData
{
get { return new ContactData(0, 0); }
}
public abstract bool Stopped { get; }
@@ -195,6 +215,11 @@ namespace OpenSim.Region.Physics.Manager
}
}
public virtual byte[] Serialize(bool PhysIsRunning)
{
return new byte[0];
}
public virtual void RaiseOutOfBounds(Vector3 pos)
{
// Make a temporary copy of the event to avoid possibility of
@@ -554,5 +579,6 @@ namespace OpenSim.Region.Physics.Manager
{
return false;
}
}
}
@@ -30,7 +30,8 @@ using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Nini.Config;
using log4net;
using log4net;
using OpenSim.Framework;
namespace OpenSim.Region.Physics.Manager
{
+15 -1
View File
@@ -128,6 +128,12 @@ namespace OpenSim.Region.Physics.Manager
public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
Vector3 size, Quaternion rotation, bool isPhysical, uint localid);
public virtual PhysicsActor AddPrimShape(string primName, PhysicsActor parent, PrimitiveBaseShape pbs, Vector3 position,
uint localid, byte[] sdata)
{
return null;
}
public virtual float TimeDilation
{
get { return 1.0f; }
@@ -225,7 +231,7 @@ namespace OpenSim.Region.Physics.Manager
}
public virtual void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents) {}
public virtual void CombineTerrain(float[] heightMap, Vector3 pOffset) {}
public virtual void UnCombine(PhysicsScene pScene) {}
/// <summary>
@@ -263,5 +269,13 @@ namespace OpenSim.Region.Physics.Manager
{
return new List<ContactResult>();
}
public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod){}
public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod) { }
public virtual List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count)
{
return new List<ContactResult>();
}
}
}
@@ -26,6 +26,7 @@
*/
using System;
using OpenMetaverse;
namespace OpenSim.Region.Physics.Manager
{
@@ -117,5 +118,47 @@ namespace OpenSim.Region.Physics.Manager
NO_DEFLECTION = 16392,
LOCK_ROTATION = 32784
}
public struct VehicleData
{
public Vehicle m_type;
public VehicleFlag m_flags;
// Linear properties
public Vector3 m_linearMotorDirection;
public Vector3 m_linearFrictionTimescale;
public float m_linearMotorDecayTimescale;
public float m_linearMotorTimescale;
public Vector3 m_linearMotorOffset;
//Angular properties
public Vector3 m_angularMotorDirection;
public float m_angularMotorTimescale;
public float m_angularMotorDecayTimescale;
public Vector3 m_angularFrictionTimescale;
//Deflection properties
public float m_angularDeflectionEfficiency;
public float m_angularDeflectionTimescale;
public float m_linearDeflectionEfficiency;
public float m_linearDeflectionTimescale;
//Banking properties
public float m_bankingEfficiency;
public float m_bankingMix;
public float m_bankingTimescale;
//Hover and Buoyancy properties
public float m_VhoverHeight;
public float m_VhoverEfficiency;
public float m_VhoverTimescale;
public float m_VehicleBuoyancy;
//Attractor properties
public float m_verticalAttractionEfficiency;
public float m_verticalAttractionTimescale;
// Axis
public Quaternion m_referenceFrame;
}
}
+70 -2
View File
@@ -46,11 +46,36 @@ namespace OpenSim.Region.Physics.Meshing
IntPtr m_indicesPtr = IntPtr.Zero;
int m_indexCount = 0;
public float[] m_normals;
Vector3 _centroid;
int _centroidDiv;
private class vertexcomp : IEqualityComparer<Vertex>
{
public bool Equals(Vertex v1, Vertex v2)
{
if (v1.X == v2.X && v1.Y == v2.Y && v1.Z == v2.Z)
return true;
else
return false;
}
public int GetHashCode(Vertex v)
{
int a = v.X.GetHashCode();
int b = v.Y.GetHashCode();
int c = v.Z.GetHashCode();
return (a << 16) ^ (b << 8) ^ c;
}
}
public Mesh()
{
m_vertices = new Dictionary<Vertex, int>();
vertexcomp vcomp = new vertexcomp();
m_vertices = new Dictionary<Vertex, int>(vcomp);
m_triangles = new List<Triangle>();
_centroid = Vector3.Zero;
_centroidDiv = 0;
}
public Mesh Clone()
@@ -61,7 +86,8 @@ namespace OpenSim.Region.Physics.Meshing
{
result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone()));
}
result._centroid = _centroid;
result._centroidDiv = _centroidDiv;
return result;
}
@@ -71,15 +97,57 @@ namespace OpenSim.Region.Physics.Meshing
throw new NotSupportedException("Attempt to Add to a pinned Mesh");
// If a vertex of the triangle is not yet in the vertices list,
// add it and set its index to the current index count
// vertex == seems broken
// skip colapsed triangles
if ((triangle.v1.X == triangle.v2.X && triangle.v1.Y == triangle.v2.Y && triangle.v1.Z == triangle.v2.Z)
|| (triangle.v1.X == triangle.v3.X && triangle.v1.Y == triangle.v3.Y && triangle.v1.Z == triangle.v3.Z)
|| (triangle.v2.X == triangle.v3.X && triangle.v2.Y == triangle.v3.Y && triangle.v2.Z == triangle.v3.Z)
)
{
return;
}
if (m_vertices.Count == 0)
{
_centroidDiv = 0;
_centroid = Vector3.Zero;
}
if (!m_vertices.ContainsKey(triangle.v1))
{
m_vertices[triangle.v1] = m_vertices.Count;
_centroid.X += triangle.v1.X;
_centroid.Y += triangle.v1.Y;
_centroid.Z += triangle.v1.Z;
_centroidDiv++;
}
if (!m_vertices.ContainsKey(triangle.v2))
{
m_vertices[triangle.v2] = m_vertices.Count;
_centroid.X += triangle.v2.X;
_centroid.Y += triangle.v2.Y;
_centroid.Z += triangle.v2.Z;
_centroidDiv++;
}
if (!m_vertices.ContainsKey(triangle.v3))
{
m_vertices[triangle.v3] = m_vertices.Count;
_centroid.X += triangle.v3.X;
_centroid.Y += triangle.v3.Y;
_centroid.Z += triangle.v3.Z;
_centroidDiv++;
}
m_triangles.Add(triangle);
}
public Vector3 GetCentroid()
{
if (_centroidDiv > 0)
return new Vector3(_centroid.X / _centroidDiv, _centroid.Y / _centroidDiv, _centroid.Z / _centroidDiv);
else
return Vector3.Zero;
}
public void CalcNormals()
{
int iTriangles = m_triangles.Count;
+20 -5
View File
@@ -74,6 +74,8 @@ namespace OpenSim.Region.Physics.Meshing
#endif
private bool cacheSculptMaps = true;
private bool cacheSculptAlphaMaps = true;
private string decodedSculptMapPath = null;
private bool useMeshiesPhysicsMesh = false;
@@ -87,7 +89,16 @@ namespace OpenSim.Region.Physics.Meshing
IConfig mesh_config = config.Configs["Mesh"];
decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache");
cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps);
if (Environment.OSVersion.Platform == PlatformID.Unix)
{
cacheSculptAlphaMaps = false;
}
else
cacheSculptAlphaMaps = cacheSculptMaps;
if(mesh_config != null)
useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
@@ -268,15 +279,18 @@ namespace OpenSim.Region.Physics.Meshing
{
if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, size, lod, out coords, out faces))
return null;
// Remove the reference to any JPEG2000 sculpt data so it can be GCed
// don't loose it
// primShape.SculptData = Utils.EmptyBytes;
}
// primShape.SculptDataLoaded = true;
}
else
{
if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, lod, out coords, out faces))
return null;
}
// Remove the reference to any JPEG2000 sculpt data so it can be GCed
// keep compatible
primShape.SculptData = Utils.EmptyBytes;
int numCoords = coords.Count;
@@ -313,7 +327,7 @@ namespace OpenSim.Region.Physics.Meshing
private bool GenerateCoordsAndFacesFromPrimMeshData(
string primName, PrimitiveBaseShape primShape, Vector3 size, out List<Coord> coords, out List<Face> faces)
{
m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName);
// m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName);
coords = new List<Coord>();
faces = new List<Face>();
@@ -321,7 +335,7 @@ namespace OpenSim.Region.Physics.Meshing
if (primShape.SculptData.Length <= 0)
{
m_log.Error("[MESH]: asset data is zero length");
m_log.ErrorFormat("[MESH]: asset data for {0} is zero length", primName);
return false;
}
@@ -482,7 +496,8 @@ namespace OpenSim.Region.Physics.Meshing
//idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData);
if (cacheSculptMaps)
if (cacheSculptMaps && (cacheSculptAlphaMaps || (((ImageFlags)(idata.Flags) & ImageFlags.HasAlpha) ==0)))
// don't cache images with alpha channel in linux since mono can't load them correctly)
{
try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); }
catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); }
+38 -24
View File
@@ -58,28 +58,24 @@ namespace PrimMesher
if (bmW == 0 || bmH == 0)
throw new Exception("SculptMap: bitmap has no data");
int numLodPixels = lod * 2 * lod * 2; // (32 * 2)^2 = 64^2 pixels for default sculpt map image
int numLodPixels = lod * lod; // (32 * 2)^2 = 64^2 pixels for default sculpt map image
bool smallMap = bmW * bmH <= numLodPixels;
bool needsScaling = false;
bool smallMap = bmW * bmH <= lod * lod;
width = bmW;
height = bmH;
while (width * height > numLodPixels)
while (width * height > numLodPixels * 4)
{
width >>= 1;
height >>= 1;
needsScaling = true;
}
try
{
if (needsScaling)
bm = ScaleImage(bm, width, height,
System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor);
bm = ScaleImage(bm, width, height);
}
catch (Exception e)
@@ -87,7 +83,7 @@ namespace PrimMesher
throw new Exception("Exception in ScaleImage(): e: " + e.ToString());
}
if (width * height > lod * lod)
if (width * height > numLodPixels)
{
width >>= 1;
height >>= 1;
@@ -144,15 +140,17 @@ namespace PrimMesher
int rowNdx, colNdx;
int smNdx = 0;
for (rowNdx = 0; rowNdx < numRows; rowNdx++)
{
List<Coord> row = new List<Coord>(numCols);
for (colNdx = 0; colNdx < numCols; colNdx++)
{
if (mirror)
row.Add(new Coord(-(redBytes[smNdx] * pixScale - 0.5f), (greenBytes[smNdx] * pixScale - 0.5f), blueBytes[smNdx] * pixScale - 0.5f));
row.Add(new Coord(-((float)redBytes[smNdx] * pixScale - 0.5f), ((float)greenBytes[smNdx] * pixScale - 0.5f), (float)blueBytes[smNdx] * pixScale - 0.5f));
else
row.Add(new Coord(redBytes[smNdx] * pixScale - 0.5f, greenBytes[smNdx] * pixScale - 0.5f, blueBytes[smNdx] * pixScale - 0.5f));
row.Add(new Coord((float)redBytes[smNdx] * pixScale - 0.5f, (float)greenBytes[smNdx] * pixScale - 0.5f, (float)blueBytes[smNdx] * pixScale - 0.5f));
++smNdx;
}
@@ -161,23 +159,39 @@ namespace PrimMesher
return rows;
}
private Bitmap ScaleImage(Bitmap srcImage, int destWidth, int destHeight,
System.Drawing.Drawing2D.InterpolationMode interpMode)
private Bitmap ScaleImage(Bitmap srcImage, int destWidth, int destHeight)
{
Bitmap scaledImage = new Bitmap(srcImage, destWidth, destHeight);
scaledImage.SetResolution(96.0f, 96.0f);
Graphics grPhoto = Graphics.FromImage(scaledImage);
grPhoto.InterpolationMode = interpMode;
Bitmap scaledImage = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);
Color c;
float xscale = srcImage.Width / destWidth;
float yscale = srcImage.Height / destHeight;
float sy = 0.5f;
for (int y = 0; y < destHeight; y++)
{
float sx = 0.5f;
for (int x = 0; x < destWidth; x++)
{
try
{
c = srcImage.GetPixel((int)(sx), (int)(sy));
scaledImage.SetPixel(x, y, Color.FromArgb(c.R, c.G, c.B));
}
catch (IndexOutOfRangeException)
{
}
grPhoto.DrawImage(srcImage,
new Rectangle(0, 0, destWidth, destHeight),
new Rectangle(0, 0, srcImage.Width, srcImage.Height),
GraphicsUnit.Pixel);
grPhoto.Dispose();
sx += xscale;
}
sy += yscale;
}
srcImage.Dispose();
return scaledImage;
}
}
}
}
#endif
@@ -156,6 +156,22 @@ namespace OpenSim.Region.Physics.OdePlugin
internal UUID m_uuid { get; private set; }
internal bool bad = false;
/// <summary>
/// ODE Avatar.
/// </summary>
/// <param name="avName"></param>
/// <param name="parent_scene"></param>
/// <param name="pos"></param>
/// <param name="size"></param>
/// <param name="pid_d"></param>
/// <param name="pid_p"></param>
/// <param name="capsule_radius"></param>
/// <param name="tensor"></param>
/// <param name="density">
/// Only used right now to return information to LSL. Not actually used to set mass in ODE!
/// </param>
/// <param name="walk_divisor"></param>
/// <param name="rundivisor"></param>
public OdeCharacter(
String avName, OdeScene parent_scene, Vector3 pos, Vector3 size, float pid_d, float pid_p,
float capsule_radius, float tensor, float density,
@@ -786,6 +802,10 @@ namespace OpenSim.Region.Physics.OdePlugin
Vector3 vec = Vector3.Zero;
d.Vector3 vel = d.BodyGetLinearVel(Body);
// m_log.DebugFormat(
// "[ODE CHARACTER]: Current velocity in Move() is <{0},{1},{2}>, target {3} for {4}",
// vel.X, vel.Y, vel.Z, _target_velocity, Name);
float movementdivisor = 1f;
if (!m_alwaysRun)
@@ -884,18 +904,20 @@ namespace OpenSim.Region.Physics.OdePlugin
if (flying)
{
// This also acts as anti-gravity so that we hover when flying rather than fall.
vec.Z = (_target_velocity.Z - vel.Z) * (PID_D);
}
}
if (flying)
{
// Anti-gravity so that we hover when flying rather than fall.
vec.Z += ((-1 * _parent_scene.gravityz) * m_mass);
//Added for auto fly height. Kitto Flora
//d.Vector3 pos = d.BodyGetPosition(Body);
float target_altitude = _parent_scene.GetTerrainHeightAtXY(_position.X, _position.Y) + MinimumGroundFlightOffset;
if (_position.Z < target_altitude)
{
vec.Z += (target_altitude - _position.Z) * PID_P * 5.0f;
@@ -921,6 +943,25 @@ namespace OpenSim.Region.Physics.OdePlugin
return;
}
d.Vector3 newVel = d.BodyGetLinearVel(Body);
if (newVel.X >= 256 || newVel.X <= 256 || newVel.Y >= 256 || newVel.Y <= 256 || newVel.Z >= 256 || newVel.Z <= 256)
{
// m_log.DebugFormat(
// "[ODE CHARACTER]: Limiting falling velocity from {0} to {1} for {2}", newVel.Z, -9.8, Name);
newVel.X = Util.Clamp<float>(newVel.X, -255f, 255f);
newVel.Y = Util.Clamp<float>(newVel.Y, -255f, 255f);
if (!flying)
newVel.Z
= Util.Clamp<float>(
newVel.Z, -_parent_scene.AvatarTerminalVelocity, _parent_scene.AvatarTerminalVelocity);
else
newVel.Z = Util.Clamp<float>(newVel.Z, -255f, 255f);
d.BodySetLinearVel(Body, newVel.X, newVel.Y, newVel.Z);
}
}
/// <summary>
+12 -2
View File
@@ -46,7 +46,7 @@ namespace OpenSim.Region.Physics.OdePlugin
/// </summary>
public class OdePlugin : IPhysicsPlugin
{
//private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private OdeScene m_scene;
@@ -59,13 +59,23 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (m_scene == null)
{
// We do this so that OpenSimulator on Windows loads the correct native ODE library depending on whether
// it's running as a 32-bit process or a 64-bit one. By invoking LoadLibary here, later DLLImports
// will find it already loaded later on.
//
// This isn't necessary for other platforms (e.g. Mac OSX and Linux) since the DLL used can be
// controlled in Ode.NET.dll.config
if (Util.IsWindows())
Util.LoadArchSpecificWindowsDll("ode.dll");
// Initializing ODE only when a scene is created allows alternative ODE plugins to co-habit (according to
// http://opensimulator.org/mantis/view.php?id=2750).
d.InitODE();
m_scene = new OdeScene(sceneIdentifier);
}
return (m_scene);
return m_scene;
}
public string GetName()
@@ -144,6 +144,8 @@ namespace OpenSim.Region.Physics.OdePlugin
public float gravityy = 0f;
public float gravityz = -9.8f;
public float AvatarTerminalVelocity { get; set; }
private float contactsurfacelayer = 0.001f;
private int worldHashspaceLow = -4;
@@ -459,6 +461,15 @@ namespace OpenSim.Region.Physics.OdePlugin
gravityy = physicsconfig.GetFloat("world_gravityy", 0f);
gravityz = physicsconfig.GetFloat("world_gravityz", -9.8f);
float avatarTerminalVelocity = physicsconfig.GetFloat("avatar_terminal_velocity", 54f);
AvatarTerminalVelocity = Util.Clamp<float>(avatarTerminalVelocity, 0, 255f);
if (AvatarTerminalVelocity != avatarTerminalVelocity)
{
m_log.WarnFormat(
"[ODE SCENE]: avatar_terminal_velocity of {0} is invalid. Clamping to {1}",
avatarTerminalVelocity, AvatarTerminalVelocity);
}
worldHashspaceLow = physicsconfig.GetInt("world_hashspace_size_low", -4);
worldHashspaceHigh = physicsconfig.GetInt("world_hashspace_size_high", 128);
@@ -1,58 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 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.
*/
using System.Reflection;
using System.Runtime.InteropServices;
// Information about this assembly is defined by the following
// attributes.
//
// change them to the information which is associated with the assembly
// you compile.
[assembly : AssemblyTitle("RealPhysXplugin")]
[assembly : AssemblyDescription("")]
[assembly : AssemblyConfiguration("")]
[assembly : AssemblyCompany("http://opensimulator.org")]
[assembly : AssemblyProduct("RealPhysXplugin")]
[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")]
[assembly : AssemblyTrademark("")]
[assembly : AssemblyCulture("")]
// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly : ComVisible(false)]
// The assembly version has following format :
//
// Major.Minor.Build.Revision
//
// You can specify all values by your own or you can build default build and revision
// numbers with the '*' character (the default):
[assembly : AssemblyVersion("0.6.5.*")]
@@ -1,349 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 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.
*/
using System;
using System.Collections.Generic;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Region.Physics.Manager;
using PhysXWrapper;
using Quaternion=OpenMetaverse.Quaternion;
using System.Reflection;
using log4net;
using OpenMetaverse;
namespace OpenSim.Region.Physics.PhysXPlugin
{
public class PhysXCharacter : PhysicsActor
{
private Vector3 _position;
private Vector3 _velocity;
private Vector3 m_rotationalVelocity = Vector3.Zero;
private Vector3 _acceleration;
private NxCharacter _character;
private bool flying;
private bool iscolliding = false;
private float gravityAccel;
public PhysXCharacter(NxCharacter character)
{
_character = character;
}
public override int PhysicsActorType
{
get { return (int) ActorTypes.Agent; }
set { return; }
}
public override bool SetAlwaysRun
{
get { return false; }
set { return; }
}
public override uint LocalID
{
set { return; }
}
public override bool Grabbed
{
set { return; }
}
public override bool Selected
{
set { return; }
}
public override float Buoyancy
{
get { return 0f; }
set { return; }
}
public override bool FloatOnWater
{
set { return; }
}
public override bool IsPhysical
{
get { return false; }
set { return; }
}
public override bool ThrottleUpdates
{
get { return false; }
set { return; }
}
public override bool Flying
{
get { return flying; }
set { flying = value; }
}
public override bool IsColliding
{
get { return iscolliding; }
set { iscolliding = value; }
}
public override bool CollidingGround
{
get { return false; }
set { return; }
}
public override bool CollidingObj
{
get { return false; }
set { return; }
}
public override Vector3 RotationalVelocity
{
get { return m_rotationalVelocity; }
set { m_rotationalVelocity = value; }
}
public override bool Stopped
{
get { return false; }
}
public override Vector3 Position
{
get { return _position; }
set
{
_position = value;
Vec3 ps = new Vec3();
ps.X = value.X;
ps.Y = value.Y;
ps.Z = value.Z;
_character.Position = ps;
}
}
public override Vector3 Size
{
get { return Vector3.Zero; }
set { }
}
public override float Mass
{
get { return 0f; }
}
public override Vector3 Force
{
get { return Vector3.Zero; }
set { return; }
}
public override int VehicleType
{
get { return 0; }
set { return; }
}
public override void VehicleFloatParam(int param, float value)
{
}
public override void VehicleVectorParam(int param, Vector3 value)
{
}
public override void VehicleRotationParam(int param, Quaternion rotation)
{
}
public override void VehicleFlags(int param, bool remove)
{
}
public override void SetVolumeDetect(int param)
{
}
public override Vector3 CenterOfMass
{
get { return Vector3.Zero; }
}
public override Vector3 GeometricCenter
{
get { return Vector3.Zero; }
}
public override Vector3 Velocity
{
get { return _velocity; }
set { _velocity = value; }
}
public override float CollisionScore
{
get { return 0f; }
set { }
}
public override bool Kinematic
{
get { return false; }
set { }
}
public override Quaternion Orientation
{
get { return Quaternion.Identity; }
set { }
}
public override Vector3 Acceleration
{
get { return _acceleration; }
set { _acceleration = value; }
}
public override void AddForce(Vector3 force, bool pushforce)
{
}
public override Vector3 Torque
{
get { return Vector3.Zero; }
set { return; }
}
public override void AddAngularForce(Vector3 force, bool pushforce)
{
}
public override void link(PhysicsActor obj)
{
}
public override void delink()
{
}
public override void LockAngularMotion(Vector3 axis)
{
}
public override void SetMomentum(Vector3 momentum)
{
}
public void Move(float timeStep)
{
Vec3 vec = new Vec3();
vec.X = _velocity.X*timeStep;
vec.Y = _velocity.Y*timeStep;
if (flying)
{
vec.Z = (_velocity.Z)*timeStep;
}
else
{
gravityAccel += -9.8f;
vec.Z = (gravityAccel + _velocity.Z)*timeStep;
}
int res = _character.Move(vec);
if (res == 1)
{
gravityAccel = 0;
}
}
public override PrimitiveBaseShape Shape
{
set { return; }
}
public void UpdatePosition()
{
Vec3 vec = _character.Position;
_position.X = vec.X;
_position.Y = vec.Y;
_position.Z = vec.Z;
}
public override void CrossingFailure()
{
}
public override Vector3 PIDTarget { set { return; } }
public override bool PIDActive { set { return; } }
public override float PIDTau { set { return; } }
public override float PIDHoverHeight { set { return; } }
public override bool PIDHoverActive { set { return; } }
public override PIDHoverType PIDHoverType { set { return; } }
public override float PIDHoverTau { set { return; } }
public override Quaternion APIDTarget
{
set { return; }
}
public override bool APIDActive
{
set { return; }
}
public override float APIDStrength
{
set { return; }
}
public override float APIDDamping
{
set { return; }
}
public override void SubscribeEvents(int ms)
{
}
public override void UnSubscribeEvents()
{
}
public override bool SubscribedEvents()
{
return false;
}
}
}
@@ -1,341 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 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.
*/
using System;
using System.Collections.Generic;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Region.Physics.Manager;
using PhysXWrapper;
using Quaternion=OpenMetaverse.Quaternion;
using System.Reflection;
using log4net;
using OpenMetaverse;
namespace OpenSim.Region.Physics.PhysXPlugin
{
public class PhysXPrim : PhysicsActor
{
private Vector3 _velocity;
private Vector3 _acceleration;
private Vector3 m_rotationalVelocity;
private NxActor _prim;
public PhysXPrim(NxActor prim)
{
_velocity = Vector3.Zero;
_acceleration = Vector3.Zero;
_prim = prim;
}
public override int PhysicsActorType
{
get { return (int) ActorTypes.Prim; }
set { return; }
}
public override bool IsPhysical
{
get { return false; }
set { return; }
}
public override bool SetAlwaysRun
{
get { return false; }
set { return; }
}
public override uint LocalID
{
set { return; }
}
public override bool Grabbed
{
set { return; }
}
public override bool Selected
{
set { return; }
}
public override float Buoyancy
{
get { return 0f; }
set { return; }
}
public override bool FloatOnWater
{
set { return; }
}
public override bool ThrottleUpdates
{
get { return false; }
set { return; }
}
public override Vector3 RotationalVelocity
{
get { return m_rotationalVelocity; }
set { m_rotationalVelocity = value; }
}
public override bool Flying
{
get { return false; //no flying prims for you
}
set { }
}
public override bool IsColliding
{
get { return false; }
set { }
}
public override bool CollidingGround
{
get { return false; }
set { return; }
}
public override bool CollidingObj
{
get { return false; }
set { return; }
}
public override bool Stopped
{
get { return false; }
}
public override Vector3 Position
{
get
{
Vector3 pos = Vector3.Zero;
Vec3 vec = _prim.Position;
pos.X = vec.X;
pos.Y = vec.Y;
pos.Z = vec.Z;
return pos;
}
set
{
Vector3 vec = value;
Vec3 pos = new Vec3();
pos.X = vec.X;
pos.Y = vec.Y;
pos.Z = vec.Z;
_prim.Position = pos;
}
}
public override PrimitiveBaseShape Shape
{
set { return; }
}
public override Vector3 Velocity
{
get { return _velocity; }
set { _velocity = value; }
}
public override Vector3 Torque
{
get { return Vector3.Zero; }
set { return; }
}
public override float CollisionScore
{
get { return 0f; }
set { }
}
public override bool Kinematic
{
get { return _prim.Kinematic; }
set { _prim.Kinematic = value; }
}
public override Quaternion Orientation
{
get
{
Quaternion res;
PhysXWrapper.Quaternion quat = _prim.GetOrientation();
res.W = quat.W;
res.X = quat.X;
res.Y = quat.Y;
res.Z = quat.Z;
return res;
}
set { }
}
public override Vector3 Acceleration
{
get { return _acceleration; }
set { _acceleration = value; }
}
public override void AddForce(Vector3 force, bool pushforce)
{
}
public override void AddAngularForce(Vector3 force, bool pushforce)
{
}
public override void SetMomentum(Vector3 momentum)
{
}
public override Vector3 Size
{
get { return Vector3.Zero; }
set { }
}
public override void link(PhysicsActor obj)
{
}
public override void delink()
{
}
public override void LockAngularMotion(Vector3 axis)
{
}
public override float Mass
{
get { return 0f; }
}
public override Vector3 Force
{
get { return Vector3.Zero; }
set { return; }
}
public override int VehicleType
{
get { return 0; }
set { return; }
}
public override void VehicleFloatParam(int param, float value)
{
}
public override void VehicleVectorParam(int param, Vector3 value)
{
}
public override void VehicleRotationParam(int param, Quaternion rotation)
{
}
public override void VehicleFlags(int param, bool remove) { }
public override void SetVolumeDetect(int param)
{
}
public override Vector3 CenterOfMass
{
get { return Vector3.Zero; }
}
public override Vector3 GeometricCenter
{
get { return Vector3.Zero; }
}
public override void CrossingFailure()
{
}
public override Vector3 PIDTarget { set { return; } }
public override bool PIDActive { set { return; } }
public override float PIDTau { set { return; } }
public override float PIDHoverHeight { set { return; } }
public override bool PIDHoverActive { set { return; } }
public override PIDHoverType PIDHoverType { set { return; } }
public override float PIDHoverTau { set { return; } }
public override Quaternion APIDTarget
{
set { return; }
}
public override bool APIDActive
{
set { return; }
}
public override float APIDStrength
{
set { return; }
}
public override float APIDDamping
{
set { return; }
}
public override void SubscribeEvents(int ms)
{
}
public override void UnSubscribeEvents()
{
}
public override bool SubscribedEvents()
{
return false;
}
}
}
@@ -1,177 +0,0 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 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.
*/
using System;
using System.Collections.Generic;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Region.Physics.Manager;
using PhysXWrapper;
using Quaternion=OpenMetaverse.Quaternion;
using System.Reflection;
using log4net;
using OpenMetaverse;
namespace OpenSim.Region.Physics.PhysXPlugin
{
public class PhysXScene : PhysicsScene
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private List<PhysXCharacter> _characters = new List<PhysXCharacter>();
private List<PhysXPrim> _prims = new List<PhysXPrim>();
private float[] _heightMap = null;
private NxPhysicsSDK mySdk;
private NxScene scene;
// protected internal string sceneIdentifier;
public PhysXScene(string _sceneIdentifier)
{
//sceneIdentifier = _sceneIdentifier;
mySdk = NxPhysicsSDK.CreateSDK();
m_log.Info("Sdk created - now creating scene");
scene = mySdk.CreateScene();
}
public override void Initialise(IMesher meshmerizer, IConfigSource config)
{
// Does nothing right now
}
public override void Dispose()
{
}
public override void SetWaterLevel(float baseheight)
{
}
public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying)
{
Vec3 pos = new Vec3();
pos.X = position.X;
pos.Y = position.Y;
pos.Z = position.Z;
PhysXCharacter act = new PhysXCharacter(scene.AddCharacter(pos));
act.Flying = isFlying;
act.Position = position;
_characters.Add(act);
return act;
}
public override void RemovePrim(PhysicsActor prim)
{
}
public override void RemoveAvatar(PhysicsActor actor)
{
}
private PhysicsActor AddPrim(Vector3 position, Vector3 size, Quaternion rotation)
{
Vec3 pos = new Vec3();
pos.X = position.X;
pos.Y = position.Y;
pos.Z = position.Z;
Vec3 siz = new Vec3();
siz.X = size.X;
siz.Y = size.Y;
siz.Z = size.Z;
PhysXPrim act = new PhysXPrim(scene.AddNewBox(pos, siz));
_prims.Add(act);
return act;
}
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
Vector3 size, Quaternion rotation, bool isPhysical, uint localid)
{
return AddPrim(position, size, rotation);
}
public override void AddPhysicsActorTaint(PhysicsActor prim)
{
}
public override float Simulate(float timeStep)
{
float fps = 0f;
try
{
foreach (PhysXCharacter actor in _characters)
{
actor.Move(timeStep);
}
scene.Simulate(timeStep);
scene.FetchResults();
scene.UpdateControllers();
foreach (PhysXCharacter actor in _characters)
{
actor.UpdatePosition();
}
}
catch (Exception e)
{
m_log.Error(e.Message);
}
return fps;
}
public override void GetResults()
{
}
public override bool IsThreaded
{
// for now we won't be multithreaded
get { return (false); }
}
public override void SetTerrain(float[] heightMap)
{
if (_heightMap != null)
{
m_log.Debug("PhysX - deleting old terrain");
scene.DeleteTerrain();
}
_heightMap = heightMap;
scene.AddTerrain(heightMap);
}
public override void DeleteTerrain()
{
scene.DeleteTerrain();
}
public override Dictionary<uint, float> GetTopColliders()
{
Dictionary<uint, float> returncolliders = new Dictionary<uint, float>();
return returncolliders;
}
}
}
@@ -26,7 +26,7 @@
*/
// Revision by Ubit 2011
// Revision by Ubit 2011/12
using System;
using System.Collections.Generic;
@@ -95,21 +95,12 @@ namespace OpenSim.Region.Physics.OdePlugin
private bool m_iscollidingObj = false;
private bool m_alwaysRun = false;
private int m_requestedUpdateFrequency = 0;
private Vector3 m_taintPosition = Vector3.Zero;
private bool m_hasTaintPosition = false;
public uint m_localID = 0;
public bool m_returnCollisions = false;
// taints and their non-tainted counterparts
public bool m_isPhysical = false; // the current physical status
public bool m_tainted_isPhysical = false; // set when the physical status is tainted (false=not existing in physics engine, true=existing)
public float MinimumGroundFlightOffset = 3f;
private Vector3 m_taintForce;
private bool m_hasTaintForce;
private float m_tainted_CAPSULE_LENGTH; // set when the capsule length changes.
private float m_buoyancy = 0f;
// private CollisionLocker ode;
@@ -135,7 +126,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public IntPtr Shell = IntPtr.Zero;
public IntPtr Amotor = IntPtr.Zero;
public d.Mass ShellMass;
public bool collidelock = false;
// public bool collidelock = false;
private bool m_haseventsubscription = false;
public int m_eventsubscription = 0;
@@ -151,15 +142,13 @@ namespace OpenSim.Region.Physics.OdePlugin
{
m_uuid = UUID.Random();
m_hasTaintPosition = false;
if (pos.IsFinite())
{
if (pos.Z > 9999999f)
if (pos.Z > 99999f)
{
pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
}
if (pos.Z < -90000f)
if (pos.Z < -100f) // shouldn't this be 0 ?
{
pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
}
@@ -187,15 +176,12 @@ namespace OpenSim.Region.Physics.OdePlugin
CAPSULE_LENGTH = size.Z * 1.15f - CAPSULE_RADIUS * 2.0f;
//m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString());
m_tainted_CAPSULE_LENGTH = CAPSULE_LENGTH;
m_isPhysical = false; // current status: no ODE information exists
m_tainted_isPhysical = true; // new tainted status: need to create ODE information
m_hasTaintForce = false;
_parent_scene.AddPhysicsActorTaint(this);
m_name = avName;
AddChange(changes.Add, null);
}
public override int PhysicsActorType
@@ -402,16 +388,11 @@ namespace OpenSim.Region.Physics.OdePlugin
{
value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
}
if (value.Z < -90000f)
if (value.Z < -100f)
{
value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
}
m_taintPosition.X = value.X;
m_taintPosition.Y = value.Y;
m_taintPosition.Z = value.Z;
m_hasTaintPosition = true;
_parent_scene.AddPhysicsActorTaint(this);
AddChange(changes.Position, value);
}
else
{
@@ -440,11 +421,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (value.IsFinite())
{
m_pidControllerActive = true;
Vector3 SetSize = value;
m_tainted_CAPSULE_LENGTH = SetSize.Z *1.15f - CAPSULE_RADIUS * 2.0f;
_parent_scene.AddPhysicsActorTaint(this);
AddChange(changes.Size, value);
}
else
{
@@ -460,129 +437,6 @@ namespace OpenSim.Region.Physics.OdePlugin
/// <param name="npositionY"></param>
/// <param name="npositionZ"></param>
// WARNING: This MUST NOT be called outside of ProcessTaints, else we can have unsynchronized access
// to ODE internals. ProcessTaints is called from within thread-locked Simulate(), so it is the only
// place that is safe to call this routine AvatarGeomAndBodyCreation.
private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ)
{
_parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace);
if (CAPSULE_LENGTH <= 0)
{
m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!");
CAPSULE_LENGTH = 0.01f;
}
if (CAPSULE_RADIUS <= 0)
{
m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!");
CAPSULE_RADIUS = 0.01f;
}
Shell = d.CreateCapsule(_parent_scene.ActiveSpace, CAPSULE_RADIUS, CAPSULE_LENGTH);
d.GeomSetCategoryBits(Shell, (int)m_collisionCategories);
d.GeomSetCollideBits(Shell, (int)m_collisionFlags);
d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH);
m_mass = ShellMass.mass; // update mass
// rescale PID parameters
PID_D = _parent_scene.avPIDD;
PID_P = _parent_scene.avPIDP;
// rescale PID parameters so that this aren't affected by mass
// and so don't get unstable for some masses
// also scale by ode time step so you don't need to refix them
PID_D /= 50 * 80; //scale to original mass of around 80 and 50 ODE fps
PID_D *= m_mass / _parent_scene.ODE_STEPSIZE;
PID_P /= 50 * 80;
PID_P *= m_mass / _parent_scene.ODE_STEPSIZE;
Body = d.BodyCreate(_parent_scene.world);
d.BodySetAutoDisableFlag(Body, false);
d.BodySetPosition(Body, npositionX, npositionY, npositionZ);
_position.X = npositionX;
_position.Y = npositionY;
_position.Z = npositionZ;
m_hasTaintPosition = false;
d.BodySetMass(Body, ref ShellMass);
d.GeomSetBody(Shell, Body);
// The purpose of the AMotor here is to keep the avatar's physical
// surrogate from rotating while moving
Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero);
d.JointAttach(Amotor, Body, IntPtr.Zero);
d.JointSetAMotorMode(Amotor, 0);
d.JointSetAMotorNumAxes(Amotor, 3);
d.JointSetAMotorAxis(Amotor, 0, 0 , 1, 0, 0);
d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0);
d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1);
d.JointSetAMotorAngle(Amotor, 0, 0);
d.JointSetAMotorAngle(Amotor, 1, 0);
d.JointSetAMotorAngle(Amotor, 2, 0);
d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM, 0f); // make it HARD
d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM2, 0f);
d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM3, 0f);
d.JointSetAMotorParam(Amotor, (int)dParam.StopERP, 0.8f);
d.JointSetAMotorParam(Amotor, (int)dParam.StopERP2, 0.8f);
d.JointSetAMotorParam(Amotor, (int)dParam.StopERP3, 0.8f);
// These lowstops and high stops are effectively (no wiggle room)
d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -1e-5f);
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 1e-5f);
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -1e-5f);
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 1e-5f);
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -1e-5f);
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 1e-5f);
d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel, 0);
d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel2, 0);
d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel3, 0);
d.JointSetAMotorParam(Amotor, (int)dParam.FMax, 5e6f);
d.JointSetAMotorParam(Amotor, (int)dParam.FMax2, 5e6f);
d.JointSetAMotorParam(Amotor, (int)dParam.FMax3, 5e6f);
}
/// <summary>
/// Destroys the avatar body and geom
private void AvatarGeomAndBodyDestroy()
{
// Kill the Amotor
if (Amotor != IntPtr.Zero)
{
d.JointDestroy(Amotor);
Amotor = IntPtr.Zero;
}
if (Body != IntPtr.Zero)
{
//kill the body
d.BodyDestroy(Body);
Body = IntPtr.Zero;
}
//kill the Geometry
if (Shell != IntPtr.Zero)
{
_parent_scene.geom_name_map.Remove(Shell);
_parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace);
d.GeomDestroy(Shell);
_parent_scene.geom_name_map.Remove(Shell);
Shell = IntPtr.Zero;
}
}
//
/// <summary>
/// Uses the capped cyllinder volume formula to calculate the avatar's mass.
@@ -705,8 +559,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (value.IsFinite())
{
m_pidControllerActive = true;
_target_velocity = value;
AddChange(changes.Velocity, value);
}
else
{
@@ -738,9 +591,6 @@ namespace OpenSim.Region.Physics.OdePlugin
get { return Quaternion.Identity; }
set
{
//Matrix3 or = Orientation.ToRotationMatrix();
//d.Matrix3 ord = new d.Matrix3(or.m00, or.m10, or.m20, or.m01, or.m11, or.m21, or.m02, or.m12, or.m22);
//d.BodySetRotation(Body, ref ord);
}
}
@@ -767,17 +617,11 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (pushforce)
{
m_pidControllerActive = false;
m_taintForce = force / _parent_scene.ODE_STEPSIZE;
m_hasTaintForce = true;
_parent_scene.AddPhysicsActorTaint(this);
AddChange(changes.Force, force * m_density / _parent_scene.ODE_STEPSIZE / 28f);
}
else
{
m_pidControllerActive = true;
_target_velocity.X += force.X;
_target_velocity.Y += force.Y;
_target_velocity.Z += force.Z;
AddChange(changes.Velocity, force);
}
}
else
@@ -797,6 +641,128 @@ namespace OpenSim.Region.Physics.OdePlugin
}
// WARNING: This MUST NOT be called outside of ProcessTaints, else we can have unsynchronized access
// to ODE internals. ProcessTaints is called from within thread-locked Simulate(), so it is the only
// place that is safe to call this routine AvatarGeomAndBodyCreation.
private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ)
{
_parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace);
if (CAPSULE_LENGTH <= 0)
{
m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!");
CAPSULE_LENGTH = 0.01f;
}
if (CAPSULE_RADIUS <= 0)
{
m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!");
CAPSULE_RADIUS = 0.01f;
}
Shell = d.CreateCapsule(_parent_scene.ActiveSpace, CAPSULE_RADIUS, CAPSULE_LENGTH);
d.GeomSetCategoryBits(Shell, (int)m_collisionCategories);
d.GeomSetCollideBits(Shell, (int)m_collisionFlags);
d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH);
m_mass = ShellMass.mass; // update mass
// rescale PID parameters
PID_D = _parent_scene.avPIDD;
PID_P = _parent_scene.avPIDP;
// rescale PID parameters so that this aren't affected by mass
// and so don't get unstable for some masses
// also scale by ode time step so you don't need to refix them
PID_D /= 50 * 80; //scale to original mass of around 80 and 50 ODE fps
PID_D *= m_mass / _parent_scene.ODE_STEPSIZE;
PID_P /= 50 * 80;
PID_P *= m_mass / _parent_scene.ODE_STEPSIZE;
Body = d.BodyCreate(_parent_scene.world);
d.BodySetAutoDisableFlag(Body, false);
d.BodySetPosition(Body, npositionX, npositionY, npositionZ);
_position.X = npositionX;
_position.Y = npositionY;
_position.Z = npositionZ;
d.BodySetMass(Body, ref ShellMass);
d.GeomSetBody(Shell, Body);
// The purpose of the AMotor here is to keep the avatar's physical
// surrogate from rotating while moving
Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero);
d.JointAttach(Amotor, Body, IntPtr.Zero);
d.JointSetAMotorMode(Amotor, 0);
d.JointSetAMotorNumAxes(Amotor, 3);
d.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0);
d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0);
d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1);
d.JointSetAMotorAngle(Amotor, 0, 0);
d.JointSetAMotorAngle(Amotor, 1, 0);
d.JointSetAMotorAngle(Amotor, 2, 0);
d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM, 0f); // make it HARD
d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM2, 0f);
d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM3, 0f);
d.JointSetAMotorParam(Amotor, (int)dParam.StopERP, 0.8f);
d.JointSetAMotorParam(Amotor, (int)dParam.StopERP2, 0.8f);
d.JointSetAMotorParam(Amotor, (int)dParam.StopERP3, 0.8f);
// These lowstops and high stops are effectively (no wiggle room)
d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -1e-5f);
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 1e-5f);
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -1e-5f);
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 1e-5f);
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -1e-5f);
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 1e-5f);
d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel, 0);
d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel2, 0);
d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel3, 0);
d.JointSetAMotorParam(Amotor, (int)dParam.FMax, 5e6f);
d.JointSetAMotorParam(Amotor, (int)dParam.FMax2, 5e6f);
d.JointSetAMotorParam(Amotor, (int)dParam.FMax3, 5e6f);
}
/// <summary>
/// Destroys the avatar body and geom
private void AvatarGeomAndBodyDestroy()
{
// Kill the Amotor
if (Amotor != IntPtr.Zero)
{
d.JointDestroy(Amotor);
Amotor = IntPtr.Zero;
}
if (Body != IntPtr.Zero)
{
//kill the body
d.BodyDestroy(Body);
Body = IntPtr.Zero;
}
//kill the Geometry
if (Shell != IntPtr.Zero)
{
_parent_scene.geom_name_map.Remove(Shell);
_parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace);
d.GeomDestroy(Shell);
_parent_scene.geom_name_map.Remove(Shell);
Shell = IntPtr.Zero;
}
}
/// <summary>
/// Called from Simulate
/// This is the avatar's movement control + PID Controller
@@ -1135,8 +1101,7 @@ namespace OpenSim.Region.Physics.OdePlugin
/// </summary>
public void Destroy()
{
m_tainted_isPhysical = false;
_parent_scene.AddPhysicsActorTaint(this);
AddChange(changes.Remove, null);
}
public override void CrossingFailure()
@@ -1206,12 +1171,11 @@ namespace OpenSim.Region.Physics.OdePlugin
return m_haseventsubscription;
}
public void ProcessTaints(float timestep)
private void changePhysicsStatus(bool NewStatus)
{
if (m_tainted_isPhysical != m_isPhysical)
if (NewStatus != m_isPhysical)
{
if (m_tainted_isPhysical)
if (NewStatus)
{
// Create avatar capsule and related ODE data
if ((Shell != IntPtr.Zero))
@@ -1236,60 +1200,246 @@ namespace OpenSim.Region.Physics.OdePlugin
AvatarGeomAndBodyDestroy();
}
m_isPhysical = m_tainted_isPhysical;
m_isPhysical = NewStatus;
}
if (m_tainted_CAPSULE_LENGTH != CAPSULE_LENGTH)
{
if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero)
{
AvatarGeomAndBodyDestroy();
m_pidControllerActive = true;
float prevCapsule = CAPSULE_LENGTH;
CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH;
AvatarGeomAndBodyCreation(_position.X, _position.Y,
_position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2));
Velocity = Vector3.Zero;
_parent_scene.geom_name_map[Shell] = m_name;
_parent_scene.actor_name_map[Shell] = (PhysicsActor)this;
}
else
{
m_log.Warn("[PHYSICS]: trying to change capsule size, but the following ODE data is missing - "
+ (Shell == IntPtr.Zero ? "Shell " : "")
+ (Body == IntPtr.Zero ? "Body " : "")
+ (Amotor == IntPtr.Zero ? "Amotor " : ""));
}
}
if (m_hasTaintPosition)
{
if (Body != IntPtr.Zero)
d.BodySetPosition(Body, m_taintPosition.X, m_taintPosition.Y, m_taintPosition.Z);
_position.X = m_taintPosition.X;
_position.Y = m_taintPosition.Y;
_position.Z = m_taintPosition.Z;
m_hasTaintPosition = false;
}
if (m_hasTaintForce)
{
if (Body != IntPtr.Zero)
{
if(m_taintForce.X !=0f || m_taintForce.Y !=0f || m_taintForce.Z !=0)
d.BodyAddForce(Body, m_taintForce.X, m_taintForce.Y, m_taintForce.Z);
m_hasTaintForce = false;
}
}
}
private void changeAdd()
{
changePhysicsStatus(true);
}
private void changeRemove()
{
changePhysicsStatus(false);
}
private void changeShape(PrimitiveBaseShape arg)
{
}
private void changeSize(Vector3 Size)
{
if (Size.IsFinite())
{
float caplen = Size.Z;
caplen = caplen * 1.15f - CAPSULE_RADIUS * 2.0f;
if (caplen != CAPSULE_LENGTH)
{
if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero)
{
AvatarGeomAndBodyDestroy();
float prevCapsule = CAPSULE_LENGTH;
CAPSULE_LENGTH = caplen;
AvatarGeomAndBodyCreation(_position.X, _position.Y,
_position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2));
Velocity = Vector3.Zero;
_parent_scene.geom_name_map[Shell] = m_name;
_parent_scene.actor_name_map[Shell] = (PhysicsActor)this;
}
else
{
m_log.Warn("[PHYSICS]: trying to change capsule size, but the following ODE data is missing - "
+ (Shell == IntPtr.Zero ? "Shell " : "")
+ (Body == IntPtr.Zero ? "Body " : "")
+ (Amotor == IntPtr.Zero ? "Amotor " : ""));
}
}
m_pidControllerActive = true;
}
else
{
m_log.Warn("[PHYSICS]: Got a NaN Size from Scene on a Character");
}
}
private void changePosition( Vector3 newPos)
{
if (Body != IntPtr.Zero)
d.BodySetPosition(Body, newPos.X, newPos.Y, newPos.Z);
_position = newPos;
}
private void changeOrientation(Quaternion newOri)
{
}
private void changeVelocity(Vector3 newVel)
{
m_pidControllerActive = true;
_target_velocity = newVel;
}
private void changeSetTorque(Vector3 newTorque)
{
}
private void changeAddForce(Vector3 newForce)
{
}
private void changeAddAngularForce(Vector3 arg)
{
}
private void changeAngularLock(Vector3 arg)
{
}
private void changeFloatOnWater(bool arg)
{
}
private void changeVolumedetetion(bool arg)
{
}
private void changeSelectedStatus(bool arg)
{
}
private void changeDisable(bool arg)
{
}
private void changeBuilding(bool arg)
{
}
private void changeForce(Vector3 newForce)
{
m_pidControllerActive = false;
if (Body != IntPtr.Zero)
{
if (newForce.X != 0f || newForce.Y != 0f || newForce.Z != 0)
d.BodyAddForce(Body, newForce.X, newForce.Y, newForce.Z);
}
}
private void donullchange()
{
}
public bool DoAChange(changes what, object arg)
{
if (Shell == IntPtr.Zero && what != changes.Add && what != changes.Remove)
{
return false;
}
// nasty switch
switch (what)
{
case changes.Add:
changeAdd();
break;
case changes.Remove:
changeRemove();
break;
case changes.Position:
changePosition((Vector3)arg);
break;
case changes.Orientation:
changeOrientation((Quaternion)arg);
break;
case changes.PosOffset:
donullchange();
break;
case changes.OriOffset:
donullchange();
break;
case changes.Velocity:
changeVelocity((Vector3)arg);
break;
// case changes.Acceleration:
// changeacceleration((Vector3)arg);
// break;
// case changes.AngVelocity:
// changeangvelocity((Vector3)arg);
// break;
case changes.Force:
changeForce((Vector3)arg);
break;
case changes.Torque:
changeSetTorque((Vector3)arg);
break;
case changes.AddForce:
changeAddForce((Vector3)arg);
break;
case changes.AddAngForce:
changeAddAngularForce((Vector3)arg);
break;
case changes.AngLock:
changeAngularLock((Vector3)arg);
break;
case changes.Size:
changeSize((Vector3)arg);
break;
/* not in use for now
case changes.Shape:
changeShape((PrimitiveBaseShape)arg);
break;
case changes.CollidesWater:
changeFloatOnWater((bool)arg);
break;
case changes.VolumeDtc:
changeVolumedetetion((bool)arg);
break;
case changes.Physical:
changePhysicsStatus((bool)arg);
break;
case changes.Selected:
changeSelectedStatus((bool)arg);
break;
case changes.disabled:
changeDisable((bool)arg);
break;
case changes.building:
changeBuilding((bool)arg);
break;
*/
case changes.Null:
donullchange();
break;
default:
donullchange();
break;
}
return false;
}
public void AddChange(changes what, object arg)
{
_parent_scene.AddChange((PhysicsActor)this, what, arg);
}
internal void AddCollisionFrameTime(int p)
{
// protect it from overflow crashing
@@ -1,630 +0,0 @@
/*
* Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces
* ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
* ODEPrim.cs contains methods dealing with Prim editing, Prim
* characteristics and Kinetic motion.
* ODEDynamics.cs contains methods dealing with Prim Physical motion
* (dynamics) and the associated settings. Old Linear and angular
* motors for dynamic motion have been replace with MoveLinear()
* and MoveAngular(); 'Physical' is used only to switch ODE dynamic
* simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
* switch between 'VEHICLE' parameter use and general dynamics
* settings use.
*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 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.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using log4net;
using OpenMetaverse;
using Ode.NET;
using OpenSim.Framework;
using OpenSim.Region.Physics.Manager;
namespace OpenSim.Region.Physics.OdePlugin
{
public class ODEDynamics
{
public Vehicle Type
{
get { return m_type; }
}
public IntPtr Body
{
get { return m_body; }
}
private int frcount = 0; // Used to limit dynamics debug output to
// every 100th frame
// private OdeScene m_parentScene = null;
private IntPtr m_body = IntPtr.Zero;
private IntPtr m_jointGroup = IntPtr.Zero;
private IntPtr m_aMotor = IntPtr.Zero;
// Vehicle properties
private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind
// private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier
private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings:
// HOVER_TERRAIN_ONLY
// HOVER_GLOBAL_HEIGHT
// NO_DEFLECTION_UP
// HOVER_WATER_ONLY
// HOVER_UP_ONLY
// LIMIT_MOTOR_UP
// LIMIT_ROLL_ONLY
// Linear properties
private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time
private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL
private Vector3 m_dir = Vector3.Zero; // velocity applied to body
private Vector3 m_linearFrictionTimescale = Vector3.Zero;
private float m_linearMotorDecayTimescale = 0;
private float m_linearMotorTimescale = 0;
private Vector3 m_lastLinearVelocityVector = Vector3.Zero;
// private bool m_LinearMotorSetLastFrame = false;
// private Vector3 m_linearMotorOffset = Vector3.Zero;
//Angular properties
private Vector3 m_angularMotorDirection = Vector3.Zero;
private Vector3 m_angularMotorDirectionLASTSET = Vector3.Zero;
private Vector3 m_angularFrictionTimescale = Vector3.Zero;
private float m_angularMotorDecayTimescale = 0;
private float m_angularMotorTimescale = 0;
private Vector3 m_lastAngularVelocityVector = Vector3.Zero;
//Deflection properties
// private float m_angularDeflectionEfficiency = 0;
// private float m_angularDeflectionTimescale = 0;
// private float m_linearDeflectionEfficiency = 0;
// private float m_linearDeflectionTimescale = 0;
//Banking properties
// private float m_bankingEfficiency = 0;
// private float m_bankingMix = 0;
// private float m_bankingTimescale = 0;
//Hover and Buoyancy properties
private float m_VhoverHeight = 0f;
private float m_VhoverEfficiency = 0f;
private float m_VhoverTimescale = 0f;
private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle.
// Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
// KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
// Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
//Attractor properties
private float m_verticalAttractionEfficiency = 0;
private float m_verticalAttractionTimescale = 0;
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
{
switch (pParam)
{
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
if (pValue < 0.01f) pValue = 0.01f;
// m_angularDeflectionEfficiency = pValue;
break;
case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
if (pValue < 0.01f) pValue = 0.01f;
// m_angularDeflectionTimescale = pValue;
break;
case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
if (pValue < 0.01f) pValue = 0.01f;
m_angularMotorDecayTimescale = pValue;
break;
case Vehicle.ANGULAR_MOTOR_TIMESCALE:
if (pValue < 0.01f) pValue = 0.01f;
m_angularMotorTimescale = pValue;
break;
case Vehicle.BANKING_EFFICIENCY:
if (pValue < 0.01f) pValue = 0.01f;
// m_bankingEfficiency = pValue;
break;
case Vehicle.BANKING_MIX:
if (pValue < 0.01f) pValue = 0.01f;
// m_bankingMix = pValue;
break;
case Vehicle.BANKING_TIMESCALE:
if (pValue < 0.01f) pValue = 0.01f;
// m_bankingTimescale = pValue;
break;
case Vehicle.BUOYANCY:
if (pValue < -1f) pValue = -1f;
if (pValue > 1f) pValue = 1f;
m_VehicleBuoyancy = pValue;
break;
case Vehicle.HOVER_EFFICIENCY:
if (pValue < 0f) pValue = 0f;
if (pValue > 1f) pValue = 1f;
m_VhoverEfficiency = pValue;
break;
case Vehicle.HOVER_HEIGHT:
m_VhoverHeight = pValue;
break;
case Vehicle.HOVER_TIMESCALE:
if (pValue < 0.01f) pValue = 0.01f;
m_VhoverTimescale = pValue;
break;
case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
if (pValue < 0.01f) pValue = 0.01f;
// m_linearDeflectionEfficiency = pValue;
break;
case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
if (pValue < 0.01f) pValue = 0.01f;
// m_linearDeflectionTimescale = pValue;
break;
case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
if (pValue < 0.01f) pValue = 0.01f;
m_linearMotorDecayTimescale = pValue;
break;
case Vehicle.LINEAR_MOTOR_TIMESCALE:
if (pValue < 0.01f) pValue = 0.01f;
m_linearMotorTimescale = pValue;
break;
case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
if (pValue < 0.0f) pValue = 0.0f;
if (pValue > 1.0f) pValue = 1.0f;
m_verticalAttractionEfficiency = pValue;
break;
case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
if (pValue < 0.01f) pValue = 0.01f;
m_verticalAttractionTimescale = pValue;
break;
// These are vector properties but the engine lets you use a single float value to
// set all of the components to the same value
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
break;
case Vehicle.ANGULAR_MOTOR_DIRECTION:
m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
m_angularMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue);
break;
case Vehicle.LINEAR_FRICTION_TIMESCALE:
m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
break;
case Vehicle.LINEAR_MOTOR_DIRECTION:
m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue);
break;
case Vehicle.LINEAR_MOTOR_OFFSET:
// m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
break;
}
}//end ProcessFloatVehicleParam
internal void ProcessVectorVehicleParam(Vehicle pParam, PhysicsVector pValue)
{
switch (pParam)
{
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
break;
case Vehicle.ANGULAR_MOTOR_DIRECTION:
m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
m_angularMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z);
break;
case Vehicle.LINEAR_FRICTION_TIMESCALE:
m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
break;
case Vehicle.LINEAR_MOTOR_DIRECTION:
m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z);
break;
case Vehicle.LINEAR_MOTOR_OFFSET:
// m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
break;
}
}//end ProcessVectorVehicleParam
internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
{
switch (pParam)
{
case Vehicle.REFERENCE_FRAME:
// m_referenceFrame = pValue;
break;
}
}//end ProcessRotationVehicleParam
internal void ProcessTypeChange(Vehicle pType)
{
Console.WriteLine("ProcessTypeChange to " + pType);
// Set Defaults For Type
m_type = pType;
switch (pType)
{
case Vehicle.TYPE_SLED:
m_linearFrictionTimescale = new Vector3(30, 1, 1000);
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
m_linearMotorDirection = Vector3.Zero;
m_linearMotorTimescale = 1000;
m_linearMotorDecayTimescale = 120;
m_angularMotorDirection = Vector3.Zero;
m_angularMotorTimescale = 1000;
m_angularMotorDecayTimescale = 120;
m_VhoverHeight = 0;
m_VhoverEfficiency = 1;
m_VhoverTimescale = 10;
m_VehicleBuoyancy = 0;
// m_linearDeflectionEfficiency = 1;
// m_linearDeflectionTimescale = 1;
// m_angularDeflectionEfficiency = 1;
// m_angularDeflectionTimescale = 1000;
// m_bankingEfficiency = 0;
// m_bankingMix = 1;
// m_bankingTimescale = 10;
// m_referenceFrame = Quaternion.Identity;
m_flags &=
~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
break;
case Vehicle.TYPE_CAR:
m_linearFrictionTimescale = new Vector3(100, 2, 1000);
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
m_linearMotorDirection = Vector3.Zero;
m_linearMotorTimescale = 1;
m_linearMotorDecayTimescale = 60;
m_angularMotorDirection = Vector3.Zero;
m_angularMotorTimescale = 1;
m_angularMotorDecayTimescale = 0.8f;
m_VhoverHeight = 0;
m_VhoverEfficiency = 0;
m_VhoverTimescale = 1000;
m_VehicleBuoyancy = 0;
// // m_linearDeflectionEfficiency = 1;
// // m_linearDeflectionTimescale = 2;
// // m_angularDeflectionEfficiency = 0;
// m_angularDeflectionTimescale = 10;
m_verticalAttractionEfficiency = 1;
m_verticalAttractionTimescale = 10;
// m_bankingEfficiency = -0.2f;
// m_bankingMix = 1;
// m_bankingTimescale = 1;
// m_referenceFrame = Quaternion.Identity;
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_UP_ONLY |
VehicleFlag.LIMIT_MOTOR_UP);
break;
case Vehicle.TYPE_BOAT:
m_linearFrictionTimescale = new Vector3(10, 3, 2);
m_angularFrictionTimescale = new Vector3(10,10,10);
m_linearMotorDirection = Vector3.Zero;
m_linearMotorTimescale = 5;
m_linearMotorDecayTimescale = 60;
m_angularMotorDirection = Vector3.Zero;
m_angularMotorTimescale = 4;
m_angularMotorDecayTimescale = 4;
m_VhoverHeight = 0;
m_VhoverEfficiency = 0.5f;
m_VhoverTimescale = 2;
m_VehicleBuoyancy = 1;
// m_linearDeflectionEfficiency = 0.5f;
// m_linearDeflectionTimescale = 3;
// m_angularDeflectionEfficiency = 0.5f;
// m_angularDeflectionTimescale = 5;
m_verticalAttractionEfficiency = 0.5f;
m_verticalAttractionTimescale = 5;
// m_bankingEfficiency = -0.3f;
// m_bankingMix = 0.8f;
// m_bankingTimescale = 1;
// m_referenceFrame = Quaternion.Identity;
m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.LIMIT_ROLL_ONLY |
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY |
VehicleFlag.LIMIT_MOTOR_UP);
break;
case Vehicle.TYPE_AIRPLANE:
m_linearFrictionTimescale = new Vector3(200, 10, 5);
m_angularFrictionTimescale = new Vector3(20, 20, 20);
m_linearMotorDirection = Vector3.Zero;
m_linearMotorTimescale = 2;
m_linearMotorDecayTimescale = 60;
m_angularMotorDirection = Vector3.Zero;
m_angularMotorTimescale = 4;
m_angularMotorDecayTimescale = 4;
m_VhoverHeight = 0;
m_VhoverEfficiency = 0.5f;
m_VhoverTimescale = 1000;
m_VehicleBuoyancy = 0;
// m_linearDeflectionEfficiency = 0.5f;
// m_linearDeflectionTimescale = 3;
// m_angularDeflectionEfficiency = 1;
// m_angularDeflectionTimescale = 2;
m_verticalAttractionEfficiency = 0.9f;
m_verticalAttractionTimescale = 2;
// m_bankingEfficiency = 1;
// m_bankingMix = 0.7f;
// m_bankingTimescale = 2;
// m_referenceFrame = Quaternion.Identity;
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
break;
case Vehicle.TYPE_BALLOON:
m_linearFrictionTimescale = new Vector3(5, 5, 5);
m_angularFrictionTimescale = new Vector3(10, 10, 10);
m_linearMotorDirection = Vector3.Zero;
m_linearMotorTimescale = 5;
m_linearMotorDecayTimescale = 60;
m_angularMotorDirection = Vector3.Zero;
m_angularMotorTimescale = 6;
m_angularMotorDecayTimescale = 10;
m_VhoverHeight = 5;
m_VhoverEfficiency = 0.8f;
m_VhoverTimescale = 10;
m_VehicleBuoyancy = 1;
// m_linearDeflectionEfficiency = 0;
// m_linearDeflectionTimescale = 5;
// m_angularDeflectionEfficiency = 0;
// m_angularDeflectionTimescale = 5;
m_verticalAttractionEfficiency = 1;
m_verticalAttractionTimescale = 1000;
// m_bankingEfficiency = 0;
// m_bankingMix = 0.7f;
// m_bankingTimescale = 5;
// m_referenceFrame = Quaternion.Identity;
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
break;
}
}//end SetDefaultsForType
internal void Enable(IntPtr pBody, OdeScene pParentScene)
{
//Console.WriteLine("Enable m_type=" + m_type + " m_VehicleBuoyancy=" + m_VehicleBuoyancy);
if (m_type == Vehicle.TYPE_NONE)
return;
m_body = pBody;
//KF: This used to set up the linear and angular joints
}
internal void Step(float pTimestep, OdeScene pParentScene)
{
if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE)
return;
frcount++; // used to limit debug comment output
if (frcount > 100)
frcount = 0;
MoveLinear(pTimestep, pParentScene);
MoveAngular(pTimestep);
}// end Step
private void MoveLinear(float pTimestep, OdeScene _pParentScene)
{
if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) // requested m_linearMotorDirection is significant
{
if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
// add drive to body
Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep);
m_lastLinearVelocityVector += (addAmount*10); // lastLinearVelocityVector is the current body velocity vector?
// This will work temporarily, but we really need to compare speed on an axis
// KF: Limit body velocity to applied velocity?
if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X))
m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X;
if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y))
m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y;
if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z))
m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z;
// decay applied velocity
Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep)));
//Console.WriteLine("decay: " + decayfraction);
m_linearMotorDirection -= m_linearMotorDirection * decayfraction;
//Console.WriteLine("actual: " + m_linearMotorDirection);
}
else
{ // requested is not significant
// if what remains of applied is small, zero it.
if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f))
m_lastLinearVelocityVector = Vector3.Zero;
}
// convert requested object velocity to world-referenced vector
m_dir = m_lastLinearVelocityVector;
d.Quaternion rot = d.BodyGetQuaternion(Body);
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
m_dir *= rotq; // apply obj rotation to velocity vector
// add Gravity andBuoyancy
// KF: So far I have found no good method to combine a script-requested
// .Z velocity and gravity. Therefore only 0g will used script-requested
// .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only.
Vector3 grav = Vector3.Zero;
if(m_VehicleBuoyancy < 1.0f)
{
// There is some gravity, make a gravity force vector
// that is applied after object velocity.
d.Mass objMass;
d.BodyGetMass(Body, out objMass);
// m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
grav.Z = _pParentScene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy);
// Preserve the current Z velocity
d.Vector3 vel_now = d.BodyGetLinearVel(Body);
m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity
} // else its 1.0, no gravity.
// Check if hovering
if( (m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
{
// We should hover, get the target height
d.Vector3 pos = d.BodyGetPosition(Body);
if((m_flags & VehicleFlag.HOVER_WATER_ONLY) == VehicleFlag.HOVER_WATER_ONLY)
{
m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight;
}
else if((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) == VehicleFlag.HOVER_TERRAIN_ONLY)
{
m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
}
else if((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == VehicleFlag.HOVER_GLOBAL_HEIGHT)
{
m_VhoverTargetHeight = m_VhoverHeight;
}
if((m_flags & VehicleFlag.HOVER_UP_ONLY) == VehicleFlag.HOVER_UP_ONLY)
{
// If body is aready heigher, use its height as target height
if(pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
}
// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped
// m_VhoverTimescale = 0f; // time to acheive height
// pTimestep is time since last frame,in secs
float herr0 = pos.Z - m_VhoverTargetHeight;
//if(frcount == 0) Console.WriteLine("herr0=" + herr0);
// Replace Vertical speed with correction figure if significant
if(Math.Abs(herr0) > 0.01f )
{
d.Mass objMass;
d.BodyGetMass(Body, out objMass);
m_dir.Z = - ( (herr0 * pTimestep * 50.0f) / m_VhoverTimescale);
// m_VhoverEfficiency is not yet implemented
}
else
{
m_dir.Z = 0f;
}
}
// Apply velocity
d.BodySetLinearVel(Body, m_dir.X, m_dir.Y, m_dir.Z);
//if(frcount == 0) Console.WriteLine("Move " + Body + ":"+ m_dir.X + " " + m_dir.Y + " " + m_dir.Z);
// apply gravity force
d.BodyAddForce(Body, grav.X, grav.Y, grav.Z);
//if(frcount == 0) Console.WriteLine("Force " + Body + ":" + grav.X + " " + grav.Y + " " + grav.Z);
// apply friction
Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep);
m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount;
} // end MoveLinear()
private void MoveAngular(float pTimestep)
{
// m_angularMotorDirection is the latest value from the script, and is decayed here
// m_angularMotorDirectionLASTSET is the latest value from the script
// m_lastAngularVelocityVector is what is being applied to the Body, varied up and down here
if (!m_angularMotorDirection.ApproxEquals(Vector3.Zero, 0.01f))
{
if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
// ramp up to new value
Vector3 addAmount = m_angularMotorDirection / (m_angularMotorTimescale / pTimestep);
m_lastAngularVelocityVector += (addAmount * 10f);
//if(frcount == 0) Console.WriteLine("add: " + addAmount);
// limit applied value to what was set by script
// This will work temporarily, but we really need to compare speed on an axis
if (Math.Abs(m_lastAngularVelocityVector.X) > Math.Abs(m_angularMotorDirectionLASTSET.X))
m_lastAngularVelocityVector.X = m_angularMotorDirectionLASTSET.X;
if (Math.Abs(m_lastAngularVelocityVector.Y) > Math.Abs(m_angularMotorDirectionLASTSET.Y))
m_lastAngularVelocityVector.Y = m_angularMotorDirectionLASTSET.Y;
if (Math.Abs(m_lastAngularVelocityVector.Z) > Math.Abs(m_angularMotorDirectionLASTSET.Z))
m_lastAngularVelocityVector.Z = m_angularMotorDirectionLASTSET.Z;
// decay the requested value
Vector3 decayfraction = ((Vector3.One / (m_angularMotorDecayTimescale / pTimestep)));
//Console.WriteLine("decay: " + decayfraction);
m_angularMotorDirection -= m_angularMotorDirection * decayfraction;
//Console.WriteLine("actual: " + m_linearMotorDirection);
}
// KF: m_lastAngularVelocityVector is rotational speed in rad/sec ?
// Vertical attractor section
// d.Mass objMass;
// d.BodyGetMass(Body, out objMass);
// float servo = 100f * objMass.mass * m_verticalAttractionEfficiency / (m_verticalAttractionTimescale * pTimestep);
float servo = 0.1f * m_verticalAttractionEfficiency / (m_verticalAttractionTimescale * pTimestep);
// get present body rotation
d.Quaternion rot = d.BodyGetQuaternion(Body);
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W);
// make a vector pointing up
Vector3 verterr = Vector3.Zero;
verterr.Z = 1.0f;
// rotate it to Body Angle
verterr = verterr * rotq;
// verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1.
// As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go
// negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body.
if (verterr.Z < 0.0f)
{
verterr.X = 2.0f - verterr.X;
verterr.Y = 2.0f - verterr.Y;
}
// Error is 0 (no error) to +/- 2 (max error)
// scale it by servo
verterr = verterr * servo;
// rotate to object frame
// verterr = verterr * rotq;
// As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so
// Change Body angular velocity X based on Y, and Y based on X. Z is not changed.
m_lastAngularVelocityVector.X += verterr.Y;
m_lastAngularVelocityVector.Y -= verterr.X;
/*
if(frcount == 0)
{
// Console.WriteLine("AngleMotor " + m_lastAngularVelocityVector);
Console.WriteLine(String.Format("VA Body:{0} servo:{1} err:<{2},{3},{4}> VAE:{5}",
Body, servo, verterr.X, verterr.Y, verterr.Z, m_verticalAttractionEfficiency));
}
*/
d.BodySetAngularVel (Body, m_lastAngularVelocityVector.X, m_lastAngularVelocityVector.Y, m_lastAngularVelocityVector.Z);
// apply friction
Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep);
m_lastAngularVelocityVector -= m_lastAngularVelocityVector * decayamount;
} //end MoveAngular
}
}
@@ -38,6 +38,8 @@
* settings use.
*/
// Ubit 2012
using System;
using System.Collections.Generic;
using System.Reflection;
@@ -57,24 +59,15 @@ namespace OpenSim.Region.Physics.OdePlugin
get { return m_type; }
}
// private OdeScene m_parentScene = null;
// private IntPtr m_aMotor = IntPtr.Zero;
private OdePrim rootPrim;
private OdeScene _pParentScene;
private Vector3 refUpAxis = new Vector3(0, 0, 1);
private Vector3 refAtAxis = new Vector3(1, 0, 0);
// Vehicle properties
private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier
private Quaternion m_RollreferenceFrame = Quaternion.Identity; // what hell is this ?
private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind
private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier
private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings:
// HOVER_TERRAIN_ONLY
// HOVER_GLOBAL_HEIGHT
@@ -84,7 +77,6 @@ namespace OpenSim.Region.Physics.OdePlugin
// LIMIT_MOTOR_UP
// LIMIT_ROLL_ONLY
private Vector3 m_BlockingEndPoint = Vector3.Zero; // not sl
private Quaternion m_RollreferenceFrame = Quaternion.Identity;
// Linear properties
private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time
@@ -116,7 +108,6 @@ namespace OpenSim.Region.Physics.OdePlugin
private float m_VhoverHeight = 0f;
private float m_VhoverEfficiency = 0f;
private float m_VhoverTimescale = 1000f;
private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle.
// Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
// KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
@@ -126,9 +117,6 @@ namespace OpenSim.Region.Physics.OdePlugin
private float m_verticalAttractionEfficiency = 1.0f; // damped
private float m_verticalAttractionTimescale = 1000f; // Timescale > 300 means no vert attractor.
// special contact data for vehicles
public ContactData VehiculeContactData = new ContactData(0f, 0.1f);
// auxiliar
private Vector3 m_dir = Vector3.Zero; // velocity applied to body
@@ -160,7 +148,9 @@ namespace OpenSim.Region.Physics.OdePlugin
m_angularDeflectionTimescale = pValue;
break;
case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
if (pValue < timestep) pValue = timestep;
// if (pValue < timestep) pValue = timestep;
// try to make impulses to work a bit better
if (pValue < 0.5f) pValue = 0.5f;
else if (pValue > 120) pValue = 120;
m_angularMotorDecayTimescale = pValue * invtimestep;
break;
@@ -209,7 +199,9 @@ namespace OpenSim.Region.Physics.OdePlugin
m_linearDeflectionTimescale = pValue;
break;
case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
if (pValue < timestep) pValue = timestep;
// if (pValue < timestep) pValue = timestep;
// try to make impulses to work a bit better
if (pValue < 0.5f) pValue = 0.5f;
else if (pValue > 120) pValue = 120;
m_linearMotorDecayTimescale = pValue * invtimestep;
break;
@@ -267,7 +259,6 @@ namespace OpenSim.Region.Physics.OdePlugin
float timestep = _pParentScene.ODE_STEPSIZE;
switch (pParam)
{
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
if (pValue.X < timestep) pValue.X = timestep;
if (pValue.Y < timestep) pValue.Y = timestep;
@@ -571,7 +562,6 @@ namespace OpenSim.Region.Physics.OdePlugin
return vec;
}
public static void GetRollPitch(Quaternion rot, out float roll, out float pitch)
{
// assuming rot is normalised
@@ -613,52 +603,47 @@ namespace OpenSim.Region.Physics.OdePlugin
d.Vector3 dvtmp;
Vector3 tmpV;
Vector3 curVel; // velocity in world
Vector3 curAngVel; // angular velocity in world
Vector3 force = Vector3.Zero; // actually linear aceleration until mult by mass in world frame
Vector3 torque = Vector3.Zero;// actually angular aceleration until mult by Inertia in vehicle frame
d.Vector3 dtorque = new d.Vector3();
dvtmp = d.BodyGetLinearVel(Body);
Vector3 curVel;
curVel.X = dvtmp.X;
curVel.Y = dvtmp.Y;
curVel.Z = dvtmp.Z;
Vector3 curLocalVel = curVel * irotq; // current velocity in local
dvtmp = d.BodyGetAngularVel(Body);
Vector3 curAngVel;
curAngVel.X = dvtmp.X;
curAngVel.Y = dvtmp.Y;
curAngVel.Z = dvtmp.Z;
Vector3 curLocalAngVel = curAngVel * irotq; // current velocity in local
Vector3 force = Vector3.Zero; // actually linear aceleration until mult by mass in world frame
Vector3 torque = Vector3.Zero;// actually angular aceleration until mult by Inertia in object frame
d.Vector3 dtorque = new d.Vector3();// actually angular aceleration until mult by Inertia in object frame
bool doathing = false;
Vector3 curLocalAngVel = curAngVel * irotq; // current angular velocity in local
// linear motor
if (m_lmEfect > 0.01 && m_linearMotorTimescale < 1000)
{
tmpV = m_linearMotorDirection - curLocalVel; // velocity error
if (tmpV.LengthSquared() > 1e-6f)
tmpV *= m_lmEfect / m_linearMotorTimescale; // error to correct in this timestep
tmpV *= rotq; // to world
if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0)
tmpV.Z = 0;
if (m_linearMotorOffset.X != 0 || m_linearMotorOffset.Y != 0 || m_linearMotorOffset.Z != 0)
{
tmpV = tmpV * (m_lmEfect / m_linearMotorTimescale); // error to correct in this timestep
tmpV *= rotq; // to world
if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0)
tmpV.Z = 0;
if (m_linearMotorOffset.X != 0 && m_linearMotorOffset.Y != 0 && m_linearMotorOffset.Z != 0)
{
// have offset, do it now
tmpV *= rootPrim.Mass;
d.BodyAddForceAtRelPos(Body, tmpV.X, tmpV.Y, tmpV.Z, m_linearMotorOffset.X, m_linearMotorOffset.Y, m_linearMotorOffset.Z);
}
else
{
force.X += tmpV.X;
force.Y += tmpV.Y;
force.Z += tmpV.Z;
}
// have offset, do it now
tmpV *= rootPrim.Mass;
d.BodyAddForceAtRelPos(Body, tmpV.X, tmpV.Y, tmpV.Z, m_linearMotorOffset.X, m_linearMotorOffset.Y, m_linearMotorOffset.Z);
}
m_lmEfect *= (1 - 1.0f / m_linearMotorDecayTimescale);
else
{
force.X += tmpV.X;
force.Y += tmpV.Y;
force.Z += tmpV.Z;
}
m_lmEfect *= (1.0f - 1.0f / m_linearMotorDecayTimescale);
}
else
m_lmEfect = 0;
@@ -719,30 +704,35 @@ namespace OpenSim.Region.Physics.OdePlugin
if (m_linearDeflectionEfficiency > 0)
{
float len = curVel.Length();
Vector3 atAxis = refAtAxis;
atAxis *= rotq; // at axis rotated to world
atAxis = Xrot(rotq);
tmpV = atAxis * len;
tmpV -= curVel; // velocity error
tmpV *= (m_linearDeflectionEfficiency / m_linearDeflectionTimescale); // error to correct in this timestep
force.X += tmpV.X;
force.Y += tmpV.Y;
if((m_flags & VehicleFlag.NO_DEFLECTION_UP) ==0)
force.Z += tmpV.Z;
Vector3 atAxis;
atAxis = Xrot(rotq); // where are we pointing to
atAxis *= len; // make it same size as world velocity vector
tmpV = -atAxis; // oposite direction
atAxis -= curVel; // error to one direction
len = atAxis.LengthSquared();
tmpV -= curVel; // error to oposite
float lens = tmpV.LengthSquared();
if (len > 0.01 || lens > 0.01) // do nothing if close enougth
{
if (len < lens)
tmpV = atAxis;
tmpV *= (m_linearDeflectionEfficiency / m_linearDeflectionTimescale); // error to correct in this timestep
force.X += tmpV.X;
force.Y += tmpV.Y;
if ((m_flags & VehicleFlag.NO_DEFLECTION_UP) == 0)
force.Z += tmpV.Z;
}
}
// angular motor
if (m_amEfect > 0.01 && m_angularMotorTimescale < 1000)
{
tmpV = m_angularMotorDirection - curLocalAngVel; // velocity error
if (tmpV.LengthSquared() > 1e-6f)
{
tmpV = tmpV * (m_amEfect / m_angularMotorTimescale); // error to correct in this timestep
tmpV *= m_referenceFrame; // to object
dtorque.X += tmpV.X;
dtorque.Y += tmpV.Y;
dtorque.Z += tmpV.Z;
}
tmpV *= m_amEfect / m_angularMotorTimescale; // error to correct in this timestep
torque.X += tmpV.X;
torque.Y += tmpV.Y;
torque.Z += tmpV.Z;
m_amEfect *= (1 - 1.0f / m_angularMotorDecayTimescale);
}
else
@@ -751,234 +741,90 @@ namespace OpenSim.Region.Physics.OdePlugin
// angular friction
if (curLocalAngVel.X != 0 || curLocalAngVel.Y != 0 || curLocalAngVel.Z != 0)
{
tmpV.X = -curLocalAngVel.X / m_angularFrictionTimescale.X;
tmpV.Y = -curLocalAngVel.Y / m_angularFrictionTimescale.Y;
tmpV.Z = -curLocalAngVel.Z / m_angularFrictionTimescale.Z;
tmpV *= m_referenceFrame; // to object
dtorque.X += tmpV.X;
dtorque.Y += tmpV.Y;
dtorque.Z += tmpV.Z;
torque.X -= curLocalAngVel.X / m_angularFrictionTimescale.X;
torque.Y -= curLocalAngVel.Y / m_angularFrictionTimescale.Y;
torque.Z -= curLocalAngVel.Z / m_angularFrictionTimescale.Z;
}
// angular deflection
if (m_angularDeflectionEfficiency > 0)
{
doathing = false;
float ftmp = m_angularDeflectionEfficiency / m_angularDeflectionTimescale / m_angularDeflectionTimescale /_pParentScene.ODE_STEPSIZE;
tmpV.X = 0;
if (Math.Abs(curLocalVel.Z) > 0.01)
{
tmpV.Y = -(float)Math.Atan2(curLocalVel.Z, curLocalVel.X) * ftmp;
doathing = true;
}
Vector3 dirv;
if (curLocalVel.X > 0.01f)
dirv = curLocalVel;
else if (curLocalVel.X < -0.01f)
// use oposite
dirv = -curLocalVel;
else
tmpV.Y = 0;
if (Math.Abs(curLocalVel.Y) > 0.01)
{
tmpV.Z = (float)Math.Atan2(curLocalVel.Y, curLocalVel.X) * ftmp;
doathing = true;
// make it fall into small positive x case
dirv.X = 0.01f;
dirv.Y = curLocalVel.Y;
dirv.Z = curLocalVel.Z;
}
else
tmpV.Z = 0;
if (doathing)
float ftmp = m_angularDeflectionEfficiency / m_angularDeflectionTimescale;
if (Math.Abs(dirv.Z) > 0.01)
{
tmpV *= m_referenceFrame; // to object
dtorque.X += tmpV.X;
dtorque.Y += tmpV.Y;
dtorque.Z += tmpV.Z;
torque.Y += - (float)Math.Atan2(dirv.Z, dirv.X) * ftmp;
}
if (Math.Abs(dirv.Y) > 0.01)
{
torque.Z += (float)Math.Atan2(dirv.Y, dirv.X) * ftmp;
}
}
// vertical atractor
if (m_verticalAttractionTimescale < 300)
{
doathing = false;
float roll;
float pitch;
GetRollPitch(rotq, out roll, out pitch);
GetRollPitch(irotq, out roll, out pitch);
float ftmp = 1.0f / m_verticalAttractionTimescale / m_verticalAttractionTimescale / _pParentScene.ODE_STEPSIZE;
float ftmp2 = m_verticalAttractionEfficiency / _pParentScene.ODE_STEPSIZE;
if (Math.Abs(roll) > 0.01) // roll
{
tmpV.X = -roll * ftmp;
tmpV.X -= curLocalAngVel.X * ftmp2;
doathing = true;
}
else
{
tmpV.X = 0;
torque.X -= -roll * ftmp + curLocalAngVel.X * ftmp2;
}
if (Math.Abs(pitch) > 0.01 && ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) == 0)) // pitch
{
tmpV.Y = -pitch * ftmp;
tmpV.Y -= curLocalAngVel.Y * ftmp2;
doathing = true;
}
else
{
tmpV.Y = 0;
torque.Y -= -pitch * ftmp + curLocalAngVel.Y * ftmp2;
}
tmpV.Z = 0;
if (m_bankingEfficiency == 0 || Math.Abs(roll) < 0.01)
tmpV.Z = 0;
else
if (m_bankingEfficiency != 0 && Math.Abs(roll) > 0.01)
{
float broll = -roll * m_bankingEfficiency; ;
float broll = roll * m_bankingEfficiency; ;
if (m_bankingMix != 0)
{
float vfact = m_bankingMix * Math.Abs(curLocalVel.X) / 10.0f;
if (vfact < m_bankingMix)
float vfact = Math.Abs(curLocalVel.X) / 10.0f;
if (vfact > 1.0f) vfact = 1.0f;
if (curLocalVel.X >= 0)
broll *= ((1 - m_bankingMix) + vfact);
else
broll *= -((1 - m_bankingMix) + vfact);
}
broll = (broll - curLocalAngVel.Z) / m_bankingTimescale;
// torque.Z += broll;
tmpV.Z = (broll - curLocalAngVel.Z) / m_bankingTimescale;
doathing = true;
}
// make z rot be in world Z not local as seems to be in sl
tmpV.X = 0;
tmpV.Y = 0;
tmpV.Z = broll;
tmpV *= irotq;
if (doathing)
{
tmpV *= m_referenceFrame; // to object
dtorque.X += tmpV.X;
dtorque.Y += tmpV.Y;
dtorque.Z += tmpV.Z;
torque.X += tmpV.X;
torque.Y += tmpV.Y;
torque.Z += tmpV.Z;
}
}
/*
d.Vector3 pos = d.BodyGetPosition(Body);
// Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f);
Vector3 posChange = new Vector3();
posChange.X = pos.X - m_lastPositionVector.X;
posChange.Y = pos.Y - m_lastPositionVector.Y;
posChange.Z = pos.Z - m_lastPositionVector.Z;
double Zchange = Math.Abs(posChange.Z);
if (m_BlockingEndPoint != Vector3.Zero)
{
if (pos.X >= (m_BlockingEndPoint.X - (float)1))
{
pos.X -= posChange.X + 1;
d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
}
if (pos.Y >= (m_BlockingEndPoint.Y - (float)1))
{
pos.Y -= posChange.Y + 1;
d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
}
if (pos.Z >= (m_BlockingEndPoint.Z - (float)1))
{
pos.Z -= posChange.Z + 1;
d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
}
if (pos.X <= 0)
{
pos.X += posChange.X + 1;
d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
}
if (pos.Y <= 0)
{
pos.Y += posChange.Y + 1;
d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
}
}
if (pos.Z < _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y))
{
pos.Z = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + 2;
d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
}
}
if ((m_flags & (VehicleFlag.NO_X)) != 0)
{
m_dir.X = 0;
}
if ((m_flags & (VehicleFlag.NO_Y)) != 0)
{
m_dir.Y = 0;
}
if ((m_flags & (VehicleFlag.NO_Z)) != 0)
{
m_dir.Z = 0;
}
*/
// angular part
/*
// Get what the body is doing, this includes 'external' influences
/*
Vector3 angularVelocity = Vector3.Zero;
// Vertical attractor section
Vector3 vertattr = Vector3.Zero;
if (m_verticalAttractionTimescale < 300)
{
float VAservo = 0.2f / m_verticalAttractionTimescale;
// get present body rotation
// make a vector pointing up
Vector3 verterr = Vector3.Zero;
verterr.Z = 1.0f;
// rotate it to Body Angle
verterr = verterr * rotq;
// verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1.
// As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go
// negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body.
if (verterr.Z < 0.0f)
{
verterr.X = 2.0f - verterr.X;
verterr.Y = 2.0f - verterr.Y;
}
// Error is 0 (no error) to +/- 2 (max error)
// scale it by VAservo
verterr = verterr * VAservo;
//if (frcount == 0) Console.WriteLine("VAerr=" + verterr);
// As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so
// Change Body angular velocity X based on Y, and Y based on X. Z is not changed.
vertattr.X = verterr.Y;
vertattr.Y = - verterr.X;
vertattr.Z = 0f;
// scaling appears better usingsquare-law
float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency);
vertattr.X += bounce * angularVelocity.X;
vertattr.Y += bounce * angularVelocity.Y;
} // else vertical attractor is off
// m_lastVertAttractor = vertattr;
// Bank section tba
// Deflection section tba
// Sum velocities
m_lastAngularVelocity = angularVelocity + vertattr; // + bank + deflection
if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
{
m_lastAngularVelocity.X = 0;
m_lastAngularVelocity.Y = 0;
}
if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
{
if (!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
}
else
{
m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
}
*/
d.Mass dmass;
d.BodyGetMass(Body,out dmass);
@@ -988,48 +834,16 @@ namespace OpenSim.Region.Physics.OdePlugin
d.BodySetForce(Body, force.X, force.Y, force.Z);
}
if (dtorque.X != 0 || dtorque.Y != 0 || dtorque.Z != 0)
if (torque.X != 0 || torque.Y != 0 || torque.Z != 0)
{
torque *= m_referenceFrame; // to object frame
dtorque.X = torque.X;
dtorque.Y = torque.Y;
dtorque.Z = torque.Z;
d.MultiplyM3V3(out dvtmp, ref dmass.I, ref dtorque);
d.BodyAddRelTorque(Body, dvtmp.X, dvtmp.Y, dvtmp.Z); // add torque in object frame
}
//end MoveAngular
// limit rotations
/*
bool changed = false;
if (m_RollreferenceFrame != Quaternion.Identity)
{
if (rotq.X >= m_RollreferenceFrame.X)
{
rot.X = rotq.X - (m_RollreferenceFrame.X / 2);
}
if (rotq.Y >= m_RollreferenceFrame.Y)
{
rot.Y = rotq.Y - (m_RollreferenceFrame.Y / 2);
}
if (rotq.X <= -m_RollreferenceFrame.X)
{
rot.X = rotq.X + (m_RollreferenceFrame.X / 2);
}
if (rotq.Y <= -m_RollreferenceFrame.Y)
{
rot.Y = rotq.Y + (m_RollreferenceFrame.Y / 2);
}
changed = true;
}
if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0)
{
rot.X = 0;
rot.Y = 0;
changed = true;
}
if (changed)
d.BodySetQuaternion(Body, ref rot);
*/
}
}
}
+206 -149
View File
@@ -25,7 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* Revision 2011 by Ubit Umarov
/* Revision 2011/12 by Ubit Umarov
*
*
*/
@@ -190,7 +190,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public ODEDynamics m_vehicle;
internal int m_material = (int)Material.Wood;
protected ContactData primContactData = new ContactData { mu = 0f, bounce = 0.1f};
protected ContactData primContactData = new ContactData { mu = 0f, bounce = 0.1f };
/// <summary>
/// Is this prim subject to physics? Even if not, it's still solid for collision purposes.
@@ -209,7 +209,7 @@ namespace OpenSim.Region.Physics.OdePlugin
AddChange(changes.Physical, value);
}
}
public override bool Building // this is not reliable for internal use
{
get { return m_building; }
@@ -225,23 +225,10 @@ namespace OpenSim.Region.Physics.OdePlugin
{
get
{
/*
ODEDynamics v;
if(childPrim && _parent !=null)
{
v =((OdePrim)_parent).m_vehicle;
if(v != null && v.Type != Vehicle.TYPE_NONE)
return v.VehiculeContactData;
return primContactData;
}
if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
return m_vehicle.VehiculeContactData;
*/
return primContactData;
return primContactData;
}
}
public override int PhysicsActorType
{
get { return (int)ActorTypes.Prim; }
@@ -276,11 +263,11 @@ namespace OpenSim.Region.Physics.OdePlugin
{
set
{
if(value)
if (value)
m_isSelected = value;
AddChange(changes.Selected, value);
}
}
}
public override bool Flying
{
@@ -400,10 +387,9 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
public override void SetVolumeDetect(int param)
{
AddChange(changes.VolumeDtc,(param != 0));
AddChange(changes.VolumeDtc, (param != 0));
}
public override Vector3 GeometricCenter
@@ -483,14 +469,6 @@ namespace OpenSim.Region.Physics.OdePlugin
// client object interpolation works a 'little' better
if (_zeroFlag)
return Vector3.Zero;
/*
Vector3 returnVelocity = Vector3.Zero;
returnVelocity.X = (m_lastVelocity.X + _velocity.X) / 2;
returnVelocity.Y = (m_lastVelocity.Y + _velocity.Y) / 2;
returnVelocity.Z = (m_lastVelocity.Z + _velocity.Z) / 2;
return returnVelocity;
*/
return _velocity;
}
set
@@ -498,7 +476,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (value.IsFinite())
{
AddChange(changes.Velocity, value);
// _velocity = value;
// _velocity = value;
}
else
@@ -548,7 +526,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{
get
{
if (givefakeori>0)
if (givefakeori > 0)
return fakeori;
else
@@ -603,7 +581,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
public override float Buoyancy
{
get { return m_buoyancy; }
@@ -652,6 +630,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public override int VehicleType
{
// we may need to put a fake on this
get
{
if (m_vehicle == null)
@@ -661,53 +640,42 @@ namespace OpenSim.Region.Physics.OdePlugin
}
set
{
if (m_vehicle == null)
{
if (value != (int)Vehicle.TYPE_NONE)
{
m_vehicle = new ODEDynamics(this);
m_vehicle.ProcessTypeChange((Vehicle)value);
}
}
else
m_vehicle.ProcessTypeChange((Vehicle)value);
AddChange(changes.VehicleType, value);
}
}
public override void VehicleFloatParam(int param, float value)
{
if (m_vehicle == null)
return;
m_vehicle.ProcessFloatVehicleParam((Vehicle)param, value);
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
d.BodyEnable(Body);
strVehicleFloatParam fp = new strVehicleFloatParam();
fp.param = param;
fp.value = value;
AddChange(changes.VehicleFloatParam, fp);
}
public override void VehicleVectorParam(int param, Vector3 value)
{
if (m_vehicle == null)
return;
m_vehicle.ProcessVectorVehicleParam((Vehicle)param, value);
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
d.BodyEnable(Body);
strVehicleVectorParam fp = new strVehicleVectorParam();
fp.param = param;
fp.value = value;
AddChange(changes.VehicleVectorParam, fp);
}
public override void VehicleRotationParam(int param, Quaternion rotation)
public override void VehicleRotationParam(int param, Quaternion value)
{
strVehicleQuatParam fp = new strVehicleQuatParam();
fp.param = param;
fp.value = value;
AddChange(changes.VehicleVectorParam, fp);
}
public override void VehicleFlags(int param, bool value)
{
if (m_vehicle == null)
return;
m_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
d.BodyEnable(Body);
}
public override void VehicleFlags(int param, bool remove)
{
if (m_vehicle == null)
return;
m_vehicle.ProcessVehicleFlags(param, remove);
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
d.BodyEnable(Body);
strVehicleBoolParam bp = new strVehicleBoolParam();
bp.param = param;
bp.value = value;
AddChange(changes.VehicleFlags, bp);
}
public void SetAcceleration(Vector3 accel)
@@ -829,7 +797,7 @@ namespace OpenSim.Region.Physics.OdePlugin
return false;
}
public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size,
Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
{
@@ -866,7 +834,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (size.Z <= 0) size.Z = 0.01f;
_size = size;
if (!QuaternionIsFinite(rotation))
{
@@ -1023,7 +991,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (_parent != null)
{
OdePrim parent = (OdePrim)_parent;
parent.ChildDelink(this,false);
parent.ChildDelink(this, false);
}
}
else
@@ -1055,9 +1023,8 @@ namespace OpenSim.Region.Physics.OdePlugin
return false;
}
// primOOBoffset = mesh.GetCentroid();
// hasOOBoffsetFromMesh = true;
hasOOBoffsetFromMesh = false;
primOOBoffset = mesh.GetCentroid();
hasOOBoffsetFromMesh = true;
_triMeshData = d.GeomTriMeshDataCreate();
@@ -1094,23 +1061,23 @@ namespace OpenSim.Region.Physics.OdePlugin
_parent_scene.geom_name_map[prim_geom] = Name;
_parent_scene.actor_name_map[prim_geom] = this;
/*
if (childPrim)
{
if (_parent != null && _parent is OdePrim)
{
OdePrim parent = (OdePrim)_parent;
//Console.WriteLine("SetGeom calls ChildSetGeom");
parent.ChildSetGeom(this);
}
}
*/
/*
if (childPrim)
{
if (_parent != null && _parent is OdePrim)
{
OdePrim parent = (OdePrim)_parent;
//Console.WriteLine("SetGeom calls ChildSetGeom");
parent.ChildSetGeom(this);
}
}
*/
}
else
m_log.Warn("Setting bad Geom");
}
/// <summary>
/// Create a geometry for the given mesh in the given target space.
/// </summary>
@@ -1129,10 +1096,10 @@ namespace OpenSim.Region.Physics.OdePlugin
if (_parent_scene.needsMeshing(_pbs))
{
haveMesh = setMesh(_parent_scene); // this will give a mesh to non trivial known prims
haveMesh = setMesh(_parent_scene); // this will give a mesh to non trivial known prims
}
if(!haveMesh)
if (!haveMesh)
{
if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1
&& _size.X == _size.Y && _size.Y == _size.Z)
@@ -1187,7 +1154,7 @@ namespace OpenSim.Region.Physics.OdePlugin
// catch (System.AccessViolationException)
catch (Exception e)
{
m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction failed for {0} exception {1}", Name,e);
m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction failed for {0} exception {1}", Name, e);
}
prim_geom = IntPtr.Zero;
@@ -1198,7 +1165,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}
Body = IntPtr.Zero;
hasOOBoffsetFromMesh = false;
// CalcPrimBodyData();
CalcPrimBodyData();
}
private void ChildSetGeom(OdePrim odePrim)
@@ -1223,7 +1190,6 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero)
{
/*
if (m_targetSpace != _parent_scene.ActiveSpace)
{
m_targetSpace = _parent_scene.ActiveSpace;
@@ -1238,7 +1204,6 @@ namespace OpenSim.Region.Physics.OdePlugin
}
d.SpaceAdd(m_targetSpace, prim_geom);
}
*/
d.GeomEnable(prim_geom);
foreach (OdePrim prm in childrenPrim)
d.GeomEnable(prm.prim_geom);
@@ -1256,7 +1221,6 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero)
{
/*
if (m_targetSpace == _parent_scene.ActiveSpace)
{
foreach (OdePrim prm in childrenPrim)
@@ -1270,7 +1234,6 @@ namespace OpenSim.Region.Physics.OdePlugin
d.SpaceRemove(m_targetSpace, prim_geom);
m_targetSpace = IntPtr.Zero;
}
*/
d.GeomDisable(prim_geom);
foreach (OdePrim prm in childrenPrim)
d.GeomDisable(prm.prim_geom);
@@ -1531,7 +1494,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}
#region Mass Calculation
private float CalculatePrimVolume()
{
float volume = _size.X * _size.Y * _size.Z; // default
@@ -1890,7 +1853,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (prm.prim_geom != IntPtr.Zero)
d.GeomSetBody(prm.prim_geom, IntPtr.Zero);
if(prm.Body != prim.Body)
if (prm.Body != prim.Body)
prm.DestroyBody(); // don't loose bodies around
prm.Body = IntPtr.Zero;
}
@@ -2062,21 +2025,18 @@ namespace OpenSim.Region.Physics.OdePlugin
SetInStaticSpace(this);
}
m_building = false; // REMOVE THIS LATER
if (m_isphysical && Body == IntPtr.Zero)
{
/*
if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
{
changeShape(_pbs);
}
else
{
*/
MakeBody();
// }
/*
if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
{
changeShape(_pbs);
}
else
{
*/
MakeBody();
// }
}
}
@@ -2119,7 +2079,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (NewParent != _parent)
{
(_parent as OdePrim).ChildDelink(this,false); // for now...
(_parent as OdePrim).ChildDelink(this, false); // for now...
childPrim = false;
if (NewParent != null)
@@ -2135,7 +2095,7 @@ namespace OpenSim.Region.Physics.OdePlugin
private void Stop()
{
if(!childPrim)
if (!childPrim)
{
m_force = Vector3.Zero;
m_forceacc = Vector3.Zero;
@@ -2143,7 +2103,7 @@ namespace OpenSim.Region.Physics.OdePlugin
_torque = Vector3.Zero;
_velocity = Vector3.Zero;
_acceleration = Vector3.Zero;
m_rotationalVelocity = Vector3.Zero;
m_rotationalVelocity = Vector3.Zero;
_target_velocity = Vector3.Zero;
if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
m_vehicle.Stop();
@@ -2155,7 +2115,7 @@ namespace OpenSim.Region.Physics.OdePlugin
d.BodySetTorque(Body, 0f, 0f, 0f);
d.BodySetLinearVel(Body, 0f, 0f, 0f);
d.BodySetAngularVel(Body, 0f, 0f, 0f);
}
}
@@ -2241,7 +2201,7 @@ namespace OpenSim.Region.Physics.OdePlugin
givefakepos--;
if (givefakepos < 0)
givefakepos = 0;
// changeSelectedStatus();
// changeSelectedStatus();
resetCollisionAccounting();
}
@@ -2386,17 +2346,17 @@ namespace OpenSim.Region.Physics.OdePlugin
if (!childPrim)
{
if (NewStatus)
if (NewStatus)
{
if (Body == IntPtr.Zero)
{
/*
if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
{
changeShape(_pbs);
}
else
*/
/*
if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
{
changeShape(_pbs);
}
else
*/
{
MakeBody();
}
@@ -2407,13 +2367,14 @@ namespace OpenSim.Region.Physics.OdePlugin
if (Body != IntPtr.Zero)
{
// UpdateChildsfromgeom();
/* if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
{
changeShape(_pbs);
}
else
*/
DestroyBody();
/* if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
{
changeShape(_pbs);
}
else
*/
DestroyBody();
Stop();
}
}
}
@@ -2422,7 +2383,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}
private void changeprimsizeshape()
{
{
OdePrim parent = (OdePrim)_parent;
bool chp = childPrim;
@@ -2614,6 +2575,57 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
private void changeVehicleType(int value)
{
if (m_vehicle == null)
{
if (value != (int)Vehicle.TYPE_NONE)
{
m_vehicle = new ODEDynamics(this);
m_vehicle.ProcessTypeChange((Vehicle)value);
}
}
else
m_vehicle.ProcessTypeChange((Vehicle)value);
}
private void changeVehicleFloatParam(strVehicleFloatParam fp)
{
if (m_vehicle == null)
return;
m_vehicle.ProcessFloatVehicleParam((Vehicle)fp.param, fp.value);
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
d.BodyEnable(Body);
}
private void changeVehicleVectorParam(strVehicleVectorParam vp)
{
if (m_vehicle == null)
return;
m_vehicle.ProcessVectorVehicleParam((Vehicle)vp.param, vp.value);
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
d.BodyEnable(Body);
}
private void changeVehicleRotationParam(strVehicleQuatParam qp)
{
if (m_vehicle == null)
return;
m_vehicle.ProcessRotationVehicleParam((Vehicle)qp.param, qp.value);
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
d.BodyEnable(Body);
}
private void changeVehicleFlags(strVehicleBoolParam bp)
{
if (m_vehicle == null)
return;
m_vehicle.ProcessVehicleFlags(bp.param, bp.value);
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
d.BodyEnable(Body);
}
#endregion
public void Move()
@@ -2621,10 +2633,10 @@ namespace OpenSim.Region.Physics.OdePlugin
if (!childPrim && m_isphysical && Body != IntPtr.Zero &&
!m_disabled && !m_isSelected && d.BodyIsEnabled(Body) && !m_building) // KF: Only move root prims.
{
// if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); // KF add 161009
// if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); // KF add 161009
float timestep = _parent_scene.ODE_STEPSIZE;
float fx = 0;
float fy = 0;
float fz = 0;
@@ -2636,13 +2648,13 @@ namespace OpenSim.Region.Physics.OdePlugin
}
else
{
float m_mass = _mass;
float m_mass = _mass;
// fz = 0f;
//m_log.Info(m_collisionFlags.ToString());
if (m_usePID)
{
// If the PID Controller isn't active then we set our force
// calculating base velocity to the current position
@@ -2800,7 +2812,7 @@ namespace OpenSim.Region.Physics.OdePlugin
fz += m_forceacc.Z;
m_forceacc = Vector3.Zero;
//m_log.Info("[OBJPID]: X:" + fx.ToString() + " Y:" + fy.ToString() + " Z:" + fz.ToString());
if (fx != 0 || fy != 0 || fz != 0)
{
@@ -2876,10 +2888,10 @@ namespace OpenSim.Region.Physics.OdePlugin
bool lastZeroFlag = _zeroFlag;
d.Vector3 lpos;
d.GeomCopyPosition(prim_geom,out lpos); // root position that is seem by rest of simulator
d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator
// we need to use root position since that's all the rest of scene uses
if ( lpos.X < 0f || lpos.X > _parent_scene.WorldExtents.X
if (lpos.X < 0f || lpos.X > _parent_scene.WorldExtents.X
|| lpos.Y < 0f || lpos.Y > _parent_scene.WorldExtents.Y
)
{
@@ -3142,10 +3154,10 @@ namespace OpenSim.Region.Physics.OdePlugin
if (_parent != null)
{
OdePrim parent = (OdePrim)_parent;
parent.ChildRemove(this,false);
parent.ChildRemove(this, false);
}
else
ChildRemove(this,false);
ChildRemove(this, false);
RemoveGeom();
m_targetSpace = IntPtr.Zero;
@@ -3182,12 +3194,12 @@ namespace OpenSim.Region.Physics.OdePlugin
changevelocity((Vector3)arg);
break;
// case changes.Acceleration:
// changeacceleration((Vector3)arg);
// break;
// case changes.AngVelocity:
// changeangvelocity((Vector3)arg);
// break;
// case changes.Acceleration:
// changeacceleration((Vector3)arg);
// break;
// case changes.AngVelocity:
// changeangvelocity((Vector3)arg);
// break;
case changes.Force:
changeForce((Vector3)arg);
@@ -3214,7 +3226,7 @@ namespace OpenSim.Region.Physics.OdePlugin
break;
case changes.Shape:
changeShape((PrimitiveBaseShape) arg);
changeShape((PrimitiveBaseShape)arg);
break;
case changes.CollidesWater:
@@ -3234,13 +3246,33 @@ namespace OpenSim.Region.Physics.OdePlugin
break;
case changes.disabled:
changeDisable((bool) arg);
changeDisable((bool)arg);
break;
case changes.building:
changeBuilding((bool)arg);
break;
case changes.VehicleType:
changeVehicleType((int)arg);
break;
case changes.VehicleFlags:
changeVehicleFlags((strVehicleBoolParam) arg);
break;
case changes.VehicleFloatParam:
changeVehicleFloatParam((strVehicleFloatParam) arg);
break;
case changes.VehicleVectorParam:
changeVehicleVectorParam((strVehicleVectorParam) arg);
break;
case changes.VehicleRotationParam:
changeVehicleRotationParam((strVehicleQuatParam) arg);
break;
case changes.Null:
donullchange();
break;
@@ -3254,7 +3286,32 @@ namespace OpenSim.Region.Physics.OdePlugin
public void AddChange(changes what, object arg)
{
_parent_scene.AddChange(this, what, arg);
_parent_scene.AddChange((PhysicsActor) this, what, arg);
}
private struct strVehicleBoolParam
{
public int param;
public bool value;
}
private struct strVehicleFloatParam
{
public int param;
public float value;
}
private struct strVehicleQuatParam
{
public int param;
public Quaternion value;
}
private struct strVehicleVectorParam
{
public int param;
public Vector3 value;
}
}
}
}
+72 -14
View File
@@ -1,3 +1,4 @@
/*
* based on:
* Ode.NET - .NET bindings for ODE
@@ -59,6 +60,7 @@ namespace OdeAPI
{
public static dReal Infinity = dReal.MaxValue;
public static int NTotalBodies = 0;
public static int NTotalGeoms = 0;
#region Flags and Enumerations
@@ -420,7 +422,7 @@ namespace OdeAPI
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCreate"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr BodyiCreate(IntPtr world);
public static IntPtr BodyCreate(IntPtr world)
public static IntPtr BodyCreate(IntPtr world)
{
NTotalBodies++;
return BodyiCreate(world);
@@ -689,22 +691,52 @@ namespace OdeAPI
public static extern IntPtr ConnectingJoint(IntPtr j1, IntPtr j2);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateBox"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr CreateBox(IntPtr space, dReal lx, dReal ly, dReal lz);
public static extern IntPtr CreateiBox(IntPtr space, dReal lx, dReal ly, dReal lz);
public static IntPtr CreateBox(IntPtr space, dReal lx, dReal ly, dReal lz)
{
NTotalGeoms++;
return CreateiBox(space, lx, ly, lz);
}
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateCapsule"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr CreateCapsule(IntPtr space, dReal radius, dReal length);
public static extern IntPtr CreateiCapsule(IntPtr space, dReal radius, dReal length);
public static IntPtr CreateCapsule(IntPtr space, dReal radius, dReal length)
{
NTotalGeoms++;
return CreateiCapsule(space, radius, length);
}
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateConvex"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr CreateConvex(IntPtr space, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons);
public static extern IntPtr CreateiConvex(IntPtr space, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons);
public static IntPtr CreateConvex(IntPtr space, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons)
{
NTotalGeoms++;
return CreateiConvex(space, planes, planeCount, points, pointCount, polygons);
}
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateCylinder"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr CreateCylinder(IntPtr space, dReal radius, dReal length);
public static extern IntPtr CreateiCylinder(IntPtr space, dReal radius, dReal length);
public static IntPtr CreateCylinder(IntPtr space, dReal radius, dReal length)
{
NTotalGeoms++;
return CreateiCylinder(space, radius, length);
}
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateHeightfield"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr CreateHeightfield(IntPtr space, IntPtr data, int bPlaceable);
public static extern IntPtr CreateiHeightfield(IntPtr space, IntPtr data, int bPlaceable);
public static IntPtr CreateHeightfield(IntPtr space, IntPtr data, int bPlaceable)
{
NTotalGeoms++;
return CreateiHeightfield(space, data, bPlaceable);
}
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeom"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr CreateGeom(int classnum);
public static extern IntPtr CreateiGeom(int classnum);
public static IntPtr CreateGeom(int classnum)
{
NTotalGeoms++;
return CreateiGeom(classnum);
}
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeomClass"), SuppressUnmanagedCodeSecurity]
public static extern int CreateGeomClass(ref GeomClass classptr);
@@ -713,19 +745,39 @@ namespace OdeAPI
public static extern IntPtr CreateGeomTransform(IntPtr space);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreatePlane"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr CreatePlane(IntPtr space, dReal a, dReal b, dReal c, dReal d);
public static extern IntPtr CreateiPlane(IntPtr space, dReal a, dReal b, dReal c, dReal d);
public static IntPtr CreatePlane(IntPtr space, dReal a, dReal b, dReal c, dReal d)
{
NTotalGeoms++;
return CreateiPlane(space, a, b, c, d);
}
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateRay"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr CreateRay(IntPtr space, dReal length);
public static extern IntPtr CreateiRay(IntPtr space, dReal length);
public static IntPtr CreateRay(IntPtr space, dReal length)
{
NTotalGeoms++;
return CreateiRay(space, length);
}
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateSphere"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr CreateSphere(IntPtr space, dReal radius);
public static extern IntPtr CreateiSphere(IntPtr space, dReal radius);
public static IntPtr CreateSphere(IntPtr space, dReal radius)
{
NTotalGeoms++;
return CreateiSphere(space, radius);
}
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateTriMesh"), SuppressUnmanagedCodeSecurity]
public static extern IntPtr CreateTriMesh(IntPtr space, IntPtr data,
public static extern IntPtr CreateiTriMesh(IntPtr space, IntPtr data,
TriCallback callback, TriArrayCallback arrayCallback, TriRayCallback rayCallback);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dDot"), SuppressUnmanagedCodeSecurity]
public static IntPtr CreateTriMesh(IntPtr space, IntPtr data,
TriCallback callback, TriArrayCallback arrayCallback, TriRayCallback rayCallback)
{
NTotalGeoms++;
return CreateiTriMesh(space, data, callback, arrayCallback, rayCallback);
}
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dDot"), SuppressUnmanagedCodeSecurity]
public static extern dReal Dot(ref dReal X0, ref dReal X1, int n);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dDQfromW"), SuppressUnmanagedCodeSecurity]
@@ -798,7 +850,13 @@ namespace OdeAPI
public static extern void GeomCylinderSetParams(IntPtr geom, dReal radius, dReal length);
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomDestroy"), SuppressUnmanagedCodeSecurity]
public static extern void GeomDestroy(IntPtr geom);
public static extern void GeomiDestroy(IntPtr geom);
public static void GeomDestroy(IntPtr geom)
{
NTotalGeoms--;
GeomiDestroy(geom);
}
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomDisable"), SuppressUnmanagedCodeSecurity]
public static extern void GeomDisable(IntPtr geom);
+21 -222
View File
@@ -25,7 +25,6 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//#define USE_DRAWSTUFF
//#define SPAM
using System;
@@ -38,9 +37,6 @@ using System.Diagnostics;
using log4net;
using Nini.Config;
using OdeAPI;
#if USE_DRAWSTUFF
using ODEDrawstuff;
#endif
using OpenSim.Framework;
using OpenSim.Region.Physics.Manager;
using OpenMetaverse;
@@ -136,12 +132,18 @@ namespace OpenSim.Region.Physics.OdePlugin
disabled,
building,
VehicleType,
VehicleFloatParam,
VehicleVectorParam,
VehicleRotationParam,
VehicleFlags,
Null //keep this last used do dim the methods array. does nothing but pulsing the prim
}
public struct ODEchangeitem
{
public OdePrim prim;
public PhysicsActor actor;
public OdeCharacter character;
public changes what;
public Object arg;
@@ -181,7 +183,6 @@ namespace OpenSim.Region.Physics.OdePlugin
public float gravityy = 0f;
public float gravityz = -9.8f;
private float waterlevel = 0f;
private int framecount = 0;
@@ -223,10 +224,6 @@ namespace OpenSim.Region.Physics.OdePlugin
private readonly HashSet<OdePrim> _prims = new HashSet<OdePrim>();
private readonly HashSet<OdePrim> _activeprims = new HashSet<OdePrim>();
private readonly Object _taintedCharacterLock = new Object();
private readonly HashSet<OdeCharacter> _taintedCharacterH = new HashSet<OdeCharacter>(); // faster verification of repeated character taints
private readonly Queue<OdeCharacter> _taintedCharacterQ = new Queue<OdeCharacter>(); // character taints
public OpenSim.Framework.LocklessQueue<ODEchangeitem> ChangesQueue = new OpenSim.Framework.LocklessQueue<ODEchangeitem>();
/// <summary>
@@ -365,31 +362,11 @@ namespace OpenSim.Region.Physics.OdePlugin
//contactgroup
d.WorldSetAutoDisableFlag(world, false);
#if USE_DRAWSTUFF
Thread viewthread = new Thread(new ParameterizedThreadStart(startvisualization));
viewthread.Start();
#endif
}
_watermap = new float[258 * 258];
}
#if USE_DRAWSTUFF
public void startvisualization(object o)
{
ds.Functions fn;
fn.version = ds.VERSION;
fn.start = new ds.CallbackFunction(start);
fn.step = new ds.CallbackFunction(step);
fn.command = new ds.CallbackFunction(command);
fn.stop = null;
fn.path_to_textures = "./textures";
string[] args = new string[0];
ds.SimulationLoop(args.Length, args, 352, 288, ref fn);
}
#endif
// Initialize the mesh plugin
// public override void Initialise(IMesher meshmerizer, IConfigSource config, RegionInfo region )
public override void Initialise(IMesher meshmerizer, IConfigSource config)
@@ -1552,23 +1529,15 @@ namespace OpenSim.Region.Physics.OdePlugin
return true;
}
public void AddChange(OdePrim prim, changes what, Object arg)
{
ODEchangeitem item = new ODEchangeitem();
item.prim = prim;
item.what = what;
item.arg = arg;
ChangesQueue.Enqueue(item);
}
/// <summary>
/// Called to queue a change to a prim
/// Called to queue a change to a actor
/// to use in place of old taint mechanism so changes do have a time sequence
/// </summary>
public void AddChange(OdeCharacter character, changes what, Object arg)
public void AddChange(PhysicsActor actor, changes what, Object arg)
{
ODEchangeitem item = new ODEchangeitem();
item.character = character;
item.actor = actor;
item.what = what;
item.arg = arg;
ChangesQueue.Enqueue(item);
@@ -1582,34 +1551,6 @@ namespace OpenSim.Region.Physics.OdePlugin
/// <param name="prim"></param>
public override void AddPhysicsActorTaint(PhysicsActor prim)
{
if (prim is OdePrim)
{
/* OdePrim taintedprim = ((OdePrim) prim);
lock (_taintedPrimLock)
{
if (!(_taintedPrimH.Contains(taintedprim)))
{
_taintedPrimH.Add(taintedprim); // HashSet for searching
_taintedPrimQ.Enqueue(taintedprim); // List for ordered readout
}
}
*/
return;
}
else if (prim is OdeCharacter)
{
OdeCharacter taintedchar = ((OdeCharacter)prim);
lock (_taintedCharacterLock)
{
if (!(_taintedCharacterH.Contains(taintedchar)))
{
_taintedCharacterH.Add(taintedchar);
_taintedCharacterQ.Enqueue(taintedchar);
if (taintedchar.bad)
m_log.DebugFormat("[PHYSICS]: Added BAD actor {0} to tainted actors", taintedchar.m_uuid);
}
}
}
}
/// <summary>
@@ -1681,25 +1622,6 @@ namespace OpenSim.Region.Physics.OdePlugin
// clear pointer/counter to contacts to pass into joints
m_global_contactcount = 0;
// do characters requested changes
OdeCharacter character;
int numtaints;
lock (_taintedCharacterLock)
{
numtaints = _taintedCharacterQ.Count;
// if (numtaints > 50)
// numtaints = 50;
while (numtaints > 0)
{
character = _taintedCharacterQ.Dequeue();
character.ProcessTaints(ODE_STEPSIZE);
_taintedCharacterH.Remove(character);
numtaints--;
}
}
// do other objects requested changes
ODEchangeitem item;
if(ChangesQueue.Count >0)
@@ -1710,14 +1632,19 @@ namespace OpenSim.Region.Physics.OdePlugin
while(ChangesQueue.Dequeue(out item))
{
if (item.prim != null)
if (item.actor != null)
{
try
{
if (item.prim.DoAChange(item.what, item.arg))
RemovePrimThreadLocked(item.prim);
if (item.actor is OdeCharacter)
((OdeCharacter)item.actor).DoAChange(item.what, item.arg);
else if (((OdePrim)item.actor).DoAChange(item.what, item.arg))
RemovePrimThreadLocked((OdePrim)item.actor);
}
catch { };
catch
{
m_log.Warn("[PHYSICS]: doChange failed for a actor");
};
}
ttmp = Util.EnvironmentTickCountSubtract(ttmpstart);
if (ttmp > 20)
@@ -1860,6 +1787,7 @@ namespace OpenSim.Region.Physics.OdePlugin
int nstaticgeoms = d.SpaceGetNumGeoms(StaticSpace);
int ntopgeoms = d.SpaceGetNumGeoms(TopSpace);
int nbodies = d.NTotalBodies;
int ngeoms = d.NTotalGeoms;
// Finished with all sim stepping. If requested, dump world state to file for debugging.
// TODO: This call to the export function is already inside lock (OdeLock) - but is an extra lock needed?
@@ -2608,134 +2536,5 @@ namespace OpenSim.Region.Physics.OdePlugin
}
return new List<ContactResult>();
}
#if USE_DRAWSTUFF
// Keyboard callback
public void command(int cmd)
{
IntPtr geom;
d.Mass mass;
d.Vector3 sides = new d.Vector3(d.RandReal() * 0.5f + 0.1f, d.RandReal() * 0.5f + 0.1f, d.RandReal() * 0.5f + 0.1f);
Char ch = Char.ToLower((Char)cmd);
switch ((Char)ch)
{
case 'w':
try
{
Vector3 rotate = (new Vector3(1, 0, 0) * Quaternion.CreateFromEulers(hpr.Z * Utils.DEG_TO_RAD, hpr.Y * Utils.DEG_TO_RAD, hpr.X * Utils.DEG_TO_RAD));
xyz.X += rotate.X; xyz.Y += rotate.Y; xyz.Z += rotate.Z;
ds.SetViewpoint(ref xyz, ref hpr);
}
catch (ArgumentException)
{ hpr.X = 0; }
break;
case 'a':
hpr.X++;
ds.SetViewpoint(ref xyz, ref hpr);
break;
case 's':
try
{
Vector3 rotate2 = (new Vector3(-1, 0, 0) * Quaternion.CreateFromEulers(hpr.Z * Utils.DEG_TO_RAD, hpr.Y * Utils.DEG_TO_RAD, hpr.X * Utils.DEG_TO_RAD));
xyz.X += rotate2.X; xyz.Y += rotate2.Y; xyz.Z += rotate2.Z;
ds.SetViewpoint(ref xyz, ref hpr);
}
catch (ArgumentException)
{ hpr.X = 0; }
break;
case 'd':
hpr.X--;
ds.SetViewpoint(ref xyz, ref hpr);
break;
case 'r':
xyz.Z++;
ds.SetViewpoint(ref xyz, ref hpr);
break;
case 'f':
xyz.Z--;
ds.SetViewpoint(ref xyz, ref hpr);
break;
case 'e':
xyz.Y++;
ds.SetViewpoint(ref xyz, ref hpr);
break;
case 'q':
xyz.Y--;
ds.SetViewpoint(ref xyz, ref hpr);
break;
}
}
public void step(int pause)
{
ds.SetColor(1.0f, 1.0f, 0.0f);
ds.SetTexture(ds.Texture.Wood);
lock (_prims)
{
foreach (OdePrim prm in _prims)
{
//IntPtr body = d.GeomGetBody(prm.prim_geom);
if (prm.prim_geom != IntPtr.Zero)
{
d.Vector3 pos;
d.GeomCopyPosition(prm.prim_geom, out pos);
//d.BodyCopyPosition(body, out pos);
d.Matrix3 R;
d.GeomCopyRotation(prm.prim_geom, out R);
//d.BodyCopyRotation(body, out R);
d.Vector3 sides = new d.Vector3();
sides.X = prm.Size.X;
sides.Y = prm.Size.Y;
sides.Z = prm.Size.Z;
ds.DrawBox(ref pos, ref R, ref sides);
}
}
}
ds.SetColor(1.0f, 0.0f, 0.0f);
lock (_characters)
{
foreach (OdeCharacter chr in _characters)
{
if (chr.Shell != IntPtr.Zero)
{
IntPtr body = d.GeomGetBody(chr.Shell);
d.Vector3 pos;
d.GeomCopyPosition(chr.Shell, out pos);
//d.BodyCopyPosition(body, out pos);
d.Matrix3 R;
d.GeomCopyRotation(chr.Shell, out R);
//d.BodyCopyRotation(body, out R);
ds.DrawCapsule(ref pos, ref R, chr.Size.Z, 0.35f);
d.Vector3 sides = new d.Vector3();
sides.X = 0.5f;
sides.Y = 0.5f;
sides.Z = 0.5f;
ds.DrawBox(ref pos, ref R, ref sides);
}
}
}
}
public void start(int unused)
{
ds.SetViewpoint(ref xyz, ref hpr);
}
#endif
}
}
@@ -1,99 +0,0 @@
/*
* Copyright ODE
* Ode.NET - .NET bindings for ODE
* Jason Perkins (starkos@industriousone.com)
* Licensed under the New BSD
* Part of the OpenDynamicsEngine
Open Dynamics Engine
Copyright (c) 2001-2007, Russell L. Smith.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
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.
Neither the names of ODE's copyright owner nor the names of its
contributors may 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
OWNER 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.
*
*
*/
using System;
using System.Runtime.InteropServices;
using OdeAPI;
namespace ODEDrawstuff
{
/*#if dDOUBLE
using dReal = System.Double;
#else
*/
using dReal = System.Single;
//#endif
public static class ds
{
public const int VERSION = 2;
public enum Texture
{
None,
Wood
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void CallbackFunction(int arg);
[StructLayout(LayoutKind.Sequential)]
public struct Functions
{
public int version;
public CallbackFunction start;
public CallbackFunction step;
public CallbackFunction command;
public CallbackFunction stop;
public string path_to_textures;
}
[DllImport("drawstuff", EntryPoint = "dsDrawBox")]
public static extern void DrawBox(ref d.Vector3 pos, ref d.Matrix3 R, ref d.Vector3 sides);
[DllImport("drawstuff", EntryPoint = "dsDrawCapsule")]
public static extern void DrawCapsule(ref d.Vector3 pos, ref d.Matrix3 R, dReal length, dReal radius);
[DllImport("drawstuff", EntryPoint = "dsDrawConvex")]
public static extern void DrawConvex(ref d.Vector3 pos, ref d.Matrix3 R, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons);
[DllImport("drawstuff", EntryPoint = "dsSetColor")]
public static extern void SetColor(float red, float green, float blue);
[DllImport("drawstuff", EntryPoint = "dsSetTexture")]
public static extern void SetTexture(Texture texture);
[DllImport("drawstuff", EntryPoint = "dsSetViewpoint")]
public static extern void SetViewpoint(ref d.Vector3 xyz, ref d.Vector3 hpr);
[DllImport("drawstuff", EntryPoint = "dsSimulationLoop")]
public static extern void SimulationLoop(int argc, string[] argv, int window_width, int window_height, ref Functions fn);
}
}
@@ -2177,6 +2177,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return real_vec;
}
public LSL_Integer llSetRegionPos(LSL_Vector pos)
{
return new LSL_Integer(SetRegionPos(m_host, pos));
}
protected int SetRegionPos(SceneObjectPart part, LSL_Vector targetPos)
{
if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
return 0;
SceneObjectGroup grp = part.ParentGroup;
if (grp.IsAttachment)
return 0;
if (grp.RootPart.PhysActor != null && grp.RootPart.PhysActor.IsPhysical)
return 0;
if (targetPos.x < -10.0f || targetPos.x >= (float)Constants.RegionSize || targetPos.y < -10.0f || targetPos.y >= (float)Constants.RegionSize || targetPos.z < 0 || targetPos.z >= 4096.0f)
return 0;
float constrainedX = (float)targetPos.x;
float constrainedY = (float)targetPos.y;
if (constrainedX < 0.0f)
constrainedX = 0.0f;
if (constrainedY < 0.0f)
constrainedY = 0.0f;
if (constrainedX >= (float)Constants.RegionSize)
constrainedX = (float)Constants.RegionSize - 0.1f;
if (constrainedY >= (float)Constants.RegionSize)
constrainedY = (float)Constants.RegionSize -0.1f;
float ground = World.GetGroundHeight(constrainedX, constrainedY);
if (targetPos.z < ground)
targetPos.z = ground;
Vector3 dest = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z);
if (!World.Permissions.CanObjectEntry(grp.UUID, false, dest))
return 0;
grp.UpdateGroupPosition(dest);
return 1;
}
protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
{
if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
@@ -2185,10 +2233,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
LSL_Vector currentPos = GetPartLocalPos(part);
LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
if (part.ParentGroup.RootPart == part)
{
SceneObjectGroup parent = part.ParentGroup;
parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z));
Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
return;
Util.FireAndForget(delegate(object x) {
parent.UpdateGroupPosition(dest);
});
}
else
{
@@ -4184,7 +4238,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// Single prim
if (m_host.LinkNum == 0)
{
if (linknum == 0)
if (linknum == 0 || linknum == ScriptBaseClass.LINK_ROOT)
return m_host.Name;
else
return UUID.Zero.ToString();
@@ -5707,7 +5761,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public LSL_Integer llGetRegionAgentCount()
{
m_host.AddScriptLPS(1);
return new LSL_Integer(World.GetRootAgentCount());
int count = 0;
World.ForEachRootScenePresence(delegate(ScenePresence sp) {
count++;
});
return new LSL_Integer(count);
}
public LSL_Vector llGetRegionCorner()
@@ -7540,27 +7600,59 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
int remain = rules.Length - idx;
switch (code)
{
case (int)ScriptBaseClass.PRIM_POSITION:
if (remain < 1)
return;
LSL_Vector v;
v = rules.GetVector3Item(idx++);
av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
av.SendAvatarDataToAllAgents();
{
if (remain < 1)
return;
LSL_Vector v;
v = rules.GetVector3Item(idx++);
SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
if (part == null)
break;
LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
if (llGetLinkNumber() > 1)
{
localRot = llGetLocalRot();
localPos = llGetLocalPos();
}
v -= localPos;
v /= localRot;
LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
v = v + 2 * sitOffset;
av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
av.SendAvatarDataToAllAgents();
}
break;
case (int)ScriptBaseClass.PRIM_ROTATION:
if (remain < 1)
return;
LSL_Rotation r;
r = rules.GetQuaternionItem(idx++);
av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
av.SendAvatarDataToAllAgents();
{
if (remain < 1)
return;
LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
if (llGetLinkNumber() > 1)
{
localRot = llGetLocalRot();
localPos = llGetLocalPos();
}
LSL_Rotation r;
r = rules.GetQuaternionItem(idx++);
r = r * llGetRootRotation() / localRot;
av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
av.SendAvatarDataToAllAgents();
}
break;
}
}
@@ -7973,7 +8065,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (part.ParentGroup.RootPart == part)
{
SceneObjectGroup parent = part.ParentGroup;
parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
Util.FireAndForget(delegate(object x) {
parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
});
}
else
{
@@ -7990,7 +8084,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (part.ParentGroup.RootPart == part)
{
SceneObjectGroup parent = part.ParentGroup;
parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
Util.FireAndForget(delegate(object x) {
parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
});
}
else
{
@@ -2254,7 +2254,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
firstname, lastname, position, notecard,
(options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
false);
// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) == 0);
// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
}
private LSL_Key NpcCreate(
@@ -2634,7 +2634,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
UUID npcID = new UUID(npc.m_string);
if (module.CheckPermissions(npcID, m_host.OwnerID))
AvatarPlayAnimation(npcID.ToString(), animation);
AvatarStopAnimation(npcID.ToString(), animation);
}
}
@@ -31,7 +31,6 @@ using System.Collections.Generic;
using OpenMetaverse;
using OpenSim.Framework;
using log4net;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.ScriptEngine.Shared;
@@ -41,6 +40,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
{
public class SensorRepeat
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public AsyncCommandManager m_CmdManager;
public SensorRepeat(AsyncCommandManager CmdManager)
@@ -450,17 +451,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
Vector3 toRegionPos;
double dis;
Action<ScenePresence> senseEntity = new Action<ScenePresence>(delegate(ScenePresence presence)
Action<ScenePresence> senseEntity = new Action<ScenePresence>(presence =>
{
if ((ts.type & NPC) == 0
&& presence.PresenceType == PresenceType.Npc
&& !npcModule.GetNPC(presence.UUID, presence.Scene).SenseAsAgent)
return;
// m_log.DebugFormat(
// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
// presence.Name, presence.PresenceType, ts.name, ts.type);
if ((ts.type & AGENT) == 0
&& (presence.PresenceType == PresenceType.User
|| npcModule.GetNPC(presence.UUID, presence.Scene).SenseAsAgent))
return;
if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
{
INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene);
if (npcData == null || !npcData.SenseAsAgent)
{
// m_log.DebugFormat(
// "[SENSOR REPEAT]: Discarding NPC {0} from agent sense sweep for script item id {1}",
// presence.Name, ts.itemID);
return;
}
}
if ((ts.type & AGENT) == 0)
{
if (presence.PresenceType == PresenceType.User)
{
return;
}
else
{
INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene);
if (npcData != null && npcData.SenseAsAgent)
{
// m_log.DebugFormat(
// "[SENSOR REPEAT]: Discarding NPC {0} from non-agent sense sweep for script item id {1}",
// presence.Name, ts.itemID);
return;
}
}
}
if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0)
return;
@@ -346,6 +346,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
void llSetParcelMusicURL(string url);
void llSetPayPrice(int price, LSL_List quick_pay_buttons);
void llSetPos(LSL_Vector pos);
LSL_Integer llSetRegionPos(LSL_Vector pos);
LSL_Integer llSetPrimMediaParams(int face, LSL_List rules);
void llSetPrimitiveParams(LSL_List rules);
void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
@@ -1580,6 +1580,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
m_LSL_Functions.llSetPos(pos);
}
public LSL_Integer llSetRegionPos(LSL_Vector pos)
{
return m_LSL_Functions.llSetRegionPos(pos);
}
public void llSetPrimitiveParams(LSL_List rules)
{
m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -538,6 +538,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
public bool Stop(int timeout)
{
// m_log.DebugFormat(
// "[SCRIPT INSTANCE]: Stopping script {0} {1} with timeout {2}", ScriptName, ItemID, timeout);
IScriptWorkItem result;
lock (m_EventQueue)
@@ -772,7 +775,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
}
catch (Exception e)
{
// m_log.DebugFormat("[SCRIPT] Exception: {0}", e.Message);
// m_log.DebugFormat(
// "[SCRIPT] Exception in script {0} {1}: {2}{3}",
// ScriptName, ItemID, e.Message, e.StackTrace);
m_InEvent = false;
m_CurrentEvent = String.Empty;
@@ -301,7 +301,7 @@ namespace OpenSim.Region.UserStatistics
public void OnRegisterCaps(UUID agentID, Caps caps)
{
m_log.DebugFormat("[VC]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps);
m_log.DebugFormat("[WEB STATS MODULE]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps);
string capsPath = "/CAPS/VS/" + UUID.Random();
caps.RegisterHandler("ViewerStats",
new RestStreamHandler("POST", capsPath,
@@ -462,7 +462,7 @@ namespace OpenSim.Region.UserStatistics
if (!m_sessions.ContainsKey(agentID))
{
m_log.Warn("[VS]: no session for stat disclosure");
m_log.Warn("[WEB STATS MODULE]: no session for stat disclosure");
return new UserSessionID();
}
uid = m_sessions[agentID];
@@ -667,14 +667,13 @@ namespace OpenSim.Region.UserStatistics
{
updatecmd.ExecuteNonQuery();
}
catch
(SqliteExecutionException)
catch (SqliteExecutionException)
{
m_log.Warn("[WEBSTATS]: failed to write stats to storage Execution Exception");
m_log.Warn("[WEB STATS MODULE]: failed to write stats to storage Execution Exception");
}
catch (SqliteSyntaxException)
{
m_log.Warn("[WEBSTATS]: failed to write stats to storage SQL Syntax Exception");
m_log.Warn("[WEB STATS MODULE]: failed to write stats to storage SQL Syntax Exception");
}
}
@@ -136,6 +136,8 @@ namespace OpenSim.Server.Handlers.Simulation
int x = 0, y = 0;
UUID uuid = UUID.Zero;
string regionname = string.Empty;
Vector3 newPosition = Vector3.Zero;
if (args.ContainsKey("destination_x") && args["destination_x"] != null)
Int32.TryParse(args["destination_x"].AsString(), out x);
if (args.ContainsKey("destination_y") && args["destination_y"] != null)
@@ -144,6 +146,8 @@ namespace OpenSim.Server.Handlers.Simulation
UUID.TryParse(args["destination_uuid"].AsString(), out uuid);
if (args.ContainsKey("destination_name") && args["destination_name"] != null)
regionname = args["destination_name"].ToString();
if (args.ContainsKey("new_position") && args["new_position"] != null)
Vector3.TryParse(args["new_position"], out newPosition);
GridRegion destination = new GridRegion();
destination.RegionID = uuid;
@@ -199,7 +203,7 @@ namespace OpenSim.Server.Handlers.Simulation
try
{
// This is the meaning of POST object
result = CreateObject(destination, sog);
result = CreateObject(destination, newPosition, sog);
}
catch (Exception e)
{
@@ -211,9 +215,9 @@ namespace OpenSim.Server.Handlers.Simulation
}
// subclasses can override this
protected virtual bool CreateObject(GridRegion destination, ISceneObject sog)
protected virtual bool CreateObject(GridRegion destination, Vector3 newPosition, ISceneObject sog)
{
return m_SimulationService.CreateObject(destination, sog, false);
return m_SimulationService.CreateObject(destination, newPosition, sog, false);
}
protected virtual void DoObjectPut(Hashtable request, Hashtable responsedata, UUID regionID)
@@ -220,7 +220,7 @@ namespace OpenSim.Services.Connectors.Friends
public bool Delete(Dictionary<string, object> sendData, string PrincipalID, string Friend)
{
string reply = string.Empty;
string uri = m_ServerURI = "/friends";
string uri = m_ServerURI + "/friends";
try
{
reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, ServerUtils.BuildQueryString(sendData));
@@ -153,6 +153,7 @@ namespace OpenSim.Services.Connectors.Simulation
return UpdateAgent(destination, (IAgentData)data, 200000); // yes, 200 seconds
}
private ExpiringCache<string, bool> _failedSims = new ExpiringCache<string, bool>();
/// <summary>
/// Send updated position information about an agent in this region to a neighbor
/// This operation may be called very frequently if an avatar is moving about in
@@ -160,6 +161,10 @@ namespace OpenSim.Services.Connectors.Simulation
/// </summary>
public bool UpdateAgent(GridRegion destination, AgentPosition data)
{
bool v = true;
if (_failedSims.TryGetValue(destination.ServerURI, out v))
return false;
// The basic idea of this code is that the first thread that needs to
// send an update for a specific avatar becomes the worker for any subsequent
// requests until there are no more outstanding requests. Further, only send the most
@@ -183,9 +188,10 @@ namespace OpenSim.Services.Connectors.Simulation
// Otherwise update the reference and start processing
m_updateAgentQueue[uri] = data;
}
AgentPosition pos = null;
while (true)
bool success = true;
while (success)
{
lock (m_updateAgentQueue)
{
@@ -205,11 +211,16 @@ namespace OpenSim.Services.Connectors.Simulation
}
}
UpdateAgent(destination, (IAgentData)pos, 10000);
success = UpdateAgent(destination, (IAgentData)pos, 10000);
}
// unreachable
// return true;
// we get here iff success == false
// blacklist sim for 2 minutes
lock (m_updateAgentQueue)
{
_failedSims.AddOrUpdate(destination.ServerURI, true, 120);
m_updateAgentQueue.Remove(uri);
}
return false;
}
/// <summary>
@@ -409,7 +420,7 @@ namespace OpenSim.Services.Connectors.Simulation
/// <summary>
///
/// </summary>
public bool CreateObject(GridRegion destination, ISceneObject sog, bool isLocalCall)
public bool CreateObject(GridRegion destination, Vector3 newPosition, ISceneObject sog, bool isLocalCall)
{
// m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: CreateObject start");
@@ -422,6 +433,7 @@ namespace OpenSim.Services.Connectors.Simulation
args["sog"] = OSD.FromString(sog.ToXml2());
args["extra"] = OSD.FromString(sog.ExtraToXmlString());
args["modified"] = OSD.FromBoolean(sog.HasGroupChanged);
args["new_position"] = newPosition.ToString();
string state = sog.GetStateSnapshot();
if (state.Length > 0)
@@ -433,11 +445,14 @@ namespace OpenSim.Services.Connectors.Simulation
args["destination_name"] = OSD.FromString(destination.RegionName);
args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
WebUtil.PostToService(uri, args, 40000);
OSDMap response = WebUtil.PostToService(uri, args, 40000);
if (response["Success"] == "False")
return false;
}
catch (Exception e)
{
m_log.WarnFormat("[REMOTE SIMULATION CONNECTOR] CreateObject failed with exception; {0}",e.ToString());
return false;
}
return true;
@@ -188,9 +188,9 @@ namespace OpenSim.Services.HypergridService
string authURL = string.Empty;
if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
authURL = aCircuit.ServiceURLs["HomeURI"].ToString();
m_log.InfoFormat("[GATEKEEPER SERVICE]: Login request for {0} {1} @ {2} ({3}) at {4} using viewer {5}, channel {6}, IP {7}, Mac {8}, Id0 {9}",
m_log.InfoFormat("[GATEKEEPER SERVICE]: Login request for {0} {1} @ {2} ({3}) at {4} using viewer {5}, channel {6}, IP {7}, Mac {8}, Id0 {9} Teleport Flags {10}",
aCircuit.firstname, aCircuit.lastname, authURL, aCircuit.AgentID, destination.RegionName,
aCircuit.Viewer, aCircuit.Channel, aCircuit.IPAddress, aCircuit.Mac, aCircuit.Id0);
aCircuit.Viewer, aCircuit.Channel, aCircuit.IPAddress, aCircuit.Mac, aCircuit.Id0, aCircuit.teleportFlags.ToString());
//
// Check client
@@ -315,6 +315,10 @@ namespace OpenSim.Services.HypergridService
// Finally launch the agent at the destination
//
Constants.TeleportFlags loginFlag = isFirstLogin ? Constants.TeleportFlags.ViaLogin : Constants.TeleportFlags.ViaHGLogin;
// Preserve our TeleportFlags we have gathered so-far
loginFlag |= (Constants.TeleportFlags) aCircuit.teleportFlags;
m_log.DebugFormat("[GATEKEEPER SERVICE]: launching agent {0}", loginFlag);
return m_SimulationService.CreateAgent(destination, aCircuit, (uint)loginFlag, out reason);
}
@@ -106,7 +106,7 @@ namespace OpenSim.Services.Interfaces
/// <param name="sog"></param>
/// <param name="isLocalCall"></param>
/// <returns></returns>
bool CreateObject(GridRegion destination, ISceneObject sog, bool isLocalCall);
bool CreateObject(GridRegion destination, Vector3 newPosition, ISceneObject sog, bool isLocalCall);
/// <summary>
/// Create an object from the user's inventory in the destination region.
@@ -472,6 +472,7 @@ namespace OpenSim.Services.LLLoginService
position = pinfo.HomePosition;
lookAt = pinfo.HomeLookAt;
flags |= TeleportFlags.ViaHome;
}
if (tryDefaults)
@@ -760,6 +761,7 @@ namespace OpenSim.Services.LLLoginService
{
circuitCode = (uint)Util.RandomClass.Next(); ;
aCircuit = MakeAgent(destination, account, avatar, session, secureSession, circuitCode, position, clientIP.Address.ToString(), viewer, channel, mac, id0);
aCircuit.teleportFlags |= (uint)flags;
success = LaunchAgentIndirectly(gatekeeper, destination, aCircuit, clientIP, out reason);
if (!success && m_GridService != null)
{
+2 -1
View File
@@ -50,7 +50,8 @@ namespace OpenSim.Tests.Common.Mock
~TestScene()
{
Console.WriteLine("TestScene destructor called for {0}", RegionInfo.RegionName);
//Console.WriteLine("TestScene destructor called for {0}", RegionInfo.RegionName);
Console.WriteLine("TestScene destructor called");
}
/// <summary>
+185
View File
@@ -0,0 +1,185 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 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.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using log4net;
using Nini.Config;
using NUnit.Framework;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Communications;
using OpenSim.Region.CoreModules.Avatar.Attachments;
using OpenSim.Region.CoreModules.Avatar.AvatarFactory;
using OpenSim.Region.CoreModules.Framework.InventoryAccess;
using OpenSim.Region.CoreModules.Framework.UserManagement;
using OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.OptionalModules.World.NPC;
using OpenSim.Services.AvatarService;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Tests.Torture
{
/// <summary>
/// NPC torture tests
/// </summary>
/// <remarks>
/// Don't rely on the numbers given by these tests - they will vary a lot depending on what is already cached,
/// how much memory is free, etc. In some cases, later larger tests will apparently take less time than smaller
/// earlier tests.
/// </remarks>
[TestFixture]
public class NPCTortureTests
{
private TestScene scene;
private AvatarFactoryModule afm;
private UserManagementModule umm;
private AttachmentsModule am;
[TestFixtureSetUp]
public void FixtureInit()
{
// Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
Util.FireAndForgetMethod = FireAndForgetMethod.None;
}
[TestFixtureTearDown]
public void TearDown()
{
// We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
// threads. Possibly, later tests should be rewritten not to worry about such things.
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
}
[SetUp]
public void Init()
{
IConfigSource config = new IniConfigSource();
config.AddConfig("NPC");
config.Configs["NPC"].Set("Enabled", "true");
config.AddConfig("Modules");
config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
afm = new AvatarFactoryModule();
umm = new UserManagementModule();
am = new AttachmentsModule();
scene = SceneHelpers.SetupScene();
SceneHelpers.SetupSceneModules(scene, config, afm, umm, am, new BasicInventoryAccessModule(), new NPCModule());
}
[Test]
public void TestAddRemove100NPCs()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
TestAddRemoveNPCs(100);
}
[Test]
public void TestAddRemove1000NPCs()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
TestAddRemoveNPCs(1000);
}
[Test]
public void TestAddRemove2000NPCs()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
TestAddRemoveNPCs(2000);
}
private void TestAddRemoveNPCs(int numberOfNpcs)
{
ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
// 8 is the index of the first baked texture in AvatarAppearance
UUID originalFace8TextureId = TestHelpers.ParseTail(0x10);
Primitive.TextureEntry originalTe = new Primitive.TextureEntry(UUID.Zero);
Primitive.TextureEntryFace originalTef = originalTe.CreateFace(8);
originalTef.TextureID = originalFace8TextureId;
// We also need to add the texture to the asset service, otherwise the AvatarFactoryModule will tell
// ScenePresence.SendInitialData() to reset our entire appearance.
scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId));
afm.SetAppearance(sp, originalTe, null);
INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
List<UUID> npcs = new List<UUID>();
long startGcMemory = GC.GetTotalMemory(true);
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < numberOfNpcs; i++)
{
npcs.Add(
npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, scene, sp.Appearance));
}
for (int i = 0; i < numberOfNpcs; i++)
{
Assert.That(npcs[i], Is.Not.Null);
ScenePresence npc = scene.GetScenePresence(npcs[i]);
Assert.That(npc, Is.Not.Null);
}
for (int i = 0; i < numberOfNpcs; i++)
{
Assert.That(npcModule.DeleteNPC(npcs[i], scene), Is.True);
ScenePresence npc = scene.GetScenePresence(npcs[i]);
Assert.That(npc, Is.Null);
}
sw.Stop();
long endGcMemory = GC.GetTotalMemory(true);
Console.WriteLine("Took {0} ms", sw.ElapsedMilliseconds);
Console.WriteLine(
"End {0} MB, Start {1} MB, Diff {2} MB",
endGcMemory / 1024 / 1024,
startGcMemory / 1024 / 1024,
(endGcMemory - startGcMemory) / 1024 / 1024);
}
}
}
+19 -2
View File
@@ -49,6 +49,13 @@ namespace OpenSim.Tests.Torture
[TestFixture]
public class ObjectTortureTests
{
[TearDown]
public void TearDown()
{
GC.Collect();
GC.WaitForPendingFinalizers();
}
// [Test]
// public void Test0000Clean()
// {
@@ -141,8 +148,18 @@ namespace OpenSim.Tests.Torture
string.Format("Object {0} could not be retrieved", i));
}
// This does not work to fire the SceneObjectGroup destructors - something else is hanging on to them.
// scene.DeleteAllSceneObjects();
// When a scene object is added to a scene, it is placed in the update list for sending to viewers
// (though in this case we have none). When it is deleted, it is not removed from the update which is
// fine since it will later be ignored.
//
// However, that means that we need to manually run an update here to clear out that list so that deleted
// objects will be clean up by the garbage collector before the next stress test is run.
scene.Update();
// Currently, we need to do this in order to garbage collect the scene objects ready for the next test run.
// However, what we really need to do is find out why the entire scene is not garbage collected in
// teardown.
scene.DeleteAllSceneObjects();
Console.WriteLine(
"Took {0}ms, {1}MB ({2} - {3}) to create {4} objects each containing {5} prim(s)",
+9 -5
View File
@@ -484,7 +484,6 @@
;; such as the Meta7 viewer.
;; It has no ill effect on viewers which do not support server-side
;; windlight settings.
;; Currently we only have support for MySQL databases.
; enable_windlight = false
@@ -573,10 +572,15 @@
; DeleteScriptsOnStartup = true
;; Set this to true (the default) to load each script into a separate
;; AppDomain. Setting this to false will load all script assemblies into the
;; current AppDomain, which will reduce the per-script overhead at the
;; expense of reduced security and the inability to garbage collect the
;; script assemblies
;; AppDomain.
;;
;; Setting this to false will load all script assemblies into the
;; current AppDomain, which will significantly improve script loading times.
;; It will also reduce initial per-script memory overhead.
;;
;; However, setting this to false will also prevent script DLLs from being unloaded from memory if the script is deleted.
;; This may cause an OutOfMemory problem over time when avatars with scripted attachments move in and out of the region.
;; Some Windows users have also reported script loading problems when AppDomainLoading = false
; AppDomainLoading = true
;# {DefaultCompileLanguage} {Enabled:true} {Default script language?} {lsl vb cs} lsl
+5 -1
View File
@@ -655,6 +655,11 @@
world_gravityy = 0
world_gravityz = -9.8
; Terminal velocity of a falling avatar
; This is the same http://en.wikipedia.org/wiki/Terminal_velocity#Examples
; Max value is 255, min value is 0
avatar_terminal_velocity = 54
; World Step size. (warning these are dangerous. Changing these will probably cause your scene to explode dramatically)
; reference: fps = (0.089/ODE_STEPSIZE) * 1000;
world_stepsize = 0.0178
@@ -1065,7 +1070,6 @@
[LightShare]
; This enables the transmission of Windlight scenes to supporting clients, such as the Meta7 viewer.
; It has no ill effect on viewers which do not support server-side windlight settings.
; Currently we only have support for MySQL databases.
enable_windlight = false
Binary file not shown.
Binary file not shown.

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