Compare commits

...

105 Commits

Author SHA1 Message Date
SignpostMarv
05648c2c4a changing to use Type argument instead of object 2012-08-31 14:32:31 +01:00
SignpostMarv
dff746df7b moving code that will be common into private static method 2012-08-31 14:32:31 +01:00
SignpostMarv
973f2e8be5 adding documentation to script invokation methods 2012-08-31 14:32:31 +01:00
Melanie
68814f904e Replace SendBannedUserList with Avination's version. Untested in core. Not even test compiled. 2012-08-31 00:37:27 +01:00
Justin Clark-Casey (justincc)
3bd3f448a2 Also do other MySQL region settings related calls under m_dbLock, in common with other calls. 2012-08-31 00:33:06 +01:00
Justin Clark-Casey (justincc)
7c6e8fab15 Do Windlight storage and removal calls in MySQL under m_dbLock, as is done with all the other database calls. 2012-08-31 00:29:57 +01:00
Justin Clark-Casey (justincc)
3ed0d79b00 Make ReuseDynamicTextures an experimental config setting in [Textures]. Default is false, as before.
If true, this setting reuses dynamically generated textures (i.e. created through osSetDynamicTextureData() and similar OSSL functions) where possible rather than always regenerating them.
This results in much quicker updates viewer-side but may bloat the asset cache (though this is fixable).
Also, sometimes issue have been seen where dynamic textures do not transfer to the viewer properly (permanently blurry).
If this happens and that flag is set then they are not regenerated, the viewer has to clear cache or wait for 24 hours before all cached uuids are invalidated.
CUrrently experimental.  Default is false, as before.
2012-08-30 22:57:40 +01:00
Justin Clark-Casey (justincc)
d89b974680 If the compile-time DynamicTextureModule.ReuseTextures flag is set, check metadata still exists for any reused asset in case some other process has removed it from the cache. 2012-08-30 22:28:45 +01:00
SignpostMarv
c76c63725b fixing bug where last element in list is ignored 2012-08-30 00:10:28 +01:00
SignpostMarv
6b277394c0 refactoring as the list funcs either skip invalid values or recall ToDoubleList 2012-08-30 00:10:28 +01:00
Justin Clark-Casey (justincc)
adce58b33a Renaming existing 'torture' tests to 'performance' tests instead, since this better matches what they really do.
nant target name changes to test-perf instead of torture, to match test-stress
still not run by default
2012-08-29 23:19:21 +01:00
Justin Clark-Casey (justincc)
1f88179a65 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-08-29 23:16:16 +01:00
Justin Clark-Casey (justincc)
ec726413dd Add VectorRenderModuleStressTests that contains a long running test that generates thousands of vector textures concurrently.
Intended for use if there are future issues with mono crashes whilst generate dynamic textures.
This test is triggered via a new test-stress nant target.
Not run by default.
2012-08-29 23:04:00 +01:00
Mic Bowman
3d736d575f This partially implements the LSL function to set the response
type for an HTTP request. Since the "official" LSL function limits
the use of the response type, it is implemented as osSetContentType
with a string for the content mime type and a threat level of high.
With this function you should be able to implement rather functional
media-on-a-prim application with much less difficulty.
2012-08-29 14:56:51 -07:00
SignpostMarv
0c3061f973 implementing rule tracking 2012-08-29 02:10:04 +01:00
SignpostMarv
3bf7bd6359 track originating IScriptApi method for SL-like error messages. Will add rule number tracking in next commit. 2012-08-29 02:10:04 +01:00
Justin Clark-Casey (justincc)
7ea832d47c Fix regression introduced in a0d178b2 (Sat Aug 25 02:00:17 2012) where folders with asset type of 'Folder' and 'Unknown' were accidentally treated as system folders.
This prevented more than one additional ordinary folder from being created in the base "My Inventory" user folder.
Added regression test for this case.
Switched tests to use XInventoryService with mostly implemented TestXInventoryDataPlugin rather than InventoryService
Disabled TestLoadIarV0_1SameNameCreator() since this has not been working for a very long time (ever since XInventoryService) started being used
since it doesnt' preserve creator data in the same way as InventoryService did and so effectively lost the OSPAs.
However, nobody noticed/complained about this issue and OSPAs have been superseded by HG like creator information via the --home save oar/iar switch.
2012-08-29 02:01:43 +01:00
Justin Clark-Casey (justincc)
c1cece4b82 Add experimental DynamicTextureModule.ReuseTextures flag, currently only configurable on compile.
Disabled (status quo) by default.
This flag makes the dynamic texture module reuse cache previously dynamically generated textures given the same input commands and extra params for 24 hours.
This occurs as long as those commands would always generate the same texture (e.g. they do not contain commands to fetch data from the web).
This makes texture changing faster as a viewer-cached texture uuid is sent and may reduce simulator load in regions with generation of lots of dynamic textures.
A downside is that this stops expiry of old temporary dynamic textures from the cache,
Another downside is that a jpeg2000 generation that partially failed is currently not regenerated until restart or after 24 hours.
2012-08-28 23:06:53 +01:00
Justin Clark-Casey (justincc)
aa44df9c04 Add IDynamicTextureManager.ConvertData() to match AsyncConvertData(). Remove mismatching ConvertStream() where there is no AsyncConvertStream and neither IDynamicTextureManager implementer implements this method. 2012-08-28 20:35:17 +01:00
SignpostMarv
1e18f0f26a copying documentation from http://opensimulator.org/wiki/Threat_level 2012-08-28 00:12:35 +01:00
SignpostMarv
8a7fbfb06a adding some files to .gitignore that get generated when debugging in c# express with OpenSim.32BitLaunch as the startup project 2012-08-27 23:48:29 +01:00
SignpostMarv
e916b1399f formatting 2012-08-27 23:39:18 +01:00
SignpostMarv
72c2d13ac6 refactoring to load from self (fixes ChanneDigger being absent) 2012-08-27 23:39:18 +01:00
SignpostMarv
a6d689c529 refactoring to assign the first argument to a variable 2012-08-27 23:39:18 +01:00
Justin Clark-Casey (justincc)
ab9bfe5156 minor: Simplify return of vector render module name and some very minor removal of unncessary syntax clutter 2012-08-27 23:06:37 +01:00
Justin Clark-Casey (justincc)
4e26d039d6 Add VectorRenderModule.TestRepeatSameDrawDifferentExtraParams() 2012-08-27 23:03:21 +01:00
Justin Clark-Casey (justincc)
3082fdd0f6 Add VectorRenderModuleTests.TestRepeatDrawContainingImage() 2012-08-27 22:58:20 +01:00
Justin Clark-Casey (justincc)
e90168c738 Add VectorRenderModuleTests.TestRepeatDraw() 2012-08-27 22:42:40 +01:00
Melanie
a5c6cb2fc9 Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim 2012-08-25 17:34:08 +01:00
Melanie
6ea95a3294 Fix and refactor region registration. Reorder checks to short-curcuit expensive and destructive ones. Properly fix region reservation and authentication.
Make region moves and flags preservation work again as intended. Prevent
failes reservation take-over from damging reservation data.
2012-08-25 17:32:00 +01:00
SignpostMarv
6e86b23012 implementing PRIM_LINK_TARGET on GetPrimParams ala SetPrimParams 2012-08-25 02:30:23 +01:00
SignpostMarv
58714b0aca minor formatting 2012-08-25 02:30:23 +01:00
SignpostMarv
5203665bb2 refactoring to local variable for cleaner code 2012-08-25 02:30:23 +01:00
SignpostMarv
2a2e120470 since we will be making the Get return type the remaining ruleset as with the Set return type, we need to move the original return type to a ref param 2012-08-25 02:30:23 +01:00
SignpostMarv
a8044999fb use SceneObjectPart instead of var 2012-08-25 02:30:23 +01:00
SignpostMarv
3d504261b0 renaming to be similar to equivalent Set command 2012-08-25 02:30:23 +01:00
Justin Clark-Casey (justincc)
a0d178b284 Following on from f8a89a79, do not allow more than one 'type' folder (e.g. calling cards) to be created in the base "My Inventory" user folder.
This is to accomodate situations where viewers will create more than one 'type' subfolder (e.g. calling cards)
But at the same time to prevent multiple such 'system' folders (those in the base "My Inventory" user folder).
This also makes GetFolderForType() only return a folder in the base "My Inventory" folder, if such a type folder exists
2012-08-25 02:00:17 +01:00
Justin Clark-Casey (justincc)
f8a89a79eb Allow multiple calling card type inventory folders to be created.
Modern viewers want to create Friends and All folders of this type inside the root Calling Cards folder.
2012-08-25 01:09:12 +01:00
Justin Clark-Casey (justincc)
e04047152f minor: Fix bad log message for failure to create an inventory folder 2012-08-25 00:49:38 +01:00
Justin Clark-Casey (justincc)
f3a5e3a02b Log initial script startup info notice when xengine actually starts to do this for debugging purposes, rather than before it actually starts to do this. 2012-08-25 00:42:32 +01:00
Justin Clark-Casey (justincc)
ba58331b29 Extend "Restarting scripts in attachments" debug log message to show actual name of user and the region they are in 2012-08-24 22:56:05 +01:00
Justin Clark-Casey (justincc)
476996bee8 If a connecting scene presence is replacing an existing scene presence then bypass close checks. 2012-08-24 22:38:07 +01:00
Justin Clark-Casey (justincc)
01771aca40 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-08-24 21:38:46 +01:00
Justin Clark-Casey (justincc)
cd325fdf02 Pass the "attachToBackup" bool given to SceneGraph.AddNewSceneObject() down into the 3-parameter AddNewSceneObject() method instead of always hardcoding true.
This doesn't affect any core OpenSimulator code since all callers were passing true anyway
But it allows region modules to create objects that are never persisted.
2012-08-24 21:36:20 +01:00
SignpostMarv
67477290ad stripping superfluous whitespace
Signed-off-by: Melanie <melanie@t-data.com>
2012-08-24 17:44:35 +01:00
SignpostMarv
582a256646 immediately returning the string.Join operation instead of checking if the list has members 2012-08-24 17:44:14 +01:00
SignpostMarv
d188272462 refactoring using List.ConvertAll<string> 2012-08-24 17:44:14 +01:00
SignpostMarv
632908db9e adding sqlite journal files to .gitignore 2012-08-24 01:26:11 +01:00
Justin Clark-Casey (justincc)
82b23f7cc1 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-08-24 01:20:23 +01:00
Justin Clark-Casey (justincc)
a08687aef3 Revert "implementing function to allow scripts to self-replicate as if the owner duplicated them, using the same script delay as llRezObject()"
This reverts commit 2ad9d656b3.

Reverted pending consideration of associated issues.
2012-08-24 01:18:35 +01:00
SignpostMarv
2ad9d656b3 implementing function to allow scripts to self-replicate as if the owner duplicated them, using the same script delay as llRezObject() 2012-08-24 00:21:42 +01:00
Melanie
1747030d19 Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim 2012-08-24 00:16:58 +01:00
Melanie
c557684666 Fix bad child prim permissions that can make objects change perms after rezzing
Port from Avination
2012-08-24 00:15:30 +01:00
TBG Renfold
a3cbda0d74 Removed land checking as suggested by SignpostMarv.
Now whatever remaining health the avatar has is displayed (float).
This will be 100% (100.000000) if no damage has occurred (as what the viewer should really be seeing anyway).

Returns -1.000000 if the avatar is not found.
2012-08-24 00:13:27 +01:00
TBG Renfold
4f3fabae5b Adds osGetHealth.
Returns the amount of health (in an integer) that an avatar has left in the scene.
If an avatar is not found or safe is enabled on a region, -1 is returned.

Example usage:

default
{
    touch_end(integer _t)
    {
        key agentID = llDetectedKey(0);
        osCauseDamage(agentID, 50);
        llSay(0, llKey2Name(agentID) + " has " + (string)osGetHealth(agentID) + "% health left.");
    }
}
2012-08-24 00:13:14 +01:00
Justin Clark-Casey (justincc)
aede42b875 If a script state save fails for some reason on shutdown/region removal, get xengine to spit out some useful information and continue to save other script states 2012-08-23 23:13:53 +01:00
Justin Clark-Casey (justincc)
a533db7e27 Add an [HGAssetService] section to SQLiteStandalone.ini with the same connection string as [AssetService].
This is necessary because commit 8131a24 (Tue Mar 27 10:08:13 2012) started passing the config section name rather than hardcoding "AssetService"
This meant that the HG external-facing asset service tried to read ConnectionString from [HGAssetService] rather than [AssetService].
On SQLite, not finding this meant that it fell back to [DatabaseService], which is set for OpenSim.db rather than Asset.db.
Therefore, all external asset requests returned null.
Solution taken here is to create an [HGAssetService] section with the same ConnectionString as [AssetService].
This bug does not affect normal MySQL/MSSQL config since they use the [DatabaseService] connection string anyway.
Addresses http://opensimulator.org/mantis/view.php?id=6200, many thanks to DanBanner for identifying the exact problem commit which was very helpful.
This was a regression from OpenSimulator 0.7.3.1 which did not contain this bug.
2012-08-23 22:30:14 +01:00
SignpostMarv
4820dfd733 this should be an if-else block in case the non-phys min/max are smaller than the physical min/max 2012-08-22 23:55:01 +01:00
Justin Clark-Casey (justincc)
1369058280 Lock disposal of separate gdi+ objects under different threads since this prevents malloc heap corruption seen under Ubuntu 10.04.1 and 11.04 - probably a libcairo issue
In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously,
the native malloc heap can become corrupted, possibly due to a double free().  This may be due to
bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX.  These problems were
seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1.  They go away if disposal is perfomed
under lock.
2012-08-22 23:04:17 +01:00
Robert Adams
568de9313a BulletSim: update DLLs and SOs to eliminate terrain update crash which manifested itself on Linux. 2012-08-21 20:55:48 -07:00
Justin Clark-Casey (justincc)
219326dd8e Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-08-21 22:29:27 +01:00
Justin Clark-Casey (justincc)
9925317239 Fix bug in SoundModule.PlayAttachedSound() where every sound update to an avatar would base its gain calculation on the previous avatar's gain, instead of the original input gain
This is similar to commit d89faa which fixed the same kind of bug in TriggerSound()
2012-08-21 22:21:35 +01:00
nebadon
150748392e testing github bot take 2 2012-08-20 15:57:28 -07:00
nebadon
555edc4ef7 testing github commit bot 2012-08-20 15:51:30 -07:00
SignpostMarv
481c00f50a refactoring out SetFaceColor 2012-08-20 23:10:25 +01:00
SignpostMarv
ede3b9ab07 making use of implicit operators and Util.Clip handling of Vector3 2012-08-20 23:10:25 +01:00
SignpostMarv
b863a15a82 single operation for PRIM_COLOR 2012-08-20 23:10:25 +01:00
SignpostMarv
aee4353e9c fix typo 2012-08-20 23:10:25 +01:00
Justin Clark-Casey (justincc)
e6fb458597 no-op change for cia.vc test 2012-08-20 22:18:29 +01:00
Justin Clark-Casey (justincc)
812c498ef4 When loading an OAR, validate any group UUIDs and properly reconstruct parcel access lists.
If a group UUID is present that is not on this simulator then the object or parcel is no longer group owned.
This is a change from previous behaviour where such invalid UUIDs were kept.
This is an adaptation of patch 0002 from http://opensimulator.org/mantis/view.php?id=6105 by Oren Hurvitz of Kitely.
My adaptations are formatting only, apart from the notices about parcel owner IDs not being saved since this has now been fixed.
Thanks Oren.
2012-08-20 22:01:02 +01:00
Justin Clark-Casey (justincc)
970727e57e Tighten up OpenSim.Framework.Cache locking to avoid race conditions.
This is to resolve a reported issue in http://opensimulator.org/mantis/view.php?id=6232
Here, the land management module is using OpenSim.Framework.Cache (the only code to currently do so apart from the non-default CoreAssetCache).
2012-08-20 20:55:58 +01:00
Justin Clark-Casey (justincc)
bcbd450fe4 Add --force flag to "kick user" console command to allow bypassing of recent race condition checks.
This is to allow a second attempt to remove an avatar even if "show connections" shows them as already inactive (i.e. close has already been attempted once).
You should only attempt --force if a normal kick fails.
This is partly for diagnostics as we have seen some connections occasionally remain on lbsa plaza even if they are registered as inactive.
This is not a permanent solution and may not work anyway - the ultimate solution is to stop this problem from happening in the first place.
2012-08-20 20:24:54 +01:00
Melanie
9aec62f0ac Fix scripted detach of temp attachments 2012-08-20 15:59:38 +01:00
Melanie
dd0556abc9 Fix llDialog responses so that they can be heard throughout the region. This now conforms to the behaviour in SL. 2012-08-19 22:05:38 +01:00
Melanie
8769e4ee73 Add a reference to OpenMetaverseType.dll to compiled script assemblies. 2012-08-18 19:08:38 +01:00
SignpostMarv
d72d599056 integrating redundant code into operator 2012-08-18 18:30:00 +01:00
SignpostMarv
ca33619e11 Rot2Quaternion is now redundant 2012-08-18 18:30:00 +01:00
SignpostMarv
ffdde05bb7 constructor means not having to manually refer to individual properties 2012-08-18 18:29:59 +01:00
SignpostMarv
fb84ff96a9 implicit operators mean one does not need to instantiate new objects manually 2012-08-18 18:29:59 +01:00
SignpostMarv
52d7af05bc adding missing refactor for LSL_Vector 2012-08-18 18:29:59 +01:00
SignpostMarv
2b0c8bc480 Implementing operators & constructors for Quaternion 2012-08-18 18:29:59 +01:00
Melanie
2a70afeca2 Fix the whitespace formatting error introduced by the last patch 2012-08-18 14:00:10 +01:00
SignpostMarv
5d7751da89 refactoring for Vector3 operator & constructor tweaks 2012-08-18 13:21:55 +01:00
Melanie
9d6fe1224a Merge branch 'master' of melanie@opensimulator.org:/var/git/opensim 2012-08-18 12:57:49 +01:00
Justin Clark-Casey (justincc)
e4e5237086 When reporting a thread timeout, create a copy of the info rather than passing the original ThreadWatchdogInfo structure.
This is to avoid the possibility of misleading reporting if a watchdog update outraces an alarm.
Should address any remaining issues from http://opensimulator.org/mantis/view.php?id=6012
2012-08-18 00:46:34 +01:00
SignpostMarv
28d0aff2e3 adding null return to fix building 2012-08-17 23:23:03 +01:00
SignpostMarv
7068fddd2f fixing bug that get/set the wrong property for prim types other than sphere & box 2012-08-17 23:23:03 +01:00
SignpostMarv
466d684fbe implemented 2012-08-17 23:23:03 +01:00
SignpostMarv
74f5253a36 attempt to handle InvalidCastException in a manner similar to Second Life 2012-08-17 23:08:24 +01:00
Justin Clark-Casey (justincc)
3ad827174e Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-08-17 22:50:54 +01:00
Justin Clark-Casey (justincc)
56da788243 Add information to ThreadStackSize about possibly increasing if suffering StackOverflowExceptions during script conversion/compilation (e.g. on Windows 64-bit) 2012-08-17 22:50:11 +01:00
Robert Adams
7243d4f842 BulletSim: Properly regenerate hulls when objects made physical.
This fixes the problem of non-base shapes (cubes and spheres)
    falling through the terrain.
2012-08-17 14:45:18 -07:00
Justin Clark-Casey (justincc)
f57c1ac386 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-08-17 22:31:58 +01:00
Justin Clark-Casey (justincc)
0860a0d856 minor: Make xengine debug message on script load a scripting loading message instead.
This is more useful if compilation fails due to an uncatchable exception since we know what was being compiled.
2012-08-17 22:30:01 +01:00
Robert Adams
03d76e9403 BulletSim: restore most of the Detail logging statements. Will have
no effect on non-logging running.
Capture region name that is passed to the physics engine and use
    it for detail logging file name prefix.
Fix problem with avatars dropping when flying across region boundries.
2012-08-17 13:34:22 -07:00
Robert Adams
5c192b9bab Modify order of code so SOP doesn't set the physics actor flying
property multiple times every time Update is called.
This eliminates zillions of settings which is better for BulletSim.
The should be no functionality change.
2012-08-17 13:34:20 -07:00
Robert Adams
ccc69d66a1 BulletSim: add parameters and functionality to specify the mesh
level of detail for large meshes.
Remove parameter and code for DetailLog (conditional logging into
   regular log file).
2012-08-17 13:34:18 -07:00
Robert Adams
8eda290262 BulletSim: comments and parameter changes in dynamics engine. 2012-08-17 13:34:16 -07:00
Robert Adams
e31e23d68d BulletSim: in BSDynamics, merge 'flags' and 'hoverFlags' as they are defined for the same bits and it makes the code less complicated. 2012-08-17 13:34:14 -07:00
Justin Clark-Casey (justincc)
99e339dd40 Merge branch 'master' of ssh://opensimulator.org/var/git/opensim 2012-08-17 18:48:35 +01:00
SignpostMarv
e9ea911563 adding a clip method to handle Vector3 objects to enable a minor amount of refactoring 2012-08-17 18:40:49 +01:00
Robert Adams
57a9879669 Correct an exception report in SceneObjectPart so it outputs the stack. 2012-08-15 16:39:00 -07:00
Robert Adams
376441e550 BulletSim: make it so objects in a linkset do not generate collisions with each other. 2012-08-15 16:29:50 -07:00
Robert Adams
ae5db637f2 BulletSim: update DLLs and SOs to fix the problem with avatars jumping around at altitudes less than 25m. 2012-08-15 16:29:46 -07:00
SignpostMarv
ef4122213c enables configurable minimum sizes for physical & non-physical prims 2012-08-15 23:35:23 +01:00
80 changed files with 2553 additions and 1166 deletions

5
.gitignore vendored
View File

@@ -26,9 +26,14 @@
bin/Debug/*.dll
bin/*.dll.mdb
bin/*.db
bin/*.db-journal
bin/addin-db-*
bin/*.dll
bin/OpenSim.vshost.exe.config
bin/OpenSim.32BitLaunch.vshost.exe.config
bin/OpenSim.32BitLaunch.log
UpgradeLog.XML
_UpgradeReport_Files/
bin/ScriptEngines/*-*-*-*-*
bin/ScriptEngines/*.dll
bin/ScriptEngines/*/*.dll

View File

@@ -135,14 +135,25 @@
<delete dir="%temp%"/>
</target>
<target name="torture" depends="build, find-nunit">
<target name="test-stress" depends="build, find-nunit">
<setenv name="MONO_THREADS_PER_CPU" value="100" />
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.torture">
<arg value="./bin/OpenSim.Tests.Torture.dll" />
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.stress">
<arg value="./bin/OpenSim.Tests.Stress.dll" />
</exec>
<fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests.torture)==0}" />
<fail message="Failures reported in stress tests." unless="${int::parse(testresult.opensim.tests.stress)==0}" />
<delete dir="%temp%"/>
</target>
<target name="test-perf" depends="build, find-nunit">
<setenv name="MONO_THREADS_PER_CPU" value="100" />
<exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.performance">
<arg value="./bin/OpenSim.Tests.Performance.dll" />
</exec>
<fail message="Failures reported in performance tests." unless="${int::parse(testresult.opensim.tests.performance)==0}" />
<delete dir="%temp%"/>
</target>

View File

@@ -40,6 +40,11 @@ namespace OpenSim.Data
public UUID folderID;
public UUID agentID;
public UUID parentFolderID;
public XInventoryFolder Clone()
{
return (XInventoryFolder)MemberwiseClone();
}
}
public class XInventoryItem
@@ -64,6 +69,11 @@ namespace OpenSim.Data
public UUID avatarID;
public UUID parentFolderID;
public int inventoryGroupPermissions;
public XInventoryItem Clone()
{
return (XInventoryItem)MemberwiseClone();
}
}
public interface IXInventoryData

View File

@@ -719,95 +719,99 @@ namespace OpenSim.Data.MySQL
RegionLightShareData nWP = new RegionLightShareData();
nWP.OnSave += StoreRegionWindlightSettings;
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
lock (m_dbLock)
{
dbcon.Open();
string command = "select * from `regionwindlight` where region_id = ?regionID";
using (MySqlCommand cmd = new MySqlCommand(command))
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
cmd.Connection = dbcon;
cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString());
IDataReader result = ExecuteReader(cmd);
if (!result.Read())
dbcon.Open();
string command = "select * from `regionwindlight` where region_id = ?regionID";
using (MySqlCommand cmd = new MySqlCommand(command))
{
//No result, so store our default windlight profile and return it
nWP.regionID = regionUUID;
StoreRegionWindlightSettings(nWP);
return nWP;
}
else
{
nWP.regionID = DBGuid.FromDB(result["region_id"]);
nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]);
nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]);
nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]);
nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]);
nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]);
nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]);
nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]);
nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]);
nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]);
nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]);
nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]);
nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]);
nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]);
nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]);
nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]);
nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]);
nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]);
UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture);
nWP.horizon.X = Convert.ToSingle(result["horizon_r"]);
nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]);
nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]);
nWP.horizon.W = Convert.ToSingle(result["horizon_i"]);
nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]);
nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]);
nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]);
nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]);
nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]);
nWP.hazeDensity = Convert.ToSingle(result["haze_density"]);
nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]);
nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]);
nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]);
nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]);
nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]);
nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]);
nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]);
nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]);
nWP.ambient.X = Convert.ToSingle(result["ambient_r"]);
nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]);
nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]);
nWP.ambient.W = Convert.ToSingle(result["ambient_i"]);
nWP.eastAngle = Convert.ToSingle(result["east_angle"]);
nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]);
nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]);
nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]);
nWP.starBrightness = Convert.ToSingle(result["star_brightness"]);
nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]);
nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]);
nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]);
nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]);
nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]);
nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]);
nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]);
nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]);
nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]);
nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]);
nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]);
nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]);
nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]);
nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]);
nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]);
nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]);
nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]);
nWP.valid = true;
cmd.Connection = dbcon;
cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString());
IDataReader result = ExecuteReader(cmd);
if (!result.Read())
{
//No result, so store our default windlight profile and return it
nWP.regionID = regionUUID;
StoreRegionWindlightSettings(nWP);
return nWP;
}
else
{
nWP.regionID = DBGuid.FromDB(result["region_id"]);
nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]);
nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]);
nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]);
nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]);
nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]);
nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]);
nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]);
nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]);
nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]);
nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]);
nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]);
nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]);
nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]);
nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]);
nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]);
nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]);
nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]);
UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture);
nWP.horizon.X = Convert.ToSingle(result["horizon_r"]);
nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]);
nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]);
nWP.horizon.W = Convert.ToSingle(result["horizon_i"]);
nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]);
nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]);
nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]);
nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]);
nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]);
nWP.hazeDensity = Convert.ToSingle(result["haze_density"]);
nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]);
nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]);
nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]);
nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]);
nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]);
nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]);
nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]);
nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]);
nWP.ambient.X = Convert.ToSingle(result["ambient_r"]);
nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]);
nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]);
nWP.ambient.W = Convert.ToSingle(result["ambient_i"]);
nWP.eastAngle = Convert.ToSingle(result["east_angle"]);
nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]);
nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]);
nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]);
nWP.starBrightness = Convert.ToSingle(result["star_brightness"]);
nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]);
nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]);
nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]);
nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]);
nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]);
nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]);
nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]);
nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]);
nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]);
nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]);
nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]);
nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]);
nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]);
nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]);
nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]);
nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]);
nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]);
nWP.valid = true;
}
}
}
}
return nWP;
}
@@ -853,118 +857,124 @@ namespace OpenSim.Data.MySQL
public void StoreRegionWindlightSettings(RegionLightShareData wl)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
lock (m_dbLock)
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, ";
cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, ";
cmd.CommandText += "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, ";
cmd.CommandText += "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, ";
cmd.CommandText += "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, ";
cmd.CommandText += "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, ";
cmd.CommandText += "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, ";
cmd.CommandText += "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, ";
cmd.CommandText += "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, ";
cmd.CommandText += "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, ";
cmd.CommandText += "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, ";
cmd.CommandText += "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, ";
cmd.CommandText += "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, ";
cmd.CommandText += "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, ";
cmd.CommandText += "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, ";
cmd.CommandText += "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, ";
cmd.CommandText += "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, ";
cmd.CommandText += "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, ";
cmd.CommandText += "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, ";
cmd.CommandText += "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, ";
cmd.CommandText += "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, ";
cmd.CommandText += "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, ";
cmd.CommandText += "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, ";
cmd.CommandText += "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, ";
cmd.CommandText += "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)";
cmd.Parameters.AddWithValue("region_id", wl.regionID);
cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X);
cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y);
cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z);
cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent);
cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier);
cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X);
cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y);
cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z);
cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale);
cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset);
cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove);
cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow);
cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier);
cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X);
cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y);
cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X);
cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y);
cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture);
cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X);
cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y);
cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z);
cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W);
cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon);
cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X);
cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y);
cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z);
cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W);
cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity);
cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier);
cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier);
cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude);
cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X);
cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y);
cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z);
cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W);
cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition);
cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X);
cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y);
cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z);
cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W);
cmd.Parameters.AddWithValue("east_angle", wl.eastAngle);
cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus);
cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize);
cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma);
cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness);
cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X);
cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y);
cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z);
cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W);
cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X);
cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y);
cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z);
cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage);
cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale);
cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X);
cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y);
cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z);
cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX);
cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock);
cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY);
cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock);
cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds);
ExecuteNonQuery(cmd);
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, ";
cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, ";
cmd.CommandText += "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, ";
cmd.CommandText += "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, ";
cmd.CommandText += "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, ";
cmd.CommandText += "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, ";
cmd.CommandText += "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, ";
cmd.CommandText += "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, ";
cmd.CommandText += "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, ";
cmd.CommandText += "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, ";
cmd.CommandText += "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, ";
cmd.CommandText += "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, ";
cmd.CommandText += "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, ";
cmd.CommandText += "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, ";
cmd.CommandText += "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, ";
cmd.CommandText += "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, ";
cmd.CommandText += "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, ";
cmd.CommandText += "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, ";
cmd.CommandText += "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, ";
cmd.CommandText += "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, ";
cmd.CommandText += "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, ";
cmd.CommandText += "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, ";
cmd.CommandText += "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, ";
cmd.CommandText += "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, ";
cmd.CommandText += "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)";
cmd.Parameters.AddWithValue("region_id", wl.regionID);
cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X);
cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y);
cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z);
cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent);
cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier);
cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X);
cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y);
cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z);
cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale);
cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset);
cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove);
cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow);
cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier);
cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X);
cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y);
cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X);
cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y);
cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture);
cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X);
cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y);
cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z);
cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W);
cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon);
cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X);
cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y);
cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z);
cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W);
cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity);
cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier);
cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier);
cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude);
cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X);
cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y);
cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z);
cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W);
cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition);
cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X);
cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y);
cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z);
cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W);
cmd.Parameters.AddWithValue("east_angle", wl.eastAngle);
cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus);
cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize);
cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma);
cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness);
cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X);
cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y);
cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z);
cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W);
cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X);
cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y);
cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z);
cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage);
cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale);
cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X);
cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y);
cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z);
cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX);
cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock);
cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY);
cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock);
cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds);
ExecuteNonQuery(cmd);
}
}
}
}
public void RemoveRegionWindlightSettings(UUID regionID)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
lock (m_dbLock)
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
cmd.CommandText = "delete from `regionwindlight` where `region_id`=?regionID";
cmd.Parameters.AddWithValue("?regionID", regionID.ToString());
ExecuteNonQuery(cmd);
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "delete from `regionwindlight` where `region_id`=?regionID";
cmd.Parameters.AddWithValue("?regionID", regionID.ToString());
ExecuteNonQuery(cmd);
}
}
}
}
@@ -972,26 +982,29 @@ namespace OpenSim.Data.MySQL
#region RegionEnvironmentSettings
public string LoadRegionEnvironmentSettings(UUID regionUUID)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
lock (m_dbLock)
{
dbcon.Open();
string command = "select * from `regionenvironment` where region_id = ?region_id";
using (MySqlCommand cmd = new MySqlCommand(command))
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
cmd.Connection = dbcon;
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
IDataReader result = ExecuteReader(cmd);
if (!result.Read())
dbcon.Open();
string command = "select * from `regionenvironment` where region_id = ?region_id";
using (MySqlCommand cmd = new MySqlCommand(command))
{
return String.Empty;
}
else
{
return Convert.ToString(result["llsd_settings"]);
cmd.Connection = dbcon;
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
IDataReader result = ExecuteReader(cmd);
if (!result.Read())
{
return String.Empty;
}
else
{
return Convert.ToString(result["llsd_settings"]);
}
}
}
}
@@ -999,33 +1012,39 @@ namespace OpenSim.Data.MySQL
public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
lock (m_dbLock)
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
cmd.CommandText = "REPLACE INTO `regionenvironment` (`region_id`, `llsd_settings`) VALUES (?region_id, ?llsd_settings)";
cmd.Parameters.AddWithValue("region_id", regionUUID);
cmd.Parameters.AddWithValue("llsd_settings", settings);
ExecuteNonQuery(cmd);
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "REPLACE INTO `regionenvironment` (`region_id`, `llsd_settings`) VALUES (?region_id, ?llsd_settings)";
cmd.Parameters.AddWithValue("region_id", regionUUID);
cmd.Parameters.AddWithValue("llsd_settings", settings);
ExecuteNonQuery(cmd);
}
}
}
}
public void RemoveRegionEnvironmentSettings(UUID regionUUID)
{
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
lock (m_dbLock)
{
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
{
cmd.CommandText = "delete from `regionenvironment` where region_id = ?region_id";
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
ExecuteNonQuery(cmd);
dbcon.Open();
using (MySqlCommand cmd = dbcon.CreateCommand())
{
cmd.CommandText = "delete from `regionenvironment` where region_id = ?region_id";
cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
ExecuteNonQuery(cmd);
}
}
}
}

View File

@@ -199,7 +199,14 @@ namespace OpenSim.Framework
//
public class Cache
{
/// <summary>
/// Must only be accessed under lock.
/// </summary>
private List<CacheItemBase> m_Index = new List<CacheItemBase>();
/// <summary>
/// Must only be accessed under m_Index lock.
/// </summary>
private Dictionary<string, CacheItemBase> m_Lookup =
new Dictionary<string, CacheItemBase>();
@@ -320,19 +327,19 @@ namespace OpenSim.Framework
{
if (m_Lookup.ContainsKey(index))
item = m_Lookup[index];
}
if (item == null)
{
if (item == null)
{
Expire(true);
return null;
}
item.hits++;
item.lastUsed = DateTime.Now;
Expire(true);
return null;
}
item.hits++;
item.lastUsed = DateTime.Now;
Expire(true);
return item;
}
@@ -385,7 +392,10 @@ namespace OpenSim.Framework
//
public Object Find(Predicate<CacheItemBase> d)
{
CacheItemBase item = m_Index.Find(d);
CacheItemBase item;
lock (m_Index)
item = m_Index.Find(d);
if (item == null)
return null;
@@ -419,12 +429,12 @@ namespace OpenSim.Framework
public virtual void Store(string index, Object data, Type container,
Object[] parameters)
{
Expire(false);
CacheItemBase item;
lock (m_Index)
{
Expire(false);
if (m_Index.Contains(new CacheItemBase(index)))
{
if ((m_Flags & CacheFlags.AllowUpdate) != 0)
@@ -450,9 +460,17 @@ namespace OpenSim.Framework
m_Index.Add(item);
m_Lookup[index] = item;
}
item.Store(data);
}
/// <summary>
/// Expire items as appropriate.
/// </summary>
/// <remarks>
/// Callers must lock m_Index.
/// </remarks>
/// <param name='getting'></param>
protected virtual void Expire(bool getting)
{
if (getting && (m_Strategy == CacheStrategy.Aggressive))
@@ -475,12 +493,10 @@ namespace OpenSim.Framework
switch (m_Strategy)
{
case CacheStrategy.Aggressive:
if (Count < Size)
return;
case CacheStrategy.Aggressive:
if (Count < Size)
return;
lock (m_Index)
{
m_Index.Sort(new SortLRU());
m_Index.Reverse();
@@ -490,7 +506,7 @@ namespace OpenSim.Framework
ExpireDelegate doExpire = OnExpire;
if (doExpire != null)
if (doExpire != null)
{
List<CacheItemBase> candidates =
m_Index.GetRange(target, Count - target);
@@ -513,27 +529,34 @@ namespace OpenSim.Framework
foreach (CacheItemBase item in m_Index)
m_Lookup[item.uuid] = item;
}
}
break;
default:
break;
break;
default:
break;
}
}
public void Invalidate(string uuid)
{
if (!m_Lookup.ContainsKey(uuid))
return;
lock (m_Index)
{
if (!m_Lookup.ContainsKey(uuid))
return;
CacheItemBase item = m_Lookup[uuid];
m_Lookup.Remove(uuid);
m_Index.Remove(item);
CacheItemBase item = m_Lookup[uuid];
m_Lookup.Remove(uuid);
m_Index.Remove(item);
}
}
public void Clear()
{
m_Index.Clear();
m_Lookup.Clear();
lock (m_Index)
{
m_Index.Clear();
m_Lookup.Clear();
}
}
}
}
}

View File

@@ -1033,7 +1033,21 @@ namespace OpenSim.Framework
void InPacket(object NewPack);
void ProcessInPacket(Packet NewPack);
/// <summary>
/// Close this client
/// </summary>
void Close();
/// <summary>
/// Close this client
/// </summary>
/// <param name='force'>
/// If true, attempts the close without checking active status. You do not want to try this except as a last
/// ditch attempt where Active == false but the ScenePresence still exists.
/// </param>
void Close(bool force);
void Kick(string message);
/// <summary>

View File

@@ -73,33 +73,27 @@ namespace OpenSim.Framework
{
}
public InventoryFolderBase(UUID id)
public InventoryFolderBase(UUID id) : this()
{
ID = id;
}
public InventoryFolderBase(UUID id, UUID owner)
public InventoryFolderBase(UUID id, UUID owner) : this(id)
{
ID = id;
Owner = owner;
}
public InventoryFolderBase(UUID id, string name, UUID owner, UUID parent)
public InventoryFolderBase(UUID id, string name, UUID owner, UUID parent) : this(id, owner)
{
ID = id;
Name = name;
Owner = owner;
ParentID = parent;
}
public InventoryFolderBase(UUID id, string name, UUID owner, short type, UUID parent, ushort version)
public InventoryFolderBase(
UUID id, string name, UUID owner, short type, UUID parent, ushort version) : this(id, name, owner, parent)
{
ID = id;
Name = name;
Owner = owner;
Type = type;
ParentID = parent;
Version = version;
}
}
}
}

View File

@@ -89,6 +89,17 @@ namespace OpenSim.Framework.Monitoring
FirstTick = Environment.TickCount & Int32.MaxValue;
LastTick = FirstTick;
}
public ThreadWatchdogInfo(ThreadWatchdogInfo previousTwi)
{
Thread = previousTwi.Thread;
FirstTick = previousTwi.FirstTick;
LastTick = previousTwi.LastTick;
Timeout = previousTwi.Timeout;
IsTimedOut = previousTwi.IsTimedOut;
AlarmIfTimeout = previousTwi.AlarmIfTimeout;
AlarmMethod = previousTwi.AlarmMethod;
}
}
/// <summary>
@@ -335,7 +346,9 @@ namespace OpenSim.Framework.Monitoring
if (callbackInfos == null)
callbackInfos = new List<ThreadWatchdogInfo>();
callbackInfos.Add(threadInfo);
// Send a copy of the watchdog info to prevent race conditions where the watchdog
// thread updates the monitoring info after an alarm has been sent out.
callbackInfos.Add(new ThreadWatchdogInfo(threadInfo));
}
}
}

View File

@@ -120,7 +120,9 @@ namespace OpenSim.Framework
public UUID lastMapUUID = UUID.Zero;
public string lastMapRefresh = "0";
private float m_nonphysPrimMin = 0;
private int m_nonphysPrimMax = 0;
private float m_physPrimMin = 0;
private int m_physPrimMax = 0;
private bool m_clampPrimSize = false;
private int m_objectCapacity = 0;
@@ -285,11 +287,21 @@ namespace OpenSim.Framework
set { m_windlight = value; }
}
public float NonphysPrimMin
{
get { return m_nonphysPrimMin; }
}
public int NonphysPrimMax
{
get { return m_nonphysPrimMax; }
}
public float PhysPrimMin
{
get { return m_physPrimMin; }
}
public int PhysPrimMax
{
get { return m_physPrimMax; }
@@ -623,16 +635,28 @@ namespace OpenSim.Framework
m_regionType = config.GetString("RegionType", String.Empty);
allKeys.Remove("RegionType");
// Prim stuff
//
#region Prim stuff
m_nonphysPrimMin = config.GetFloat("NonphysicalPrimMin", 0);
allKeys.Remove("NonphysicalPrimMin");
m_nonphysPrimMax = config.GetInt("NonphysicalPrimMax", 0);
allKeys.Remove("NonphysicalPrimMax");
m_physPrimMin = config.GetFloat("PhysicalPrimMin", 0);
allKeys.Remove("PhysicalPrimMin");
m_physPrimMax = config.GetInt("PhysicalPrimMax", 0);
allKeys.Remove("PhysicalPrimMax");
m_clampPrimSize = config.GetBoolean("ClampPrimSize", false);
allKeys.Remove("ClampPrimSize");
m_objectCapacity = config.GetInt("MaxPrims", 15000);
allKeys.Remove("MaxPrims");
#endregion
m_agentCapacity = config.GetInt("MaxAgents", 100);
allKeys.Remove("MaxAgents");
@@ -668,10 +692,18 @@ namespace OpenSim.Framework
config.Set("ExternalHostName", m_externalHostName);
if (m_nonphysPrimMin != 0)
config.Set("NonphysicalPrimMax", m_nonphysPrimMin);
if (m_nonphysPrimMax != 0)
config.Set("NonphysicalPrimMax", m_nonphysPrimMax);
if (m_physPrimMin != 0)
config.Set("PhysicalPrimMax", m_physPrimMin);
if (m_physPrimMax != 0)
config.Set("PhysicalPrimMax", m_physPrimMax);
config.Set("ClampPrimSize", m_clampPrimSize.ToString());
if (m_objectCapacity != 0)
@@ -754,9 +786,15 @@ namespace OpenSim.Framework
configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
"Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true);
configMember.addConfigurationOption("nonphysical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
"Minimum size for nonphysical prims", m_nonphysPrimMin.ToString(), true);
configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
"Maximum size for nonphysical prims", m_nonphysPrimMax.ToString(), true);
configMember.addConfigurationOption("physical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
"Minimum size for nonphysical prims", m_physPrimMin.ToString(), true);
configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
"Maximum size for physical prims", m_physPrimMax.ToString(), true);

View File

@@ -65,9 +65,14 @@ namespace OpenSim.Framework.Serialization
UserAccount account = userService.GetUserAccount(UUID.Zero, userId);
if (account != null)
{
return MakeOspa(account.FirstName, account.LastName);
}
// else
// {
// m_log.WarnFormat("[OSP RESOLVER]: No user account for {0}", userId);
// System.Console.WriteLine("[OSP RESOLVER]: No user account for {0}", userId);
// }
return null;
}
@@ -79,10 +84,13 @@ namespace OpenSim.Framework.Serialization
/// <returns></returns>
public static string MakeOspa(string firstName, string lastName)
{
// m_log.DebugFormat("[OSP RESOLVER]: Making OSPA for {0} {1}", firstName, lastName);
string ospa
= OSPA_PREFIX + OSPA_NAME_KEY + OSPA_PAIR_SEPARATOR + firstName + OSPA_NAME_VALUE_SEPARATOR + lastName;
// m_log.DebugFormat("[OSP RESOLVER]: Made OSPA {0} for {1} {2}", ospa, firstName, lastName);
// System.Console.WriteLine("[OSP RESOLVER]: Made OSPA {0} for {1} {2}", ospa, firstName, lastName);
return
OSPA_PREFIX + OSPA_NAME_KEY + OSPA_PAIR_SEPARATOR + firstName + OSPA_NAME_VALUE_SEPARATOR + lastName;
return ospa;
}
/// <summary>

View File

@@ -850,6 +850,12 @@ namespace OpenSim.Framework
return Math.Min(Math.Max(x, min), max);
}
public static Vector3 Clip(Vector3 vec, float min, float max)
{
return new Vector3(Clip(vec.X, min, max), Clip(vec.Y, min, max),
Clip(vec.Z, min, max));
}
/// <summary>
/// Convert an UUID to a raw uuid string. Right now this is a string without hyphens.
/// </summary>

View File

@@ -35,6 +35,7 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Timers;
using log4net;
using NDesk.Options;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
@@ -310,8 +311,11 @@ namespace OpenSim
"Change the scale of a named prim", HandleEditScale);
m_console.Commands.AddCommand("Users", false, "kick user",
"kick user <first> <last> [message]",
"Kick a user off the simulator", KickUserCommand);
"kick user <first> <last> [--force] [message]",
"Kick a user off the simulator",
"The --force option will kick the user without any checks to see whether it's already in the process of closing\n"
+ "Only use this option if you are sure the avatar is inactive and a normal kick user operation does not removed them",
KickUserCommand);
m_console.Commands.AddCommand("Users", false, "show users",
"show users [full]",
@@ -416,6 +420,7 @@ namespace OpenSim
{
RunCommandScript(m_shutdownCommandsFile);
}
base.ShutdownSpecific();
}
@@ -453,11 +458,17 @@ namespace OpenSim
/// <param name="cmdparams">name of avatar to kick</param>
private void KickUserCommand(string module, string[] cmdparams)
{
if (cmdparams.Length < 4)
bool force = false;
OptionSet options = new OptionSet().Add("f|force", delegate (string v) { force = v != null; });
List<string> mainParams = options.Parse(cmdparams);
if (mainParams.Count < 4)
return;
string alert = null;
if (cmdparams.Length > 4)
if (mainParams.Count > 4)
alert = String.Format("\n{0}\n", String.Join(" ", cmdparams, 4, cmdparams.Length - 4));
IList agents = SceneManager.GetCurrentSceneAvatars();
@@ -466,8 +477,8 @@ namespace OpenSim
{
RegionInfo regionInfo = presence.Scene.RegionInfo;
if (presence.Firstname.ToLower().Contains(cmdparams[2].ToLower()) &&
presence.Lastname.ToLower().Contains(cmdparams[3].ToLower()))
if (presence.Firstname.ToLower().Contains(mainParams[2].ToLower()) &&
presence.Lastname.ToLower().Contains(mainParams[3].ToLower()))
{
MainConsole.Instance.Output(
String.Format(
@@ -480,7 +491,7 @@ namespace OpenSim
else
presence.ControllingClient.Kick("\nThe OpenSim manager kicked you out.\n");
presence.Scene.IncomingCloseAgent(presence.UUID);
presence.Scene.IncomingCloseAgent(presence.UUID, force);
}
}

View File

@@ -94,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
UUID spId = TestHelpers.ParseTail(0x1);
SceneHelpers.AddScenePresence(m_scene, spId);
m_scene.IncomingCloseAgent(spId);
m_scene.IncomingCloseAgent(spId, false);
// TODO: Add more assertions for the other aspects of event queues
Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0));

View File

@@ -487,16 +487,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region Client Methods
/// <summary>
/// Close down the client view
/// </summary>
public void Close()
{
Close(false);
}
public void Close(bool force)
{
// We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
// a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
lock (CloseSyncLock)
{
if (!IsActive)
// We still perform a force close inside the sync lock since this is intended to attempt close where
// there is some unidentified connection problem, not where we have issues due to deadlock
if (!IsActive && !force)
return;
IsActive = false;
@@ -4447,37 +4451,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (bl[i].BannedUserID == UUID.Zero)
continue;
BannedUsers.Add(bl[i].BannedUserID);
if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
{
EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
packet.AgentData.TransactionID = UUID.Random();
packet.AgentData.AgentID = AgentId;
packet.AgentData.SessionID = SessionId;
packet.MethodData.Invoice = invoice;
packet.MethodData.Method = Utils.StringToBytes("setaccess");
EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
int j;
for (j = 0; j < (6 + BannedUsers.Count); j++)
{
returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
}
j = 0;
returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
foreach (UUID banned in BannedUsers)
{
returnblock[j].Parameter = banned.GetBytes(); j++;
}
packet.ParamList = returnblock;
packet.Header.Reliable = true;
OutPacket(packet, ThrottleOutPacketType.Task);
BannedUsers.Clear();
}
}
EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
packet.AgentData.TransactionID = UUID.Random();
packet.AgentData.AgentID = AgentId;
packet.AgentData.SessionID = SessionId;
packet.MethodData.Invoice = invoice;
packet.MethodData.Method = Utils.StringToBytes("setaccess");
EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
for (int i = 0; i < (6 + BannedUsers.Count); i++)
{
returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock();
}
int j = 0;
returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
foreach (UUID banned in BannedUsers)
{
returnblock[j].Parameter = banned.GetBytes(); j++;
}
packet.ParamList = returnblock;
packet.Header.Reliable = false;
OutPacket(packet, ThrottleOutPacketType.Task);
}
public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -5810,7 +5821,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
args.Channel = ch;
args.From = String.Empty;
args.Message = Utils.BytesToString(msg);
args.Type = ChatTypeEnum.Shout;
args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
args.Position = new Vector3();
args.Scene = Scene;
args.Sender = this;
@@ -11989,7 +12000,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
Kick(reason);
Thread.Sleep(1000);
Close();
Disconnect();
}
public void Disconnect()

View File

@@ -458,10 +458,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so)
{
// As per Linden spec, detach (take) is disabled for temp attachs
if (so.FromItemID == UUID.Zero)
return;
lock (sp.AttachmentsSyncLock)
{
// Save avatar attachment information
@@ -976,7 +972,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
if (sp != null && group != null)
if (sp != null && group != null && group.FromItemID != UUID.Zero)
DetachSingleAttachmentToInv(sp, group);
}
@@ -994,7 +990,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
foreach (SceneObjectGroup group in attachments)
{
if (group.FromItemID == itemID)
if (group.FromItemID == itemID && group.FromItemID != UUID.Zero)
{
DetachSingleAttachmentToInv(sp, group);
return;

View File

@@ -461,7 +461,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
SceneObjectGroup rezzedAtt = presence.GetAttachments()[0];
scene.IncomingCloseAgent(presence.UUID);
scene.IncomingCloseAgent(presence.UUID, false);
// Check that we can't retrieve this attachment from the scene.
Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null);

View File

@@ -350,38 +350,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID));
}
/// <summary>
/// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
/// an account exists with the same name as the creator, though not the same id.
/// </summary>
[Test]
public void TestLoadIarV0_1SameNameCreator()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood");
UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire");
m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);
InventoryItemBase foundItem1
= InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
Assert.That(
foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()),
"Loaded item non-uuid creator doesn't match original");
Assert.That(
foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID),
"Loaded item uuid creator doesn't match original");
Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID),
"Loaded item owner doesn't match inventory reciever");
AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString());
string xmlData = Utils.BytesToString(asset1.Data);
SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID));
}
// /// <summary>
// /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
// /// an account exists with the same name as the creator, though not the same id.
// /// </summary>
// [Test]
// public void TestLoadIarV0_1SameNameCreator()
// {
// TestHelpers.InMethod();
// TestHelpers.EnableLogging();
//
// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood");
// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire");
//
// m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);
// InventoryItemBase foundItem1
// = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
//
// Assert.That(
// foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()),
// "Loaded item non-uuid creator doesn't match original");
// Assert.That(
// foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID),
// "Loaded item uuid creator doesn't match original");
// Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID),
// "Loaded item owner doesn't match inventory reciever");
//
// AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString());
// string xmlData = Utils.BytesToString(asset1.Data);
// SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
//
// Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID));
// }
/// <summary>
/// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where

View File

@@ -644,7 +644,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// an agent cannot teleport back to this region if it has teleported away.
Thread.Sleep(2000);
sp.Scene.IncomingCloseAgent(sp.UUID);
sp.Scene.IncomingCloseAgent(sp.UUID, false);
}
else
{

View File

@@ -49,6 +49,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
public const int DISP_EXPIRE = 1;
public const int DISP_TEMP = 2;
/// <summary>
/// If true then where possible dynamic textures are reused.
/// </summary>
public bool ReuseTextures { get; set; }
private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>();
private Dictionary<string, IDynamicTextureRender> RenderPlugins =
@@ -56,6 +61,15 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>();
/// <summary>
/// Record dynamic textures that we can reuse for a given data and parameter combination rather than
/// regenerate.
/// </summary>
/// <remarks>
/// Key is string.Format("{0}{1}", data
/// </remarks>
private Cache m_reuseableDynamicTextures;
#region IDynamicTextureManager Members
public void RegisterRender(string handleType, IDynamicTextureRender render)
@@ -71,7 +85,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
/// </summary>
/// <param name="id"></param>
/// <param name="data"></param>
public void ReturnData(UUID id, byte[] data)
/// <param name="isReuseable">True if the data generated can be reused for subsequent identical requests</param>
public void ReturnData(UUID id, byte[] data, bool isReuseable)
{
DynamicTextureUpdater updater = null;
@@ -88,7 +103,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
if (RegisteredScenes.ContainsKey(updater.SimUUID))
{
Scene scene = RegisteredScenes[updater.SimUUID];
updater.DataReceived(data, scene);
UUID newTextureID = updater.DataReceived(data, scene);
if (ReuseTextures && isReuseable && !updater.BlendWithOldTexture)
m_reuseableDynamicTextures.Store(
GenerateReusableTextureKey(updater.BodyData, updater.Params), newTextureID);
}
}
@@ -167,22 +186,61 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data,
string extraParams, int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face)
{
if (RenderPlugins.ContainsKey(contentType))
{
DynamicTextureUpdater updater = new DynamicTextureUpdater();
updater.SimUUID = simID;
updater.PrimID = primID;
updater.ContentType = contentType;
updater.BodyData = data;
updater.UpdateTimer = updateTimer;
updater.UpdaterID = UUID.Random();
updater.Params = extraParams;
updater.BlendWithOldTexture = SetBlending;
updater.FrontAlpha = AlphaValue;
updater.Face = face;
updater.Url = "Local image";
updater.Disp = disp;
if (!RenderPlugins.ContainsKey(contentType))
return UUID.Zero;
Scene scene;
RegisteredScenes.TryGetValue(simID, out scene);
if (scene == null)
return UUID.Zero;
SceneObjectPart part = scene.GetSceneObjectPart(primID);
if (part == null)
return UUID.Zero;
// If we want to reuse dynamic textures then we have to ignore any request from the caller to expire
// them.
if (ReuseTextures)
disp = disp & ~DISP_EXPIRE;
DynamicTextureUpdater updater = new DynamicTextureUpdater();
updater.SimUUID = simID;
updater.PrimID = primID;
updater.ContentType = contentType;
updater.BodyData = data;
updater.UpdateTimer = updateTimer;
updater.UpdaterID = UUID.Random();
updater.Params = extraParams;
updater.BlendWithOldTexture = SetBlending;
updater.FrontAlpha = AlphaValue;
updater.Face = face;
updater.Url = "Local image";
updater.Disp = disp;
object objReusableTextureUUID = null;
if (ReuseTextures && !updater.BlendWithOldTexture)
{
string reuseableTextureKey = GenerateReusableTextureKey(data, extraParams);
objReusableTextureUUID = m_reuseableDynamicTextures.Get(reuseableTextureKey);
if (objReusableTextureUUID != null)
{
// If something else has removed this temporary asset from the cache, detect and invalidate
// our cached uuid.
if (scene.AssetService.GetMetadata(objReusableTextureUUID.ToString()) == null)
{
m_reuseableDynamicTextures.Invalidate(reuseableTextureKey);
objReusableTextureUUID = null;
}
}
}
// We cannot reuse a dynamic texture if the data is going to be blended with something already there.
if (objReusableTextureUUID == null)
{
lock (Updaters)
{
if (!Updaters.ContainsKey(updater.UpdaterID))
@@ -192,10 +250,20 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
}
RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams);
return updater.UpdaterID;
}
return UUID.Zero;
else
{
// No need to add to updaters as the texture is always the same. Not that this functionality
// apppears to be implemented anyway.
updater.UpdatePart(part, (UUID)objReusableTextureUUID);
}
return updater.UpdaterID;
}
private string GenerateReusableTextureKey(string data, string extraParams)
{
return string.Format("{0}{1}", data, extraParams);
}
public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize,
@@ -215,6 +283,10 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
public void Initialise(Scene scene, IConfigSource config)
{
IConfig texturesConfig = config.Configs["Textures"];
if (texturesConfig != null)
ReuseTextures = texturesConfig.GetBoolean("ReuseDynamicTextures", false);
if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
{
RegisteredScenes.Add(scene.RegionInfo.RegionID, scene);
@@ -224,6 +296,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
public void PostInitialise()
{
if (ReuseTextures)
{
m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative);
m_reuseableDynamicTextures.DefaultTTL = new TimeSpan(24, 0, 0);
}
}
public void Close()
@@ -268,10 +345,61 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
BodyData = null;
}
/// <summary>
/// Update the given part with the new texture.
/// </summary>
/// <returns>
/// The old texture UUID.
/// </returns>
public UUID UpdatePart(SceneObjectPart part, UUID textureID)
{
UUID oldID;
lock (part)
{
// mostly keep the values from before
Primitive.TextureEntry tmptex = part.Shape.Textures;
// FIXME: Need to return the appropriate ID if only a single face is replaced.
oldID = tmptex.DefaultTexture.TextureID;
if (Face == ALL_SIDES)
{
oldID = tmptex.DefaultTexture.TextureID;
tmptex.DefaultTexture.TextureID = textureID;
}
else
{
try
{
Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
texface.TextureID = textureID;
tmptex.FaceTextures[Face] = texface;
}
catch (Exception)
{
tmptex.DefaultTexture.TextureID = textureID;
}
}
// I'm pretty sure we always want to force this to true
// I'm pretty sure noone whats to set fullbright true if it wasn't true before.
// tmptex.DefaultTexture.Fullbright = true;
part.UpdateTextureEntry(tmptex.GetBytes());
}
return oldID;
}
/// <summary>
/// Called once new texture data has been received for this updater.
/// </summary>
public void DataReceived(byte[] data, Scene scene)
/// <param name="data"></param>
/// <param name="scene"></param>
/// <param name="isReuseable">True if the data given is reuseable.</param>
/// <returns>The asset UUID given to the incoming data.</returns>
public UUID DataReceived(byte[] data, Scene scene)
{
SceneObjectPart part = scene.GetSceneObjectPart(PrimID);
@@ -281,7 +409,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url);
scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say,
0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false);
return;
return UUID.Zero;
}
byte[] assetData = null;
@@ -323,52 +452,23 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
cacheLayerDecode = null;
}
UUID oldID = UUID.Zero;
lock (part)
{
// mostly keep the values from before
Primitive.TextureEntry tmptex = part.Shape.Textures;
// remove the old asset from the cache
oldID = tmptex.DefaultTexture.TextureID;
if (Face == ALL_SIDES)
{
tmptex.DefaultTexture.TextureID = asset.FullID;
}
else
{
try
{
Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
texface.TextureID = asset.FullID;
tmptex.FaceTextures[Face] = texface;
}
catch (Exception)
{
tmptex.DefaultTexture.TextureID = asset.FullID;
}
}
// I'm pretty sure we always want to force this to true
// I'm pretty sure noone whats to set fullbright true if it wasn't true before.
// tmptex.DefaultTexture.Fullbright = true;
part.UpdateTextureEntry(tmptex.GetBytes());
}
UUID oldID = UpdatePart(part, asset.FullID);
if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0))
{
if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString());
if (oldAsset == null)
oldAsset = scene.AssetService.Get(oldID.ToString());
if (oldAsset != null)
{
if (oldAsset.Temporary == true)
if (oldAsset.Temporary)
{
scene.AssetService.Delete(oldID.ToString());
}
}
}
return asset.FullID;
}
private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha)

View File

@@ -84,6 +84,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
public string body;
public int responseCode;
public string responseBody;
public string responseType = "text/plain";
//public ManualResetEvent ev;
public bool requestDone;
public int startTime;
@@ -302,6 +303,22 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
}
}
public void HttpContentType(UUID request, string type)
{
lock (m_UrlMap)
{
if (m_RequestMap.ContainsKey(request))
{
UrlData urlData = m_RequestMap[request];
urlData.requests[request].responseType = type;
}
else
{
m_log.Info("[HttpRequestHandler] There is no http-in request with id " + request.ToString());
}
}
}
public void HttpResponse(UUID request, int status, string body)
{
lock (m_UrlMap)
@@ -504,7 +521,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
//put response
response["int_response_code"] = requestData.responseCode;
response["str_response_string"] = requestData.responseBody;
response["content_type"] = "text/plain";
response["content_type"] = requestData.responseType;
// response["content_type"] = "text/plain";
response["keepalive"] = false;
response["reusecontext"] = false;

View File

@@ -67,12 +67,18 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
return true;
}
// public bool AlwaysIdenticalConversion(string bodyData, string extraParams)
// {
// // We don't support conversion of body data.
// return false;
// }
public byte[] ConvertUrl(string url, string extraParams)
{
return null;
}
public byte[] ConvertStream(Stream data, string extraParams)
public byte[] ConvertData(string bodyData, string extraParams)
{
return null;
}
@@ -236,9 +242,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
stream.Close();
}
}
m_log.DebugFormat("[LOADIMAGEURLMODULE] Returning {0} bytes of image data for request {1}",
imageJ2000.Length, state.RequestID);
m_textureManager.ReturnData(state.RequestID, imageJ2000);
m_textureManager.ReturnData(state.RequestID, imageJ2000, false);
}
#region Nested type: RequestState

View File

@@ -45,31 +45,250 @@ using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
{
[TestFixture]
public class VectorRenderModuleTests
public class VectorRenderModuleTests : OpenSimTestCase
{
Scene m_scene;
DynamicTextureModule m_dtm;
VectorRenderModule m_vrm;
private void SetupScene(bool reuseTextures)
{
m_scene = new SceneHelpers().SetupScene();
m_dtm = new DynamicTextureModule();
m_dtm.ReuseTextures = reuseTextures;
m_vrm = new VectorRenderModule();
SceneHelpers.SetupSceneModules(m_scene, m_dtm, m_vrm);
}
[Test]
public void TestDraw()
{
TestHelpers.InMethod();
Scene scene = new SceneHelpers().SetupScene();
DynamicTextureModule dtm = new DynamicTextureModule();
VectorRenderModule vrm = new VectorRenderModule();
SceneHelpers.SetupSceneModules(scene, dtm, vrm);
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene);
SetupScene(false);
SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
dtm.AddDynamicTextureData(
scene.RegionInfo.RegionID,
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
vrm.GetContentType(),
m_vrm.GetContentType(),
"PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
"",
0);
Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
}
[Test]
public void TestRepeatSameDraw()
{
TestHelpers.InMethod();
string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
SetupScene(false);
SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"",
0);
UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"",
0);
Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
}
[Test]
public void TestRepeatSameDrawDifferentExtraParams()
{
TestHelpers.InMethod();
string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
SetupScene(false);
SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"",
0);
UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"alpha:250",
0);
Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
}
[Test]
public void TestRepeatSameDrawContainingImage()
{
TestHelpers.InMethod();
string dtText
= "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png";
SetupScene(false);
SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"",
0);
UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"",
0);
Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
}
[Test]
public void TestDrawReusingTexture()
{
TestHelpers.InMethod();
SetupScene(true);
SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
"PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
"",
0);
Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
}
[Test]
public void TestRepeatSameDrawReusingTexture()
{
TestHelpers.InMethod();
string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
SetupScene(true);
SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"",
0);
UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"",
0);
Assert.That(firstDynamicTextureID, Is.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
}
[Test]
public void TestRepeatSameDrawDifferentExtraParamsReusingTexture()
{
TestHelpers.InMethod();
string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
SetupScene(true);
SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"",
0);
UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"alpha:250",
0);
Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
}
[Test]
public void TestRepeatSameDrawContainingImageReusingTexture()
{
TestHelpers.InMethod();
string dtText
= "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png";
SetupScene(true);
SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"",
0);
UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
m_dtm.AddDynamicTextureData(
m_scene.RegionInfo.RegionID,
so.UUID,
m_vrm.GetContentType(),
dtText,
"",
0);
Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
}
}
}

View File

@@ -30,6 +30,7 @@ using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using Nini.Config;
using OpenMetaverse;
@@ -47,7 +48,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private string m_name = "VectorRenderModule";
private Scene m_scene;
private IDynamicTextureManager m_textureManager;
private Graphics m_graph;
@@ -61,12 +61,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
public string GetContentType()
{
return ("vector");
return "vector";
}
public string GetName()
{
return m_name;
return Name;
}
public bool SupportsAsynchronous()
@@ -74,14 +74,26 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
return true;
}
// public bool AlwaysIdenticalConversion(string bodyData, string extraParams)
// {
// string[] lines = GetLines(bodyData);
// return lines.Any((str, r) => str.StartsWith("Image"));
// }
public byte[] ConvertUrl(string url, string extraParams)
{
return null;
}
public byte[] ConvertStream(Stream data, string extraParams)
public byte[] ConvertData(string bodyData, string extraParams)
{
return null;
bool reuseable;
return Draw(bodyData, extraParams, out reuseable);
}
private byte[] ConvertData(string bodyData, string extraParams, out bool reuseable)
{
return Draw(bodyData, extraParams, out reuseable);
}
public bool AsyncConvertUrl(UUID id, string url, string extraParams)
@@ -91,7 +103,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
public bool AsyncConvertData(UUID id, string bodyData, string extraParams)
{
Draw(bodyData, id, extraParams);
// XXX: This isn't actually being done asynchronously!
bool reuseable;
byte[] data = ConvertData(bodyData, extraParams, out reuseable);
m_textureManager.ReturnData(id, data, reuseable);
return true;
}
@@ -152,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
public string Name
{
get { return m_name; }
get { return "VectorRenderModule"; }
}
public bool IsSharedModule
@@ -162,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
#endregion
private void Draw(string data, UUID id, string extraParams)
private byte[] Draw(string data, string extraParams, out bool reuseable)
{
// We need to cater for old scripts that didnt use extraParams neatly, they use either an integer size which represents both width and height, or setalpha
// we will now support multiple comma seperated params in the form width:256,height:512,alpha:255
@@ -308,36 +325,44 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
try
{
if (alpha == 256)
bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
else
bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
graph = Graphics.FromImage(bitmap);
// this is really just to save people filling the
// background color in their scripts, only do when fully opaque
if (alpha >= 255)
// XXX: In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously,
// the native malloc heap can become corrupted, possibly due to a double free(). This may be due to
// bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX. These problems were
// seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1. They go away if disposal is perfomed
// under lock.
lock (this)
{
using (SolidBrush bgFillBrush = new SolidBrush(bgColor))
{
graph.FillRectangle(bgFillBrush, 0, 0, width, height);
}
}
if (alpha == 256)
bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
else
bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
for (int w = 0; w < bitmap.Width; w++)
{
if (alpha <= 255)
graph = Graphics.FromImage(bitmap);
// this is really just to save people filling the
// background color in their scripts, only do when fully opaque
if (alpha >= 255)
{
for (int h = 0; h < bitmap.Height; h++)
using (SolidBrush bgFillBrush = new SolidBrush(bgColor))
{
bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h)));
graph.FillRectangle(bgFillBrush, 0, 0, width, height);
}
}
for (int w = 0; w < bitmap.Width; w++)
{
if (alpha <= 255)
{
for (int h = 0; h < bitmap.Height; h++)
{
bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h)));
}
}
}
GDIDraw(data, graph, altDataDelim, out reuseable);
}
GDIDraw(data, graph, altDataDelim);
byte[] imageJ2000 = new byte[0];
try
@@ -351,15 +376,23 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
e.Message, e.StackTrace);
}
m_textureManager.ReturnData(id, imageJ2000);
return imageJ2000;
}
finally
{
if (graph != null)
graph.Dispose();
if (bitmap != null)
bitmap.Dispose();
// XXX: In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously,
// the native malloc heap can become corrupted, possibly due to a double free(). This may be due to
// bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX. These problems were
// seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1. They go away if disposal is perfomed
// under lock.
lock (this)
{
if (graph != null)
graph.Dispose();
if (bitmap != null)
bitmap.Dispose();
}
}
}
@@ -418,8 +451,21 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
}
*/
private void GDIDraw(string data, Graphics graph, char dataDelim)
/// <summary>
/// Split input data into discrete command lines.
/// </summary>
/// <returns></returns>
/// <param name='data'></param>
/// <param name='dataDelim'></param>
private string[] GetLines(string data, char dataDelim)
{
char[] lineDelimiter = { dataDelim };
return data.Split(lineDelimiter);
}
private void GDIDraw(string data, Graphics graph, char dataDelim, out bool reuseable)
{
reuseable = true;
Point startPoint = new Point(0, 0);
Point endPoint = new Point(0, 0);
Pen drawPen = null;
@@ -434,11 +480,9 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
myFont = new Font(fontName, fontSize);
myBrush = new SolidBrush(Color.Black);
char[] lineDelimiter = {dataDelim};
char[] partsDelimiter = {','};
string[] lines = data.Split(lineDelimiter);
foreach (string line in lines)
foreach (string line in GetLines(data, dataDelim))
{
string nextLine = line.Trim();
//replace with switch, or even better, do some proper parsing
@@ -469,6 +513,10 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
}
else if (nextLine.StartsWith("Image"))
{
// We cannot reuse any generated texture involving fetching an image via HTTP since that image
// can change.
reuseable = false;
float x = 0;
float y = 0;
GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y);

View File

@@ -312,7 +312,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
// s.RegionInfo.RegionName, destination.RegionHandle);
Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id); });
Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id, false); });
return true;
}

View File

@@ -97,6 +97,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver
}
}
/// <summary>
/// Used to cache lookups for valid groups.
/// </summary>
private IDictionary<UUID, bool> m_validGroupUuids = new Dictionary<UUID, bool>();
private IGroupsModule m_groupsModule;
public ArchiveReadRequest(Scene scene, string loadPath, bool merge, bool skipAssets, Guid requestId)
{
m_scene = scene;
@@ -120,6 +127,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
// Zero can never be a valid user id
m_validUserUuids[UUID.Zero] = false;
m_groupsModule = m_scene.RequestModuleInterface<IGroupsModule>();
}
public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge, bool skipAssets, Guid requestId)
@@ -132,6 +141,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
// Zero can never be a valid user id
m_validUserUuids[UUID.Zero] = false;
m_groupsModule = m_scene.RequestModuleInterface<IGroupsModule>();
}
/// <summary>
@@ -302,6 +313,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
if (!ResolveUserUuid(part.LastOwnerID))
part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
if (!ResolveGroupUuid(part.GroupID))
part.GroupID = UUID.Zero;
// And zap any troublesome sit target information
// part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
// part.SitTargetPosition = new Vector3(0, 0, 0);
@@ -318,13 +332,18 @@ namespace OpenSim.Region.CoreModules.World.Archiver
{
kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
}
if (kvp.Value.CreatorData == null || kvp.Value.CreatorData == string.Empty)
{
if (!ResolveUserUuid(kvp.Value.CreatorID))
kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner;
}
if (UserManager != null)
UserManager.AddUser(kvp.Value.CreatorID, kvp.Value.CreatorData);
if (!ResolveGroupUuid(kvp.Value.GroupID))
kvp.Value.GroupID = UUID.Zero;
}
}
}
@@ -364,9 +383,27 @@ namespace OpenSim.Region.CoreModules.World.Archiver
foreach (string serialisedParcel in serialisedParcels)
{
LandData parcel = LandDataSerializer.Deserialize(serialisedParcel);
// Validate User and Group UUID's
if (!ResolveUserUuid(parcel.OwnerID))
parcel.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
if (!ResolveGroupUuid(parcel.GroupID))
{
parcel.GroupID = UUID.Zero;
parcel.IsGroupOwned = false;
}
List<LandAccessEntry> accessList = new List<LandAccessEntry>();
foreach (LandAccessEntry entry in parcel.ParcelAccessList)
{
if (ResolveUserUuid(entry.AgentID))
accessList.Add(entry);
// else, drop this access rule
}
parcel.ParcelAccessList = accessList;
// m_log.DebugFormat(
// "[ARCHIVER]: Adding parcel {0}, local id {1}, area {2}",
// parcel.Name, parcel.LocalID, parcel.Area);
@@ -401,6 +438,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver
}
/// <summary>
/// Look up the given group id to check whether it's one that is valid for this grid.
/// </summary>
/// <param name="uuid"></param>
/// <returns></returns>
private bool ResolveGroupUuid(UUID uuid)
{
if (uuid == UUID.Zero)
return true; // this means the object has no group
if (!m_validGroupUuids.ContainsKey(uuid))
{
bool exists;
if (m_groupsModule == null)
exists = false;
else
exists = (m_groupsModule.GetGroupRecord(uuid) != null);
m_validGroupUuids.Add(uuid, exists);
}
return m_validGroupUuids[uuid];
}
/// Load an asset
/// </summary>
/// <param name="assetFilename"></param>

View File

@@ -85,13 +85,15 @@ namespace OpenSim.Region.CoreModules.World.Sound
dis = 0;
}
float thisSpGain;
// Scale by distance
if (radius == 0)
gain = (float)((double)gain * ((100.0 - dis) / 100.0));
thisSpGain = (float)((double)gain * ((100.0 - dis) / 100.0));
else
gain = (float)((double)gain * ((radius - dis) / radius));
thisSpGain = (float)((double)gain * ((radius - dis) / radius));
sp.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, (float)gain, flags);
sp.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, thisSpGain, flags);
});
}

View File

@@ -414,6 +414,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
private void LoadPlugins()
{
m_plugineffects = new Dictionary<string, ITerrainEffect>();
LoadPlugins(Assembly.GetCallingAssembly());
string plugineffectsPath = "Terrain";
// Load the files in the Terrain/ dir
@@ -427,32 +428,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
try
{
Assembly library = Assembly.LoadFrom(file);
foreach (Type pluginType in library.GetTypes())
{
try
{
if (pluginType.IsAbstract || pluginType.IsNotPublic)
continue;
string typeName = pluginType.Name;
if (pluginType.GetInterface("ITerrainEffect", false) != null)
{
ITerrainEffect terEffect = (ITerrainEffect) Activator.CreateInstance(library.GetType(pluginType.ToString()));
InstallPlugin(typeName, terEffect);
}
else if (pluginType.GetInterface("ITerrainLoader", false) != null)
{
ITerrainLoader terLoader = (ITerrainLoader) Activator.CreateInstance(library.GetType(pluginType.ToString()));
m_loaders[terLoader.FileExtension] = terLoader;
m_log.Info("L ... " + typeName);
}
}
catch (AmbiguousMatchException)
{
}
}
LoadPlugins(library);
}
catch (BadImageFormatException)
{
@@ -460,6 +436,36 @@ namespace OpenSim.Region.CoreModules.World.Terrain
}
}
private void LoadPlugins(Assembly library)
{
foreach (Type pluginType in library.GetTypes())
{
try
{
if (pluginType.IsAbstract || pluginType.IsNotPublic)
continue;
string typeName = pluginType.Name;
if (pluginType.GetInterface("ITerrainEffect", false) != null)
{
ITerrainEffect terEffect = (ITerrainEffect)Activator.CreateInstance(library.GetType(pluginType.ToString()));
InstallPlugin(typeName, terEffect);
}
else if (pluginType.GetInterface("ITerrainLoader", false) != null)
{
ITerrainLoader terLoader = (ITerrainLoader)Activator.CreateInstance(library.GetType(pluginType.ToString()));
m_loaders[terLoader.FileExtension] = terLoader;
m_log.Info("L ... " + typeName);
}
}
catch (AmbiguousMatchException)
{
}
}
}
public void InstallPlugin(string pluginName, ITerrainEffect effect)
{
lock (m_plugineffects)
@@ -1176,7 +1182,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
private void InterfaceRunPluginEffect(Object[] args)
{
if ((string) args[0] == "list")
string firstArg = (string)args[0];
if (firstArg == "list")
{
m_log.Info("List of loaded plugins");
foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects)
@@ -1185,14 +1192,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain
}
return;
}
if ((string) args[0] == "reload")
if (firstArg == "reload")
{
LoadPlugins();
return;
}
if (m_plugineffects.ContainsKey((string) args[0]))
if (m_plugineffects.ContainsKey(firstArg))
{
m_plugineffects[(string) args[0]].RunEffect(m_channel);
m_plugineffects[firstArg].RunEffect(m_channel);
CheckForTerrainUpdates();
}
else

View File

@@ -33,7 +33,7 @@ namespace OpenSim.Region.Framework.Interfaces
public interface IDynamicTextureManager
{
void RegisterRender(string handleType, IDynamicTextureRender render);
void ReturnData(UUID id, byte[] data);
void ReturnData(UUID id, byte[] data, bool isReuseable);
UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams,
int updateTimer);
@@ -113,8 +113,20 @@ namespace OpenSim.Region.Framework.Interfaces
string GetName();
string GetContentType();
bool SupportsAsynchronous();
// /// <summary>
// /// Return true if converting the input body and extra params data will always result in the same byte[] array
// /// </summary>
// /// <remarks>
// /// This method allows the caller to use a previously generated asset if it has one.
// /// </remarks>
// /// <returns></returns>
// /// <param name='bodyData'></param>
// /// <param name='extraParams'></param>
// bool AlwaysIdenticalConversion(string bodyData, string extraParams);
byte[] ConvertUrl(string url, string extraParams);
byte[] ConvertStream(Stream data, string extraParams);
byte[] ConvertData(string bodyData, string extraParams);
bool AsyncConvertUrl(UUID id, string url, string extraParams);
bool AsyncConvertData(UUID id, string bodyData, string extraParams);
void GetDrawStringSize(string text, string fontName, int fontSize,

View File

@@ -46,9 +46,31 @@ namespace OpenSim.Region.Framework.Interfaces
/// </summary>
event ScriptCommand OnScriptCommand;
/// <summary>
/// Register an instance method as a script call by method name
/// </summary>
/// <param name="target"></param>
/// <param name="method"></param>
void RegisterScriptInvocation(object target, string method);
/// <summary>
/// Register an instance method as a script call by method info
/// </summary>
/// <param name="target"></param>
/// <param name="method"></param>
void RegisterScriptInvocation(object target, MethodInfo method);
/// <summary>
/// Register one or more instance methods as script calls by method name
/// </summary>
/// <param name="target"></param>
/// <param name="methods"></param>
void RegisterScriptInvocation(object target, string[] methods);
/// <summary>
/// Returns an array of all registered script calls
/// </summary>
/// <returns></returns>
Delegate[] GetScriptInvocationList();
Delegate LookupScriptInvocation(string fname);

View File

@@ -39,6 +39,8 @@ namespace OpenSim.Region.Framework.Interfaces
UUID RequestSecureURL(IScriptModule engine, SceneObjectPart host, UUID itemID);
void ReleaseURL(string url);
void HttpResponse(UUID request, int status, string body);
void HttpContentType(UUID request, string type);
string GetHttpHeader(UUID request, string header);
int GetFreeUrls();

View File

@@ -93,7 +93,7 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
public void StartScripts()
{
m_log.InfoFormat("[SCENE]: Starting scripts in {0}, please wait.", RegionInfo.RegionName);
// m_log.InfoFormat("[SCENE]: Starting scripts in {0}, please wait.", RegionInfo.RegionName);
IScriptModule[] engines = RequestModuleInterfaces<IScriptModule>();
@@ -1943,6 +1943,9 @@ namespace OpenSim.Region.Framework.Scenes
deleteIDs.Add(localID);
deleteGroups.Add(grp);
// If child prims have invalid perms, fix them
grp.AdjustChildPrimPermissions();
if (remoteClient == null)
{
// Autoreturn has a null client. Nothing else does. So

View File

@@ -468,7 +468,7 @@ namespace OpenSim.Region.Framework.Scenes
if (!InventoryService.AddFolder(folder))
{
m_log.WarnFormat(
"[AGENT INVENTORY]: Failed to move create folder for user {0} {1}",
"[AGENT INVENTORY]: Failed to create folder for user {0} {1}",
remoteClient.Name, remoteClient.AgentId);
}
}

View File

@@ -103,8 +103,26 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
public bool CollidablePrims { get; private set; }
/// <summary>
/// Minimum value of the size of a non-physical prim in each axis
/// </summary>
public float m_minNonphys = 0.01f;
/// <summary>
/// Maximum value of the size of a non-physical prim in each axis
/// </summary>
public float m_maxNonphys = 256;
/// <summary>
/// Minimum value of the size of a physical prim in each axis
/// </summary>
public float m_minPhys = 0.01f;
/// <summary>
/// Maximum value of the size of a physical prim in each axis
/// </summary>
public float m_maxPhys = 10;
public bool m_clampPrimSize;
public bool m_trustBinaries;
public bool m_allowScriptCrossings;
@@ -721,14 +739,25 @@ namespace OpenSim.Region.Framework.Scenes
PhysicalPrims = startupConfig.GetBoolean("physical_prim", PhysicalPrims);
CollidablePrims = startupConfig.GetBoolean("collidable_prim", CollidablePrims);
m_minNonphys = startupConfig.GetFloat("NonphysicalPrimMin", m_minNonphys);
if (RegionInfo.NonphysPrimMin > 0)
{
m_minNonphys = RegionInfo.NonphysPrimMin;
}
m_maxNonphys = startupConfig.GetFloat("NonphysicalPrimMax", m_maxNonphys);
if (RegionInfo.NonphysPrimMax > 0)
{
m_maxNonphys = RegionInfo.NonphysPrimMax;
}
m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys);
m_minPhys = startupConfig.GetFloat("PhysicalPrimMin", m_minPhys);
if (RegionInfo.PhysPrimMin > 0)
{
m_minPhys = RegionInfo.PhysPrimMin;
}
m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys);
if (RegionInfo.PhysPrimMax > 0)
{
m_maxPhys = RegionInfo.PhysPrimMax;
@@ -3533,7 +3562,7 @@ namespace OpenSim.Region.Framework.Scenes
"[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
sp.Name, sp.UUID, RegionInfo.RegionName);
sp.ControllingClient.Close();
sp.ControllingClient.Close(true);
sp = null;
}
@@ -4087,16 +4116,19 @@ namespace OpenSim.Region.Framework.Scenes
/// <summary>
/// Tell a single agent to disconnect from the region.
/// </summary>
/// <param name="regionHandle"></param>
/// <param name="agentID"></param>
public bool IncomingCloseAgent(UUID agentID)
/// <param name="force">
/// Force the agent to close even if it might be in the middle of some other operation. You do not want to
/// force unless you are absolutely sure that the agent is dead and a normal close is not working.
/// </param>
public bool IncomingCloseAgent(UUID agentID, bool force)
{
//m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
if (presence != null)
{
presence.ControllingClient.Close();
presence.ControllingClient.Close(force);
return true;
}

View File

@@ -300,7 +300,7 @@ namespace OpenSim.Region.Framework.Scenes
public bool AddNewSceneObject(
SceneObjectGroup sceneObject, bool attachToBackup, Vector3? pos, Quaternion? rot, Vector3 vel)
{
AddNewSceneObject(sceneObject, true, false);
AddNewSceneObject(sceneObject, attachToBackup, false);
if (pos != null)
sceneObject.AbsolutePosition = (Vector3)pos;
@@ -375,12 +375,9 @@ namespace OpenSim.Region.Framework.Scenes
{
Vector3 scale = part.Shape.Scale;
if (scale.X > m_parentScene.m_maxNonphys)
scale.X = m_parentScene.m_maxNonphys;
if (scale.Y > m_parentScene.m_maxNonphys)
scale.Y = m_parentScene.m_maxNonphys;
if (scale.Z > m_parentScene.m_maxNonphys)
scale.Z = m_parentScene.m_maxNonphys;
scale.X = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.X));
scale.Y = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Y));
scale.Z = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Z));
part.Shape.Scale = scale;
}

View File

@@ -2131,6 +2131,9 @@ namespace OpenSim.Region.Framework.Scenes
// Can't do this yet since backup still makes use of the root part without any synchronization
// objectGroup.m_rootPart = null;
// If linking prims with different permissions, fix them
AdjustChildPrimPermissions();
AttachToBackup();
// Here's the deal, this is ABSOLUTELY CRITICAL so the physics scene gets the update about the
@@ -2622,12 +2625,21 @@ namespace OpenSim.Region.Framework.Scenes
}
}
public void AdjustChildPrimPermissions()
{
ForEachPart(part =>
{
if (part != RootPart)
part.ClonePermissions(RootPart);
});
}
public void UpdatePermissions(UUID AgentID, byte field, uint localID,
uint mask, byte addRemTF)
{
SceneObjectPart[] parts = m_parts.GetArray();
for (int i = 0; i < parts.Length; i++)
parts[i].UpdatePermissions(AgentID, field, localID, mask, addRemTF);
RootPart.UpdatePermissions(AgentID, field, localID, mask, addRemTF);
AdjustChildPrimPermissions();
HasGroupChanged = true;
@@ -2674,17 +2686,17 @@ namespace OpenSim.Region.Framework.Scenes
RootPart.StoreUndoState(true);
scale.X = Math.Min(scale.X, Scene.m_maxNonphys);
scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys);
scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys);
scale.X = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.X));
scale.Y = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Y));
scale.Z = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Z));
PhysicsActor pa = m_rootPart.PhysActor;
if (pa != null && pa.IsPhysical)
{
scale.X = Math.Min(scale.X, Scene.m_maxPhys);
scale.Y = Math.Min(scale.Y, Scene.m_maxPhys);
scale.Z = Math.Min(scale.Z, Scene.m_maxPhys);
scale.X = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.X));
scale.Y = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Y));
scale.Z = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Z));
}
float x = (scale.X / RootPart.Scale.X);
@@ -2716,6 +2728,14 @@ namespace OpenSim.Region.Framework.Scenes
y *= a;
z *= a;
}
else if (oldSize.X * x < m_scene.m_minPhys)
{
f = m_scene.m_minPhys / oldSize.X;
a = f / x;
x *= a;
y *= a;
z *= a;
}
if (oldSize.Y * y > m_scene.m_maxPhys)
{
@@ -2725,6 +2745,14 @@ namespace OpenSim.Region.Framework.Scenes
y *= a;
z *= a;
}
else if (oldSize.Y * y < m_scene.m_minPhys)
{
f = m_scene.m_minPhys / oldSize.Y;
a = f / y;
x *= a;
y *= a;
z *= a;
}
if (oldSize.Z * z > m_scene.m_maxPhys)
{
@@ -2734,6 +2762,14 @@ namespace OpenSim.Region.Framework.Scenes
y *= a;
z *= a;
}
else if (oldSize.Z * z < m_scene.m_minPhys)
{
f = m_scene.m_minPhys / oldSize.Z;
a = f / z;
x *= a;
y *= a;
z *= a;
}
}
else
{
@@ -2745,6 +2781,14 @@ namespace OpenSim.Region.Framework.Scenes
y *= a;
z *= a;
}
else if (oldSize.X * x < m_scene.m_minNonphys)
{
f = m_scene.m_minNonphys / oldSize.X;
a = f / x;
x *= a;
y *= a;
z *= a;
}
if (oldSize.Y * y > m_scene.m_maxNonphys)
{
@@ -2754,6 +2798,14 @@ namespace OpenSim.Region.Framework.Scenes
y *= a;
z *= a;
}
else if (oldSize.Y * y < m_scene.m_minNonphys)
{
f = m_scene.m_minNonphys / oldSize.Y;
a = f / y;
x *= a;
y *= a;
z *= a;
}
if (oldSize.Z * z > m_scene.m_maxNonphys)
{
@@ -2763,6 +2815,14 @@ namespace OpenSim.Region.Framework.Scenes
y *= a;
z *= a;
}
else if (oldSize.Z * z < m_scene.m_minNonphys)
{
f = m_scene.m_minNonphys / oldSize.Z;
a = f / z;
x *= a;
y *= a;
z *= a;
}
}
// obPart.IgnoreUndoUpdate = false;

View File

@@ -733,7 +733,7 @@ namespace OpenSim.Region.Framework.Scenes
}
catch (Exception e)
{
m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message);
m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e);
}
}
@@ -2368,17 +2368,16 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="scale"></param>
public void Resize(Vector3 scale)
{
scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxNonphys);
scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxNonphys);
scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxNonphys);
scale.X = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.X));
scale.Y = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Y));
scale.Z = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Z));
PhysicsActor pa = PhysActor;
if (pa != null && pa.IsPhysical)
{
scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxPhys);
scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxPhys);
scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxPhys);
scale.X = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.X));
scale.Y = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Y));
scale.Z = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Z));
}
// m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale);
@@ -2852,23 +2851,32 @@ namespace OpenSim.Region.Framework.Scenes
}
/// <summary>
/// Set the color of prim faces
/// Set the color & alpha of prim faces
/// </summary>
/// <param name="color"></param>
/// <param name="face"></param>
public void SetFaceColor(Vector3 color, int face)
/// <param name="color"></param>
/// <param name="alpha"></param>
public void SetFaceColorAlpha(int face, Vector3 color, double ?alpha)
{
Vector3 clippedColor = Util.Clip(color, 0.0f, 1.0f);
float clippedAlpha = alpha.HasValue ?
Util.Clip((float)alpha.Value, 0.0f, 1.0f) : 0;
// The only way to get a deep copy/ If we don't do this, we can
// mever detect color changes further down.
// never detect color changes further down.
Byte[] buf = Shape.Textures.GetBytes();
Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length);
Color4 texcolor;
if (face >= 0 && face < GetNumberOfSides())
{
texcolor = tex.CreateFace((uint)face).RGBA;
texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f);
texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f);
texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f);
texcolor.R = clippedColor.X;
texcolor.G = clippedColor.Y;
texcolor.B = clippedColor.Z;
if (alpha.HasValue)
{
texcolor.A = clippedAlpha;
}
tex.FaceTextures[face].RGBA = texcolor;
UpdateTextureEntry(tex.GetBytes());
return;
@@ -2880,15 +2888,23 @@ namespace OpenSim.Region.Framework.Scenes
if (tex.FaceTextures[i] != null)
{
texcolor = tex.FaceTextures[i].RGBA;
texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f);
texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f);
texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f);
texcolor.R = clippedColor.X;
texcolor.G = clippedColor.Y;
texcolor.B = clippedColor.Z;
if (alpha.HasValue)
{
texcolor.A = clippedAlpha;
}
tex.FaceTextures[i].RGBA = texcolor;
}
texcolor = tex.DefaultTexture.RGBA;
texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f);
texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f);
texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f);
texcolor.R = clippedColor.X;
texcolor.G = clippedColor.Y;
texcolor.B = clippedColor.Z;
if (alpha.HasValue)
{
texcolor.A = clippedAlpha;
}
tex.DefaultTexture.RGBA = texcolor;
}
UpdateTextureEntry(tex.GetBytes());
@@ -3874,6 +3890,27 @@ namespace OpenSim.Region.Framework.Scenes
}
}
public void ClonePermissions(SceneObjectPart source)
{
bool update = false;
if (BaseMask != source.BaseMask ||
OwnerMask != source.OwnerMask ||
GroupMask != source.GroupMask ||
EveryoneMask != source.EveryoneMask ||
NextOwnerMask != source.NextOwnerMask)
update = true;
BaseMask = source.BaseMask;
OwnerMask = source.OwnerMask;
GroupMask = source.GroupMask;
EveryoneMask = source.EveryoneMask;
NextOwnerMask = source.NextOwnerMask;
if (update)
SendFullUpdateToAllClients();
}
public bool IsHingeJoint()
{
// For now, we use the NINJA naming scheme for identifying joints.
@@ -4237,6 +4274,57 @@ namespace OpenSim.Region.Framework.Scenes
ScheduleFullUpdate();
}
public void UpdateSlice(float begin, float end)
{
if (end < begin)
{
float temp = begin;
begin = end;
end = temp;
}
end = Math.Min(1f, Math.Max(0f, end));
begin = Math.Min(Math.Min(1f, Math.Max(0f, begin)), end - 0.02f);
if (begin < 0.02f && end < 0.02f)
{
begin = 0f;
end = 0.02f;
}
ushort uBegin = (ushort)(50000.0 * begin);
ushort uEnd = (ushort)(50000.0 * (1f - end));
bool updatePossiblyNeeded = false;
PrimType primType = GetPrimType();
if (primType == PrimType.SPHERE || primType == PrimType.TORUS || primType == PrimType.TUBE || primType == PrimType.RING)
{
if (m_shape.ProfileBegin != uBegin || m_shape.ProfileEnd != uEnd)
{
m_shape.ProfileBegin = uBegin;
m_shape.ProfileEnd = uEnd;
updatePossiblyNeeded = true;
}
}
else if (m_shape.PathBegin != uBegin || m_shape.PathEnd != uEnd)
{
m_shape.PathBegin = uBegin;
m_shape.PathEnd = uEnd;
updatePossiblyNeeded = true;
}
if (updatePossiblyNeeded && ParentGroup != null)
{
ParentGroup.HasGroupChanged = true;
}
if (updatePossiblyNeeded && PhysActor != null)
{
PhysActor.Shape = m_shape;
ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
}
if (updatePossiblyNeeded)
{
ScheduleFullUpdate();
}
}
/// <summary>
/// If the part is a sculpt/mesh, retrieve the mesh data and reinsert it into the shape so that the physics
/// engine can use it.

View File

@@ -891,7 +891,9 @@ namespace OpenSim.Region.Framework.Scenes
{
if (wasChild && HasAttachments())
{
m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments...");
m_log.DebugFormat(
"[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
// Resume scripts
foreach (SceneObjectGroup sog in m_attachments)
{
@@ -1385,17 +1387,22 @@ namespace OpenSim.Region.Framework.Scenes
bool DCFlagKeyPressed = false;
Vector3 agent_control_v3 = Vector3.Zero;
bool oldflying = Flying;
bool newFlying = actor.Flying;
if (ForceFly)
actor.Flying = true;
newFlying = true;
else if (FlyDisabled)
actor.Flying = false;
newFlying = false;
else
actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
newFlying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
if (actor.Flying != oldflying)
if (actor.Flying != newFlying)
{
// Note: ScenePresence.Flying is actually fetched from the physical actor
// so setting PhysActor.Flying here also sets the ScenePresence's value.
actor.Flying = newFlying;
update_movementflag = true;
}
if (ParentID == 0)
{

View File

@@ -141,7 +141,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
TestScene scene = new SceneHelpers().SetupScene();
ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
scene.IncomingCloseAgent(sp.UUID);
scene.IncomingCloseAgent(sp.UUID, false);
Assert.That(scene.GetScenePresence(sp.UUID), Is.Null);
Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null);

View File

@@ -50,8 +50,40 @@ using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.Framework.Tests
{
[TestFixture]
public class UserInventoryTests
public class UserInventoryTests : OpenSimTestCase
{
[Test]
public void TestCreateInventoryFolders()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
// For this test both folders will have the same name which is legal in SL user inventories.
string foldersName = "f1";
Scene scene = new SceneHelpers().SetupScene();
UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));
UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName);
List<InventoryFolderBase> oneFolder
= UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, foldersName);
Assert.That(oneFolder.Count, Is.EqualTo(1));
InventoryFolderBase firstRetrievedFolder = oneFolder[0];
Assert.That(firstRetrievedFolder.Name, Is.EqualTo(foldersName));
UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName);
List<InventoryFolderBase> twoFolders
= UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, foldersName);
Assert.That(twoFolders.Count, Is.EqualTo(2));
Assert.That(twoFolders[0].Name, Is.EqualTo(foldersName));
Assert.That(twoFolders[1].Name, Is.EqualTo(foldersName));
Assert.That(twoFolders[0].ID, Is.Not.EqualTo(twoFolders[1].ID));
}
[Test]
public void TestGiveInventoryItem()
{
@@ -83,7 +115,7 @@ namespace OpenSim.Region.Framework.Tests
public void TestGiveInventoryFolder()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
// TestHelpers.EnableLogging();
Scene scene = new SceneHelpers().SetupScene();
UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));

View File

@@ -885,6 +885,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
}
public void Close()
{
Close(false);
}
public void Close(bool force)
{
Disconnect();
}

View File

@@ -130,10 +130,17 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
m_scriptModule.PostScriptEvent(script, "link_message", args);
}
private static MethodInfo GetMethodInfoFromType(Type target, string meth)
{
MethodInfo mi = target.GetMethod(meth,
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
return mi;
}
public void RegisterScriptInvocation(object target, string meth)
{
MethodInfo mi = target.GetType().GetMethod(meth,
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
MethodInfo mi = GetMethodInfoFromType(target.GetType(), meth);
if (mi == null)
{
m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}",meth);

View File

@@ -900,6 +900,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC
}
public void Close()
{
Close(false);
}
public void Close(bool force)
{
// Remove ourselves from the scene
m_scene.RemoveClient(AgentId, false);

View File

@@ -124,10 +124,14 @@ public class BSCharacter : PhysicsActor
// do actual create at taint time
_scene.TaintedObject("BSCharacter.create", delegate()
{
DetailLog("{0},BSCharacter.create", _localID);
BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData);
// Set the buoyancy for flying. This will be refactored when all the settings happen in C#
BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy);
m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
// avatars get all collisions no matter what
// avatars get all collisions no matter what (makes walking on ground and such work)
BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
});
@@ -137,7 +141,7 @@ public class BSCharacter : PhysicsActor
// called when this character is being destroyed and the resources should be released
public void Destroy()
{
// DetailLog("{0},BSCharacter.Destroy", LocalID);
DetailLog("{0},BSCharacter.Destroy", LocalID);
_scene.TaintedObject("BSCharacter.destroy", delegate()
{
BulletSimAPI.DestroyObject(_scene.WorldID, _localID);
@@ -319,14 +323,13 @@ public class BSCharacter : PhysicsActor
public override bool Flying {
get { return _flying; }
set {
if (_flying != value)
{
_flying = value;
// simulate flying by changing the effect of gravity
this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
}
_flying = value;
// simulate flying by changing the effect of gravity
this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
}
}
// Flying is implimented by changing the avatar's buoyancy.
// Would this be done better with a vehicle type?
private float ComputeBuoyancyFromFlying(bool ifFlying) {
return ifFlying ? 1f : 0f;
}
@@ -488,11 +491,9 @@ public class BSCharacter : PhysicsActor
// Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
// base.RequestPhysicsterseUpdate();
/*
DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,
entprop.Acceleration, entprop.RotationalVelocity);
*/
}
// Called by the scene when a collision with this object is reported

View File

@@ -57,6 +57,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
private int frcount = 0; // Used to limit dynamics debug output to
// every 100th frame
private BSScene m_physicsScene;
private BSPrim m_prim; // the prim this dynamic controller belongs to
// Vehicle properties
@@ -74,7 +75,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// HOVER_UP_ONLY
// LIMIT_MOTOR_UP
// LIMIT_ROLL_ONLY
private VehicleFlag m_Hoverflags = (VehicleFlag)0;
private Vector3 m_BlockingEndPoint = Vector3.Zero;
private Quaternion m_RollreferenceFrame = Quaternion.Identity;
// Linear properties
@@ -124,15 +124,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
private float m_verticalAttractionEfficiency = 1.0f; // damped
private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor.
public BSDynamics(BSPrim myPrim)
public BSDynamics(BSScene myScene, BSPrim myPrim)
{
m_physicsScene = myScene;
m_prim = myPrim;
m_type = Vehicle.TYPE_NONE;
}
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue, float timestep)
{
DetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
switch (pParam)
{
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
@@ -231,7 +232,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue, float timestep)
{
DetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
switch (pParam)
{
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
@@ -266,7 +267,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
{
DetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
VDetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
switch (pParam)
{
case Vehicle.REFERENCE_FRAME:
@@ -280,164 +281,27 @@ namespace OpenSim.Region.Physics.BulletSPlugin
internal void ProcessVehicleFlags(int pParam, bool remove)
{
DetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", m_prim.LocalID, pParam, remove);
VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", m_prim.LocalID, pParam, remove);
VehicleFlag parm = (VehicleFlag)pParam;
if (remove)
{
if (pParam == -1)
{
m_flags = (VehicleFlag)0;
m_Hoverflags = (VehicleFlag)0;
return;
}
if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT)
else
{
if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != (VehicleFlag)0)
m_Hoverflags &= ~(VehicleFlag.HOVER_GLOBAL_HEIGHT);
}
if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
{
if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != (VehicleFlag)0)
m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY);
}
if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
{
if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != (VehicleFlag)0)
m_Hoverflags &= ~(VehicleFlag.HOVER_UP_ONLY);
}
if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
{
if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != (VehicleFlag)0)
m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY);
}
if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
{
if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.LIMIT_MOTOR_UP);
}
if ((pParam & (int)VehicleFlag.LIMIT_ROLL_ONLY) == (int)VehicleFlag.LIMIT_ROLL_ONLY)
{
if ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
}
if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
{
if ((m_flags & VehicleFlag.MOUSELOOK_BANK) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.MOUSELOOK_BANK);
}
if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
{
if ((m_flags & VehicleFlag.MOUSELOOK_STEER) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.MOUSELOOK_STEER);
}
if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
{
if ((m_flags & VehicleFlag.NO_DEFLECTION_UP) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP);
}
if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
{
if ((m_flags & VehicleFlag.CAMERA_DECOUPLED) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.CAMERA_DECOUPLED);
}
if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
{
if ((m_flags & VehicleFlag.NO_X) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.NO_X);
}
if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
{
if ((m_flags & VehicleFlag.NO_Y) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.NO_Y);
}
if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
{
if ((m_flags & VehicleFlag.NO_Z) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.NO_Z);
}
if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT)
{
if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != (VehicleFlag)0)
m_Hoverflags &= ~(VehicleFlag.LOCK_HOVER_HEIGHT);
}
if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
{
if ((m_flags & VehicleFlag.NO_DEFLECTION) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.NO_DEFLECTION);
}
if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
{
if ((m_flags & VehicleFlag.LOCK_ROTATION) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.LOCK_ROTATION);
m_flags &= ~parm;
}
}
else
{
if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT)
{
m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT | m_flags);
}
if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
{
m_Hoverflags |= (VehicleFlag.HOVER_TERRAIN_ONLY | m_flags);
}
if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
{
m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY | m_flags);
}
if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
{
m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY | m_flags);
}
if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
{
m_flags |= (VehicleFlag.LIMIT_MOTOR_UP | m_flags);
}
if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
{
m_flags |= (VehicleFlag.MOUSELOOK_BANK | m_flags);
}
if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
{
m_flags |= (VehicleFlag.MOUSELOOK_STEER | m_flags);
}
if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
{
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | m_flags);
}
if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
{
m_flags |= (VehicleFlag.CAMERA_DECOUPLED | m_flags);
}
if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
{
m_flags |= (VehicleFlag.NO_X);
}
if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
{
m_flags |= (VehicleFlag.NO_Y);
}
if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
{
m_flags |= (VehicleFlag.NO_Z);
}
if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT)
{
m_Hoverflags |= (VehicleFlag.LOCK_HOVER_HEIGHT);
}
if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
{
m_flags |= (VehicleFlag.NO_DEFLECTION);
}
if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
{
m_flags |= (VehicleFlag.LOCK_ROTATION);
}
else {
m_flags |= parm;
}
}//end ProcessVehicleFlags
internal void ProcessTypeChange(Vehicle pType)
internal void ProcessTypeChange(Vehicle pType, float stepSize)
{
DetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType);
VDetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType);
// Set Defaults For Type
m_type = pType;
switch (pType)
@@ -478,10 +342,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// m_bankingMix = 1;
// m_bankingTimescale = 10;
// m_referenceFrame = Quaternion.Identity;
m_Hoverflags &=
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
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);
@@ -506,10 +370,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// m_bankingMix = 1;
// m_bankingTimescale = 1;
// m_referenceFrame = Quaternion.Identity;
m_Hoverflags &= ~(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);
m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY);
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
m_flags |= (VehicleFlag.HOVER_UP_ONLY);
break;
case Vehicle.TYPE_BOAT:
m_linearFrictionTimescale = new Vector3(10, 3, 2);
@@ -534,12 +398,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// m_bankingMix = 0.8f;
// m_bankingTimescale = 1;
// m_referenceFrame = Quaternion.Identity;
m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
VehicleFlag.LIMIT_MOTOR_UP);
m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY);
m_flags |= (VehicleFlag.HOVER_WATER_ONLY);
break;
case Vehicle.TYPE_AIRPLANE:
m_linearFrictionTimescale = new Vector3(200, 10, 5);
@@ -564,7 +428,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// m_bankingMix = 0.7f;
// m_bankingTimescale = 2;
// m_referenceFrame = Quaternion.Identity;
m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
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_MOTOR_UP);
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
@@ -592,11 +456,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// m_bankingMix = 0.7f;
// m_bankingTimescale = 5;
// m_referenceFrame = Quaternion.Identity;
m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
VehicleFlag.HOVER_UP_ONLY);
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT);
m_flags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT);
break;
}
}//end SetDefaultsForType
@@ -613,7 +477,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
MoveAngular(pTimestep);
LimitRotation(pTimestep);
DetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity);
}// end Step
@@ -657,7 +521,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
*/
DetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}",
VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}",
m_prim.LocalID, origDir, origVel, addAmount, decayfraction, m_linearMotorDirection, m_lastLinearVelocityVector);
}
else
@@ -669,7 +533,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
m_lastLinearVelocityVector = Vector3.Zero;
}
// convert requested object velocity to world-referenced vector
// convert requested object velocity to object relative vector
Quaternion rotq = m_prim.Orientation;
m_dir = m_lastLinearVelocityVector * rotq;
@@ -722,7 +586,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
if (changed)
{
m_prim.Position = pos;
DetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
m_prim.LocalID, m_BlockingEndPoint, posChange, pos);
}
}
@@ -732,32 +596,32 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{
pos.Z = m_prim.Scene.GetTerrainHeightAtXYZ(pos) + 2;
m_prim.Position = pos;
DetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos);
VDetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos);
}
// Check if hovering
if ((m_Hoverflags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
{
// We should hover, get the target height
if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != 0)
if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
{
m_VhoverTargetHeight = m_prim.Scene.GetWaterLevel() + m_VhoverHeight;
}
if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
{
m_VhoverTargetHeight = m_prim.Scene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
}
if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0)
if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0)
{
m_VhoverTargetHeight = m_VhoverHeight;
}
if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != 0)
if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0)
{
// If body is aready heigher, use its height as target height
if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
}
if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
{
if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2)
{
@@ -779,7 +643,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
}
}
DetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight);
VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight);
// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped
// m_VhoverTimescale = 0f; // time to acheive height
@@ -815,7 +679,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{
grav.Z = (float)(grav.Z * 1.037125);
}
DetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav);
VDetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav);
//End Experimental Values
}
if ((m_flags & (VehicleFlag.NO_X)) != 0)
@@ -844,7 +708,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep);
m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount;
DetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}",
VDetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}",
m_prim.LocalID, m_lastPositionVector, m_dir, grav, decayamount);
} // end MoveLinear()
@@ -870,13 +734,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// There are m_angularMotorApply steps.
Vector3 origAngularVelocity = m_angularMotorVelocity;
// ramp up to new value
// current velocity += error / (time to get there / step interval)
// current velocity += error / (time to get there / step interval)
// requested speed - last motor speed
m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep);
m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep);
m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep);
DetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}",
VDetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}",
m_prim.LocalID,m_angularMotorApply,origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity);
m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected
@@ -887,6 +751,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// No motor recently applied, keep the body velocity
// and decay the velocity
m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep);
if (m_angularMotorVelocity.LengthSquared() < 0.00001)
m_angularMotorVelocity = Vector3.Zero;
} // end motor section
// Vertical attractor section
@@ -924,7 +790,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
vertattr.X += bounce * angularVelocity.X;
vertattr.Y += bounce * angularVelocity.Y;
DetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}",
VDetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}",
m_prim.LocalID, verterr, bounce, vertattr);
} // else vertical attractor is off
@@ -942,13 +808,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{
m_lastAngularVelocity.X = 0;
m_lastAngularVelocity.Y = 0;
DetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
}
if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
{
m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
DetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
VDetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
}
// apply friction
@@ -958,7 +824,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// Apply to the body
m_prim.RotationalVelocity = m_lastAngularVelocity;
DetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", m_prim.LocalID, decayamount, m_lastAngularVelocity);
VDetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", m_prim.LocalID, decayamount, m_lastAngularVelocity);
} //end MoveAngular
internal void LimitRotation(float timestep)
@@ -1005,11 +871,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
if (changed)
m_prim.Orientation = m_rot;
DetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot);
VDetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot);
}
// Invoke the detailed logger and output something if it's enabled.
private void DetailLog(string msg, params Object[] args)
private void VDetailLog(string msg, params Object[] args)
{
if (m_prim.Scene.VehicleLoggingEnabled)
m_prim.Scene.PhysicsLogging.Write(msg, args);

View File

@@ -42,6 +42,9 @@ public class BSLinkset
private BSScene m_physicsScene;
public BSScene PhysicsScene { get { return m_physicsScene; } }
static int m_nextLinksetID = 1;
public int LinksetID { get; private set; }
// The children under the root in this linkset
private List<BSPrim> m_children;
@@ -74,6 +77,10 @@ public class BSLinkset
public BSLinkset(BSScene scene, BSPrim parent)
{
// A simple linkset of one (no children)
LinksetID = m_nextLinksetID++;
// We create LOTS of linksets.
if (m_nextLinksetID < 0)
m_nextLinksetID = 1;
m_physicsScene = scene;
m_linksetRoot = parent;
m_children = new List<BSPrim>();
@@ -258,8 +265,7 @@ public class BSLinkset
BSPrim childx = child;
m_physicsScene.TaintedObject("AddChildToLinkset", delegate()
{
// DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID);
// DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
PhysicallyLinkAChildToRoot(rootx, childx); // build the physical binding between me and the child
});
}
@@ -287,8 +293,7 @@ public class BSLinkset
BSPrim childx = child;
m_physicsScene.TaintedObject("RemoveChildFromLinkset", delegate()
{
// DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID);
// DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
PhysicallyUnlinkAChildFromRoot(rootx, childx);
});
@@ -319,7 +324,6 @@ public class BSLinkset
// create a constraint that allows no freedom of movement between the two objects
// http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
// DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2},rLoc={3},cLoc={4},midLoc={5}",
rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID, rootPrim.Position, childPrim.Position, midPoint);
BS6DofConstraint constrain = new BS6DofConstraint(
@@ -328,10 +332,10 @@ public class BSLinkset
true,
true
);
/* NOTE: attempt to build constraint with full frame computation, etc.
/* NOTE: below is an attempt to build constraint with full frame computation, etc.
* Using the midpoint is easier since it lets the Bullet code use the transforms
* of the objects.
* Code left here as an example.
* Code left as a warning to future programmers.
// ==================================================================================
// relative position normalized to the root prim
OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation);
@@ -343,7 +347,6 @@ public class BSLinkset
// create a constraint that allows no freedom of movement between the two objects
// http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
// DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
BS6DofConstraint constrain = new BS6DofConstraint(
PhysicsScene.World, rootPrim.Body, childPrim.Body,
@@ -382,8 +385,6 @@ public class BSLinkset
// Called at taint time!
private void PhysicallyUnlinkAChildFromRoot(BSPrim rootPrim, BSPrim childPrim)
{
// DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}",
// LogHeader, rootPrim.LocalID, childPrim.LocalID);
DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
// Find the constraint for this link and get rid of it from the overall collection and from my list
@@ -397,19 +398,11 @@ public class BSLinkset
// Called at taint time!
private void PhysicallyUnlinkAllChildrenFromRoot(BSPrim rootPrim)
{
// DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader);
DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body);
}
// Invoke the detailed logger and output something if it's enabled.
private void DebugLog(string msg, params Object[] args)
{
if (m_physicsScene.ShouldDebugLog)
m_physicsScene.Logger.DebugFormat(msg, args);
}
// Invoke the detailed logger and output something if it's enabled.
private void DetailLog(string msg, params Object[] args)
{

View File

@@ -42,8 +42,6 @@ public sealed class BSPrim : PhysicsActor
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string LogHeader = "[BULLETS PRIM]";
private void DebugLog(string mm, params Object[] xx) { if (_scene.ShouldDebugLog) m_log.DebugFormat(mm, xx); }
private IMesh _mesh;
private PrimitiveBaseShape _pbs;
private ShapeData.PhysicsShapeType _shapeType;
@@ -141,8 +139,8 @@ public sealed class BSPrim : PhysicsActor
_friction = _scene.Params.defaultFriction; // TODO: compute based on object material
_density = _scene.Params.defaultDensity; // TODO: compute based on object material
_restitution = _scene.Params.defaultRestitution;
_linkset = new BSLinkset(_scene, this); // a linkset of one
_vehicle = new BSDynamics(this); // add vehicleness
_linkset = new BSLinkset(Scene, this); // a linkset of one
_vehicle = new BSDynamics(Scene, this); // add vehicleness
_mass = CalculateMass();
// do the actual object creation at taint time
DetailLog("{0},BSPrim.constructor,call", LocalID);
@@ -193,7 +191,7 @@ public sealed class BSPrim : PhysicsActor
{
_mass = CalculateMass(); // changing size changes the mass
BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical);
// DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical);
DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical);
RecreateGeomAndObject();
});
}
@@ -232,7 +230,6 @@ public sealed class BSPrim : PhysicsActor
BSPrim parent = obj as BSPrim;
if (parent != null)
{
DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, parent.LocalID);
BSPrim parentBefore = _linkset.LinksetRoot;
int childrenBefore = _linkset.NumberOfChildren;
@@ -248,8 +245,6 @@ public sealed class BSPrim : PhysicsActor
public override void delink() {
// TODO: decide if this parent checking needs to happen at taint time
// Race condition here: if link() and delink() in same simulation tick, the delink will not happen
DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID,
_linkset.LinksetRoot._avName+"/"+_linkset.LinksetRoot.LocalID.ToString());
BSPrim parentBefore = _linkset.LinksetRoot;
int childrenBefore = _linkset.NumberOfChildren;
@@ -280,7 +275,7 @@ public sealed class BSPrim : PhysicsActor
public override void LockAngularMotion(OMV.Vector3 axis)
{
// DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
return;
}
@@ -299,7 +294,7 @@ public sealed class BSPrim : PhysicsActor
// TODO: what does it mean to set the position of a child prim?? Rebuild the constraint?
_scene.TaintedObject("BSPrim.setPosition", delegate()
{
// DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
});
}
@@ -336,7 +331,7 @@ public sealed class BSPrim : PhysicsActor
_force = value;
_scene.TaintedObject("BSPrim.setForce", delegate()
{
// DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force);
DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force);
// BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
BulletSimAPI.SetObjectForce2(Body.Ptr, _force);
});
@@ -354,7 +349,7 @@ public sealed class BSPrim : PhysicsActor
{
// Done at taint time so we're sure the physics engine is not using the variables
// Vehicle code changes the parameters for this vehicle type.
_vehicle.ProcessTypeChange(type);
_vehicle.ProcessTypeChange(type, Scene.LastSimulatedTimestep);
// Tell the scene about the vehicle so it will get processing each frame.
_scene.VehicleInSceneTypeChanged(this, type);
});
@@ -414,7 +409,7 @@ public sealed class BSPrim : PhysicsActor
_velocity = value;
_scene.TaintedObject("BSPrim.setVelocity", delegate()
{
// DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity);
DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity);
BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity);
});
}
@@ -422,7 +417,7 @@ public sealed class BSPrim : PhysicsActor
public override OMV.Vector3 Torque {
get { return _torque; }
set { _torque = value;
// DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque);
DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque);
}
}
public override float CollisionScore {
@@ -449,7 +444,7 @@ public sealed class BSPrim : PhysicsActor
_scene.TaintedObject("BSPrim.setOrientation", delegate()
{
// _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
// DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
});
}
@@ -486,11 +481,8 @@ public sealed class BSPrim : PhysicsActor
// No locking here because only called when it is safe
private void SetObjectDynamic()
{
// RA: remove this for the moment.
// The problem is that dynamic objects are hulls so if we are becoming physical
// the shape has to be checked and possibly built.
// Maybe a VerifyCorrectPhysicalShape() routine?
// RecreateGeomAndObject();
// If it's becoming dynamic, it will need hullness
VerifyCorrectPhysicalShape();
// Bullet wants static objects to have a mass of zero
float mass = IsStatic ? 0f : _mass;
@@ -501,13 +493,15 @@ public sealed class BSPrim : PhysicsActor
_linkset.Refresh(this);
CollisionFlags cf = BulletSimAPI.GetCollisionFlags2(Body.Ptr);
// DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, cf);
DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, cf);
}
// prims don't fly
public override bool Flying {
get { return _flying; }
set { _flying = value; }
set {
_flying = value;
}
}
public override bool SetAlwaysRun {
get { return _setAlwaysRun; }
@@ -558,7 +552,7 @@ public sealed class BSPrim : PhysicsActor
// m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
_scene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
{
// DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity);
});
}
@@ -575,7 +569,7 @@ public sealed class BSPrim : PhysicsActor
_buoyancy = value;
_scene.TaintedObject("BSPrim.setBuoyancy", delegate()
{
// DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy);
});
}
@@ -638,17 +632,17 @@ public sealed class BSPrim : PhysicsActor
}
m_accumulatedForces.Clear();
}
// DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force);
DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force);
BulletSimAPI.AddObjectForce2(Body.Ptr, fSum);
});
}
public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
// DetailLog("{0},BSPrim.AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce);
DetailLog("{0},BSPrim.AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce);
// m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce);
}
public override void SetMomentum(OMV.Vector3 momentum) {
// DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum);
DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum);
}
public override void SubscribeEvents(int ms) {
_subscribedEventsMs = ms;
@@ -992,7 +986,7 @@ public sealed class BSPrim : PhysicsActor
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size);
if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE))
{
// DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild);
DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild);
_shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE;
// Bullet native objects are scaled by the Bullet engine so pass the size in
_scale = _size;
@@ -1006,7 +1000,7 @@ public sealed class BSPrim : PhysicsActor
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size);
if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX))
{
// DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild);
DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild);
_shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
_scale = _size;
// TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
@@ -1042,19 +1036,26 @@ public sealed class BSPrim : PhysicsActor
// No locking here because this is done when we know physics is not simulating
private void CreateGeomMesh()
{
float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD;
// level of detail based on size and type of the object
float lod = _scene.MeshLOD;
if (_pbs.SculptEntry)
lod = _scene.SculptLOD;
float maxAxis = Math.Max(_size.X, Math.Max(_size.Y, _size.Z));
if (maxAxis > _scene.MeshMegaPrimThreshold)
lod = _scene.MeshMegaPrimLOD;
ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod);
// m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey);
// if this new shape is the same as last time, don't recreate the mesh
if (_meshKey == newMeshKey) return;
// DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey);
DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey);
// Since we're recreating new, get rid of any previously generated shape
if (_meshKey != 0)
{
// m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey);
// DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey);
DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey);
BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey);
_mesh = null;
_meshKey = 0;
@@ -1084,7 +1085,7 @@ public sealed class BSPrim : PhysicsActor
_shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH;
// meshes are already scaled by the meshmerizer
_scale = new OMV.Vector3(1f, 1f, 1f);
// DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID);
DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID);
return;
}
@@ -1098,13 +1099,13 @@ public sealed class BSPrim : PhysicsActor
// if the hull hasn't changed, don't rebuild it
if (newHullKey == _hullKey) return;
// DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey);
DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey);
// Since we're recreating new, get rid of any previously generated shape
if (_hullKey != 0)
{
// m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey);
// DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey);
DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey);
BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey);
_hullKey = 0;
}
@@ -1198,7 +1199,7 @@ public sealed class BSPrim : PhysicsActor
_shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL;
// meshes are already scaled by the meshmerizer
_scale = new OMV.Vector3(1f, 1f, 1f);
// DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID);
DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID);
return;
}
@@ -1210,6 +1211,27 @@ public sealed class BSPrim : PhysicsActor
return;
}
private void VerifyCorrectPhysicalShape()
{
if (IsStatic)
{
// if static, we don't need a hull so, if there is one, rebuild without it
if (_hullKey != 0)
{
RecreateGeomAndObject();
}
}
else
{
// if not static, it will need a hull to efficiently collide with things
if (_hullKey == 0)
{
RecreateGeomAndObject();
}
}
}
// Create an object in Bullet if it has not already been created
// No locking here because this is done when the physics engine is not simulating
// Returns 'true' if an object was actually created.
@@ -1334,10 +1356,8 @@ public sealed class BSPrim : PhysicsActor
_acceleration = entprop.Acceleration;
_rotationalVelocity = entprop.RotationalVelocity;
// m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}, vel={5}, acc={6}, rvel={7}",
// LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
// DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
// LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
base.RequestPhysicsterseUpdate();
}
@@ -1353,6 +1373,7 @@ public sealed class BSPrim : PhysicsActor
}
// I've collided with something
// Called at taint time from within the Step() function
CollisionEventUpdate collisionCollection;
public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
{
@@ -1366,6 +1387,15 @@ public sealed class BSPrim : PhysicsActor
}
// DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith);
BSPrim collidingWithPrim;
if (_scene.Prims.TryGetValue(collidingWith, out collidingWithPrim))
{
// prims in the same linkset cannot collide with each other
if (this.Linkset.LinksetID == collidingWithPrim.Linkset.LinksetID)
{
return;
}
}
// if someone is subscribed to collision events....
if (_subscribedEventsMs != 0) {

View File

@@ -73,15 +73,22 @@ public class BSScene : PhysicsScene, IPhysicsParameters
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string LogHeader = "[BULLETS SCENE]";
public void DebugLog(string mm, params Object[] xx) { if (ShouldDebugLog) m_log.DebugFormat(mm, xx); }
// The name of the region we're working for.
public string RegionName { get; private set; }
public string BulletSimVersion = "?";
private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>();
public Dictionary<uint, BSCharacter> Characters { get { return m_avatars; } }
private Dictionary<uint, BSPrim> m_prims = new Dictionary<uint, BSPrim>();
public Dictionary<uint, BSPrim> Prims { get { return m_prims; } }
private HashSet<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>();
private HashSet<BSPrim> m_primsWithCollisions = new HashSet<BSPrim>();
private List<BSPrim> m_vehicles = new List<BSPrim>();
private float[] m_heightMap;
private float m_waterLevel;
private uint m_worldID;
@@ -95,16 +102,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
private int m_detailedStatsStep = 0;
public IMesher mesher;
private float m_meshLOD;
public float MeshLOD
{
get { return m_meshLOD; }
}
private float m_sculptLOD;
public float SculptLOD
{
get { return m_sculptLOD; }
}
// Level of Detail values kept as float because that's what the Meshmerizer wants
public float MeshLOD { get; private set; }
public float MeshMegaPrimLOD { get; private set; }
public float MeshMegaPrimThreshold { get; private set; }
public float SculptLOD { get; private set; }
private BulletSim m_worldSim;
public BulletSim World
@@ -179,8 +181,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
ConfigurationParameters[] m_params;
GCHandle m_paramsHandle;
public bool ShouldDebugLog { get; private set; }
// Handle to the callback used by the unmanaged code to call into the managed code.
// Used for debug logging.
// Need to store the handle in a persistant variable so it won't be freed.
private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle;
// Sometimes you just have to log everything.
@@ -196,6 +199,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
public BSScene(string identifier)
{
m_initialized = false;
// we are passed the name of the region we're working for.
RegionName = identifier;
}
public override void Initialise(IMesher meshmerizer, IConfigSource config)
@@ -281,10 +286,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
// Very detailed logging for physics debugging
m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false);
m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", ".");
m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-");
m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-");
m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5);
// Very detailed logging for vehicle debugging
m_vehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false);
// Do any replacements in the parameters
m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName);
}
}
}
@@ -362,7 +370,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
BSPrim bsprim = prim as BSPrim;
if (bsprim != null)
{
// DetailLog("{0},RemovePrim,call", bsprim.LocalID);
DetailLog("{0},RemovePrim,call", bsprim.LocalID);
// m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID);
try
{
@@ -388,7 +396,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
if (!m_initialized) return null;
// DetailLog("{0},AddPrimShape,call", localID);
DetailLog("{0},AddPrimShape,call", localID);
BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical);
lock (m_prims) m_prims.Add(localID, prim);
@@ -429,13 +437,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
{
numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep,
out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
// DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount);
DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount);
}
catch (Exception e)
{
m_log.WarnFormat("{0},PhysicsStep Exception: substeps={1}, updates={2}, colliders={3}, e={4}", LogHeader, numSubSteps, updatedEntityCount, collidersCount, e);
// DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount);
// updatedEntityCount = 0;
updatedEntityCount = 0;
collidersCount = 0;
}
@@ -534,6 +542,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
else if (m_avatars.ContainsKey(collidingWith))
type = ActorTypes.Agent;
// DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith);
BSPrim prim;
if (m_prims.TryGetValue(localID, out prim)) {
prim.Collide(collidingWith, type, collidePoint, collideNormal, penitration);
@@ -897,16 +907,26 @@ public class BSScene : PhysicsScene, IPhysicsParameters
(s) => { return s.NumericBool(s._forceSimplePrimMeshing); },
(s,p,l,v) => { s._forceSimplePrimMeshing = s.BoolNumeric(v); } ),
new ParameterDefn("MeshLOD", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)",
new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)",
8f,
(s,cf,p,v) => { s.m_meshLOD = cf.GetInt(p, (int)v); },
(s) => { return (float)s.m_meshLOD; },
(s,p,l,v) => { s.m_meshLOD = (int)v; } ),
new ParameterDefn("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)",
(s,cf,p,v) => { s.MeshLOD = (float)cf.GetInt(p, (int)v); },
(s) => { return s.MeshLOD; },
(s,p,l,v) => { s.MeshLOD = v; } ),
new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters",
16f,
(s,cf,p,v) => { s.MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); },
(s) => { return s.MeshMegaPrimLOD; },
(s,p,l,v) => { s.MeshMegaPrimLOD = v; } ),
new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD",
10f,
(s,cf,p,v) => { s.MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); },
(s) => { return s.MeshMegaPrimThreshold; },
(s,p,l,v) => { s.MeshMegaPrimThreshold = v; } ),
new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)",
32f,
(s,cf,p,v) => { s.m_sculptLOD = cf.GetInt(p, (int)v); },
(s) => { return (float)s.m_sculptLOD; },
(s,p,l,v) => { s.m_sculptLOD = (int)v; } ),
(s,cf,p,v) => { s.SculptLOD = (float)cf.GetInt(p, (int)v); },
(s) => { return s.SculptLOD; },
(s,p,l,v) => { s.SculptLOD = v; } ),
new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps",
10f,
@@ -1137,12 +1157,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
(s,cf,p,v) => { s.m_detailedStatsStep = cf.GetInt(p, (int)v); },
(s) => { return (float)s.m_detailedStatsStep; },
(s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ),
new ParameterDefn("ShouldDebugLog", "Enables detailed DEBUG log statements",
ConfigurationParameters.numericFalse,
(s,cf,p,v) => { s.ShouldDebugLog = cf.GetBoolean(p, s.BoolNumeric(v)); },
(s) => { return s.NumericBool(s.ShouldDebugLog); },
(s,p,l,v) => { s.ShouldDebugLog = s.BoolNumeric(v); } ),
};
// Convert a boolean to our numeric true and false values

View File

@@ -330,14 +330,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return key;
}
// convert a LSL_Rotation to a Quaternion
public static Quaternion Rot2Quaternion(LSL_Rotation r)
{
Quaternion q = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
q.Normalize();
return q;
}
//These are the implementations of the various ll-functions used by the LSL scripts.
public LSL_Float llSin(double f)
{
@@ -1097,9 +1089,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public LSL_Float llGround(LSL_Vector offset)
{
m_host.AddScriptLPS(1);
Vector3 pos = m_host.GetWorldPosition() + new Vector3((float)offset.x,
(float)offset.y,
(float)offset.z);
Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset;
//Get the slope normal. This gives us the equation of the plane tangent to the slope.
LSL_Vector vsn = llGroundNormal(offset);
@@ -1343,31 +1333,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (part == null || part.ParentGroup.IsDeleted)
return;
if (scale.x < 0.01)
scale.x = 0.01;
if (scale.y < 0.01)
scale.y = 0.01;
if (scale.z < 0.01)
scale.z = 0.01;
// First we need to check whether or not we need to clamp the size of a physics-enabled prim
PhysicsActor pa = part.ParentGroup.RootPart.PhysActor;
if (pa != null && pa.IsPhysical)
{
if (scale.x > World.m_maxPhys)
scale.x = World.m_maxPhys;
if (scale.y > World.m_maxPhys)
scale.y = World.m_maxPhys;
if (scale.z > World.m_maxPhys)
scale.z = World.m_maxPhys;
scale.x = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.x));
scale.y = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.y));
scale.z = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.z));
}
else
{
// If not physical, then we clamp the scale to the non-physical min/max
scale.x = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.x));
scale.y = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.y));
scale.z = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.z));
}
if (scale.x > World.m_maxNonphys)
scale.x = World.m_maxNonphys;
if (scale.y > World.m_maxNonphys)
scale.y = World.m_maxNonphys;
if (scale.z > World.m_maxNonphys)
scale.z = World.m_maxNonphys;
Vector3 tmp = part.Scale;
tmp.X = (float)scale.x;
@@ -1399,7 +1379,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (face == ScriptBaseClass.ALL_SIDES)
face = SceneObjectPart.ALL_SIDES;
m_host.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
m_host.SetFaceColorAlpha(face, color, null);
}
public void SetTexGen(SceneObjectPart part, int face,int style)
@@ -1986,7 +1966,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
bool sameParcel = here.GlobalID == there.GlobalID;
if (!sameParcel && !World.Permissions.CanRezObject(m_host.ParentGroup.PrimCount, m_host.ParentGroup.OwnerID, new Vector3((float)pos.x, (float)pos.y, (float)pos.z)))
if (!sameParcel && !World.Permissions.CanRezObject(
m_host.ParentGroup.PrimCount, m_host.ParentGroup.OwnerID, pos))
{
return 0;
}
@@ -2046,13 +2027,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
targetPos.z = ground;
SceneObjectGroup parent = part.ParentGroup;
LSL_Vector real_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos);
parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
parent.UpdateGroupPosition(!adjust ? targetPos :
SetPosAdjust(currentPos, targetPos));
}
else
{
LSL_Vector rel_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos);
part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
part.OffsetPosition = !adjust ? targetPos :
SetPosAdjust(currentPos, targetPos);
SceneObjectGroup parent = part.ParentGroup;
parent.HasGroupChanged = true;
parent.ScheduleGroupForTerseUpdate();
@@ -2096,7 +2077,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
return new LSL_Vector(pos.X, pos.Y, pos.Z);
return new LSL_Vector(pos);
}
public void llSetRot(LSL_Rotation rot)
@@ -2107,7 +2088,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (m_host.ParentID == 0)
{
// special case: If we are root, rotate complete SOG to new rotation
SetRot(m_host, Rot2Quaternion(rot));
SetRot(m_host, rot);
}
else
{
@@ -2115,7 +2096,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
SceneObjectPart rootPart = m_host.ParentGroup.RootPart;
if (rootPart != null) // better safe than sorry
{
SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot));
SetRot(m_host, rootPart.RotationOffset * (Quaternion)rot);
}
}
@@ -2125,7 +2106,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public void llSetLocalRot(LSL_Rotation rot)
{
m_host.AddScriptLPS(1);
SetRot(m_host, Rot2Quaternion(rot));
SetRot(m_host, rot);
ScriptSleep(200);
}
@@ -2210,7 +2191,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (local != 0)
force *= llGetRot();
m_host.ParentGroup.RootPart.SetForce(new Vector3((float)force.x, (float)force.y, (float)force.z));
m_host.ParentGroup.RootPart.SetForce(force);
}
}
@@ -2222,10 +2203,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (!m_host.ParentGroup.IsDeleted)
{
Vector3 tmpForce = m_host.ParentGroup.RootPart.GetForce();
force.x = tmpForce.X;
force.y = tmpForce.Y;
force.z = tmpForce.Z;
force = m_host.ParentGroup.RootPart.GetForce();
}
return force;
@@ -2234,8 +2212,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public LSL_Integer llTarget(LSL_Vector position, double range)
{
m_host.AddScriptLPS(1);
return m_host.ParentGroup.registerTargetWaypoint(
new Vector3((float)position.x, (float)position.y, (float)position.z), (float)range);
return m_host.ParentGroup.registerTargetWaypoint(position,
(float)range);
}
public void llTargetRemove(int number)
@@ -2247,8 +2225,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public LSL_Integer llRotTarget(LSL_Rotation rot, double error)
{
m_host.AddScriptLPS(1);
return m_host.ParentGroup.registerRotTargetWaypoint(
new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s), (float)error);
return m_host.ParentGroup.registerRotTargetWaypoint(rot, (float)error);
}
public void llRotTargetRemove(int number)
@@ -2260,7 +2237,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public void llMoveToTarget(LSL_Vector target, double tau)
{
m_host.AddScriptLPS(1);
m_host.MoveToTarget(new Vector3((float)target.x, (float)target.y, (float)target.z), (float)tau);
m_host.MoveToTarget(target, (float)tau);
}
public void llStopMoveToTarget()
@@ -2273,7 +2250,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
m_host.AddScriptLPS(1);
//No energy force yet
Vector3 v = new Vector3((float)force.x, (float)force.y, (float)force.z);
Vector3 v = force;
if (v.Length() > 20000.0f)
{
v.Normalize();
@@ -2285,13 +2262,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public void llApplyRotationalImpulse(LSL_Vector force, int local)
{
m_host.AddScriptLPS(1);
m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
m_host.ApplyAngularImpulse(force, local != 0);
}
public void llSetTorque(LSL_Vector torque, int local)
{
m_host.AddScriptLPS(1);
m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
m_host.SetAngularImpulse(torque, local != 0);
}
public LSL_Vector llGetTorque()
@@ -2842,13 +2819,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return;
}
Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z);
// need the magnitude later
// float velmag = (float)Util.GetMagnitude(llvel);
SceneObjectGroup new_group = World.RezObject(m_host, item, llpos, Rot2Quaternion(rot), llvel, param);
SceneObjectGroup new_group = World.RezObject(m_host, item, pos, rot, vel, param);
// If either of these are null, then there was an unknown error.
if (new_group == null)
@@ -2869,10 +2843,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
PhysicsActor pa = new_group.RootPart.PhysActor;
if (pa != null && pa.IsPhysical && llvel != Vector3.Zero)
if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
{
//Recoil.
llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0);
llApplyImpulse(vel * groupmass, 0);
}
// Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
});
@@ -2917,7 +2891,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
else
{
m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping);
m_host.StartLookAt(rot, (float)strength, (float)damping);
}
}
@@ -3312,7 +3286,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
else
{
m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
m_host.RotLookAt(target, (float)strength, (float)damping);
}
}
@@ -3393,7 +3367,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain)
{
part.UpdateAngularVelocity(new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate)));
part.UpdateAngularVelocity(axis * spinrate);
}
public LSL_Integer llGetStartParameter()
@@ -3600,7 +3574,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
List<SceneObjectPart> parts = GetLinkParts(linknumber);
foreach (SceneObjectPart part in parts)
part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
part.SetFaceColorAlpha(face, color, null);
}
public void llCreateLink(string target, int parent)
@@ -4031,9 +4005,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public void llSetText(string text, LSL_Vector color, double alpha)
{
m_host.AddScriptLPS(1);
Vector3 av3 = new Vector3(Util.Clip((float)color.x, 0.0f, 1.0f),
Util.Clip((float)color.y, 0.0f, 1.0f),
Util.Clip((float)color.z, 0.0f, 1.0f));
Vector3 av3 = Util.Clip(color, 0.0f, 1.0f);
m_host.SetText(text.Length > 254 ? text.Remove(254) : text, av3, Util.Clip((float)alpha, 0.0f, 1.0f));
//m_host.ParentGroup.HasGroupChanged = true;
//m_host.ParentGroup.ScheduleGroupForFullUpdate();
@@ -4230,14 +4202,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
ScriptSleep(5000);
}
public void llTeleportAgent(string agent, string destination, LSL_Vector pos, LSL_Vector lookAt)
public void llTeleportAgent(string agent, string destination, LSL_Vector targetPos, LSL_Vector targetLookAt)
{
m_host.AddScriptLPS(1);
UUID agentId = new UUID();
Vector3 targetPos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
Vector3 targetLookAt = new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z);
if (UUID.TryParse(agent, out agentId))
{
ScenePresence presence = World.GetScenePresence(agentId);
@@ -4266,15 +4235,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
}
public void llTeleportAgentGlobalCoords(string agent, LSL_Vector global_coords, LSL_Vector pos, LSL_Vector lookAt)
public void llTeleportAgentGlobalCoords(string agent, LSL_Vector global_coords, LSL_Vector targetPos, LSL_Vector targetLookAt)
{
m_host.AddScriptLPS(1);
UUID agentId = new UUID();
ulong regionHandle = Utils.UIntsToLong((uint)global_coords.x, (uint)global_coords.y);
Vector3 targetPos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
Vector3 targetLookAt = new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z);
if (UUID.TryParse(agent, out agentId))
{
ScenePresence presence = World.GetScenePresence(agentId);
@@ -4558,7 +4525,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
distance_attenuation = 1f / normalized_units;
}
Vector3 applied_linear_impulse = new Vector3((float)impulse.x, (float)impulse.y, (float)impulse.z);
Vector3 applied_linear_impulse = impulse;
{
float impulse_length = applied_linear_impulse.Length();
@@ -5198,25 +5165,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
/// separated list. There is a space after
/// each comma.
/// </summary>
public LSL_String llList2CSV(LSL_List src)
{
string ret = String.Empty;
int x = 0;
m_host.AddScriptLPS(1);
if (src.Data.Length > 0)
{
ret = src.Data[x++].ToString();
for (; x < src.Data.Length; x++)
{
ret += ", "+src.Data[x].ToString();
}
}
return ret;
return string.Join(", ",
(new List<object>(src.Data)).ConvertAll<string>(o =>
{
return o.ToString();
}).ToArray());
}
/// <summary>
@@ -5871,7 +5828,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
List<SceneObjectPart> parts = GetLinkParts(linknumber);
foreach (var part in parts)
foreach (SceneObjectPart part in parts)
{
SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
}
@@ -6057,9 +6014,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
//Plug the x,y coordinates of the slope normal into the equation of the plane to get
//the height of that point on the plane. The resulting vector gives the slope.
Vector3 vsl = new Vector3();
vsl.X = (float)vsn.x;
vsl.Y = (float)vsn.y;
Vector3 vsl = vsn;
vsl.Z = (float)(((vsn.x * vsn.x) + (vsn.y * vsn.y)) / (-1 * vsn.z));
vsl.Normalize();
//Normalization might be overkill here
@@ -6070,9 +6025,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public LSL_Vector llGroundNormal(LSL_Vector offset)
{
m_host.AddScriptLPS(1);
Vector3 pos = m_host.GetWorldPosition() + new Vector3((float)offset.x,
(float)offset.y,
(float)offset.z);
Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset;
// Clamp to valid position
if (pos.X < 0)
pos.X = 0;
@@ -6237,7 +6190,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
List<SceneObjectPart> parts = GetLinkParts(linknumber);
foreach (var part in parts)
foreach (SceneObjectPart part in parts)
{
SetParticleSystem(part, rules);
}
@@ -6525,8 +6478,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (!m_host.ParentGroup.IsDeleted)
{
m_host.ParentGroup.RootPart.SetVehicleVectorParam(param,
new Vector3((float)vec.x, (float)vec.y, (float)vec.z));
m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, vec);
}
}
@@ -6538,7 +6490,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (!m_host.ParentGroup.IsDeleted)
{
m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, Rot2Quaternion(rot));
m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, rot);
}
}
@@ -6564,12 +6516,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
{
// LSL quaternions can normalize to 0, normal Quaternions can't.
if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
rot.z = 1; // ZERO_ROTATION = 0,0,0,1
part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z);
part.SitTargetOrientation = Rot2Quaternion(rot);
part.SitTargetPosition = offset;
part.SitTargetOrientation = rot;
part.ParentGroup.HasGroupChanged = true;
}
@@ -6672,13 +6620,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public void llSetCameraEyeOffset(LSL_Vector offset)
{
m_host.AddScriptLPS(1);
m_host.SetCameraEyeOffset(new Vector3((float)offset.x, (float)offset.y, (float)offset.z));
m_host.SetCameraEyeOffset(offset);
}
public void llSetCameraAtOffset(LSL_Vector offset)
{
m_host.AddScriptLPS(1);
m_host.SetCameraAtOffset(new Vector3((float)offset.x, (float)offset.y, (float)offset.z));
m_host.SetCameraAtOffset(offset);
}
public LSL_String llDumpList2String(LSL_List src, string seperator)
@@ -6700,7 +6648,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public LSL_Integer llScriptDanger(LSL_Vector pos)
{
m_host.AddScriptLPS(1);
bool result = World.ScriptDanger(m_host.LocalId, new Vector3((float)pos.x, (float)pos.y, (float)pos.z));
bool result = World.ScriptDanger(m_host.LocalId, pos);
if (result)
{
return 1;
@@ -7260,7 +7208,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
m_host.AddScriptLPS(1);
setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules);
setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules, "llSetPrimitiveParams");
ScriptSleep(200);
}
@@ -7269,7 +7217,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
m_host.AddScriptLPS(1);
setLinkPrimParams(linknumber, rules);
setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
ScriptSleep(200);
}
@@ -7278,32 +7226,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
m_host.AddScriptLPS(1);
setLinkPrimParams(linknumber, rules);
setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
}
protected void setLinkPrimParams(int linknumber, LSL_List rules)
protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
{
List<SceneObjectPart> parts = GetLinkParts(linknumber);
LSL_List remaining = null;
uint rulesParsed = 0;
foreach (SceneObjectPart part in parts)
remaining = SetPrimParams(part, rules);
remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
while(remaining != null && remaining.Length > 2)
while (remaining != null && remaining.Length > 2)
{
linknumber = remaining.GetLSLIntegerItem(0);
rules = remaining.GetSublist(1,-1);
rules = remaining.GetSublist(1, -1);
parts = GetLinkParts(linknumber);
foreach (SceneObjectPart part in parts)
remaining = SetPrimParams(part, rules);
remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
}
}
protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules)
protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
{
int idx = 0;
int idxStart = 0;
bool positionChanged = false;
LSL_Vector currentPosition = GetPartLocalPos(part);
@@ -7312,9 +7262,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
while (idx < rules.Length)
{
++rulesParsed;
int code = rules.GetLSLIntegerItem(idx++);
int remain = rules.Length - idx;
idxStart = idx;
int face;
LSL_Vector v;
@@ -7348,13 +7300,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (part.ParentID == 0)
{
// special case: If we are root, rotate complete SOG to new rotation
SetRot(part, Rot2Quaternion(q));
SetRot(part, q);
}
else
{
// we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
SceneObjectPart rootPart = part.ParentGroup.RootPart;
SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q));
SetRot(part, rootPart.RotationOffset * (Quaternion)q);
}
break;
@@ -7528,8 +7480,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
LSL_Vector color=rules.GetVector3Item(idx++);
double alpha=(double)rules.GetLSLFloatItem(idx++);
part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
SetAlpha(part, alpha, face);
part.SetFaceColorAlpha(face, color, alpha);
break;
@@ -7647,9 +7598,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
string primText = rules.GetLSLStringItem(idx++);
LSL_Vector primTextColor = rules.GetVector3Item(idx++);
LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++);
Vector3 av3 = new Vector3(Util.Clip((float)primTextColor.x, 0.0f, 1.0f),
Util.Clip((float)primTextColor.y, 0.0f, 1.0f),
Util.Clip((float)primTextColor.z, 0.0f, 1.0f));
Vector3 av3 = Util.Clip(primTextColor, 0.0f, 1.0f);
part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f));
break;
@@ -7668,8 +7617,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
if (remain < 1)
return null;
LSL_Rotation lr = rules.GetQuaternionItem(idx++);
SetRot(part, Rot2Quaternion(lr));
SetRot(part, rules.GetQuaternionItem(idx++));
break;
case (int)ScriptBaseClass.PRIM_OMEGA:
if (remain < 3)
@@ -7679,6 +7627,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
LSL_Float gain = rules.GetLSLFloatItem(idx++);
TargetOmega(part, axis, (double)spinrate, (double)gain);
break;
case (int)ScriptBaseClass.PRIM_SLICE:
if (remain < 1)
return null;
LSL_Vector slice = rules.GetVector3Item(idx++);
part.UpdateSlice((float)slice.x, (float)slice.y);
break;
case (int)ScriptBaseClass.PRIM_LINK_TARGET:
if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
return null;
@@ -7687,6 +7641,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
}
}
catch (InvalidCastException e)
{
ShoutError(string.Format(
"{0} error running rule #{1}: arg #{2} ",
originFunc, rulesParsed, idx - idxStart) + e.Message);
}
finally
{
if (positionChanged)
@@ -7694,11 +7654,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (part.ParentGroup.RootPart == part)
{
SceneObjectGroup parent = part.ParentGroup;
parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
parent.UpdateGroupPosition(currentPosition);
}
else
{
part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
part.OffsetPosition = currentPosition;
SceneObjectGroup parent = part.ParentGroup;
parent.HasGroupChanged = true;
parent.ScheduleGroupForTerseUpdate();
@@ -7935,8 +7895,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (part != null)
{
Vector3 halfSize = part.Scale / 2.0f;
LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f);
LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z);
LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f;
LSL_Vector upper = new LSL_Vector(halfSize);
result.Add(lower);
result.Add(upper);
return result;
@@ -7956,7 +7916,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public LSL_List llGetPrimitiveParams(LSL_List rules)
{
m_host.AddScriptLPS(1);
return GetLinkPrimitiveParams(m_host, rules);
LSL_List result = new LSL_List();
LSL_List remaining = GetPrimParams(m_host, rules, ref result);
while (remaining != null && remaining.Length > 2)
{
int linknumber = remaining.GetLSLIntegerItem(0);
rules = remaining.GetSublist(1, -1);
List<SceneObjectPart> parts = GetLinkParts(linknumber);
foreach (SceneObjectPart part in parts)
remaining = GetPrimParams(part, rules, ref result);
}
return result;
}
public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
@@ -7966,19 +7941,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
List<SceneObjectPart> parts = GetLinkParts(linknumber);
LSL_List res = new LSL_List();
LSL_List remaining = null;
foreach (var part in parts)
foreach (SceneObjectPart part in parts)
{
LSL_List partRes = GetLinkPrimitiveParams(part, rules);
res += partRes;
remaining = GetPrimParams(part, rules, ref res);
}
while (remaining != null && remaining.Length > 2)
{
linknumber = remaining.GetLSLIntegerItem(0);
rules = remaining.GetSublist(1, -1);
parts = GetLinkParts(linknumber);
foreach (SceneObjectPart part in parts)
remaining = GetPrimParams(part, rules, ref res);
}
return res;
}
public LSL_List GetLinkPrimitiveParams(SceneObjectPart part, LSL_List rules)
public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res)
{
LSL_List res = new LSL_List();
int idx=0;
while (idx < rules.Length)
{
@@ -8123,7 +8107,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TEXTURE:
if (remain < 1)
return res;
return null;
int face = (int)rules.GetLSLIntegerItem(idx++);
Primitive.TextureEntry tex = part.Shape.Textures;
@@ -8163,7 +8147,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_COLOR:
if (remain < 1)
return res;
return null;
face=(int)rules.GetLSLIntegerItem(idx++);
@@ -8192,7 +8176,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
if (remain < 1)
return res;
return null;
face=(int)rules.GetLSLIntegerItem(idx++);
@@ -8223,7 +8207,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
if (remain < 1)
return res;
return null;
face=(int)rules.GetLSLIntegerItem(idx++);
@@ -8265,7 +8249,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TEXGEN:
if (remain < 1)
return res;
return null;
face=(int)rules.GetLSLIntegerItem(idx++);
@@ -8306,7 +8290,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_GLOW:
if (remain < 1)
return res;
return null;
face=(int)rules.GetLSLIntegerItem(idx++);
@@ -8349,9 +8333,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_POS_LOCAL:
res.Add(new LSL_Vector(GetPartLocalPos(part)));
break;
case (int)ScriptBaseClass.PRIM_SLICE:
PrimType prim_type = part.GetPrimType();
bool useProfileBeginEnd = (prim_type == PrimType.SPHERE || prim_type == PrimType.TORUS || prim_type == PrimType.TUBE || prim_type == PrimType.RING);
res.Add(new LSL_Vector(
(useProfileBeginEnd ? part.Shape.ProfileBegin : part.Shape.PathBegin) / 50000.0,
1 - (useProfileBeginEnd ? part.Shape.ProfileEnd : part.Shape.PathEnd) / 50000.0,
0
));
break;
case (int)ScriptBaseClass.PRIM_LINK_TARGET:
if(remain < 3)
return null;
return rules.GetSublist(idx, -1);
}
}
return res;
return null;
}
public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
@@ -9937,9 +9936,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
if (avatar != null)
{
avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, simname,
new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
simname, pos, lookAt);
}
ScriptSleep(1000);
}
@@ -10121,31 +10119,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public LSL_Float llListStatistics(int operation, LSL_List src)
{
m_host.AddScriptLPS(1);
LSL_List nums = LSL_List.ToDoubleList(src);
switch (operation)
{
case ScriptBaseClass.LIST_STAT_RANGE:
return nums.Range();
return src.Range();
case ScriptBaseClass.LIST_STAT_MIN:
return nums.Min();
return src.Min();
case ScriptBaseClass.LIST_STAT_MAX:
return nums.Max();
return src.Max();
case ScriptBaseClass.LIST_STAT_MEAN:
return nums.Mean();
return src.Mean();
case ScriptBaseClass.LIST_STAT_MEDIAN:
return nums.Median();
return LSL_List.ToDoubleList(src).Median();
case ScriptBaseClass.LIST_STAT_NUM_COUNT:
return nums.NumericLength();
return src.NumericLength();
case ScriptBaseClass.LIST_STAT_STD_DEV:
return nums.StdDev();
return src.StdDev();
case ScriptBaseClass.LIST_STAT_SUM:
return nums.Sum();
return src.Sum();
case ScriptBaseClass.LIST_STAT_SUM_SQUARES:
return nums.SumSqrs();
return src.SumSqrs();
case ScriptBaseClass.LIST_STAT_GEOMETRIC_MEAN:
return nums.GeometricMean();
return src.GeometricMean();
case ScriptBaseClass.LIST_STAT_HARMONIC_MEAN:
return nums.HarmonicMean();
return src.HarmonicMean();
default:
return 0.0;
}
@@ -10546,12 +10543,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
else
rot = obj.GetWorldRotation();
LSL_Rotation objrot = new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
LSL_Rotation objrot = new LSL_Rotation(rot);
ret.Add(objrot);
}
break;
case ScriptBaseClass.OBJECT_VELOCITY:
ret.Add(new LSL_Vector(obj.Velocity.X, obj.Velocity.Y, obj.Velocity.Z));
ret.Add(new LSL_Vector(obj.Velocity));
break;
case ScriptBaseClass.OBJECT_OWNER:
ret.Add(new LSL_String(obj.OwnerID.ToString()));
@@ -10769,7 +10766,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return tid.ToString();
}
public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules)
public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc)
{
SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
if (obj == null)
@@ -10778,28 +10775,41 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (obj.OwnerID != m_host.OwnerID)
return;
LSL_List remaining = SetPrimParams(obj, rules);
uint rulesParsed = 0;
LSL_List remaining = SetPrimParams(obj, rules, originFunc, ref rulesParsed);
while ((object)remaining != null && remaining.Length > 2)
{
LSL_Integer newLink = remaining.GetLSLIntegerItem(0);
LSL_List newrules = remaining.GetSublist(1, -1);
foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){
remaining = SetPrimParams(part, newrules);
remaining = SetPrimParams(part, newrules, originFunc, ref rulesParsed);
}
}
}
public LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules)
public LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules)
{
SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
if (obj == null)
return new LSL_List();
if (obj.OwnerID != m_host.OwnerID)
return new LSL_List();
LSL_List result = new LSL_List();
return GetLinkPrimitiveParams(obj, rules);
if (obj != null && obj.OwnerID != m_host.OwnerID)
{
LSL_List remaining = GetPrimParams(obj, rules, ref result);
while (remaining != null && remaining.Length > 2)
{
int linknumber = remaining.GetLSLIntegerItem(0);
rules = remaining.GetSublist(1, -1);
List<SceneObjectPart> parts = GetLinkParts(linknumber);
foreach (SceneObjectPart part in parts)
remaining = GetPrimParams(part, rules, ref result);
}
}
return result;
}
public void print(string str)
@@ -11137,8 +11147,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.AddScriptLPS(1);
Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z);
Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z);
Vector3 rayStart = start;
Vector3 rayEnd = end;
Vector3 dir = rayEnd - rayStart;
float dist = Vector3.Mag(dir);

View File

@@ -304,7 +304,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY:
idx++;
iV = rules.GetVector3Item(idx);
wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
wl.cloudDetailXYDensity = iV;
break;
case (int)ScriptBaseClass.WL_CLOUD_SCALE:
idx++;
@@ -329,7 +329,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY:
idx++;
iV = rules.GetVector3Item(idx);
wl.cloudXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
wl.cloudXYDensity = iV;
break;
case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER:
idx++;
@@ -384,7 +384,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE:
idx++;
iV = rules.GetVector3Item(idx);
wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
wl.reflectionWaveletScale = iV;
break;
case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE:
idx++;
@@ -422,7 +422,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.WL_WATER_COLOR:
idx++;
iV = rules.GetVector3Item(idx);
wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
wl.waterColor = iV;
break;
case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT:
idx++;

View File

@@ -333,8 +333,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
if (type == typeof(OpenMetaverse.Quaternion))
{
LSL_Rotation rot = (LSL_Rotation)lslparm;
return new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s);
return (OpenMetaverse.Quaternion)((LSL_Rotation)lslparm);
}
}
@@ -343,8 +342,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
if (type == typeof(OpenMetaverse.Vector3))
{
LSL_Vector vect = (LSL_Vector)lslparm;
return new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z);
return (OpenMetaverse.Vector3)((LSL_Vector)lslparm);
}
}
@@ -367,13 +365,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
result[i] = new UUID((LSL_Key)plist[i]);
else if (plist[i] is LSL_Rotation)
{
LSL_Rotation rot = (LSL_Rotation)plist[i];
result[i] = new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s);
result[i] = (OpenMetaverse.Quaternion)(
(LSL_Rotation)plist[i]);
}
else if (plist[i] is LSL_Vector)
{
LSL_Vector vect = (LSL_Vector)plist[i];
result[i] = new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z);
result[i] = (OpenMetaverse.Vector3)(
(LSL_Vector)plist[i]);
}
else
MODError("unknown LSL list element type");

View File

@@ -140,12 +140,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
internal float m_ScriptDistanceFactor = 1.0f;
internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
protected IUrlModule m_UrlModule = null;
public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
{
m_ScriptEngine = ScriptEngine;
m_host = host;
m_item = item;
m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
m_OSFunctionsEnabled = true;
@@ -773,10 +777,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// We will launch the teleport on a new thread so that when the script threads are terminated
// before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
Util.FireAndForget(
o => World.RequestTeleportLocation(presence.ControllingClient, regionName,
new Vector3((float)position.x, (float)position.y, (float)position.z),
new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation));
Util.FireAndForget(o => World.RequestTeleportLocation(
presence.ControllingClient, regionName, position,
lookat, (uint)TPFlags.ViaLocation));
ScriptSleep(5000);
@@ -819,10 +822,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// We will launch the teleport on a new thread so that when the script threads are terminated
// before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
Util.FireAndForget(
o => World.RequestTeleportLocation(presence.ControllingClient, regionHandle,
new Vector3((float)position.x, (float)position.y, (float)position.z),
new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation));
Util.FireAndForget(o => World.RequestTeleportLocation(
presence.ControllingClient, regionHandle,
position, lookat, (uint)TPFlags.ViaLocation));
ScriptSleep(5000);
@@ -2248,11 +2250,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
CheckThreatLevel(ThreatLevel.High, "osGetLinkPrimitiveParams");
m_host.AddScriptLPS(1);
InitLSL();
// One needs to cast m_LSL_Api because we're using functions not
// on the ILSL_Api interface.
LSL_Api LSL_Api = (LSL_Api)m_LSL_Api;
LSL_List retVal = new LSL_List();
List<SceneObjectPart> parts = ((LSL_Api)m_LSL_Api).GetLinkParts(linknumber);
LSL_List remaining = null;
List<SceneObjectPart> parts = LSL_Api.GetLinkParts(linknumber);
foreach (SceneObjectPart part in parts)
{
retVal += ((LSL_Api)m_LSL_Api).GetLinkPrimitiveParams(part, rules);
remaining = LSL_Api.GetPrimParams(part, rules, ref retVal);
}
while (remaining != null && remaining.Length > 2)
{
linknumber = remaining.GetLSLIntegerItem(0);
rules = remaining.GetSublist(1, -1);
parts = LSL_Api.GetLinkParts(linknumber);
foreach (SceneObjectPart part in parts)
remaining = LSL_Api.GetPrimParams(part, rules, ref retVal);
}
return retVal;
}
@@ -2329,7 +2345,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
ownerID = m_host.OwnerID;
UUID x = module.CreateNPC(firstname,
lastname,
new Vector3((float) position.x, (float) position.y, (float) position.z),
position,
ownerID,
senseAsAgent,
World,
@@ -2446,7 +2462,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return new LSL_Vector(0, 0, 0);
}
public void osNpcMoveTo(LSL_Key npc, LSL_Vector position)
public void osNpcMoveTo(LSL_Key npc, LSL_Vector pos)
{
CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo");
m_host.AddScriptLPS(1);
@@ -2461,7 +2477,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (!module.CheckPermissions(npcId, m_host.OwnerID))
return;
Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z);
module.MoveToTarget(npcId, World, pos, false, true, false);
}
}
@@ -2481,11 +2496,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (!module.CheckPermissions(npcId, m_host.OwnerID))
return;
Vector3 pos = new Vector3((float)target.x, (float)target.y, (float)target.z);
module.MoveToTarget(
new UUID(npc.m_string),
World,
pos,
target,
(options & ScriptBaseClass.OS_NPC_NO_FLY) != 0,
(options & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0,
(options & ScriptBaseClass.OS_NPC_RUNNING) != 0);
@@ -2537,7 +2551,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
ScenePresence sp = World.GetScenePresence(npcId);
if (sp != null)
sp.Rotation = LSL_Api.Rot2Quaternion(rotation);
sp.Rotation = rotation;
}
}
@@ -2881,7 +2895,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
avatar.SpeedModifier = (float)SpeedModifier;
}
public void osKickAvatar(string FirstName,string SurName,string alert)
public void osKickAvatar(string FirstName, string SurName, string alert)
{
CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar");
m_host.AddScriptLPS(1);
@@ -2895,10 +2909,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
sp.ControllingClient.Kick(alert);
// ...and close on our side
sp.Scene.IncomingCloseAgent(sp.UUID);
sp.Scene.IncomingCloseAgent(sp.UUID, false);
}
});
}
public LSL_Float osGetHealth(string avatar)
{
CheckThreatLevel(ThreatLevel.None, "osGetHealth");
m_host.AddScriptLPS(1);
LSL_Float health = new LSL_Float(-1);
ScenePresence presence = World.GetScenePresence(new UUID(avatar));
if (presence != null) health = presence.Health;
return health;
}
public void osCauseDamage(string avatar, double damage)
{
@@ -2958,7 +2983,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.AddScriptLPS(1);
InitLSL();
return m_LSL_Api.GetLinkPrimitiveParamsEx(prim, rules);
return m_LSL_Api.GetPrimitiveParamsEx(prim, rules);
}
public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules)
@@ -2967,7 +2992,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.AddScriptLPS(1);
InitLSL();
m_LSL_Api.SetPrimitiveParamsEx(prim, rules);
m_LSL_Api.SetPrimitiveParamsEx(prim, rules, "osSetPrimitiveParams");
}
/// <summary>
@@ -3337,5 +3362,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return new LSL_Key(m_host.ParentGroup.FromPartID.ToString());
}
}
/// <summary>
/// Sets the response type for an HTTP request/response
/// </summary>
/// <returns></returns>
public void osSetContentType(LSL_Key id, string type)
{
CheckThreatLevel(ThreatLevel.High,"osSetResponseType");
if (m_UrlModule != null)
m_UrlModule.HttpContentType(new UUID(id),type);
}
}
}

View File

@@ -351,7 +351,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
q = avatar.Rotation * q;
}
LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
@@ -428,9 +428,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
try
{
Vector3 diff = toRegionPos - fromRegionPos;
LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z);
double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir);
double mag_obj = LSL_Types.Vector3.Mag(obj_dir);
double dot = LSL_Types.Vector3.Dot(forward_dir, diff);
double mag_obj = LSL_Types.Vector3.Mag(diff);
ang_obj = Math.Acos(dot / (mag_fwd * mag_obj));
}
catch
@@ -479,7 +478,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
q = avatar.Rotation * q;
}
LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0);
@@ -560,8 +559,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
double ang_obj = 0;
try
{
Vector3 diff = toRegionPos - fromRegionPos;
LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z);
LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(
toRegionPos - fromRegionPos);
double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir);
double mag_obj = LSL_Types.Vector3.Mag(obj_dir);
ang_obj = Math.Acos(dot / (mag_fwd * mag_obj));

View File

@@ -424,7 +424,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
LSL_String llXorBase64StringsCorrect(string str1, string str2);
void print(string str);
void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc);
LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
}
}

View File

@@ -40,16 +40,75 @@ using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
{
/// <summary>
/// To permit region owners to enable the extended scripting functionality
/// of OSSL, without allowing malicious scripts to access potentially
/// troublesome functions, each OSSL function is assigned a threat level,
/// and access to the functions is granted or denied based on a default
/// threshold set in OpenSim.ini (which can be overridden for individual
/// functions on a case-by-case basis)
/// </summary>
public enum ThreatLevel
{
// Not documented, presumably means permanently disabled ?
NoAccess = -1,
/// <summary>
/// Function is no threat at all. It doesn't constitute a threat to
/// either users or the system and has no known side effects.
/// </summary>
None = 0,
/// <summary>
/// Abuse of this command can cause a nuisance to the region operator,
/// such as log message spew.
/// </summary>
Nuisance = 1,
/// <summary>
/// Extreme levels of abuse of this function can cause impaired
/// functioning of the region, or very gullible users can be tricked
/// into experiencing harmless effects.
/// </summary>
VeryLow = 2,
/// <summary>
/// Intentional abuse can cause crashes or malfunction under certain
/// circumstances, which can be easily rectified; or certain users can
/// be tricked into certain situations in an avoidable manner.
/// </summary>
Low = 3,
/// <summary>
/// Intentional abuse can cause denial of service and crashes with
/// potential of data or state loss; or trusting users can be tricked
/// into embarrassing or uncomfortable situations.
/// </summary>
Moderate = 4,
/// <summary>
/// Casual abuse can cause impaired functionality or temporary denial
/// of service conditions. Intentional abuse can easily cause crashes
/// with potential data loss, or can be used to trick experienced and
/// cautious users into unwanted situations, or changes global data
/// permanently and without undo ability.
/// </summary>
High = 5,
/// <summary>
/// Even normal use may, depending on the number of instances, or
/// frequency of use, result in severe service impairment or crash
/// with loss of data, or can be used to cause unwanted or harmful
/// effects on users without giving the user a means to avoid it.
/// </summary>
VeryHigh = 6,
/// <summary>
/// Even casual use is a danger to region stability, or function allows
/// console or OS command execution, or function allows taking money
/// without consent, or allows deletion or modification of user data,
/// or allows the compromise of sensitive data by design.
/// </summary>
Severe = 7
};
@@ -258,6 +317,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
int osGetSimulatorMemory();
void osKickAvatar(string FirstName,string SurName,string alert);
void osSetSpeed(string UUID, LSL_Float SpeedModifier);
LSL_Float osGetHealth(string avatar);
void osCauseHealing(string avatar, double healing);
void osCauseDamage(string avatar, double damage);
LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules);
@@ -305,5 +365,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
/// </summary>
/// <returns>Rezzing object key or NULL_KEY if rezzed by agent or otherwise unknown.</returns>
LSL_Key osGetRezzingObject();
/// <summary>
/// Sets the response type for an HTTP request/response
/// </summary>
/// <returns></returns>
void osSetContentType(LSL_Key id, string type);
}
}

View File

@@ -328,6 +328,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public const int PRIM_OMEGA = 32;
public const int PRIM_POS_LOCAL = 33;
public const int PRIM_LINK_TARGET = 34;
public const int PRIM_SLICE = 35;
public const int PRIM_TEXGEN_DEFAULT = 0;
public const int PRIM_TEXGEN_PLANAR = 1;

View File

@@ -865,7 +865,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
{
m_OSSL_Functions.osSetSpeed(UUID, SpeedModifier);
}
public LSL_Float osGetHealth(string avatar)
{
return m_OSSL_Functions.osGetHealth(avatar);
}
public void osCauseDamage(string avatar, double damage)
{
m_OSSL_Functions.osCauseDamage(avatar, damage);
@@ -950,5 +955,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
{
return m_OSSL_Functions.osGetRezzingObject();
}
public void osSetContentType(LSL_Key id, string type)
{
m_OSSL_Functions.osSetContentType(id,type);
}
}
}

View File

@@ -546,6 +546,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
"OpenSim.Region.ScriptEngine.Shared.dll"));
parameters.ReferencedAssemblies.Add(Path.Combine(rootPath,
"OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll"));
parameters.ReferencedAssemblies.Add(Path.Combine(rootPath,
"OpenMetaverseTypes.dll"));
if (lang == enumCompileType.yp)
{

View File

@@ -160,11 +160,11 @@ namespace OpenSim.Region.ScriptEngine.Shared
else
{
// Set the values from the touch data provided by the client
touchST = new LSL_Types.Vector3(value.STCoord.X, value.STCoord.Y, value.STCoord.Z);
touchUV = new LSL_Types.Vector3(value.UVCoord.X, value.UVCoord.Y, value.UVCoord.Z);
touchNormal = new LSL_Types.Vector3(value.Normal.X, value.Normal.Y, value.Normal.Z);
touchBinormal = new LSL_Types.Vector3(value.Binormal.X, value.Binormal.Y, value.Binormal.Z);
touchPos = new LSL_Types.Vector3(value.Position.X, value.Position.Y, value.Position.Z);
touchST = new LSL_Types.Vector3(value.STCoord);
touchUV = new LSL_Types.Vector3(value.UVCoord);
touchNormal = new LSL_Types.Vector3(value.Normal);
touchBinormal = new LSL_Types.Vector3(value.Binormal);
touchPos = new LSL_Types.Vector3(value.Position);
touchFace = value.FaceIndex;
}
}
@@ -181,19 +181,13 @@ namespace OpenSim.Region.ScriptEngine.Shared
Name = presence.Firstname + " " + presence.Lastname;
Owner = Key;
Position = new LSL_Types.Vector3(
presence.AbsolutePosition.X,
presence.AbsolutePosition.Y,
presence.AbsolutePosition.Z);
Position = new LSL_Types.Vector3(presence.AbsolutePosition);
Rotation = new LSL_Types.Quaternion(
presence.Rotation.X,
presence.Rotation.Y,
presence.Rotation.Z,
presence.Rotation.W);
Velocity = new LSL_Types.Vector3(
presence.Velocity.X,
presence.Velocity.Y,
presence.Velocity.Z);
Velocity = new LSL_Types.Vector3(presence.Velocity);
if (presence.PresenceType != PresenceType.Npc)
{
@@ -241,16 +235,12 @@ namespace OpenSim.Region.ScriptEngine.Shared
}
}
Position = new LSL_Types.Vector3(part.AbsolutePosition.X,
part.AbsolutePosition.Y,
part.AbsolutePosition.Z);
Position = new LSL_Types.Vector3(part.AbsolutePosition);
Quaternion wr = part.ParentGroup.GroupRotation;
Rotation = new LSL_Types.Quaternion(wr.X, wr.Y, wr.Z, wr.W);
Velocity = new LSL_Types.Vector3(part.Velocity.X,
part.Velocity.Y,
part.Velocity.Z);
Velocity = new LSL_Types.Vector3(part.Velocity);
}
}

View File

@@ -31,6 +31,11 @@ using System.Globalization;
using System.Text.RegularExpressions;
using OpenSim.Framework;
using OpenMetaverse;
using OMV_Vector3 = OpenMetaverse.Vector3;
using OMV_Vector3d = OpenMetaverse.Vector3d;
using OMV_Quaternion = OpenMetaverse.Quaternion;
namespace OpenSim.Region.ScriptEngine.Shared
{
[Serializable]
@@ -54,6 +59,20 @@ namespace OpenSim.Region.ScriptEngine.Shared
z = (float)vector.z;
}
public Vector3(OMV_Vector3 vector)
{
x = vector.X;
y = vector.Y;
z = vector.Z;
}
public Vector3(OMV_Vector3d vector)
{
x = vector.X;
y = vector.Y;
z = vector.Z;
}
public Vector3(double X, double Y, double Z)
{
x = X;
@@ -109,6 +128,26 @@ namespace OpenSim.Region.ScriptEngine.Shared
return new list(new object[] { vec });
}
public static implicit operator OMV_Vector3(Vector3 vec)
{
return new OMV_Vector3((float)vec.x, (float)vec.y, (float)vec.z);
}
public static implicit operator Vector3(OMV_Vector3 vec)
{
return new Vector3(vec);
}
public static implicit operator OMV_Vector3d(Vector3 vec)
{
return new OMV_Vector3d(vec.x, vec.y, vec.z);
}
public static implicit operator Vector3(OMV_Vector3d vec)
{
return new Vector3(vec);
}
public static bool operator ==(Vector3 lhs, Vector3 rhs)
{
return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z);
@@ -322,6 +361,14 @@ namespace OpenSim.Region.ScriptEngine.Shared
s = 1;
}
public Quaternion(OMV_Quaternion rot)
{
x = rot.X;
y = rot.Y;
z = rot.Z;
s = rot.W;
}
#endregion
#region Overriders
@@ -368,6 +415,21 @@ namespace OpenSim.Region.ScriptEngine.Shared
return new list(new object[] { r });
}
public static implicit operator OMV_Quaternion(Quaternion rot)
{
// LSL quaternions can normalize to 0, normal Quaternions can't.
if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
rot.z = 1; // ZERO_ROTATION = 0,0,0,1
OMV_Quaternion omvrot = new OMV_Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
omvrot.Normalize();
return omvrot;
}
public static implicit operator Quaternion(OMV_Quaternion rot)
{
return new Quaternion(rot);
}
public static bool operator ==(Quaternion lhs, Quaternion rhs)
{
// Return true if the fields match:
@@ -560,12 +622,23 @@ namespace OpenSim.Region.ScriptEngine.Shared
else if (m_data[itemIndex] is LSL_Types.LSLString)
return new LSLInteger(m_data[itemIndex].ToString());
else
throw new InvalidCastException();
throw new InvalidCastException(string.Format(
"{0} expected but {1} given",
typeof(LSL_Types.LSLInteger).Name,
m_data[itemIndex] != null ?
m_data[itemIndex].GetType().Name : "null"));
}
public LSL_Types.Vector3 GetVector3Item(int itemIndex)
{
return (LSL_Types.Vector3)m_data[itemIndex];
if(m_data[itemIndex] is LSL_Types.Vector3)
return (LSL_Types.Vector3)m_data[itemIndex];
else
throw new InvalidCastException(string.Format(
"{0} expected but {1} given",
typeof(LSL_Types.Vector3).Name,
m_data[itemIndex] != null ?
m_data[itemIndex].GetType().Name : "null"));
}
public LSL_Types.Quaternion GetQuaternionItem(int itemIndex)
@@ -1064,7 +1137,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
{
list ret = new list();
double entry;
for (int i = 0; i < src.Data.Length - 1; i++)
for (int i = 0; i < src.Data.Length; i++)
{
if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
{

View File

@@ -152,9 +152,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
det[0] = new DetectParams();
det[0].Key = remoteClient.AgentId;
det[0].Populate(myScriptEngine.World);
det[0].OffsetPos = new LSL_Types.Vector3(offsetPos.X,
offsetPos.Y,
offsetPos.Z);
det[0].OffsetPos = offsetPos;
if (originalID == 0)
{
@@ -298,9 +296,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
foreach (DetectedObject detobj in col.Colliders)
{
DetectParams d = new DetectParams();
d.Position = new LSL_Types.Vector3(detobj.posVector.X,
detobj.posVector.Y,
detobj.posVector.Z);
d.Position = detobj.posVector;
d.Populate(myScriptEngine.World);
det.Add(d);
myScriptEngine.PostObjectEvent(localID, new EventParams(
@@ -318,9 +314,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
foreach (DetectedObject detobj in col.Colliders)
{
DetectParams d = new DetectParams();
d.Position = new LSL_Types.Vector3(detobj.posVector.X,
detobj.posVector.Y,
detobj.posVector.Z);
d.Position = detobj.posVector;
d.Populate(myScriptEngine.World);
det.Add(d);
myScriptEngine.PostObjectEvent(localID, new EventParams(
@@ -337,9 +331,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
foreach (DetectedObject detobj in col.Colliders)
{
DetectParams d = new DetectParams();
d.Position = new LSL_Types.Vector3(detobj.posVector.X,
detobj.posVector.Y,
detobj.posVector.Z);
d.Position = detobj.posVector;
d.Populate(myScriptEngine.World);
det.Add(d);
myScriptEngine.PostObjectEvent(localID, new EventParams(
@@ -381,8 +373,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
myScriptEngine.PostObjectEvent(localID, new EventParams(
"at_target", new object[] {
new LSL_Types.LSLInteger(handle),
new LSL_Types.Vector3(targetpos.X,targetpos.Y,targetpos.Z),
new LSL_Types.Vector3(atpos.X,atpos.Y,atpos.Z) },
new LSL_Types.Vector3(targetpos),
new LSL_Types.Vector3(atpos) },
new DetectParams[0]));
}
@@ -399,8 +391,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
myScriptEngine.PostObjectEvent(localID, new EventParams(
"at_rot_target", new object[] {
new LSL_Types.LSLInteger(handle),
new LSL_Types.Quaternion(targetrot.X,targetrot.Y,targetrot.Z,targetrot.W),
new LSL_Types.Quaternion(atrot.X,atrot.Y,atrot.Z,atrot.W) },
new LSL_Types.Quaternion(targetrot),
new LSL_Types.Quaternion(atrot) },
new DetectParams[0]));
}

View File

@@ -589,7 +589,19 @@ namespace OpenSim.Region.ScriptEngine.XEngine
if (m_Assemblies.ContainsKey(instance.AssetID))
{
string assembly = m_Assemblies[instance.AssetID];
instance.SaveState(assembly);
try
{
instance.SaveState(assembly);
}
catch (Exception e)
{
m_log.Error(
string.Format(
"[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
, e);
}
}
// Clear the event queue and abort the instance thread
@@ -707,7 +719,18 @@ namespace OpenSim.Region.ScriptEngine.XEngine
assembly = m_Assemblies[i.AssetID];
}
i.SaveState(assembly);
try
{
i.SaveState(assembly);
}
catch (Exception e)
{
m_log.Error(
string.Format(
"[XEngine]: Failed to save state of script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
i.PrimName, i.ScriptName, i.ItemID, i.ObjectID, World.Name)
, e);
}
}
instances.Clear();
@@ -900,6 +923,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
// This delay exists to stop mono problems where script compilation and startup would stop the sim
// working properly for the session.
System.Threading.Thread.Sleep(m_StartDelay);
m_log.InfoFormat("[XEngine]: Performing initial script startup on {0}", m_Scene.Name);
}
object[] o;
@@ -915,13 +940,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
if (m_InitialStartup)
if (scriptsStarted % 50 == 0)
m_log.InfoFormat(
"[XEngine]: Started {0} scripts in {1}", scriptsStarted, m_Scene.RegionInfo.RegionName);
"[XEngine]: Started {0} scripts in {1}", scriptsStarted, m_Scene.Name);
}
}
if (m_InitialStartup)
m_log.InfoFormat(
"[XEngine]: Completed starting {0} scripts on {1}", scriptsStarted, m_Scene.RegionInfo.RegionName);
"[XEngine]: Completed starting {0} scripts on {1}", scriptsStarted, m_Scene.Name);
// NOTE: Despite having a lockless queue, this lock is required
// to make sure there is never no compile thread while there
@@ -982,10 +1007,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
return false;
}
UUID assetID = item.AssetID;
m_log.DebugFormat(
"[XEngine] Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
//m_log.DebugFormat("[XEngine] Compiling script {0} ({1} on object {2})",
// item.Name, itemID.ToString(), part.ParentGroup.RootPart.Name);
UUID assetID = item.AssetID;
ScenePresence presence = m_Scene.GetScenePresence(item.OwnerID);
@@ -1164,10 +1191,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
stateSource, m_MaxScriptQueue);
// if (DebugLevel >= 1)
m_log.DebugFormat(
"[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
// m_log.DebugFormat(
// "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
// part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
if (presence != null)
{
@@ -1465,9 +1492,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
else if (p[i] is string)
lsl_p[i] = new LSL_Types.LSLString((string)p[i]);
else if (p[i] is Vector3)
lsl_p[i] = new LSL_Types.Vector3(((Vector3)p[i]).X, ((Vector3)p[i]).Y, ((Vector3)p[i]).Z);
lsl_p[i] = new LSL_Types.Vector3((Vector3)p[i]);
else if (p[i] is Quaternion)
lsl_p[i] = new LSL_Types.Quaternion(((Quaternion)p[i]).X, ((Quaternion)p[i]).Y, ((Quaternion)p[i]).Z, ((Quaternion)p[i]).W);
lsl_p[i] = new LSL_Types.Quaternion((Quaternion)p[i]);
else if (p[i] is float)
lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]);
else
@@ -1491,9 +1518,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
else if (p[i] is string)
lsl_p[i] = new LSL_Types.LSLString((string)p[i]);
else if (p[i] is Vector3)
lsl_p[i] = new LSL_Types.Vector3(((Vector3)p[i]).X, ((Vector3)p[i]).Y, ((Vector3)p[i]).Z);
lsl_p[i] = new LSL_Types.Vector3((Vector3)p[i]);
else if (p[i] is Quaternion)
lsl_p[i] = new LSL_Types.Quaternion(((Quaternion)p[i]).X, ((Quaternion)p[i]).Y, ((Quaternion)p[i]).Z, ((Quaternion)p[i]).W);
lsl_p[i] = new LSL_Types.Quaternion((Quaternion)p[i]);
else if (p[i] is float)
lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]);
else

View File

@@ -137,9 +137,14 @@ namespace OpenSim.Services.GridService
if (regionInfos.RegionID == UUID.Zero)
return "Invalid RegionID - cannot be zero UUID";
// This needs better sanity testing. What if regionInfo is registering in
// overlapping coords?
RegionData region = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID);
if ((region != null) && (region.RegionID != regionInfos.RegionID))
{
m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register in coordinates {1}, {2} which are already in use in scope {3}.",
regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID);
return "Region overlaps another region";
}
if (region != null)
{
// There is a preexisting record
@@ -176,32 +181,7 @@ namespace OpenSim.Services.GridService
}
}
if ((region != null) && (region.RegionID != regionInfos.RegionID))
{
m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register in coordinates {1}, {2} which are already in use in scope {3}.",
regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID);
return "Region overlaps another region";
}
if ((region != null) && (region.RegionID == regionInfos.RegionID) &&
((region.posX != regionInfos.RegionLocX) || (region.posY != regionInfos.RegionLocY)))
{
if ((Convert.ToInt32(region.Data["flags"]) & (int)OpenSim.Data.RegionFlags.NoMove) != 0)
return "Can't move this region";
// Region reregistering in other coordinates. Delete the old entry
m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) was previously registered at {2}-{3}. Deleting old entry.",
regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY);
try
{
m_Database.Delete(regionInfos.RegionID);
}
catch (Exception e)
{
m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e);
}
}
// If we get here, the destination is clear. Now for the real check.
if (!m_AllowDuplicateNames)
{
@@ -220,6 +200,31 @@ namespace OpenSim.Services.GridService
}
}
// If there is an old record for us, delete it if it is elsewhere.
region = m_Database.Get(regionInfos.RegionID, scopeID);
if ((region != null) && (region.RegionID == regionInfos.RegionID) &&
((region.posX != regionInfos.RegionLocX) || (region.posY != regionInfos.RegionLocY)))
{
if ((Convert.ToInt32(region.Data["flags"]) & (int)OpenSim.Data.RegionFlags.NoMove) != 0)
return "Can't move this region";
if ((Convert.ToInt32(region.Data["flags"]) & (int)OpenSim.Data.RegionFlags.LockedOut) != 0)
return "Region locked out";
// Region reregistering in other coordinates. Delete the old entry
m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) was previously registered at {2}-{3}. Deleting old entry.",
regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY);
try
{
m_Database.Delete(regionInfos.RegionID);
}
catch (Exception e)
{
m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e);
}
}
// Everything is ok, let's register
RegionData rdata = RegionInfo2RegionData(regionInfos);
rdata.ScopeID = scopeID;
@@ -227,8 +232,6 @@ namespace OpenSim.Services.GridService
if (region != null)
{
int oldFlags = Convert.ToInt32(region.Data["flags"]);
if ((oldFlags & (int)OpenSim.Data.RegionFlags.LockedOut) != 0)
return "Region locked out";
oldFlags &= ~(int)OpenSim.Data.RegionFlags.Reservation;

View File

@@ -94,6 +94,7 @@ namespace OpenSim.Services.InventoryService
m_Database = LoadPlugin<IXInventoryData>(dllName,
new Object[] {connString, String.Empty});
if (m_Database == null)
throw new Exception("Could not find a storage interface in the given module");
}
@@ -229,10 +230,28 @@ namespace OpenSim.Services.InventoryService
public virtual InventoryFolderBase GetFolderForType(UUID principalID, AssetType type)
{
// m_log.DebugFormat("[XINVENTORY SERVICE]: Getting folder type {0} for user {1}", type, principalID);
InventoryFolderBase rootFolder = GetRootFolder(principalID);
if (rootFolder == null)
{
m_log.WarnFormat(
"[XINVENTORY]: Found no root folder for {0} in GetFolderForType() when looking for {1}",
principalID, type);
return null;
}
return GetSystemFolderForType(rootFolder, type);
}
private InventoryFolderBase GetSystemFolderForType(InventoryFolderBase rootFolder, AssetType type)
{
// m_log.DebugFormat("[XINVENTORY SERVICE]: Getting folder type {0} for user {1}", type, principalID);
XInventoryFolder[] folders = m_Database.GetFolders(
new string[] { "agentID", "type"},
new string[] { principalID.ToString(), ((int)type).ToString() });
new string[] { "agentID", "parentFolderID", "type"},
new string[] { rootFolder.Owner.ToString(), rootFolder.ID.ToString(), ((int)type).ToString() });
if (folders.Length == 0)
{
@@ -308,22 +327,38 @@ namespace OpenSim.Services.InventoryService
if (check != null)
return false;
if (folder.Type == (short)AssetType.Folder
|| folder.Type == (short)AssetType.Unknown
|| folder.Type == (short)AssetType.OutfitFolder
|| GetFolderForType(folder.Owner, (AssetType)(folder.Type)) == null)
if (folder.Type != (short)AssetType.Folder && folder.Type != (short)AssetType.Unknown)
{
XInventoryFolder xFolder = ConvertFromOpenSim(folder);
return m_Database.StoreFolder(xFolder);
}
else
{
m_log.WarnFormat(
"[XINVENTORY]: Folder of type {0} already exists when tried to add {1} to {2} for {3}",
folder.Type, folder.Name, folder.ParentID, folder.Owner);
InventoryFolderBase rootFolder = GetRootFolder(folder.Owner);
if (rootFolder == null)
{
m_log.WarnFormat(
"[XINVENTORY]: Found no root folder for {0} in AddFolder() when looking for {1}",
folder.Owner, folder.Type);
return false;
}
// Check we're not trying to add this as a system folder.
if (folder.ParentID == rootFolder.ID)
{
InventoryFolderBase existingSystemFolder
= GetSystemFolderForType(rootFolder, (AssetType)folder.Type);
if (existingSystemFolder != null)
{
m_log.WarnFormat(
"[XINVENTORY]: System folder of type {0} already exists when tried to add {1} to {2} for {3}",
folder.Type, folder.Name, folder.ParentID, folder.Owner);
return false;
}
}
}
return false;
XInventoryFolder xFolder = ConvertFromOpenSim(folder);
return m_Database.StoreFolder(xFolder);
}
public virtual bool UpdateFolder(InventoryFolderBase folder)

View File

@@ -245,7 +245,7 @@ namespace OpenSim.Tests.Common
config.AddConfig("Modules");
config.AddConfig("InventoryService");
config.Configs["Modules"].Set("InventoryServices", "LocalInventoryServicesConnector");
config.Configs["InventoryService"].Set("LocalServiceModule", "OpenSim.Services.InventoryService.dll:InventoryService");
config.Configs["InventoryService"].Set("LocalServiceModule", "OpenSim.Services.InventoryService.dll:XInventoryService");
config.Configs["InventoryService"].Set("StorageProvider", "OpenSim.Tests.Common.dll");
LocalInventoryServicesConnector inventoryService = new LocalInventoryServicesConnector();

View File

@@ -199,7 +199,9 @@ namespace OpenSim.Tests.Common
string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None);
InventoryFolderBase newFolder
= new InventoryFolderBase(UUID.Random(), components[0], parentFolder.Owner, parentFolder.ID);
= new InventoryFolderBase(
UUID.Random(), components[0], parentFolder.Owner, (short)AssetType.Unknown, parentFolder.ID, 0);
inventoryService.AddFolder(newFolder);
if (components.Length > 1)

View File

@@ -933,6 +933,11 @@ namespace OpenSim.Tests.Common.Mock
}
public void Close()
{
Close(false);
}
public void Close(bool force)
{
// Fire the callback for this connection closing
// This is necesary to get the presence detector to notice that a client has logged out.

View File

@@ -0,0 +1,131 @@
/*
* 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.Linq;
using System.Reflection;
using log4net;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Data;
namespace OpenSim.Tests.Common.Mock
{
public class TestXInventoryDataPlugin : IXInventoryData
{
private Dictionary<UUID, XInventoryFolder> m_allFolders = new Dictionary<UUID, XInventoryFolder>();
private Dictionary<UUID, XInventoryItem> m_allItems = new Dictionary<UUID, XInventoryItem>();
public TestXInventoryDataPlugin(string conn, string realm) {}
public XInventoryItem[] GetItems(string[] fields, string[] vals)
{
List<XInventoryItem> origItems = Get<XInventoryItem>(fields, vals, m_allItems.Values.ToList());
return origItems.Select(i => i.Clone()).ToArray();
}
public XInventoryFolder[] GetFolders(string[] fields, string[] vals)
{
List<XInventoryFolder> origFolders
= Get<XInventoryFolder>(fields, vals, m_allFolders.Values.ToList());
return origFolders.Select(f => f.Clone()).ToArray();
}
private List<T> Get<T>(string[] fields, string[] vals, List<T> inputEntities)
{
List<T> entities = inputEntities;
for (int i = 0; i < fields.Length; i++)
{
entities
= entities.Where(
e =>
{
FieldInfo fi = typeof(T).GetField(fields[i]);
if (fi == null)
throw new NotImplementedException(string.Format("No field {0} for val {1}", fields[i], vals[i]));
return fi.GetValue(e).ToString() == vals[i];
}
).ToList();
}
return entities;
}
public bool StoreFolder(XInventoryFolder folder)
{
m_allFolders[folder.folderID] = folder.Clone();
// Console.WriteLine("Added folder {0} {1}", folder.folderName, folder.folderID);
return true;
}
public bool StoreItem(XInventoryItem item)
{
m_allItems[item.inventoryID] = item.Clone();
// Console.WriteLine("Added item {0} {1}, creator {2}, owner {3}", item.inventoryName, item.inventoryID, item.creatorID, item.avatarID);
return true;
}
public bool DeleteFolders(string field, string val)
{
return DeleteFolders(new string[] { field }, new string[] { val });
}
public bool DeleteFolders(string[] fields, string[] vals)
{
XInventoryFolder[] foldersToDelete = GetFolders(fields, vals);
Array.ForEach(foldersToDelete, f => m_allFolders.Remove(f.folderID));
return true;
}
public bool DeleteItems(string field, string val)
{
return DeleteItems(new string[] { field }, new string[] { val });
}
public bool DeleteItems(string[] fields, string[] vals)
{
XInventoryItem[] itemsToDelete = GetItems(fields, vals);
Array.ForEach(itemsToDelete, i => m_allItems.Remove(i.inventoryID));
return true;
}
public bool MoveItem(string id, string newParent) { throw new NotImplementedException(); }
public XInventoryItem[] GetActiveGestures(UUID principalID) { throw new NotImplementedException(); }
public int GetAssetPermissions(UUID principalID, UUID assetID) { throw new NotImplementedException(); }
}
}

View File

@@ -95,6 +95,7 @@ namespace OpenSim.Tests.Common
public static void EnableLogging()
{
log4net.Config.XmlConfigurator.Configure(EnableLoggingConfigStream);
EnableLoggingConfigStream.Position = 0;
}
/// <summary>

View File

@@ -47,10 +47,10 @@ using OpenSim.Services.AvatarService;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Tests.Torture
namespace OpenSim.Tests.Performance
{
/// <summary>
/// NPC torture tests
/// NPC performance tests
/// </summary>
/// <remarks>
/// Don't rely on the numbers given by these tests - they will vary a lot depending on what is already cached,
@@ -58,7 +58,7 @@ namespace OpenSim.Tests.Torture
/// earlier tests.
/// </remarks>
[TestFixture]
public class NPCTortureTests
public class NPCPerformanceTests
{
private TestScene scene;
private AvatarFactoryModule afm;

View File

@@ -36,10 +36,10 @@ using OpenSim.Region.Framework.Scenes;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Tests.Torture
namespace OpenSim.Tests.Performance
{
/// <summary>
/// Object torture tests
/// Object performance tests
/// </summary>
/// <remarks>
/// Don't rely on the numbers given by these tests - they will vary a lot depending on what is already cached,
@@ -47,7 +47,7 @@ namespace OpenSim.Tests.Torture
/// earlier tests.
/// </remarks>
[TestFixture]
public class ObjectTortureTests
public class ObjectPerformanceTests
{
[TearDown]
public void TearDown()

View File

@@ -42,10 +42,10 @@ using OpenSim.Region.ScriptEngine.XEngine;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Tests.Torture
namespace OpenSim.Tests.Performance
{
/// <summary>
/// Script torture tests
/// Script performance tests
/// </summary>
/// <remarks>
/// Don't rely on the numbers given by these tests - they will vary a lot depending on what is already cached,
@@ -53,7 +53,7 @@ namespace OpenSim.Tests.Torture
/// earlier tests.
/// </remarks>
[TestFixture]
public class ScriptTortureTests
public class ScriptPerformanceTests
{
private TestScene m_scene;
private XEngine m_xEngine;

View File

@@ -0,0 +1,132 @@
/*
* 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.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using log4net.Config;
using NUnit.Framework;
using OpenMetaverse;
using OpenMetaverse.Assets;
using OpenSim.Framework;
using OpenSim.Region.CoreModules.Scripting.DynamicTexture;
using OpenSim.Region.CoreModules.Scripting.VectorRender;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Tests.Stress
{
[TestFixture]
public class VectorRenderModuleStressTests : OpenSimTestCase
{
public Scene Scene { get; private set; }
public DynamicTextureModule Dtm { get; private set; }
public VectorRenderModule Vrm { get; private set; }
private void SetupScene(bool reuseTextures)
{
Scene = new SceneHelpers().SetupScene();
Dtm = new DynamicTextureModule();
Dtm.ReuseTextures = reuseTextures;
Vrm = new VectorRenderModule();
SceneHelpers.SetupSceneModules(Scene, Dtm, Vrm);
}
[Test]
public void TestConcurrentRepeatedDraw()
{
int threads = 4;
TestHelpers.InMethod();
SetupScene(false);
List<Drawer> drawers = new List<Drawer>();
for (int i = 0; i < threads; i++)
{
Drawer d = new Drawer(this, i);
drawers.Add(d);
Console.WriteLine("Starting drawer {0}", i);
Util.FireAndForget(o => d.Draw());
}
Thread.Sleep(10 * 60 * 1000);
drawers.ForEach(d => d.Ready = false);
drawers.ForEach(d => Console.WriteLine("Drawer {0} drew {1} textures", d.Number, d.Pass + 1));
}
class Drawer
{
public int Number { get; private set; }
public int Pass { get; private set; }
public bool Ready { get; set; }
private VectorRenderModuleStressTests m_tests;
public Drawer(VectorRenderModuleStressTests tests, int number)
{
m_tests = tests;
Number = number;
Ready = true;
}
public void Draw()
{
SceneObjectGroup so = SceneHelpers.AddSceneObject(m_tests.Scene);
while (Ready)
{
UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
// Ensure unique text
string text = string.Format("{0:D2}{1}", Number, Pass);
m_tests.Dtm.AddDynamicTextureData(
m_tests.Scene.RegionInfo.RegionID,
so.UUID,
m_tests.Vrm.GetContentType(),
string.Format("PenColour BLACK; MoveTo 40,220; FontSize 32; Text {0};", text),
"",
0);
Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
Pass++;
}
}
}
}
}

View File

@@ -87,10 +87,18 @@
;; from the selected region_info_source.
; allow_regionless = false
;# {NonPhysicalPrimMin} {} {Minimum size of nonphysical prims?} {} 0.01
;; Minimum size for non-physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonphysicalPrimMin!).
; NonphysicalPrimMin = 0.01
;# {NonPhysicalPrimMax} {} {Maximum size of nonphysical prims?} {} 256
;; Maximum size for non-physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonphysicalPrimMax!).
; NonphysicalPrimMax = 256
;# {PhysicalPrimMin} {} {Minimum size of physical prims?} {} 10
;; Maximum size where a prim can be physical. Affects resizing of existing prims. This can be overriden in the region config file.
; PhysicalPrimMin = 0.01
;# {PhysicalPrimMax} {} {Maximum size of physical prims?} {} 10
;; Maximum size where a prim can be physical. Affects resizing of existing prims. This can be overriden in the region config file.
; PhysicalPrimMax = 10
@@ -675,7 +683,9 @@
;; Maximum number of events to queue for a script (excluding timers)
; MaxScriptEventQueue = 300
;; Stack size per thread created
;; Stack size per script engine thread in bytes.
;; If you are experiencing StackOverflowExceptions you may want to increase this (e.g. double it).
;; The trade-off may be increased memory usage by the script engine.
; ThreadStackSize = 262144
;# {DeleteScriptsOnStartup} {} {Delete previously compiled script DLLs on startup?} (true false) true

View File

@@ -693,6 +693,17 @@
;LevelUpload = 0
[Textures]
; If true, textures generated dynamically (i.e. through osSetDynamicTextureData() and similar OSSL functions) are reused where possible
; Chiefly, reuse occurs if a texture has already been generated with identical data and settings, and that texture contains no dynamic components
; (e.g. images pulled from an external HTTP address).
; Reusing previously generated textures results in a much faster update on the viewer but may cause issues if the viewer didn't receive all resolutions of the texture.
; Currently, it will also increase asset cache use since temporary dynamic textures are no longer deleted.
; Hence, currently considered experimental.
; Default is false.
ReuseDynamicTextures = false
[ODEPhysicsSettings]
; ##
; ## Physics stats settings
@@ -931,6 +942,9 @@
; level of detail for physical meshes. 32,16,8 or 4 with 32 being full detail
MeshLevelOfDetail = 8
; if mesh size is > threshold meters, we need to add more detail because people will notice
MeshLevelOfDetailMegaPrimThreshold = 10
MeshLevelOfDetailMegaPrim = 16
; number^2 non-physical level of detail of the sculpt texture. 32x32 - 1024 verticies
SculptLevelOfDetail = 32

View File

@@ -7,6 +7,16 @@
[AssetService]
ConnectionString = "URI=file:Asset.db,version=3"
; The HGAssetService section controls the connection given to the AssetService in a Hypergrid configuration.
; This has to be separate from [AssetService] because the Hypergrid facing connector uses [HGAssetService] for its config data instead.
; However, the internal asset service will still use the [AssetService] section.
; Therefore, you will almost certainly want the ConnectionString in [HGAssetService] to be the same as in [AssetService]
; so that they both access the same database.
; This issue does not apply to normal MySQL/MSSQL configurations, since by default they use the settings in [DatabaseService] and
; do not have separate connection strings for different services.
[HGAssetService]
ConnectionString = "URI=file:Asset.db,version=3"
[InventoryService]
;ConnectionString = "URI=file:inventory.db,version=3"
; if you have a legacy inventory store use the connection string below

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1760,6 +1760,7 @@
<Reference name="System.Core"/>
<Reference name="System.Xml"/>
<Reference name="Mono.Addins" path="../../../bin/"/>
<Reference name="NDesk.Options" path="../../../bin/"/>
<Reference name="OpenMetaverseTypes" path="../../../bin/"/>
<Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
<Reference name="OpenMetaverse" path="../../../bin/"/>
@@ -3249,7 +3250,47 @@
</Files>
</Project>
<Project frameworkVersion="v3_5" name="OpenSim.Tests.Torture" path="OpenSim/Tests/Torture" type="Library">
<Project frameworkVersion="v3_5" name="OpenSim.Tests.Stress" path="OpenSim/Tests/Stress" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../../../bin/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../../bin/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../../bin/</ReferencePath>
<Reference name="System"/>
<Reference name="System.Xml"/>
<Reference name="System.Data"/>
<Reference name="log4net" path="../../../bin/"/>
<Reference name="Nini" path="../../../bin/"/>
<Reference name="nunit.framework" path="../../../bin/"/>
<Reference name="OpenMetaverse" path="../../../bin/"/>
<Reference name="OpenMetaverseTypes" path="../../../bin/"/>
<Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
<Reference name="XMLRPC" path="../../../bin/"/>
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Communications"/>
<Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Region.CoreModules"/>
<Reference name="OpenSim.Region.Framework"/>
<Reference name="OpenSim.Region.OptionalModules"/>
<Reference name="OpenSim.Region.ScriptEngine.Shared"/>
<Reference name="OpenSim.Region.ScriptEngine.XEngine"/>
<Reference name="OpenSim.Services.Interfaces"/>
<Reference name="OpenSim.Services.AvatarService"/>
<Reference name="OpenSim.Tests.Common"/>
<Files>
<Match pattern="*.cs" recurse="false"/>
</Files>
</Project>
<Project frameworkVersion="v3_5" name="OpenSim.Tests.Performance" path="OpenSim/Tests/Performance" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../../../bin/</OutputPath>