Compare commits

...

104 Commits

Author SHA1 Message Date
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
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
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
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
UbitUmarov
43a74d8481 test on git 2012-02-10 23:51:55 +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
UbitUmarov
6af01f6767 initial introdution of physics actor building control. 2012-02-08 23:14:53 +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
UbitUmarov
815f3af1d7 UbitODE plugin initial commit 2012-02-08 15:24:10 +00:00
73 changed files with 15583 additions and 1706 deletions

View File

@@ -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

View File

@@ -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;

File diff suppressed because it is too large Load Diff

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()

View File

@@ -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();
}
}
}
}
}

View File

@@ -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();

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,20 @@ 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 IsEnvironmentSupported(ref string reason)
@@ -1469,6 +1484,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

View File

@@ -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

View File

@@ -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>

View File

@@ -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);

View File

@@ -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");
}
}
}
}

View File

@@ -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)
{
@@ -1281,13 +1217,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)
@@ -1719,35 +1658,38 @@ 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;
// NOT here
// 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))
Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
if (destination != null)
{
m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID);
// 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);
// 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.AbsolutePosition = oldGroupPosition;
grp.ScheduleGroupForFullUpdate();
grp.RootPart.GroupPosition = pos; // only change this if we think there is anywhere to go
if (CrossPrimGroupIntoNewRegion(destination, 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>

View File

@@ -565,9 +565,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
// "[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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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))

View File

@@ -707,7 +707,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)
{

View File

@@ -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()
{

View File

@@ -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>

View File

@@ -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

View File

@@ -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;

View File

@@ -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();
}
}
}

View File

@@ -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;
}
@@ -1643,9 +1647,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;
@@ -1726,6 +1734,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;
@@ -1954,7 +1966,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

View File

@@ -3395,8 +3395,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 +3411,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 +3574,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);
@@ -4766,7 +4792,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
}
}

View File

@@ -140,6 +140,7 @@ namespace OpenSim.Region.Framework.Scenes
icon.EndInvoke(iar);
}
ExpiringCache<string, bool> _failedSims = new ExpiringCache<string, bool>();
public void SendChildAgentDataUpdate(AgentPosition cAgentData, ScenePresence presence)
{
// This assumes that we know what our neighbors are.
@@ -156,16 +157,22 @@ 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);
if (! simulatorList.Contains(dest.ServerURI))
bool v = true;
if (! simulatorList.Contains(dest.ServerURI) && !_failedSims.TryGetValue(dest.ServerURI, out v))
{
// 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.
if (!m_scene.SimulationService.UpdateAgent(dest, cAgentData))
// Also if it fails, get it out of the loop for a bit
_failedSims.Add(dest.ServerURI, true, 120);
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);
}
}
}

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;

View File

@@ -43,6 +43,7 @@ using OpenSim.Region.Framework.Scenes.Serialization;
namespace OpenSim.Region.Framework.Scenes
{
[Flags]
public enum scriptEvents
{
@@ -461,15 +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;
if (IsDeleted)
return;
val = AbsolutePosition;
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);
}
}
@@ -528,6 +605,23 @@ namespace OpenSim.Region.Framework.Scenes
}
}
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; }
@@ -1285,7 +1379,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);
@@ -1584,22 +1679,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);
}
}
@@ -1671,7 +1776,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);
@@ -1770,6 +1875,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>();
@@ -1833,13 +1939,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)
{
@@ -1850,6 +1959,7 @@ namespace OpenSim.Region.Framework.Scenes
ScheduleGroupForFullUpdate();
}
m_dupeInProgress = false;
return dupe;
}
@@ -2857,12 +2967,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);
}
}

View File

@@ -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;
@@ -1539,7 +1546,8 @@ namespace OpenSim.Region.Framework.Scenes
Shape,
AbsolutePosition,
Scale,
RotationOffset,
// RotationOffset,
GetWorldRotation(), // physics wants world rotation
RigidBody,
m_localId);
}
@@ -1554,8 +1562,16 @@ 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);
if (!building)
PhysActor.Building = false;
}
}
}
@@ -1601,9 +1617,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 +1807,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 +2632,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 +3180,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 +3255,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 +3268,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 +3460,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 +4347,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 +4366,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 +4450,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 +4536,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;

View File

@@ -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,7 +874,26 @@ 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);
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;
}
bool wasChild = IsChildAgent;
IsChildAgent = false;
@@ -881,62 +906,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,11 +981,13 @@ 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.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
sog.ResumeScripts();
}
});
}
}
@@ -1814,8 +1843,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 +1882,10 @@ namespace OpenSim.Region.Framework.Scenes
ParentPosition = Vector3.Zero;
ParentID = 0;
if (PhysicsActor == null)
AddToPhysicalScene(false);
SendAvatarDataToAllAgents();
m_requestedSitTargetID = 0;
@@ -1857,6 +1893,9 @@ namespace OpenSim.Region.Framework.Scenes
part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
}
else if (PhysicsActor == null)
AddToPhysicalScene(false);
Animator.TrySetMovementAnimation("STAND");
}
@@ -2748,7 +2787,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 +3152,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 +3214,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

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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 )
{

View File

@@ -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;

File diff suppressed because it is too large Load Diff

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,17 +3438,17 @@ 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 258 x 258 (Meters) (1 extra each side)
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; // to have 258m we need 259 samples
int heightmapHeightSamples = (int)regionsize + 3;
// Array of height samples for ODE
float[] _heightmap;
_heightmap = new float[(heightmapWidthSamples * heightmapHeightSamples)]; // loaded samples 258 x 258
_heightmap = new float[(heightmapWidthSamples * heightmapHeightSamples)]; // loaded samples 259 x 259
// Other ODE parameters
const float scale = 1.0f;
@@ -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

View File

@@ -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;
}
}
}

View File

@@ -65,5 +65,6 @@ namespace OpenSim.Region.Physics.Manager
void releasePinned();
void Append(IMesh newMesh);
void TransformLinear(float[,] matrix, float[] offset);
Vector3 GetCentroid();
}
}

View File

@@ -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;
}
}
}

View File

@@ -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
{

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>();
}
}
}

View File

@@ -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;
}
}

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;

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); }

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

View File

@@ -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>

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,36 @@ 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())
{
string nativeLibraryPath;
if (Util.Is64BitProcess())
nativeLibraryPath = "lib64/ode.dll";
else
nativeLibraryPath = "lib32/ode.dll";
m_log.DebugFormat("[ODE PLUGIN]: Loading native Windows ODE library at {0}", nativeLibraryPath);
if (Util.LoadLibrary(nativeLibraryPath) == IntPtr.Zero)
m_log.ErrorFormat(
"[ODE PLUGIN]: Couldn't find native Windows ODE library at {0}", nativeLibraryPath);
}
// 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()

View File

@@ -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);

View File

@@ -0,0 +1,58 @@
/*
* 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("OdePlugin")]
[assembly : AssemblyDescription("Ubit Variation")]
[assembly : AssemblyConfiguration("")]
[assembly : AssemblyCompany("http://opensimulator.org")]
[assembly : AssemblyProduct("OdePlugin")]
[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.*")]

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,849 @@
/*
* 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.
*/
/* Revised Aug, Sept 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.
*/
// Ubit 2012
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using log4net;
using OpenMetaverse;
using OdeAPI;
using OpenSim.Framework;
using OpenSim.Region.Physics.Manager;
namespace OpenSim.Region.Physics.OdePlugin
{
public class ODEDynamics
{
public Vehicle Type
{
get { return m_type; }
}
private OdePrim rootPrim;
private OdeScene _pParentScene;
// 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 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
private Vector3 m_BlockingEndPoint = Vector3.Zero; // not sl
// Linear properties
private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time
private Vector3 m_linearFrictionTimescale = new Vector3(1000, 1000, 1000);
private float m_linearMotorDecayTimescale = 120;
private float m_linearMotorTimescale = 1000;
private Vector3 m_lastLinearVelocityVector = Vector3.Zero;
private Vector3 m_linearMotorOffset = Vector3.Zero;
//Angular properties
private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor
private float m_angularMotorTimescale = 1000; // motor angular velocity ramp up rate
private float m_angularMotorDecayTimescale = 120; // motor angular velocity decay rate
private Vector3 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); // body angular velocity decay rate
private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body
//Deflection properties
private float m_angularDeflectionEfficiency = 0;
private float m_angularDeflectionTimescale = 1000;
private float m_linearDeflectionEfficiency = 0;
private float m_linearDeflectionTimescale = 1000;
//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 = 1000f;
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 = 1.0f; // damped
private float m_verticalAttractionTimescale = 1000f; // Timescale > 300 means no vert attractor.
// auxiliar
private Vector3 m_dir = Vector3.Zero; // velocity applied to body
private float m_lmEfect = 0; // current linear motor eficiency
private float m_amEfect = 0; // current angular motor eficiency
public ODEDynamics(OdePrim rootp)
{
rootPrim = rootp;
_pParentScene = rootPrim._parent_scene;
}
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
{
float len;
float invtimestep = 1.0f / _pParentScene.ODE_STEPSIZE;
float timestep = _pParentScene.ODE_STEPSIZE;
switch (pParam)
{
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
if (pValue < 0f) pValue = 0f;
if (pValue > 1f) pValue = 1f;
m_angularDeflectionEfficiency = pValue;
break;
case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
if (pValue < timestep) pValue = timestep;
m_angularDeflectionTimescale = pValue;
break;
case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
// 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;
case Vehicle.ANGULAR_MOTOR_TIMESCALE:
if (pValue < timestep) pValue = timestep;
m_angularMotorTimescale = pValue;
break;
case Vehicle.BANKING_EFFICIENCY:
if (pValue < -1f) pValue = -1f;
if (pValue > 1f) pValue = 1f;
m_bankingEfficiency = pValue;
break;
case Vehicle.BANKING_MIX:
if (pValue < 0f) pValue = 0f;
if (pValue > 1f) pValue = 1f;
m_bankingMix = pValue;
break;
case Vehicle.BANKING_TIMESCALE:
if (pValue < timestep) pValue = timestep;
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 < timestep) pValue = timestep;
m_VhoverTimescale = pValue;
break;
case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
if (pValue < 0f) pValue = 0f;
if (pValue > 1f) pValue = 1f;
m_linearDeflectionEfficiency = pValue;
break;
case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
if (pValue < timestep) pValue = timestep;
m_linearDeflectionTimescale = pValue;
break;
case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
// 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;
case Vehicle.LINEAR_MOTOR_TIMESCALE:
if (pValue < timestep) pValue = timestep;
m_linearMotorTimescale = pValue;
break;
case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
if (pValue < 0f) pValue = 0f;
if (pValue > 1f) pValue = 1f;
m_verticalAttractionEfficiency = pValue;
break;
case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
if (pValue < timestep) pValue = timestep;
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;
m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
break;
case Vehicle.ANGULAR_MOTOR_DIRECTION:
m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
len = m_angularMotorDirection.Length();
if (len > 12.566f)
m_angularMotorDirection *= (12.566f / len);
m_amEfect = 1.0f; // turn it on
break;
case Vehicle.LINEAR_FRICTION_TIMESCALE:
if (pValue < timestep) pValue = timestep;
m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
break;
case Vehicle.LINEAR_MOTOR_DIRECTION:
m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
len = m_linearMotorDirection.Length();
if (len > 30.0f)
m_linearMotorDirection *= (30.0f / len);
m_lmEfect = 1.0f; // turn it on
break;
case Vehicle.LINEAR_MOTOR_OFFSET:
m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
len = m_linearMotorOffset.Length();
if (len > 100.0f)
m_linearMotorOffset *= (100.0f / len);
break;
}
}//end ProcessFloatVehicleParam
internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue)
{
float len;
float invtimestep = 1.0f / _pParentScene.ODE_STEPSIZE;
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;
if (pValue.Z < timestep) pValue.Z = timestep;
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);
// Limit requested angular speed to 2 rps= 4 pi rads/sec
len = m_angularMotorDirection.Length();
if (len > 12.566f)
m_angularMotorDirection *= (12.566f / len);
m_amEfect = 1.0f; // turn it on
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;
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);
len = m_linearMotorDirection.Length();
if (len > 30.0f)
m_linearMotorDirection *= (30.0f / len);
m_lmEfect = 1.0f; // turn it on
break;
case Vehicle.LINEAR_MOTOR_OFFSET:
m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
len = m_linearMotorOffset.Length();
if (len > 100.0f)
m_linearMotorOffset *= (100.0f / len);
break;
case Vehicle.BLOCK_EXIT:
m_BlockingEndPoint = 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 = Quaternion.Inverse(pValue);
break;
case Vehicle.ROLL_FRAME:
m_RollreferenceFrame = pValue;
break;
}
}//end ProcessRotationVehicleParam
internal void ProcessVehicleFlags(int pParam, bool remove)
{
if (remove)
{
m_flags &= ~((VehicleFlag)pParam);
}
else
{
m_flags |= (VehicleFlag)pParam;
}
}//end ProcessVehicleFlags
internal void ProcessTypeChange(Vehicle pType)
{
float invtimestep = _pParentScene.ODE_STEPSIZE;
m_lmEfect = 0;
m_amEfect = 0;
m_linearMotorDirection = Vector3.Zero;
m_angularMotorDirection = Vector3.Zero;
m_BlockingEndPoint = Vector3.Zero;
m_RollreferenceFrame = Quaternion.Identity;
m_linearMotorOffset = Vector3.Zero;
m_referenceFrame = Quaternion.Identity;
// Set Defaults For Type
m_type = pType;
switch (pType)
{
case Vehicle.TYPE_NONE:
m_linearFrictionTimescale = new Vector3(1000, 1000, 1000);
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
m_linearMotorTimescale = 1000;
m_linearMotorDecayTimescale = 120 * invtimestep;
m_angularMotorTimescale = 1000;
m_angularMotorDecayTimescale = 1000 * invtimestep;
m_VhoverHeight = 0;
m_VhoverTimescale = 1000;
m_VehicleBuoyancy = 0;
m_flags = (VehicleFlag)0;
break;
case Vehicle.TYPE_SLED:
m_linearFrictionTimescale = new Vector3(30, 1, 1000);
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
m_linearMotorTimescale = 1000;
m_linearMotorDecayTimescale = 120 * invtimestep;
m_angularMotorTimescale = 1000;
m_angularMotorDecayTimescale = 120 * invtimestep;
m_VhoverHeight = 0;
m_VhoverEfficiency = 1;
m_VhoverTimescale = 10;
m_VehicleBuoyancy = 0;
m_linearDeflectionEfficiency = 1;
m_linearDeflectionTimescale = 1;
m_angularDeflectionEfficiency = 0;
m_angularDeflectionTimescale = 1000;
m_bankingEfficiency = 0;
m_bankingMix = 1;
m_bankingTimescale = 10;
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_linearMotorTimescale = 1;
m_linearMotorDecayTimescale = 60 * invtimestep;
m_angularMotorTimescale = 1;
m_angularMotorDecayTimescale = 0.8f * invtimestep;
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 = 1f;
m_verticalAttractionTimescale = 10f;
m_bankingEfficiency = -0.2f;
m_bankingMix = 1;
m_bankingTimescale = 1;
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.LIMIT_MOTOR_UP | VehicleFlag.HOVER_UP_ONLY);
break;
case Vehicle.TYPE_BOAT:
m_linearFrictionTimescale = new Vector3(10, 3, 2);
m_angularFrictionTimescale = new Vector3(10, 10, 10);
m_linearMotorTimescale = 5;
m_linearMotorDecayTimescale = 60 * invtimestep;
m_angularMotorTimescale = 4;
m_angularMotorDecayTimescale = 4 * invtimestep;
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 = 5f;
m_bankingEfficiency = -0.3f;
m_bankingMix = 0.8f;
m_bankingTimescale = 1;
m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
VehicleFlag.HOVER_GLOBAL_HEIGHT |
VehicleFlag.HOVER_UP_ONLY |
VehicleFlag.LIMIT_ROLL_ONLY);
m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
VehicleFlag.LIMIT_MOTOR_UP |
VehicleFlag.HOVER_WATER_ONLY);
break;
case Vehicle.TYPE_AIRPLANE:
m_linearFrictionTimescale = new Vector3(200, 10, 5);
m_angularFrictionTimescale = new Vector3(20, 20, 20);
m_linearMotorTimescale = 2;
m_linearMotorDecayTimescale = 60 * invtimestep;
m_angularMotorTimescale = 4;
m_angularMotorDecayTimescale = 8 * invtimestep;
m_VhoverHeight = 0;
m_VhoverEfficiency = 0.5f;
m_VhoverTimescale = 1000;
m_VehicleBuoyancy = 0;
m_linearDeflectionEfficiency = 0.5f;
m_linearDeflectionTimescale = 0.5f;
m_angularDeflectionEfficiency = 1;
m_angularDeflectionTimescale = 2;
m_verticalAttractionEfficiency = 0.9f;
m_verticalAttractionTimescale = 2f;
m_bankingEfficiency = 1;
m_bankingMix = 0.7f;
m_bankingTimescale = 2;
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);
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_linearMotorTimescale = 5;
m_linearMotorDecayTimescale = 60 * invtimestep;
m_angularMotorTimescale = 6;
m_angularMotorDecayTimescale = 10 * invtimestep;
m_VhoverHeight = 5;
m_VhoverEfficiency = 0.8f;
m_VhoverTimescale = 10;
m_VehicleBuoyancy = 1;
m_linearDeflectionEfficiency = 0;
m_linearDeflectionTimescale = 5 * invtimestep;
m_angularDeflectionEfficiency = 0;
m_angularDeflectionTimescale = 5;
m_verticalAttractionEfficiency = 0f;
m_verticalAttractionTimescale = 1000f;
m_bankingEfficiency = 0;
m_bankingMix = 0.7f;
m_bankingTimescale = 5;
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY |
VehicleFlag.HOVER_TERRAIN_ONLY |
VehicleFlag.HOVER_UP_ONLY |
VehicleFlag.NO_DEFLECTION_UP |
VehicleFlag.LIMIT_MOTOR_UP);
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY |
VehicleFlag.HOVER_GLOBAL_HEIGHT);
break;
}
}//end SetDefaultsForType
internal void Stop()
{
m_lmEfect = 0;
m_amEfect = 0;
}
public static Vector3 Xrot(Quaternion rot)
{
Vector3 vec;
rot.Normalize(); // just in case
vec.X = 2 * (rot.X * rot.X + rot.W * rot.W) - 1;
vec.Y = 2 * (rot.X * rot.Y + rot.Z * rot.W);
vec.Z = 2 * (rot.X * rot.Z - rot.Y * rot.W);
return vec;
}
public static Vector3 Zrot(Quaternion rot)
{
Vector3 vec;
rot.Normalize(); // just in case
vec.X = 2 * (rot.X * rot.Z + rot.Y * rot.W);
vec.Y = 2 * (rot.Y * rot.Z - rot.X * rot.W);
vec.Z = 2 * (rot.Z * rot.Z + rot.W * rot.W) - 1;
return vec;
}
private const float halfpi = 0.5f * (float)Math.PI;
public static Vector3 ubitRot2Euler(Quaternion rot)
{
// returns roll in X
// pitch in Y
// yaw in Z
Vector3 vec;
// assuming rot is normalised
// rot.Normalize();
float zX = rot.X * rot.Z + rot.Y * rot.W;
if (zX < -0.49999f)
{
vec.X = 0;
vec.Y = -halfpi;
vec.Z = (float)(-2d * Math.Atan(rot.X / rot.W));
}
else if (zX > 0.49999f)
{
vec.X = 0;
vec.Y = halfpi;
vec.Z = (float)(2d * Math.Atan(rot.X / rot.W));
}
else
{
vec.Y = (float)Math.Asin(2 * zX);
float sqw = rot.W * rot.W;
float minuszY = rot.X * rot.W - rot.Y * rot.Z;
float zZ = rot.Z * rot.Z + sqw - 0.5f;
vec.X = (float)Math.Atan2(minuszY, zZ);
float yX = rot.Z * rot.W - rot.X * rot.Y; //( have negative ?)
float yY = rot.X * rot.X + sqw - 0.5f;
vec.Z = (float)Math.Atan2(yX, yY);
}
return vec;
}
public static void GetRollPitch(Quaternion rot, out float roll, out float pitch)
{
// assuming rot is normalised
// rot.Normalize();
float zX = rot.X * rot.Z + rot.Y * rot.W;
if (zX < -0.49999f)
{
roll = 0;
pitch = -halfpi;
}
else if (zX > 0.49999f)
{
roll = 0;
pitch = halfpi;
}
else
{
pitch = (float)Math.Asin(2 * zX);
float minuszY = rot.X * rot.W - rot.Y * rot.Z;
float zZ = rot.Z * rot.Z + rot.W * rot.W - 0.5f;
roll = (float)Math.Atan2(minuszY, zZ);
}
return ;
}
internal void Step()//float pTimestep)
{
IntPtr Body = rootPrim.Body;
d.Quaternion rot = d.BodyGetQuaternion(Body);
Quaternion objrotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
Quaternion rotq = objrotq; // rotq = rotation of object
rotq *= m_referenceFrame; // rotq is now rotation in vehicle reference frame
Quaternion irotq = Quaternion.Inverse(rotq);
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);
curVel.X = dvtmp.X;
curVel.Y = dvtmp.Y;
curVel.Z = dvtmp.Z;
Vector3 curLocalVel = curVel * irotq; // current velocity in local
dvtmp = d.BodyGetAngularVel(Body);
curAngVel.X = dvtmp.X;
curAngVel.Y = dvtmp.Y;
curAngVel.Z = dvtmp.Z;
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
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;
}
m_lmEfect *= (1.0f - 1.0f / m_linearMotorDecayTimescale);
}
else
m_lmEfect = 0;
// friction
if (curLocalVel.X != 0 || curLocalVel.Y != 0 || curLocalVel.Z != 0)
{
tmpV.X = -curLocalVel.X / m_linearFrictionTimescale.X;
tmpV.Y = -curLocalVel.Y / m_linearFrictionTimescale.Y;
tmpV.Z = -curLocalVel.Z / m_linearFrictionTimescale.Z;
tmpV *= rotq; // to world
force.X += tmpV.X;
force.Y += tmpV.Y;
force.Z += tmpV.Z;
}
// hover
if (m_VhoverTimescale < 300)
{
d.Vector3 pos = d.BodyGetPosition(Body);
// default to global
float perr = m_VhoverHeight - pos.Z;;
if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
{
perr += _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y);
}
else if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
{
perr += _pParentScene.GetWaterLevel();
}
else if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == 0)
{
float t = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y);
float w = _pParentScene.GetWaterLevel();
if (t > w)
perr += t;
else
perr += w;
}
if ((m_flags & VehicleFlag.HOVER_UP_ONLY) == 0 || perr > 0)
{
force.Z += (perr / m_VhoverTimescale / m_VhoverTimescale - curVel.Z * m_VhoverEfficiency) / _pParentScene.ODE_STEPSIZE;
force.Z += _pParentScene.gravityz * (1f - m_VehicleBuoyancy);
}
else // no buoyancy
force.Z += _pParentScene.gravityz;
}
else
{
// default gravity and buoancy
force.Z += _pParentScene.gravityz * (1f - m_VehicleBuoyancy);
}
// linear deflection
if (m_linearDeflectionEfficiency > 0)
{
float len = curVel.Length();
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
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
m_amEfect = 0;
// angular friction
if (curLocalAngVel.X != 0 || curLocalAngVel.Y != 0 || curLocalAngVel.Z != 0)
{
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)
{
Vector3 dirv;
if (curLocalVel.X > 0.01f)
dirv = curLocalVel;
else if (curLocalVel.X < -0.01f)
// use oposite
dirv = -curLocalVel;
else
{
// make it fall into small positive x case
dirv.X = 0.01f;
dirv.Y = curLocalVel.Y;
dirv.Z = curLocalVel.Z;
}
float ftmp = m_angularDeflectionEfficiency / m_angularDeflectionTimescale;
if (Math.Abs(dirv.Z) > 0.01)
{
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)
{
float roll;
float 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
{
torque.X -= -roll * ftmp + curLocalAngVel.X * ftmp2;
}
if (Math.Abs(pitch) > 0.01 && ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) == 0)) // pitch
{
torque.Y -= -pitch * ftmp + curLocalAngVel.Y * ftmp2;
}
if (m_bankingEfficiency != 0 && Math.Abs(roll) > 0.01)
{
float broll = roll * m_bankingEfficiency; ;
if (m_bankingMix != 0)
{
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;
// 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;
torque.X += tmpV.X;
torque.Y += tmpV.Y;
torque.Z += tmpV.Z;
}
}
d.Mass dmass;
d.BodyGetMass(Body,out dmass);
if (force.X != 0 || force.Y != 0 || force.Z != 0)
{
force *= dmass.mass;
d.BodySetForce(Body, force.X, force.Y, force.Z);
}
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
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,443 @@
/*
* 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 System.Text;
using OpenMetaverse;
using OpenSim.Region.Physics.Manager;
using OdeAPI;
using log4net;
namespace OpenSim.Region.Physics.OdePlugin
{
/// <summary>
/// Processes raycast requests as ODE is in a state to be able to do them.
/// This ensures that it's thread safe and there will be no conflicts.
/// Requests get returned by a different thread then they were requested by.
/// </summary>
public class ODERayCastRequestManager
{
/// <summary>
/// Pending ray requests
/// </summary>
protected OpenSim.Framework.LocklessQueue<ODERayRequest> m_PendingRequests = new OpenSim.Framework.LocklessQueue<ODERayRequest>();
/// <summary>
/// Scene that created this object.
/// </summary>
private OdeScene m_scene;
IntPtr ray;
private const int ColisionContactGeomsPerTest = 5;
/// <summary>
/// ODE near callback delegate
/// </summary>
private d.NearCallback nearCallback;
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private List<ContactResult> m_contactResults = new List<ContactResult>();
public ODERayCastRequestManager(OdeScene pScene)
{
m_scene = pScene;
nearCallback = near;
ray = d.CreateRay(IntPtr.Zero, 1.0f);
}
/// <summary>
/// Queues a raycast
/// </summary>
/// <param name="position">Origin of Ray</param>
/// <param name="direction">Ray normal</param>
/// <param name="length">Ray length</param>
/// <param name="retMethod">Return method to send the results</param>
public void QueueRequest(Vector3 position, Vector3 direction, float length, RayCallback retMethod)
{
ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero;
req.callbackMethod = retMethod;
req.Count = 0;
req.length = length;
req.Normal = direction;
req.Origin = position;
m_PendingRequests.Enqueue(req);
}
public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RayCallback retMethod)
{
ODERayRequest req = new ODERayRequest();
req.geom = geom;
req.callbackMethod = retMethod;
req.length = length;
req.Normal = direction;
req.Origin = position;
req.Count = 0;
m_PendingRequests.Enqueue(req);
}
public void QueueRequest(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
{
ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero;
req.callbackMethod = retMethod;
req.Count = 0;
req.length = length;
req.Normal = direction;
req.Origin = position;
m_PendingRequests.Enqueue(req);
}
public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
{
ODERayRequest req = new ODERayRequest();
req.geom = geom;
req.callbackMethod = retMethod;
req.length = length;
req.Normal = direction;
req.Origin = position;
req.Count = 0;
m_PendingRequests.Enqueue(req);
}
/// <summary>
/// Queues a raycast
/// </summary>
/// <param name="position">Origin of Ray</param>
/// <param name="direction">Ray normal</param>
/// <param name="length">Ray length</param>
/// <param name="count"></param>
/// <param name="retMethod">Return method to send the results</param>
public void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod)
{
ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero;
req.callbackMethod = retMethod;
req.length = length;
req.Normal = direction;
req.Origin = position;
req.Count = count;
m_PendingRequests.Enqueue(req);
}
public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod)
{
ODERayRequest req = new ODERayRequest();
req.geom = geom;
req.callbackMethod = retMethod;
req.length = length;
req.Normal = direction;
req.Origin = position;
req.Count = count;
m_PendingRequests.Enqueue(req);
}
public void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RaycastCallback retMethod)
{
ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero;
req.callbackMethod = retMethod;
req.length = length;
req.Normal = direction;
req.Origin = position;
req.Count = count;
m_PendingRequests.Enqueue(req);
}
public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, int count, RaycastCallback retMethod)
{
ODERayRequest req = new ODERayRequest();
req.geom = geom;
req.callbackMethod = retMethod;
req.length = length;
req.Normal = direction;
req.Origin = position;
req.Count = count;
m_PendingRequests.Enqueue(req);
}
/// <summary>
/// Process all queued raycast requests
/// </summary>
/// <returns>Time in MS the raycasts took to process.</returns>
public int ProcessQueuedRequests()
{
int time = System.Environment.TickCount;
if (m_PendingRequests.Count <= 0)
return 0;
if (m_scene.ContactgeomsArray == IntPtr.Zero) // oops something got wrong or scene isn't ready still
{
m_PendingRequests.Clear();
return 0;
}
ODERayRequest req;
int i = 50; // arbitary limit of processed tests per frame
while(m_PendingRequests.Dequeue(out req))
{
if (req.geom == IntPtr.Zero)
doSpaceRay(req);
else
doGeomRay(req);
if(--i < 0)
break;
}
lock (m_contactResults)
m_contactResults.Clear();
return System.Environment.TickCount - time;
}
/// <summary>
/// Method that actually initiates the raycast with full top space
/// </summary>
/// <param name="req"></param>
private void doSpaceRay(ODERayRequest req)
{
// Create the ray
// IntPtr ray = d.CreateRay(m_scene.TopSpace, req.length);
d.GeomRaySetLength(ray, req.length);
d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
// Collide test
d.SpaceCollide2(m_scene.TopSpace, ray, IntPtr.Zero, nearCallback);
// Remove Ray
// d.GeomDestroy(ray);
if (req.callbackMethod == null)
return;
if (req.callbackMethod is RaycastCallback)
{
// Define default results
bool hitYN = false;
uint hitConsumerID = 0;
float distance = 999999999999f;
Vector3 closestcontact = new Vector3(99999f, 99999f, 99999f);
Vector3 snormal = Vector3.Zero;
// Find closest contact and object.
lock (m_contactResults)
{
foreach (ContactResult cResult in m_contactResults)
{
if (Vector3.Distance(req.Origin, cResult.Pos) < Vector3.Distance(req.Origin, closestcontact))
{
closestcontact = cResult.Pos;
hitConsumerID = cResult.ConsumerID;
distance = cResult.Depth;
hitYN = true;
snormal = cResult.Normal;
}
}
m_contactResults.Clear();
}
((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal);
}
else
{
((RayCallback)req.callbackMethod)(m_contactResults);
lock (m_PendingRequests)
m_contactResults.Clear();
}
}
/// <summary>
/// Method that actually initiates the raycast with a geom
/// </summary>
/// <param name="req"></param>
private void doGeomRay(ODERayRequest req)
{
// Create the ray
// IntPtr ray = d.CreateRay(m_scene.TopSpace, req.length);
d.GeomRaySetLength(ray, req.length);
d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
// Collide test
d.SpaceCollide2(req.geom, ray, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test
// Remove Ray
// d.GeomDestroy(ray);
if (req.callbackMethod == null)
return;
if (req.callbackMethod is RaycastCallback)
{
// Define default results
bool hitYN = false;
uint hitConsumerID = 0;
float distance = 999999999999f;
Vector3 closestcontact = new Vector3(99999f, 99999f, 99999f);
Vector3 snormal = Vector3.Zero;
// Find closest contact and object.
lock (m_contactResults)
{
foreach (ContactResult cResult in m_contactResults)
{
if (Vector3.Distance(req.Origin, cResult.Pos) < Vector3.Distance(req.Origin, closestcontact))
{
closestcontact = cResult.Pos;
hitConsumerID = cResult.ConsumerID;
distance = cResult.Depth;
hitYN = true;
snormal = cResult.Normal;
}
}
m_contactResults.Clear();
}
((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal);
}
else
{
((RayCallback)req.callbackMethod)(m_contactResults);
lock (m_PendingRequests)
m_contactResults.Clear();
}
}
private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom)
{
IntPtr ContactgeomsArray = m_scene.ContactgeomsArray;
if (ContactgeomsArray == IntPtr.Zero || index >= ColisionContactGeomsPerTest)
return false;
IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * d.ContactGeom.unmanagedSizeOf));
newcontactgeom = (d.ContactGeom)Marshal.PtrToStructure(contactptr, typeof(d.ContactGeom));
return true;
}
// This is the standard Near. g2 is the ray
private void near(IntPtr space, IntPtr g1, IntPtr g2)
{
//Don't test against heightfield Geom, or you'll be sorry!
// Exclude heightfield geom
if (g1 == IntPtr.Zero || g1 == g2)
return;
if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass)
return;
// Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
if (d.GeomIsSpace(g1))
{
try
{
d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
}
catch (Exception e)
{
m_log.WarnFormat("[PHYSICS Ray]: Unable to Space collide test an object: {0}", e.Message);
}
return;
}
int count = 0;
try
{
count = d.CollidePtr(g1, g2, ColisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
}
catch (SEHException)
{
m_log.Error("[PHYSICS Ray]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim.");
}
catch (Exception e)
{
m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message);
return;
}
if (count == 0)
return;
PhysicsActor p1 = null;
if (g1 != IntPtr.Zero)
m_scene.actor_name_map.TryGetValue(g1, out p1);
d.ContactGeom curcontact = new d.ContactGeom();
// Loop over contacts, build results.
for (int i = 0; i < count; i++)
{
if (!GetCurContactGeom(i, ref curcontact))
break;
if (p1 != null) {
if (p1 is OdePrim)
{
ContactResult collisionresult = new ContactResult();
collisionresult.ConsumerID = ((OdePrim)p1).m_localID;
collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z);
collisionresult.Depth = curcontact.depth;
collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y,
curcontact.normal.Z);
lock (m_contactResults)
m_contactResults.Add(collisionresult);
}
}
}
}
/// <summary>
/// Dereference the creator scene so that it can be garbage collected if needed.
/// </summary>
internal void Dispose()
{
m_scene = null;
}
}
public struct ODERayRequest
{
public IntPtr geom;
public Vector3 Origin;
public Vector3 Normal;
public int Count;
public float length;
public object callbackMethod;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,86 @@
/*
* 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 System.Threading;
using System.IO;
using System.Diagnostics;
using log4net;
using Nini.Config;
using OdeAPI;
using OpenSim.Framework;
using OpenSim.Region.Physics.Manager;
using OpenMetaverse;
namespace OpenSim.Region.Physics.OdePlugin
{
/// <summary>
/// ODE plugin
/// </summary>
public class OdePlugin : IPhysicsPlugin
{
//private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private OdeScene m_scene;
public bool Init()
{
if (d.InitODE2(0) != 0)
{
if (d.AllocateODEDataForThread(~0U) == 0)
{
d.CloseODE();
return false;
}
return true;
}
return false;
}
public PhysicsScene GetScene(String sceneIdentifier)
{
if (m_scene == null)
{
m_scene = new OdeScene(sceneIdentifier);
}
return (m_scene);
}
public string GetName()
{
return ("UbitODE");
}
public void Dispose()
{
d.CloseODE();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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);
}
}

View File

@@ -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)
@@ -452,11 +453,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
Action<ScenePresence> senseEntity = new Action<ScenePresence>(presence =>
{
// 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 & 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)
@@ -469,7 +479,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
{
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;
}
}
}

View File

@@ -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));

View File

@@ -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);
}

View File

@@ -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)
{

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>

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)",

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

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

View File

@@ -0,0 +1,7 @@
<configuration>
<dllmap os="osx" dll="ode" target="libode.dylib" />
<dllmap os="!windows,osx" cpu="x86-64,ia64" dll="ode" target="libode-x86_64" />
<dllmap os="!windows,osx" cpu="x86" dll="ode" target="libode" />
<dllmap os="!windows,osx" cpu="ppc64" dll="ode" target="libode-ppc64" />
<dllmap os="!windows,osx" cpu="s390x" dll="ode" target="libode-s390x" />
</configuration>

Binary file not shown.

BIN
bin/Physics/libode.so Normal file

Binary file not shown.

BIN
bin/lib64/ode.dll Executable file

Binary file not shown.

View File

@@ -6,7 +6,7 @@
<CompilerDefines>TRACE;DEBUG</CompilerDefines>
<OptimizeCode>false</OptimizeCode>
<CheckUnderflowOverflow>false</CheckUnderflowOverflow>
<AllowUnsafe>false</AllowUnsafe>
<AllowUnsafe>true</AllowUnsafe>
<WarningLevel>4</WarningLevel>
<WarningsAsErrors>false</WarningsAsErrors>
<SuppressWarnings/>
@@ -606,6 +606,36 @@
</Files>
</Project>
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.UbitOdePlugin" path="OpenSim/Region/Physics/UbitOdePlugin" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../../../../bin/Physics/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../../../bin/Physics/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../../../bin/</ReferencePath>
<Reference name="System"/>
<Reference name="System.Core"/>
<Reference name="OpenMetaverseTypes" path="../../../../bin/"/>
<Reference name="Nini" path="../../../../bin/"/>
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Region.Physics.Manager"/>
<Reference name="log4net" path="../../../../bin/"/>
<Files>
<Match pattern="*.cs" recurse="true">
<Exclude name="Tests" pattern="Tests"/>
</Match>
</Files>
</Project>
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.ConvexDecompositionDotNet" path="OpenSim/Region/Physics/ConvexDecompositionDotNet" type="Library">
<Configuration name="Debug">
<Options>

View File

@@ -1,4 +1,4 @@
bin\Prebuild.exe /target nant
bin\Prebuild.exe /target vs2008
echo C:\WINDOWS\Microsoft.NET\Framework\v3.5\msbuild opensim.sln > compile.bat
echo C:\WINDOWS\Microsoft.NET\Framework\v3.5\msbuild OpenSim.sln > compile.bat