Compare commits
176 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5145980c74 | |||
| e74bf46007 | |||
| 7c520cf531 | |||
| daf58575f8 | |||
| e7cebaa4bd | |||
| 90ea00a109 | |||
| 1c0adfa6e0 | |||
| f3ea2bde61 | |||
| 8994ab1336 | |||
| dc835717d6 | |||
| f266c54f82 | |||
| 56cc573d2f | |||
| e827bcaf2b | |||
| f1a76195ea | |||
| 9ed4245d9e | |||
| 1dfc990264 | |||
| 15bc539bd4 | |||
| aa77d1d486 | |||
| c0b8f3d0bc | |||
| 3796e08b59 | |||
| 1e1270166f | |||
| 5d31267185 | |||
| 65f5f60317 | |||
| cf9b3e7708 | |||
| 1273ec6c7d | |||
| 1c533eb520 | |||
| 5397a6d4c6 | |||
| 24a49011cb | |||
| 76f411147d | |||
| 15ce73caca | |||
| cb4509f3b8 | |||
| dede31174e | |||
| 0e4d5a4d3c | |||
| 03e7bc1526 | |||
| a27e5a9c95 | |||
| daee2eda93 | |||
| a15b00d3ef | |||
| 1b906ef2ad | |||
| 68a4ef5ef6 | |||
| 90dc5f47e7 | |||
| 19d271d3fc | |||
| ee62bf3c69 | |||
| 3b2900e884 | |||
| 4a329098e8 | |||
| 99b9c1a9d5 | |||
| d6b8febbf4 | |||
| 8f8206f478 | |||
| 1c3ee5d1ce | |||
| b489c85226 | |||
| dcea23906b | |||
| 20c65ac438 | |||
| 77575ec51b | |||
| 756baff86a | |||
| 4bc3a0ecf4 | |||
| 433d5f1d3e | |||
| 3c9b7f2c0c | |||
| d6f212059e | |||
| 96409cc2ee | |||
| 60d68ee312 | |||
| bcb9577495 | |||
| 488ec59408 | |||
| b77d354e6d | |||
| 185bf55804 | |||
| d22715126c | |||
| a114367b9b | |||
| 2ffc055f7e | |||
| 736fb0b41d | |||
| 985526b662 | |||
| 7a1ab03b75 | |||
| a62baf8ea4 | |||
| 028dc1f4ed | |||
| 70b3b599bc | |||
| 3aee642190 | |||
| 91a326331f | |||
| 5351ff925c | |||
| 14e9bf894c | |||
| f4cd35322f | |||
| 7bdcf9eb26 | |||
| 9846a1e56e | |||
| 4cc97df8f3 | |||
| 0ef64fbe03 | |||
| fbccff4994 | |||
| 84184708de | |||
| 8f8b478d36 | |||
| b817c337dc | |||
| d03e878d53 | |||
| b313d16493 | |||
| 784263f5e3 | |||
| 7d77ccc659 | |||
| 6baa13ab7a | |||
| 0e16e0fb6a | |||
| ba98d6fffe | |||
| 972f73ed2b | |||
| c5ff37bf3e | |||
| 6b867773a8 | |||
| 912aac3447 | |||
| 4486b7d8e8 | |||
| 1267094a51 | |||
| 2b842958cc | |||
| 80ec2ac167 | |||
| df960d5767 | |||
| 0c1074537b | |||
| c0760f9f91 | |||
| c906128191 | |||
| 819fcdaee1 | |||
| 3bffdddc9d | |||
| f6c35cf26f | |||
| b59275355e | |||
| a758abaa9f | |||
| f6f0d884bd | |||
| 04279e36d1 | |||
| f574d3c8fc | |||
| ebe5e1731d | |||
| 2ebb421331 | |||
| 7be9ba5564 | |||
| 272ba5a741 | |||
| 2d3381b795 | |||
| a9e8bd59a3 | |||
| 4589ce61bc | |||
| 33e66107be | |||
| db90dea9bd | |||
| 04544b4510 | |||
| 0b17a66e68 | |||
| 04986bbb15 | |||
| b0d02adeee | |||
| 48b962c401 | |||
| e321306517 | |||
| 04a195266b | |||
| 21393af631 | |||
| 189c67db95 | |||
| 6fd6919a0b | |||
| f168fefb79 | |||
| bcf59a574f | |||
| 09f6647aa3 | |||
| 022ae33ed5 | |||
| d4e28ed113 | |||
| 3f9c390b4d | |||
| 33a9f0f1c5 | |||
| f415256e0b | |||
| b617411b97 | |||
| b92b9228ef | |||
| f49897a419 | |||
| 83868c0387 | |||
| aab30f5e67 | |||
| e7fd732209 | |||
| acfe7e555e | |||
| 5023cc86f0 | |||
| 4455140f30 | |||
| 43a74d8481 | |||
| 71e484516a | |||
| 38f878952c | |||
| d80422eba7 | |||
| e3f5fd81f1 | |||
| 7cf73cb92a | |||
| ee078f717a | |||
| 73f34de1f9 | |||
| b3d152f3ba | |||
| a7dc7e636e | |||
| 44d84bc277 | |||
| 215acbcc96 | |||
| 7273e05995 | |||
| ddca5347c3 | |||
| e8cc1bd329 | |||
| 9c84a8162f | |||
| 16c4636048 | |||
| 7c888f6af1 | |||
| dbe32a1f6d | |||
| 6af01f6767 | |||
| 3fa61c4a39 | |||
| dfa19e23f0 | |||
| 6cc9aa30ac | |||
| 754129b903 | |||
| 12c3239666 | |||
| c75fa8b8a1 | |||
| d5c08c44bf | |||
| bef2a368f4 |
@@ -235,4 +235,11 @@ CREATE NONCLUSTERED INDEX IX_regions_name ON dbo.regions
|
||||
regionName
|
||||
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
|
||||
|
||||
COMMIT
|
||||
COMMIT
|
||||
|
||||
:VERSION 9
|
||||
|
||||
BEGIN TRANSACTION
|
||||
ALTER TABLE regions ADD parcelMapTexture uniqueidentifier NULL;
|
||||
|
||||
COMMIT
|
||||
|
||||
@@ -472,3 +472,95 @@ COMMIT;
|
||||
BEGIN;
|
||||
ALTER TABLE regionsettings ADD COLUMN covenant_datetime INTEGER NOT NULL default 0;
|
||||
COMMIT;
|
||||
|
||||
:VERSION 23
|
||||
BEGIN;
|
||||
CREATE TABLE regionwindlight (
|
||||
region_id VARCHAR(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000' PRIMARY KEY,
|
||||
water_color_r FLOAT NOT NULL DEFAULT '4.000000',
|
||||
water_color_g FLOAT NOT NULL DEFAULT '38.000000',
|
||||
water_color_b FLOAT NOT NULL DEFAULT '64.000000',
|
||||
water_color_i FLOAT NOT NULL DEFAULT '1.000000',
|
||||
water_fog_density_exponent FLOAT NOT NULL DEFAULT '4.0',
|
||||
underwater_fog_modifier FLOAT NOT NULL DEFAULT '0.25',
|
||||
reflection_wavelet_scale_1 FLOAT NOT NULL DEFAULT '2.0',
|
||||
reflection_wavelet_scale_2 FLOAT NOT NULL DEFAULT '2.0',
|
||||
reflection_wavelet_scale_3 FLOAT NOT NULL DEFAULT '2.0',
|
||||
fresnel_scale FLOAT NOT NULL DEFAULT '0.40',
|
||||
fresnel_offset FLOAT NOT NULL DEFAULT '0.50',
|
||||
refract_scale_above FLOAT NOT NULL DEFAULT '0.03',
|
||||
refract_scale_below FLOAT NOT NULL DEFAULT '0.20',
|
||||
blur_multiplier FLOAT NOT NULL DEFAULT '0.040',
|
||||
big_wave_direction_x FLOAT NOT NULL DEFAULT '1.05',
|
||||
big_wave_direction_y FLOAT NOT NULL DEFAULT '-0.42',
|
||||
little_wave_direction_x FLOAT NOT NULL DEFAULT '1.11',
|
||||
little_wave_direction_y FLOAT NOT NULL DEFAULT '-1.16',
|
||||
normal_map_texture VARCHAR(36) NOT NULL DEFAULT '822ded49-9a6c-f61c-cb89-6df54f42cdf4',
|
||||
horizon_r FLOAT NOT NULL DEFAULT '0.25',
|
||||
horizon_g FLOAT NOT NULL DEFAULT '0.25',
|
||||
horizon_b FLOAT NOT NULL DEFAULT '0.32',
|
||||
horizon_i FLOAT NOT NULL DEFAULT '0.32',
|
||||
haze_horizon FLOAT NOT NULL DEFAULT '0.19',
|
||||
blue_density_r FLOAT NOT NULL DEFAULT '0.12',
|
||||
blue_density_g FLOAT NOT NULL DEFAULT '0.22',
|
||||
blue_density_b FLOAT NOT NULL DEFAULT '0.38',
|
||||
blue_density_i FLOAT NOT NULL DEFAULT '0.38',
|
||||
haze_density FLOAT NOT NULL DEFAULT '0.70',
|
||||
density_multiplier FLOAT NOT NULL DEFAULT '0.18',
|
||||
distance_multiplier FLOAT NOT NULL DEFAULT '0.8',
|
||||
max_altitude INTEGER NOT NULL DEFAULT '1605',
|
||||
sun_moon_color_r FLOAT NOT NULL DEFAULT '0.24',
|
||||
sun_moon_color_g FLOAT NOT NULL DEFAULT '0.26',
|
||||
sun_moon_color_b FLOAT NOT NULL DEFAULT '0.30',
|
||||
sun_moon_color_i FLOAT NOT NULL DEFAULT '0.30',
|
||||
sun_moon_position FLOAT NOT NULL DEFAULT '0.317',
|
||||
ambient_r FLOAT NOT NULL DEFAULT '0.35',
|
||||
ambient_g FLOAT NOT NULL DEFAULT '0.35',
|
||||
ambient_b FLOAT NOT NULL DEFAULT '0.35',
|
||||
ambient_i FLOAT NOT NULL DEFAULT '0.35',
|
||||
east_angle FLOAT NOT NULL DEFAULT '0.00',
|
||||
sun_glow_focus FLOAT NOT NULL DEFAULT '0.10',
|
||||
sun_glow_size FLOAT NOT NULL DEFAULT '1.75',
|
||||
scene_gamma FLOAT NOT NULL DEFAULT '1.00',
|
||||
star_brightness FLOAT NOT NULL DEFAULT '0.00',
|
||||
cloud_color_r FLOAT NOT NULL DEFAULT '0.41',
|
||||
cloud_color_g FLOAT NOT NULL DEFAULT '0.41',
|
||||
cloud_color_b FLOAT NOT NULL DEFAULT '0.41',
|
||||
cloud_color_i FLOAT NOT NULL DEFAULT '0.41',
|
||||
cloud_x FLOAT NOT NULL DEFAULT '1.00',
|
||||
cloud_y FLOAT NOT NULL DEFAULT '0.53',
|
||||
cloud_density FLOAT NOT NULL DEFAULT '1.00',
|
||||
cloud_coverage FLOAT NOT NULL DEFAULT '0.27',
|
||||
cloud_scale FLOAT NOT NULL DEFAULT '0.42',
|
||||
cloud_detail_x FLOAT NOT NULL DEFAULT '1.00',
|
||||
cloud_detail_y FLOAT NOT NULL DEFAULT '0.53',
|
||||
cloud_detail_density FLOAT NOT NULL DEFAULT '0.12',
|
||||
cloud_scroll_x FLOAT NOT NULL DEFAULT '0.20',
|
||||
cloud_scroll_x_lock INTEGER NOT NULL DEFAULT '0',
|
||||
cloud_scroll_y FLOAT NOT NULL DEFAULT '0.01',
|
||||
cloud_scroll_y_lock INTEGER NOT NULL DEFAULT '0',
|
||||
draw_classic_clouds INTEGER NOT NULL DEFAULT '1');
|
||||
|
||||
COMMIT;
|
||||
|
||||
|
||||
:VERSION 24
|
||||
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `spawn_points` (
|
||||
`RegionID` varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000',
|
||||
`Yaw` float NOT NULL,
|
||||
`Pitch` float NOT NULL,
|
||||
`Distance` float NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE `regionsettings` ADD COLUMN `TelehubObject` varchar(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
|
||||
|
||||
COMMIT;
|
||||
|
||||
:VERSION 25
|
||||
|
||||
BEGIN;
|
||||
ALTER TABLE `regionsettings` ADD COLUMN `parcel_tile_ID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
|
||||
COMMIT;
|
||||
|
||||
@@ -81,6 +81,9 @@ namespace OpenSim.Data.SQLite
|
||||
/// <param name="dbconnect">connect string</param>
|
||||
override public void Initialise(string dbconnect)
|
||||
{
|
||||
if (Util.IsWindows())
|
||||
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
|
||||
|
||||
if (dbconnect == string.Empty)
|
||||
{
|
||||
dbconnect = "URI=file:Asset.db,version=3";
|
||||
|
||||
@@ -65,6 +65,9 @@ namespace OpenSim.Data.SQLite
|
||||
|
||||
if (!m_initialized)
|
||||
{
|
||||
if (Util.IsWindows())
|
||||
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
|
||||
|
||||
m_Connection = new SqliteConnection(connectionString);
|
||||
m_Connection.Open();
|
||||
|
||||
|
||||
@@ -69,6 +69,9 @@ namespace OpenSim.Data.SQLite
|
||||
|
||||
public void Initialise(string connectionString)
|
||||
{
|
||||
if (Util.IsWindows())
|
||||
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
|
||||
|
||||
m_connectionString = connectionString;
|
||||
|
||||
m_log.Info("[ESTATE DB]: Sqlite - connecting: "+m_connectionString);
|
||||
|
||||
@@ -48,6 +48,8 @@ namespace OpenSim.Data.SQLite
|
||||
|
||||
protected SQLiteFramework(string connectionString)
|
||||
{
|
||||
if (Util.IsWindows())
|
||||
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace OpenSim.Data.SQLite
|
||||
cmd.Parameters.AddWithValue(":PrincipalID", principalID.ToString());
|
||||
cmd.Parameters.AddWithValue(":Friend", friend);
|
||||
|
||||
ExecuteNonQuery(cmd, cmd.Connection);
|
||||
ExecuteNonQuery(cmd, m_Connection);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -77,6 +77,9 @@ namespace OpenSim.Data.SQLite
|
||||
{
|
||||
m_Initialized = true;
|
||||
|
||||
if (Util.IsWindows())
|
||||
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
|
||||
|
||||
if (dbconnect == string.Empty)
|
||||
{
|
||||
dbconnect = "URI=file:inventoryStore.db,version=3";
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -52,6 +52,9 @@ namespace OpenSim.Data.SQLite
|
||||
|
||||
public SQLiteXInventoryData(string conn, string realm)
|
||||
{
|
||||
if (Util.IsWindows())
|
||||
Util.LoadArchSpecificWindowsDll("sqlite3.dll");
|
||||
|
||||
m_Folders = new SQLiteGenericTableHandler<XInventoryFolder>(
|
||||
conn, "inventoryfolders", "XInventoryStore");
|
||||
m_Items = new SqliteItemHandler(
|
||||
|
||||
@@ -308,6 +308,8 @@ namespace OpenSim.Framework
|
||||
public Animation[] Anims;
|
||||
|
||||
public UUID GranterID;
|
||||
public UUID ParentPart;
|
||||
public Vector3 SitOffset;
|
||||
|
||||
// Appearance
|
||||
public AvatarAppearance Appearance;
|
||||
@@ -468,6 +470,10 @@ namespace OpenSim.Framework
|
||||
}
|
||||
args["attach_objects"] = attObjs;
|
||||
}
|
||||
|
||||
args["parent_part"] = OSD.FromUUID(ParentPart);
|
||||
args["sit_offset"] = OSD.FromString(SitOffset.ToString());
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
@@ -675,6 +681,11 @@ namespace OpenSim.Framework
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (args["parent_part"] != null)
|
||||
ParentPart = args["parent_part"].AsUUID();
|
||||
if (args["sit_offset"] != null)
|
||||
Vector3.TryParse(args["sit_offset"].AsString(), out SitOffset);
|
||||
}
|
||||
|
||||
public AgentData()
|
||||
|
||||
@@ -31,6 +31,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using OpenSim.Framework;
|
||||
@@ -531,6 +532,11 @@ namespace OpenSim.Framework.Console
|
||||
|
||||
public class Parser
|
||||
{
|
||||
// If an unquoted portion ends with an element matching this regex
|
||||
// and the next element contains a space, then we have stripped
|
||||
// embedded quotes that should not have been stripped
|
||||
private static Regex optionRegex = new Regex("^--[a-zA-Z0-9-]+=$");
|
||||
|
||||
public static string[] Parse(string text)
|
||||
{
|
||||
List<string> result = new List<string>();
|
||||
@@ -544,10 +550,38 @@ namespace OpenSim.Framework.Console
|
||||
if (index % 2 == 0)
|
||||
{
|
||||
string[] words = unquoted[index].Split(new char[] {' '});
|
||||
|
||||
bool option = false;
|
||||
foreach (string w in words)
|
||||
{
|
||||
if (w != String.Empty)
|
||||
{
|
||||
if (optionRegex.Match(w) == Match.Empty)
|
||||
option = false;
|
||||
else
|
||||
option = true;
|
||||
result.Add(w);
|
||||
}
|
||||
}
|
||||
// The last item matched the regex, put the quotes back
|
||||
if (option)
|
||||
{
|
||||
// If the line ended with it, don't do anything
|
||||
if (index < (unquoted.Length - 1))
|
||||
{
|
||||
// Get and remove the option name
|
||||
string optionText = result[result.Count - 1];
|
||||
result.RemoveAt(result.Count - 1);
|
||||
|
||||
// Add the quoted value back
|
||||
optionText += "\"" + unquoted[index + 1] + "\"";
|
||||
|
||||
// Push the result into our return array
|
||||
result.Add(optionText);
|
||||
|
||||
// Skip the already used value
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -627,7 +627,6 @@ namespace OpenSim.Framework
|
||||
|
||||
foreach (String s in allKeys)
|
||||
{
|
||||
string val = config.GetString(s);
|
||||
SetOtherSetting(s, config.GetString(s));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,15 +49,16 @@ namespace OpenSim.Framework.Serialization.External
|
||||
/// <param name="nodeToFill"></param>
|
||||
/// <param name="processors">/param>
|
||||
/// <param name="xtr"></param>
|
||||
public static void ExecuteReadProcessors<NodeType>(
|
||||
/// <returns>true on successful, false if there were any processing failures</returns>
|
||||
public static bool ExecuteReadProcessors<NodeType>(
|
||||
NodeType nodeToFill, Dictionary<string, Action<NodeType, XmlTextReader>> processors, XmlTextReader xtr)
|
||||
{
|
||||
ExecuteReadProcessors(
|
||||
return ExecuteReadProcessors(
|
||||
nodeToFill,
|
||||
processors,
|
||||
xtr,
|
||||
(o, name, e)
|
||||
=> m_log.ErrorFormat(
|
||||
=> m_log.DebugFormat(
|
||||
"[ExternalRepresentationUtils]: Exception while parsing element {0}, continuing. Exception {1}{2}",
|
||||
name, e.Message, e.StackTrace));
|
||||
}
|
||||
@@ -71,12 +72,15 @@ namespace OpenSim.Framework.Serialization.External
|
||||
/// <param name="parseExceptionAction">
|
||||
/// Action to take if there is a parsing problem. This will usually just be to log the exception
|
||||
/// </param>
|
||||
public static void ExecuteReadProcessors<NodeType>(
|
||||
/// <returns>true on successful, false if there were any processing failures</returns>
|
||||
public static bool ExecuteReadProcessors<NodeType>(
|
||||
NodeType nodeToFill,
|
||||
Dictionary<string, Action<NodeType, XmlTextReader>> processors,
|
||||
XmlTextReader xtr,
|
||||
Action<NodeType, string, Exception> parseExceptionAction)
|
||||
{
|
||||
bool errors = false;
|
||||
|
||||
string nodeName = string.Empty;
|
||||
while (xtr.NodeType != XmlNodeType.EndElement)
|
||||
{
|
||||
@@ -95,6 +99,7 @@ namespace OpenSim.Framework.Serialization.External
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
errors = true;
|
||||
parseExceptionAction(nodeToFill, nodeName, e);
|
||||
|
||||
if (xtr.NodeType == XmlNodeType.EndElement)
|
||||
@@ -107,6 +112,8 @@ namespace OpenSim.Framework.Serialization.External
|
||||
xtr.ReadOuterXml(); // ignore
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -140,6 +147,7 @@ namespace OpenSim.Framework.Serialization.External
|
||||
UUID.TryParse(node.InnerText, out uuid);
|
||||
creator = userService.GetUserAccount(scopeID, uuid);
|
||||
}
|
||||
|
||||
if (node.Name == "CreatorData" && node.InnerText != null && node.InnerText != string.Empty)
|
||||
hasCreatorData = true;
|
||||
|
||||
@@ -163,7 +171,6 @@ namespace OpenSim.Framework.Serialization.External
|
||||
doc.Save(wr);
|
||||
return wr.ToString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -308,7 +308,9 @@ namespace OpenSim.Framework.Servers
|
||||
// clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and
|
||||
// the clr version number doesn't match the project version number under Mono.
|
||||
//m_log.Info("[STARTUP]: Virtual machine runtime version: " + Environment.Version + Environment.NewLine);
|
||||
m_log.Info("[STARTUP]: Operating system version: " + Environment.OSVersion + Environment.NewLine);
|
||||
m_log.InfoFormat(
|
||||
"[STARTUP]: Operating system version: {0}, .NET platform {1}, {2}-bit\n",
|
||||
Environment.OSVersion, Environment.OSVersion.Platform, Util.Is64BitProcess() ? "64" : "32");
|
||||
|
||||
StartupSpecific();
|
||||
|
||||
|
||||
@@ -35,7 +35,8 @@ using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Reflection;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using System.Security.Cryptography;
|
||||
@@ -375,6 +376,50 @@ namespace OpenSim.Framework
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the platform Windows?
|
||||
/// </summary>
|
||||
/// <returns>true if so, false otherwise</returns>
|
||||
public static bool IsWindows()
|
||||
{
|
||||
PlatformID platformId = Environment.OSVersion.Platform;
|
||||
|
||||
return (platformId == PlatformID.Win32NT
|
||||
|| platformId == PlatformID.Win32S
|
||||
|| platformId == PlatformID.Win32Windows
|
||||
|| platformId == PlatformID.WinCE);
|
||||
}
|
||||
|
||||
public static bool LoadArchSpecificWindowsDll(string libraryName)
|
||||
{
|
||||
// We do this so that OpenSimulator on Windows loads the correct native library depending on whether
|
||||
// it's running as a 32-bit process or a 64-bit one. By invoking LoadLibary here, later DLLImports
|
||||
// will find it already loaded later on.
|
||||
//
|
||||
// This isn't necessary for other platforms (e.g. Mac OSX and Linux) since the DLL used can be
|
||||
// controlled in config files.
|
||||
string nativeLibraryPath;
|
||||
|
||||
if (Util.Is64BitProcess())
|
||||
nativeLibraryPath = "lib64/" + libraryName;
|
||||
else
|
||||
nativeLibraryPath = "lib32/" + libraryName;
|
||||
|
||||
m_log.DebugFormat("[UTIL]: Loading native Windows library at {0}", nativeLibraryPath);
|
||||
|
||||
if (Util.LoadLibrary(nativeLibraryPath) == IntPtr.Zero)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[UTIL]: Couldn't find native Windows library at {0}", nativeLibraryPath);
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsEnvironmentSupported(ref string reason)
|
||||
@@ -1469,6 +1514,27 @@ namespace OpenSim.Framework
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to trigger an early library load on Windows systems.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Required to get 32-bit and 64-bit processes to automatically use the
|
||||
/// appropriate native library.
|
||||
/// </remarks>
|
||||
/// <param name="dllToLoad"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern IntPtr LoadLibrary(string dllToLoad);
|
||||
|
||||
/// <summary>
|
||||
/// Determine whether the current process is 64 bit
|
||||
/// </summary>
|
||||
/// <returns>true if so, false if not</returns>
|
||||
public static bool Is64BitProcess()
|
||||
{
|
||||
return IntPtr.Size == 8;
|
||||
}
|
||||
|
||||
#region FireAndForget Threading Pattern
|
||||
@@ -1676,13 +1742,14 @@ namespace OpenSim.Framework
|
||||
/// </summary>
|
||||
public static void PrintCallStack()
|
||||
{
|
||||
StackTrace stackTrace = new StackTrace(); // get call stack
|
||||
StackTrace stackTrace = new StackTrace(true); // get call stack
|
||||
StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
|
||||
|
||||
// write call stack method names
|
||||
foreach (StackFrame stackFrame in stackFrames)
|
||||
{
|
||||
m_log.Debug(stackFrame.GetMethod().DeclaringType + "." + stackFrame.GetMethod().Name); // write method name
|
||||
MethodBase mb = stackFrame.GetMethod();
|
||||
m_log.DebugFormat("{0}.{1}:{2}", mb.DeclaringType, mb.Name, stackFrame.GetFileLineNumber()); // write method name
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -422,7 +422,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
string assetType)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"Uploaded asset {0} for inventory item {1}, inv type {2}, asset type {3}",
|
||||
"[BUNCH OF CAPS]: Uploaded asset {0} for inventory item {1}, inv type {2}, asset type {3}",
|
||||
assetID, inventoryItem, inventoryType, assetType);
|
||||
|
||||
sbyte assType = 0;
|
||||
@@ -625,7 +625,12 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
item.AssetType = assType;
|
||||
item.InvType = inType;
|
||||
item.Folder = parentFolder;
|
||||
item.CurrentPermissions = (uint)PermissionMask.All;
|
||||
|
||||
// If we set PermissionMask.All then when we rez the item the next permissions will replace the current
|
||||
// (owner) permissions. This becomes a problem if next permissions are changed.
|
||||
item.CurrentPermissions
|
||||
= (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
|
||||
|
||||
item.BasePermissions = (uint)PermissionMask.All;
|
||||
item.EveryOnePermissions = 0;
|
||||
item.NextPermissions = (uint)PermissionMask.All;
|
||||
|
||||
@@ -50,8 +50,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||
public class NewFileAgentInventoryVariablePriceModule : INonSharedRegionModule
|
||||
{
|
||||
// private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Scene m_scene;
|
||||
// private IAssetService m_assetService;
|
||||
@@ -210,6 +209,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
|
||||
string assetType,UUID AgentID)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[NEW FILE AGENT INVENTORY VARIABLE PRICE MODULE]: Upload complete for {0}", inventoryItem);
|
||||
|
||||
sbyte assType = 0;
|
||||
sbyte inType = 0;
|
||||
|
||||
@@ -259,13 +261,13 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
item.AssetType = assType;
|
||||
item.InvType = inType;
|
||||
item.Folder = parentFolder;
|
||||
item.CurrentPermissions = (uint)PermissionMask.All;
|
||||
item.CurrentPermissions
|
||||
= (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
|
||||
item.BasePermissions = (uint)PermissionMask.All;
|
||||
item.EveryOnePermissions = 0;
|
||||
item.NextPermissions = (uint)PermissionMask.All;
|
||||
item.CreationDate = Util.UnixTimeSinceEpoch();
|
||||
m_scene.AddInventoryItem(item);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
m_scene.AddSceneObject(grp);
|
||||
grp.AbsolutePosition = obj.Position;
|
||||
}
|
||||
|
||||
|
||||
allparts[i] = grp;
|
||||
}
|
||||
|
||||
|
||||
@@ -1549,7 +1549,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
public void SendKillObject(ulong regionHandle, List<uint> localIDs)
|
||||
{
|
||||
// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle);
|
||||
// foreach (uint id in localIDs)
|
||||
// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
|
||||
|
||||
KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
|
||||
// TODO: don't create new blocks if recycling an old packet
|
||||
@@ -3773,6 +3774,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// doesn't seem to be attached, skip
|
||||
if (!found)
|
||||
continue;
|
||||
|
||||
// On vehicle crossing, the attachments are received
|
||||
// while the avatar is still a child. Don't send
|
||||
// updates here because the LocalId has not yet
|
||||
// been updated and the viewer will derender the
|
||||
// attachments until the avatar becomes root.
|
||||
if (sp.IsChildAgent)
|
||||
continue;
|
||||
}
|
||||
if (part.ParentGroup.IsAttachment && m_disableFacelights)
|
||||
{
|
||||
@@ -4827,9 +4836,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
ScenePresence presence = (ScenePresence)entity;
|
||||
|
||||
position = presence.OffsetPosition;
|
||||
rotation = presence.Rotation;
|
||||
|
||||
if (presence.ParentID != 0)
|
||||
{
|
||||
SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
|
||||
if (part != null && part != part.ParentGroup.RootPart)
|
||||
{
|
||||
position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
|
||||
rotation = part.RotationOffset * presence.Rotation;
|
||||
}
|
||||
}
|
||||
|
||||
attachPoint = 0;
|
||||
collisionPlane = presence.CollisionPlane;
|
||||
position = presence.OffsetPosition;
|
||||
velocity = presence.Velocity;
|
||||
acceleration = Vector3.Zero;
|
||||
|
||||
@@ -4839,7 +4860,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// acceleration = new Vector3(1, 0, 0);
|
||||
|
||||
angularVelocity = Vector3.Zero;
|
||||
rotation = presence.Rotation;
|
||||
|
||||
if (sendTexture)
|
||||
textureEntry = presence.Appearance.Texture.GetBytes();
|
||||
@@ -4944,13 +4964,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
|
||||
{
|
||||
Vector3 offsetPosition = data.OffsetPosition;
|
||||
Quaternion rotation = data.Rotation;
|
||||
uint parentID = data.ParentID;
|
||||
|
||||
if (parentID != 0)
|
||||
{
|
||||
SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
|
||||
if (part != null && part != part.ParentGroup.RootPart)
|
||||
{
|
||||
offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
|
||||
rotation = part.RotationOffset * data.Rotation;
|
||||
parentID = part.ParentGroup.RootPart.LocalId;
|
||||
}
|
||||
}
|
||||
|
||||
byte[] objectData = new byte[76];
|
||||
|
||||
data.CollisionPlane.ToBytes(objectData, 0);
|
||||
data.OffsetPosition.ToBytes(objectData, 16);
|
||||
offsetPosition.ToBytes(objectData, 16);
|
||||
// data.Velocity.ToBytes(objectData, 28);
|
||||
// data.Acceleration.ToBytes(objectData, 40);
|
||||
data.Rotation.ToBytes(objectData, 52);
|
||||
rotation.ToBytes(objectData, 52);
|
||||
//data.AngularVelocity.ToBytes(objectData, 64);
|
||||
|
||||
ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
|
||||
@@ -4964,7 +4999,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
|
||||
data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
|
||||
update.ObjectData = objectData;
|
||||
update.ParentID = data.ParentID;
|
||||
update.ParentID = parentID;
|
||||
update.PathCurve = 16;
|
||||
update.PathScaleX = 100;
|
||||
update.PathScaleY = 100;
|
||||
@@ -5168,7 +5203,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage, false);
|
||||
AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship);
|
||||
AddLocalPacketHandler(PacketType.DeclineFriendship, HandlerDeclineFriendship);
|
||||
AddLocalPacketHandler(PacketType.TerminateFriendship, HandlerTerminateFrendship);
|
||||
AddLocalPacketHandler(PacketType.TerminateFriendship, HandlerTerminateFriendship);
|
||||
AddLocalPacketHandler(PacketType.RezObject, HandlerRezObject);
|
||||
AddLocalPacketHandler(PacketType.DeRezObject, HandlerDeRezObject);
|
||||
AddLocalPacketHandler(PacketType.ModifyLand, HandlerModifyLand);
|
||||
@@ -5891,7 +5926,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool HandlerTerminateFrendship(IClientAPI sender, Packet Pack)
|
||||
private bool HandlerTerminateFriendship(IClientAPI sender, Packet Pack)
|
||||
{
|
||||
TerminateFriendshipPacket tfriendpack = (TerminateFriendshipPacket)Pack;
|
||||
|
||||
@@ -5906,13 +5941,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
UUID listOwnerAgentID = tfriendpack.AgentData.AgentID;
|
||||
UUID exFriendID = tfriendpack.ExBlock.OtherID;
|
||||
|
||||
FriendshipTermination handlerTerminateFriendship = OnTerminateFriendship;
|
||||
if (handlerTerminateFriendship != null)
|
||||
FriendshipTermination TerminateFriendshipHandler = OnTerminateFriendship;
|
||||
if (TerminateFriendshipHandler != null)
|
||||
{
|
||||
handlerTerminateFriendship(this, listOwnerAgentID, exFriendID);
|
||||
TerminateFriendshipHandler(this, listOwnerAgentID, exFriendID);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool HandleFindAgent(IClientAPI client, Packet Packet)
|
||||
@@ -7689,6 +7724,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate)
|
||||
{
|
||||
//TransferRequestPacket does not include covenant uuid?
|
||||
//get scene covenant uuid
|
||||
taskID = m_scene.RegionInfo.RegionSettings.Covenant;
|
||||
}
|
||||
|
||||
MakeAssetRequest(transfer, taskID);
|
||||
|
||||
@@ -12113,6 +12155,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
{
|
||||
requestID = new UUID(transferRequest.TransferInfo.Params, 80);
|
||||
}
|
||||
else if (transferRequest.TransferInfo.SourceType == (int)SourceType.SimEstate)
|
||||
{
|
||||
requestID = taskID;
|
||||
}
|
||||
|
||||
|
||||
// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
|
||||
|
||||
|
||||
@@ -903,47 +903,64 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
private void HandleUseCircuitCode(object o)
|
||||
{
|
||||
// DateTime startTime = DateTime.Now;
|
||||
object[] array = (object[])o;
|
||||
UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
|
||||
UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
|
||||
IPEndPoint remoteEndPoint = null;
|
||||
IClientAPI client = null;
|
||||
|
||||
try
|
||||
{
|
||||
// DateTime startTime = DateTime.Now;
|
||||
object[] array = (object[])o;
|
||||
UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
|
||||
UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
|
||||
|
||||
m_log.DebugFormat("[LLUDPSERVER]: Handling UseCircuitCode request from {0}", buffer.RemoteEndPoint);
|
||||
|
||||
remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
|
||||
|
||||
AuthenticateResponse sessionInfo;
|
||||
if (IsClientAuthorized(uccp, out sessionInfo))
|
||||
{
|
||||
// Begin the process of adding the client to the simulator
|
||||
client
|
||||
= AddClient(
|
||||
uccp.CircuitCode.Code,
|
||||
uccp.CircuitCode.ID,
|
||||
uccp.CircuitCode.SessionID,
|
||||
remoteEndPoint,
|
||||
sessionInfo);
|
||||
|
||||
m_log.DebugFormat("[LLUDPSERVER]: Handling UseCircuitCode request from {0}", buffer.RemoteEndPoint);
|
||||
// Send ack straight away to let the viewer know that the connection is active.
|
||||
// The client will be null if it already exists (e.g. if on a region crossing the client sends a use
|
||||
// circuit code to the existing child agent. This is not particularly obvious.
|
||||
SendAckImmediate(remoteEndPoint, uccp.Header.Sequence);
|
||||
|
||||
// We only want to send initial data to new clients, not ones which are being converted from child to root.
|
||||
if (client != null)
|
||||
client.SceneAgent.SendInitialDataToMe();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't create clients for unauthorized requesters.
|
||||
m_log.WarnFormat(
|
||||
"[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
|
||||
uccp.CircuitCode.ID, uccp.CircuitCode.Code, remoteEndPoint);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
|
||||
// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds);
|
||||
|
||||
IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
|
||||
|
||||
AuthenticateResponse sessionInfo;
|
||||
if (IsClientAuthorized(uccp, out sessionInfo))
|
||||
{
|
||||
// Begin the process of adding the client to the simulator
|
||||
IClientAPI client
|
||||
= AddClient(
|
||||
uccp.CircuitCode.Code,
|
||||
uccp.CircuitCode.ID,
|
||||
uccp.CircuitCode.SessionID,
|
||||
remoteEndPoint,
|
||||
sessionInfo);
|
||||
|
||||
// Send ack straight away to let the viewer know that the connection is active.
|
||||
// The client will be null if it already exists (e.g. if on a region crossing the client sends a use
|
||||
// circuit code to the existing child agent. This is not particularly obvious.
|
||||
SendAckImmediate(remoteEndPoint, uccp.Header.Sequence);
|
||||
|
||||
// We only want to send initial data to new clients, not ones which are being converted from child to root.
|
||||
if (client != null)
|
||||
client.SceneAgent.SendInitialDataToMe();
|
||||
}
|
||||
else
|
||||
catch (Exception e)
|
||||
{
|
||||
// Don't create clients for unauthorized requesters.
|
||||
m_log.WarnFormat(
|
||||
"[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
|
||||
uccp.CircuitCode.ID, uccp.CircuitCode.Code, remoteEndPoint);
|
||||
m_log.ErrorFormat(
|
||||
"[LLUDPSERVER]: UseCircuitCode handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}",
|
||||
remoteEndPoint != null ? remoteEndPoint.ToString() : "n/a",
|
||||
client != null ? client.Name : "unknown",
|
||||
client != null ? client.AgentId.ToString() : "unknown",
|
||||
e.Message,
|
||||
e.StackTrace);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
|
||||
// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -417,7 +417,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
so.AttachedAvatar = UUID.Zero;
|
||||
rootPart.SetParentLocalId(0);
|
||||
so.ClearPartAttachmentData();
|
||||
rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive);
|
||||
rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive,false);
|
||||
so.HasGroupChanged = true;
|
||||
rootPart.Rezzed = DateTime.Now;
|
||||
rootPart.RemFlag(PrimFlags.TemporaryOnRez);
|
||||
|
||||
@@ -111,6 +111,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
|
||||
#region IAvatarFactoryModule
|
||||
|
||||
/// </summary>
|
||||
/// <param name="sp"></param>
|
||||
/// <param name="texture"></param>
|
||||
/// <param name="visualParam"></param>
|
||||
public void SetAppearance(IScenePresence sp, AvatarAppearance appearance)
|
||||
{
|
||||
SetAppearance(sp, appearance.Texture, appearance.VisualParams);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set appearance data (texture asset IDs and slider settings)
|
||||
/// </summary>
|
||||
@@ -156,14 +165,23 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
|
||||
|
||||
// WriteBakedTexturesReport(sp, m_log.DebugFormat);
|
||||
if (!ValidateBakedTextureCache(sp))
|
||||
|
||||
// If bake textures are missing and this is not an NPC, request a rebake from client
|
||||
if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc))
|
||||
RequestRebake(sp, true);
|
||||
|
||||
// This appears to be set only in the final stage of the appearance
|
||||
// update transaction. In theory, we should be able to do an immediate
|
||||
// appearance send and save here.
|
||||
}
|
||||
|
||||
|
||||
// NPC should send to clients immediately and skip saving appearance
|
||||
if (((ScenePresence)sp).PresenceType == PresenceType.Npc)
|
||||
{
|
||||
SendAppearance((ScenePresence)sp);
|
||||
return;
|
||||
}
|
||||
|
||||
// save only if there were changes, send no matter what (doesn't hurt to send twice)
|
||||
if (changed)
|
||||
QueueAppearanceSave(sp.ControllingClient.AgentId);
|
||||
@@ -174,6 +192,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
// m_log.WarnFormat("[AVFACTORY]: complete SetAppearance for {0}:\n{1}",client.AgentId,sp.Appearance.ToString());
|
||||
}
|
||||
|
||||
private void SendAppearance(ScenePresence sp)
|
||||
{
|
||||
// Send the appearance to everyone in the scene
|
||||
sp.SendAppearanceToAllOtherAgents();
|
||||
|
||||
// Send animations back to the avatar as well
|
||||
sp.Animator.SendAnimPack();
|
||||
}
|
||||
|
||||
public bool SendAppearance(UUID agentId)
|
||||
{
|
||||
// m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId);
|
||||
@@ -185,12 +212,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send the appearance to everyone in the scene
|
||||
sp.SendAppearanceToAllOtherAgents();
|
||||
|
||||
// Send animations back to the avatar as well
|
||||
sp.Animator.SendAnimPack();
|
||||
|
||||
SendAppearance(sp);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -474,6 +496,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
SetAppearanceAssets(sp.UUID, sp.Appearance);
|
||||
|
||||
m_scene.AvatarService.SetAppearance(agentid, sp.Appearance);
|
||||
|
||||
// Trigger this here because it's the final step in the set/queue/save process for appearance setting.
|
||||
// Everything has been updated and stored. Ensures bakes have been persisted (if option is set to persist bakes).
|
||||
m_scene.EventManager.TriggerAvatarAppearanceChanged(sp);
|
||||
}
|
||||
|
||||
private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance)
|
||||
@@ -626,4 +652,4 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||
outputAction("{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -681,11 +681,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
|
||||
#region Agent Crossings
|
||||
|
||||
public bool Cross(ScenePresence agent, bool isFlying)
|
||||
public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos)
|
||||
{
|
||||
Scene scene = agent.Scene;
|
||||
Vector3 pos = agent.AbsolutePosition;
|
||||
Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
|
||||
version = String.Empty;
|
||||
newpos = new Vector3(pos.X, pos.Y, pos.Z);
|
||||
uint neighbourx = scene.RegionInfo.RegionLocX;
|
||||
uint neighboury = scene.RegionInfo.RegionLocY;
|
||||
const float boundaryDistance = 1.7f;
|
||||
@@ -706,53 +705,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
}
|
||||
else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
|
||||
{
|
||||
Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
|
||||
if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0)
|
||||
{
|
||||
neighboury--;
|
||||
newpos.Y = Constants.RegionSize - enterDistance;
|
||||
}
|
||||
else
|
||||
{
|
||||
agent.IsInTransit = true;
|
||||
|
||||
neighboury = b.TriggerRegionY;
|
||||
neighbourx = b.TriggerRegionX;
|
||||
|
||||
Vector3 newposition = pos;
|
||||
newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
|
||||
newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
|
||||
agent.ControllingClient.SendAgentAlertMessage(
|
||||
String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
|
||||
InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
|
||||
return true;
|
||||
}
|
||||
neighboury--;
|
||||
newpos.Y = Constants.RegionSize - enterDistance;
|
||||
}
|
||||
|
||||
Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W);
|
||||
if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0)
|
||||
{
|
||||
neighbourx--;
|
||||
newpos.X = Constants.RegionSize - enterDistance;
|
||||
}
|
||||
else
|
||||
{
|
||||
agent.IsInTransit = true;
|
||||
|
||||
neighboury = ba.TriggerRegionY;
|
||||
neighbourx = ba.TriggerRegionX;
|
||||
|
||||
|
||||
Vector3 newposition = pos;
|
||||
newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
|
||||
newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
|
||||
agent.ControllingClient.SendAgentAlertMessage(
|
||||
String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
|
||||
InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
neighbourx--;
|
||||
newpos.X = Constants.RegionSize - enterDistance;
|
||||
|
||||
}
|
||||
else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
|
||||
@@ -763,26 +721,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
|
||||
if (scene.TestBorderCross(pos + southCross, Cardinals.S))
|
||||
{
|
||||
Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
|
||||
if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0)
|
||||
{
|
||||
neighboury--;
|
||||
newpos.Y = Constants.RegionSize - enterDistance;
|
||||
}
|
||||
else
|
||||
{
|
||||
agent.IsInTransit = true;
|
||||
|
||||
neighboury = ba.TriggerRegionY;
|
||||
neighbourx = ba.TriggerRegionX;
|
||||
Vector3 newposition = pos;
|
||||
newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
|
||||
newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
|
||||
agent.ControllingClient.SendAgentAlertMessage(
|
||||
String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
|
||||
InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
|
||||
return true;
|
||||
}
|
||||
neighboury--;
|
||||
newpos.Y = Constants.RegionSize - enterDistance;
|
||||
}
|
||||
else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
|
||||
{
|
||||
@@ -790,35 +730,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize);
|
||||
newpos.Y = enterDistance;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
|
||||
{
|
||||
Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
|
||||
if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0)
|
||||
{
|
||||
neighboury--;
|
||||
newpos.Y = Constants.RegionSize - enterDistance;
|
||||
}
|
||||
else
|
||||
{
|
||||
agent.IsInTransit = true;
|
||||
|
||||
neighboury = b.TriggerRegionY;
|
||||
neighbourx = b.TriggerRegionX;
|
||||
Vector3 newposition = pos;
|
||||
newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
|
||||
newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
|
||||
agent.ControllingClient.SendAgentAlertMessage(
|
||||
String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
|
||||
InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
|
||||
return true;
|
||||
}
|
||||
neighboury--;
|
||||
newpos.Y = Constants.RegionSize - enterDistance;
|
||||
}
|
||||
else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
|
||||
{
|
||||
|
||||
Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
|
||||
neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
|
||||
newpos.Y = enterDistance;
|
||||
@@ -849,19 +769,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
}
|
||||
*/
|
||||
|
||||
ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
|
||||
xDest = neighbourx;
|
||||
yDest = neighboury;
|
||||
|
||||
int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);
|
||||
|
||||
ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);
|
||||
|
||||
ExpiringCache<ulong, DateTime> r;
|
||||
DateTime banUntil;
|
||||
|
||||
if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r))
|
||||
if (m_bannedRegions.TryGetValue(agentID, out r))
|
||||
{
|
||||
if (r.TryGetValue(neighbourHandle, out banUntil))
|
||||
{
|
||||
if (DateTime.Now < banUntil)
|
||||
return false;
|
||||
return null;
|
||||
r.Remove(neighbourHandle);
|
||||
}
|
||||
}
|
||||
@@ -873,28 +796,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
|
||||
|
||||
string reason;
|
||||
string version;
|
||||
if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason))
|
||||
if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
|
||||
{
|
||||
agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
|
||||
if (r == null)
|
||||
{
|
||||
r = new ExpiringCache<ulong, DateTime>();
|
||||
r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
|
||||
|
||||
m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45));
|
||||
m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45));
|
||||
}
|
||||
else
|
||||
{
|
||||
r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return neighbourRegion;
|
||||
}
|
||||
|
||||
public bool Cross(ScenePresence agent, bool isFlying)
|
||||
{
|
||||
uint x;
|
||||
uint y;
|
||||
Vector3 newpos;
|
||||
string version;
|
||||
|
||||
GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos);
|
||||
if (neighbourRegion == null)
|
||||
{
|
||||
agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
|
||||
return false;
|
||||
}
|
||||
|
||||
agent.IsInTransit = true;
|
||||
|
||||
CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
|
||||
d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
|
||||
d.BeginInvoke(agent, newpos, x, y, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -951,13 +889,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
icon.EndInvoke(iar);
|
||||
}
|
||||
|
||||
public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version);
|
||||
|
||||
/// <summary>
|
||||
/// This Closes child agents on neighbouring regions
|
||||
/// Calls an asynchronous method to do so.. so it doesn't lag the sim.
|
||||
/// </summary>
|
||||
protected ScenePresence CrossAgentToNewRegionAsync(
|
||||
public ScenePresence CrossAgentToNewRegionAsync(
|
||||
ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion,
|
||||
bool isFlying, string version)
|
||||
{
|
||||
@@ -1013,6 +949,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
neighbourRegion.RegionHandle);
|
||||
return agent;
|
||||
}
|
||||
// No turning back
|
||||
agent.IsChildAgent = true;
|
||||
|
||||
string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
|
||||
|
||||
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
|
||||
@@ -1161,7 +1100,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
|
||||
/// <summary>
|
||||
/// This informs all neighbouring regions about agent "avatar".
|
||||
/// Calls an asynchronous method to do so.. so it doesn't lag the sim.
|
||||
/// </summary>
|
||||
/// <param name="sp"></param>
|
||||
public void EnableChildAgents(ScenePresence sp)
|
||||
@@ -1281,13 +1219,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
|
||||
if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle)
|
||||
{
|
||||
InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
|
||||
try
|
||||
{
|
||||
//neighbour.ExternalEndPoint may return null, which will be caught
|
||||
d.BeginInvoke(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent,
|
||||
InformClientOfNeighbourCompleted,
|
||||
d);
|
||||
// Let's put this back at sync, so that it doesn't clog
|
||||
// the network, especially for regions in the same physical server.
|
||||
// We're really not in a hurry here.
|
||||
InformClientOfNeighbourAsync(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent);
|
||||
//InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
|
||||
//d.BeginInvoke(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent,
|
||||
// InformClientOfNeighbourCompleted,
|
||||
// d);
|
||||
}
|
||||
|
||||
catch (ArgumentOutOfRangeException)
|
||||
@@ -1720,34 +1661,34 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
|
||||
// Offset the positions for the new region across the border
|
||||
Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
|
||||
grp.RootPart.GroupPosition = pos;
|
||||
|
||||
// If we fail to cross the border, then reset the position of the scene object on that border.
|
||||
uint x = 0, y = 0;
|
||||
Utils.LongToUInts(newRegionHandle, out x, out y);
|
||||
GridRegion destination = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
|
||||
|
||||
if (destination == null || !CrossPrimGroupIntoNewRegion(destination, grp, silent))
|
||||
if (destination != null)
|
||||
{
|
||||
m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID);
|
||||
|
||||
// We are going to move the object back to the old position so long as the old position
|
||||
// is in the region
|
||||
oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1);
|
||||
oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1);
|
||||
oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f);
|
||||
|
||||
grp.RootPart.GroupPosition = oldGroupPosition;
|
||||
|
||||
// Need to turn off the physics flags, otherwise the object will continue to attempt to
|
||||
// move out of the region creating an infinite loop of failed attempts to cross
|
||||
grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false);
|
||||
|
||||
grp.ScheduleGroupForFullUpdate();
|
||||
if (CrossPrimGroupIntoNewRegion(destination, pos, grp, silent))
|
||||
return; // we did it
|
||||
}
|
||||
|
||||
// no one or failed lets go back and tell physics to go on
|
||||
oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 0.5f, (float)Constants.RegionSize - 0.5f);
|
||||
oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
|
||||
oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 0.5f, 4096.0f);
|
||||
|
||||
grp.AbsolutePosition = oldGroupPosition;
|
||||
grp.Velocity = Vector3.Zero;
|
||||
|
||||
if (grp.RootPart.PhysActor != null)
|
||||
grp.RootPart.PhysActor.CrossingFailure();
|
||||
|
||||
grp.ScheduleGroupForFullUpdate();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Move the given scene object into a new region
|
||||
/// </summary>
|
||||
@@ -1757,7 +1698,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
/// true if the crossing itself was successful, false on failure
|
||||
/// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region
|
||||
/// </returns>
|
||||
protected bool CrossPrimGroupIntoNewRegion(GridRegion destination, SceneObjectGroup grp, bool silent)
|
||||
protected bool CrossPrimGroupIntoNewRegion(GridRegion destination, Vector3 newPosition, SceneObjectGroup grp, bool silent)
|
||||
{
|
||||
//m_log.Debug(" >>> CrossPrimGroupIntoNewRegion <<<");
|
||||
|
||||
@@ -1782,7 +1723,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
//if (m_interregionCommsOut != null)
|
||||
// successYN = m_interregionCommsOut.SendCreateObject(newRegionHandle, grp, true);
|
||||
if (m_aScene.SimulationService != null)
|
||||
successYN = m_aScene.SimulationService.CreateObject(destination, grp, true);
|
||||
successYN = m_aScene.SimulationService.CreateObject(destination, newPosition, grp, true);
|
||||
|
||||
if (successYN)
|
||||
{
|
||||
@@ -1841,7 +1782,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
gobj.IsAttachment = false;
|
||||
//gobj.RootPart.LastOwnerID = gobj.GetFromAssetID();
|
||||
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", gobj.UUID, destination.RegionName);
|
||||
CrossPrimGroupIntoNewRegion(destination, gobj, silent);
|
||||
CrossPrimGroupIntoNewRegion(destination, Vector3.Zero, gobj, silent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -560,12 +560,25 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
return null;
|
||||
|
||||
userID = remoteClient.AgentId;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[INVENTORY ACCESS MODULE]: Target of {0} in CreateItemForObject() is {1} {2}",
|
||||
// action, remoteClient.Name, userID);
|
||||
}
|
||||
else if (so.RootPart.OwnerID == so.RootPart.GroupID)
|
||||
{
|
||||
// Group owned objects go to the last owner before the object was transferred.
|
||||
userID = so.RootPart.LastOwnerID;
|
||||
}
|
||||
else
|
||||
{
|
||||
// All returns / deletes go to the object owner
|
||||
// Other returns / deletes go to the object owner
|
||||
//
|
||||
userID = so.RootPart.OwnerID;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[INVENTORY ACCESS MODULE]: Target of {0} in CreateItemForObject() is object owner {1}",
|
||||
// action, userID);
|
||||
}
|
||||
|
||||
if (userID == UUID.Zero) // Can't proceed
|
||||
@@ -651,11 +664,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
}
|
||||
|
||||
// Override and put into where it came from, if it came
|
||||
// from anywhere in inventory
|
||||
// from anywhere in inventory and the owner is taking it back.
|
||||
//
|
||||
if (action == DeRezAction.Take || action == DeRezAction.TakeCopy)
|
||||
{
|
||||
if (so.RootPart.FromFolderID != UUID.Zero)
|
||||
if (so.RootPart.FromFolderID != UUID.Zero && userID == remoteClient.AgentId)
|
||||
{
|
||||
InventoryFolderBase f = new InventoryFolderBase(so.RootPart.FromFolderID, userID);
|
||||
if (f != null)
|
||||
@@ -830,6 +843,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
group = objlist[i];
|
||||
SceneObjectPart rootPart = group.RootPart;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[InventoryAccessModule]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
|
||||
// group.Name, group.LocalId, group.UUID,
|
||||
// group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask,
|
||||
// remoteClient.Name);
|
||||
|
||||
// Vector3 storedPosition = group.AbsolutePosition;
|
||||
if (group.UUID == UUID.Zero)
|
||||
{
|
||||
@@ -892,6 +911,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
|
||||
rootPart.ScheduleFullUpdate();
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[InventoryAccessModule]: Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
|
||||
// group.Name, group.LocalId, group.UUID,
|
||||
// group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask,
|
||||
// remoteClient.Name);
|
||||
}
|
||||
|
||||
group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
|
||||
@@ -958,7 +983,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
}
|
||||
|
||||
rootPart.FromFolderID = item.Folder;
|
||||
|
||||
|
||||
// Console.WriteLine("rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}",
|
||||
// rootPart.OwnerID, item.Owner, item.CurrentPermissions);
|
||||
|
||||
if ((rootPart.OwnerID != item.Owner) ||
|
||||
(item.CurrentPermissions & 16) != 0 ||
|
||||
(item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)
|
||||
|
||||
@@ -65,13 +65,26 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||
}
|
||||
}
|
||||
|
||||
internal struct ScopedRegionPosition
|
||||
{
|
||||
public UUID m_scopeID;
|
||||
public ulong m_regionHandle;
|
||||
public ScopedRegionPosition(UUID scopeID, ulong handle)
|
||||
{
|
||||
m_scopeID = scopeID;
|
||||
m_regionHandle = handle;
|
||||
}
|
||||
}
|
||||
|
||||
private ExpiringCache<ScopedRegionUUID, GridRegion> m_UUIDCache;
|
||||
private ExpiringCache<ScopedRegionName, ScopedRegionUUID> m_NameCache;
|
||||
private ExpiringCache<ScopedRegionPosition, GridRegion> m_PositionCache;
|
||||
|
||||
public RegionInfoCache()
|
||||
{
|
||||
m_UUIDCache = new ExpiringCache<ScopedRegionUUID, GridRegion>();
|
||||
m_NameCache = new ExpiringCache<ScopedRegionName, ScopedRegionUUID>();
|
||||
m_NameCache = new ExpiringCache<ScopedRegionName, ScopedRegionUUID>();
|
||||
m_PositionCache = new ExpiringCache<ScopedRegionPosition, GridRegion>();
|
||||
}
|
||||
|
||||
public void Cache(GridRegion rinfo)
|
||||
@@ -96,6 +109,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||
{
|
||||
ScopedRegionName name = new ScopedRegionName(scopeID,rinfo.RegionName);
|
||||
m_NameCache.AddOrUpdate(name, id, CACHE_EXPIRATION_SECONDS);
|
||||
|
||||
ScopedRegionPosition pos = new ScopedRegionPosition(scopeID, rinfo.RegionHandle);
|
||||
m_PositionCache.AddOrUpdate(pos, rinfo, CACHE_EXPIRATION_SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,6 +130,22 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||
return null;
|
||||
}
|
||||
|
||||
public GridRegion Get(UUID scopeID, ulong handle, out bool inCache)
|
||||
{
|
||||
inCache = false;
|
||||
|
||||
GridRegion rinfo = null;
|
||||
ScopedRegionPosition pos = new ScopedRegionPosition(scopeID, handle);
|
||||
if (m_PositionCache.TryGetValue(pos, out rinfo))
|
||||
{
|
||||
inCache = true;
|
||||
return rinfo;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public GridRegion Get(UUID scopeID, string name, out bool inCache)
|
||||
{
|
||||
inCache = false;
|
||||
|
||||
@@ -186,10 +186,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||
|
||||
public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
|
||||
{
|
||||
GridRegion rinfo = m_LocalGridService.GetRegionByPosition(scopeID, x, y);
|
||||
bool inCache = false;
|
||||
GridRegion rinfo = m_RegionInfoCache.Get(scopeID, Util.UIntsToLong((uint)x, (uint)y), out inCache);
|
||||
if (inCache)
|
||||
return rinfo;
|
||||
|
||||
rinfo = m_LocalGridService.GetRegionByPosition(scopeID, x, y);
|
||||
if (rinfo == null)
|
||||
rinfo = m_RemoteGridService.GetRegionByPosition(scopeID, x, y);
|
||||
|
||||
m_RegionInfoCache.Cache(rinfo);
|
||||
return rinfo;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -328,7 +328,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
|
||||
* Object-related communications
|
||||
*/
|
||||
|
||||
public bool CreateObject(GridRegion destination, ISceneObject sog, bool isLocalCall)
|
||||
public bool CreateObject(GridRegion destination, Vector3 newPosition, ISceneObject sog, bool isLocalCall)
|
||||
{
|
||||
if (destination == null)
|
||||
return false;
|
||||
@@ -343,12 +343,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
|
||||
// We need to make a local copy of the object
|
||||
ISceneObject sogClone = sog.CloneForNewScene();
|
||||
sogClone.SetState(sog.GetStateSnapshot(), s);
|
||||
return s.IncomingCreateObject(sogClone);
|
||||
return s.IncomingCreateObject(newPosition, sogClone);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the object as it came through the wire
|
||||
return s.IncomingCreateObject(sog);
|
||||
return s.IncomingCreateObject(newPosition, sog);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -297,13 +297,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
|
||||
* Object-related communications
|
||||
*/
|
||||
|
||||
public bool CreateObject(GridRegion destination, ISceneObject sog, bool isLocalCall)
|
||||
public bool CreateObject(GridRegion destination, Vector3 newPosition, ISceneObject sog, bool isLocalCall)
|
||||
{
|
||||
if (destination == null)
|
||||
return false;
|
||||
|
||||
// Try local first
|
||||
if (m_localBackend.CreateObject(destination, sog, isLocalCall))
|
||||
if (m_localBackend.CreateObject(destination, newPosition, sog, isLocalCall))
|
||||
{
|
||||
//m_log.Debug("[REST COMMS]: LocalBackEnd SendCreateObject succeeded");
|
||||
return true;
|
||||
@@ -311,7 +311,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
|
||||
|
||||
// else do the remote thing
|
||||
if (!m_localBackend.IsLocalRegion(destination.RegionHandle))
|
||||
return m_remoteConnector.CreateObject(destination, sog, isLocalCall);
|
||||
return m_remoteConnector.CreateObject(destination, newPosition, sog, isLocalCall);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -290,7 +290,8 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||
ParcelFlags.AllowGroupScripts |
|
||||
ParcelFlags.CreateGroupObjects |
|
||||
ParcelFlags.AllowAPrimitiveEntry |
|
||||
ParcelFlags.AllowGroupObjectEntry);
|
||||
ParcelFlags.AllowGroupObjectEntry |
|
||||
ParcelFlags.AllowFly);
|
||||
}
|
||||
|
||||
if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandSetSale))
|
||||
|
||||
@@ -677,18 +677,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||
bool permission = false;
|
||||
bool locked = false;
|
||||
|
||||
if (!m_scene.Entities.ContainsKey(objId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
SceneObjectPart part = m_scene.GetSceneObjectPart(objId);
|
||||
|
||||
// If it's not an object, we cant edit it.
|
||||
if ((!(m_scene.Entities[objId] is SceneObjectGroup)))
|
||||
{
|
||||
if (part == null)
|
||||
return false;
|
||||
}
|
||||
|
||||
SceneObjectGroup group = (SceneObjectGroup)m_scene.Entities[objId];
|
||||
SceneObjectGroup group = part.ParentGroup;
|
||||
|
||||
UUID objectOwner = group.OwnerID;
|
||||
locked = ((group.RootPart.OwnerMask & PERM_LOCKED) == 0);
|
||||
@@ -707,7 +701,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||
// Object owners should be able to edit their own content
|
||||
if (currentUser == objectOwner)
|
||||
{
|
||||
permission = true;
|
||||
// there is no way that later code can change this back to false
|
||||
// so just return true immediately and short circuit the more
|
||||
// expensive group checks
|
||||
return true;
|
||||
|
||||
//permission = true;
|
||||
}
|
||||
else if (group.IsAttachment)
|
||||
{
|
||||
@@ -972,16 +971,6 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||
DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name);
|
||||
if (m_bypassPermissions) return m_bypassPermissionsValue;
|
||||
|
||||
SceneObjectPart part = m_scene.GetSceneObjectPart(objectID);
|
||||
|
||||
// If we selected a sub-prim to edit, the objectID won't represent the object, but only a part.
|
||||
// We have to check the permissions of the group, though.
|
||||
if (part.ParentID != 0)
|
||||
{
|
||||
objectID = part.ParentUUID;
|
||||
part = m_scene.GetSceneObjectPart(objectID);
|
||||
}
|
||||
|
||||
return GenericObjectPermission(editorID, objectID, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -148,6 +148,113 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
|
||||
<OtherParts />
|
||||
</SceneObjectGroup>";
|
||||
|
||||
private string badFloatsXml = @"
|
||||
<SceneObjectGroup>
|
||||
<RootPart>
|
||||
<SceneObjectPart xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
|
||||
<AllowedDrop>false</AllowedDrop>
|
||||
<CreatorID><Guid>a6dacf01-4636-4bb9-8a97-30609438af9d</Guid></CreatorID>
|
||||
<FolderID><Guid>e6a5a05e-e8cc-4816-8701-04165e335790</Guid></FolderID>
|
||||
<InventorySerial>1</InventorySerial>
|
||||
<TaskInventory />
|
||||
<ObjectFlags>0</ObjectFlags>
|
||||
<UUID><Guid>e6a5a05e-e8cc-4816-8701-04165e335790</Guid></UUID>
|
||||
<LocalId>2698615125</LocalId>
|
||||
<Name>NaughtyPrim</Name>
|
||||
<Material>0</Material>
|
||||
<PassTouches>false</PassTouches>
|
||||
<RegionHandle>1099511628032000</RegionHandle>
|
||||
<ScriptAccessPin>0</ScriptAccessPin>
|
||||
<GroupPosition><X>147.23</X><Y>92.698</Y><Z>22.78084</Z></GroupPosition>
|
||||
<OffsetPosition><X>0</X><Y>0</Y><Z>0</Z></OffsetPosition>
|
||||
<RotationOffset><X>-4.371139E-08</X><Y>-1</Y><Z>-4.371139E-08</Z><W>0</W></RotationOffset>
|
||||
<Velocity><X>0</X><Y>0</Y><Z>0</Z></Velocity>
|
||||
<RotationalVelocity><X>0</X><Y>0</Y><Z>0</Z></RotationalVelocity>
|
||||
<AngularVelocity><X>0</X><Y>0</Y><Z>0</Z></AngularVelocity>
|
||||
<Acceleration><X>0</X><Y>0</Y><Z>0</Z></Acceleration>
|
||||
<Description />
|
||||
<Color />
|
||||
<Text />
|
||||
<SitName />
|
||||
<TouchName />
|
||||
<LinkNum>0</LinkNum>
|
||||
<ClickAction>0</ClickAction>
|
||||
<Shape>
|
||||
<ProfileCurve>1</ProfileCurve>
|
||||
<TextureEntry>AAAAAAAAERGZmQAAAAAABQCVlZUAAAAAQEAAAABAQAAAAAAAAAAAAAAAAAAAAA==</TextureEntry>
|
||||
<ExtraParams>AA==</ExtraParams>
|
||||
<PathBegin>0</PathBegin>
|
||||
<PathCurve>16</PathCurve>
|
||||
<PathEnd>0</PathEnd>
|
||||
<PathRadiusOffset>0</PathRadiusOffset>
|
||||
<PathRevolutions>0</PathRevolutions>
|
||||
<PathScaleX>100</PathScaleX>
|
||||
<PathScaleY>100</PathScaleY>
|
||||
<PathShearX>0</PathShearX>
|
||||
<PathShearY>0</PathShearY>
|
||||
<PathSkew>0</PathSkew>
|
||||
<PathTaperX>0</PathTaperX>
|
||||
<PathTaperY>0</PathTaperY>
|
||||
<PathTwist>0</PathTwist>
|
||||
<PathTwistBegin>0</PathTwistBegin>
|
||||
<PCode>9</PCode>
|
||||
<ProfileBegin>0</ProfileBegin>
|
||||
<ProfileEnd>0</ProfileEnd>
|
||||
<ProfileHollow>0</ProfileHollow>
|
||||
<Scale><X>10</X><Y>10</Y><Z>0.5</Z></Scale>
|
||||
<State>0</State>
|
||||
<ProfileShape>Square</ProfileShape>
|
||||
<HollowShape>Same</HollowShape>
|
||||
<SculptTexture><Guid>00000000-0000-0000-0000-000000000000</Guid></SculptTexture>
|
||||
<SculptType>0</SculptType><SculptData />
|
||||
<FlexiSoftness>0</FlexiSoftness>
|
||||
<FlexiTension>0,5</FlexiTension>
|
||||
<FlexiDrag>yo mamma</FlexiDrag>
|
||||
<FlexiGravity>0</FlexiGravity>
|
||||
<FlexiWind>0</FlexiWind>
|
||||
<FlexiForceX>0</FlexiForceX>
|
||||
<FlexiForceY>0</FlexiForceY>
|
||||
<FlexiForceZ>0</FlexiForceZ>
|
||||
<LightColorR>0</LightColorR>
|
||||
<LightColorG>0</LightColorG>
|
||||
<LightColorB>0</LightColorB>
|
||||
<LightColorA>1</LightColorA>
|
||||
<LightRadius>0</LightRadius>
|
||||
<LightCutoff>0</LightCutoff>
|
||||
<LightFalloff>0</LightFalloff>
|
||||
<LightIntensity>1</LightIntensity>
|
||||
<FlexiEntry>false</FlexiEntry>
|
||||
<LightEntry>false</LightEntry>
|
||||
<SculptEntry>false</SculptEntry>
|
||||
</Shape>
|
||||
<Scale><X>10</X><Y>10</Y><Z>0.5</Z></Scale>
|
||||
<UpdateFlag>0</UpdateFlag>
|
||||
<SitTargetOrientation><X>0</X><Y>0</Y><Z>0</Z><W>1</W></SitTargetOrientation>
|
||||
<SitTargetPosition><X>0</X><Y>0</Y><Z>0</Z></SitTargetPosition>
|
||||
<SitTargetPositionLL><X>0</X><Y>0</Y><Z>0</Z></SitTargetPositionLL>
|
||||
<SitTargetOrientationLL><X>0</X><Y>0</Y><Z>0</Z><W>1</W></SitTargetOrientationLL>
|
||||
<ParentID>0</ParentID>
|
||||
<CreationDate>1211330445</CreationDate>
|
||||
<Category>0</Category>
|
||||
<SalePrice>0</SalePrice>
|
||||
<ObjectSaleType>0</ObjectSaleType>
|
||||
<OwnershipCost>0</OwnershipCost>
|
||||
<GroupID><Guid>00000000-0000-0000-0000-000000000000</Guid></GroupID>
|
||||
<OwnerID><Guid>a6dacf01-4636-4bb9-8a97-30609438af9d</Guid></OwnerID>
|
||||
<LastOwnerID><Guid>a6dacf01-4636-4bb9-8a97-30609438af9d</Guid></LastOwnerID>
|
||||
<BaseMask>2147483647</BaseMask>
|
||||
<OwnerMask>2147483647</OwnerMask>
|
||||
<GroupMask>0</GroupMask>
|
||||
<EveryoneMask>0</EveryoneMask>
|
||||
<NextOwnerMask>2147483647</NextOwnerMask>
|
||||
<Flags>None</Flags>
|
||||
<CollisionSound><Guid>00000000-0000-0000-0000-000000000000</Guid></CollisionSound>
|
||||
<CollisionSoundVolume>0</CollisionSoundVolume>
|
||||
</SceneObjectPart>
|
||||
</RootPart>
|
||||
<OtherParts />
|
||||
</SceneObjectGroup>";
|
||||
|
||||
private string xml2 = @"
|
||||
<SceneObjectGroup>
|
||||
<SceneObjectPart xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
|
||||
@@ -256,6 +363,32 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests
|
||||
// TODO: Check other properties
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDeserializeBadFloatsXml()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
SceneObjectGroup so = SceneObjectSerializer.FromOriginalXmlFormat(badFloatsXml);
|
||||
SceneObjectPart rootPart = so.RootPart;
|
||||
|
||||
Assert.That(rootPart.UUID, Is.EqualTo(new UUID("e6a5a05e-e8cc-4816-8701-04165e335790")));
|
||||
Assert.That(rootPart.CreatorID, Is.EqualTo(new UUID("a6dacf01-4636-4bb9-8a97-30609438af9d")));
|
||||
Assert.That(rootPart.Name, Is.EqualTo("NaughtyPrim"));
|
||||
|
||||
// This terminates the deserialization earlier if couldn't be parsed.
|
||||
// TODO: Need to address this
|
||||
Assert.That(rootPart.GroupPosition.X, Is.EqualTo(147.23f));
|
||||
|
||||
Assert.That(rootPart.Shape.PathCurve, Is.EqualTo(16));
|
||||
|
||||
// Defaults for bad parses
|
||||
Assert.That(rootPart.Shape.FlexiTension, Is.EqualTo(0));
|
||||
Assert.That(rootPart.Shape.FlexiDrag, Is.EqualTo(0));
|
||||
|
||||
// TODO: Check other properties
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSerializeXml()
|
||||
{
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
|
||||
public interface IAvatarFactoryModule
|
||||
{
|
||||
void SetAppearance(IScenePresence sp, AvatarAppearance appearance);
|
||||
void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -35,6 +35,8 @@ using OpenSim.Region.Framework.Scenes;
|
||||
|
||||
namespace OpenSim.Region.Framework.Interfaces
|
||||
{
|
||||
public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version);
|
||||
|
||||
public interface IEntityTransferModule
|
||||
{
|
||||
void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position,
|
||||
@@ -53,7 +55,12 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
|
||||
void EnableChildAgent(ScenePresence agent, GridRegion region);
|
||||
|
||||
GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos);
|
||||
|
||||
void Cross(SceneObjectGroup sog, Vector3 position, bool silent);
|
||||
|
||||
ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version);
|
||||
|
||||
}
|
||||
|
||||
public interface IUserAgentVerificationModule
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||
/// </param>
|
||||
/// <param name="scene"></param>
|
||||
/// <param name="appearance">The avatar appearance to use for the new NPC.</param>
|
||||
/// <returns>The UUID of the ScenePresence created.</returns>
|
||||
/// <returns>The UUID of the ScenePresence created. UUID.Zero if there was a failure.</returns>
|
||||
UUID CreateNPC(
|
||||
string firstname,
|
||||
string lastname,
|
||||
|
||||
@@ -148,7 +148,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
x = m_inventoryDeletes.Dequeue();
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[ASYNC DELETER]: Sending object to user's inventory, action {1}, count {2}, {0} item(s) remaining.", left, x.action, x.objectGroups.Count);
|
||||
"[ASYNC DELETER]: Sending object to user's inventory, action {1}, count {2}, {0} item(s) remaining.",
|
||||
left, x.action, x.objectGroups.Count);
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@@ -177,6 +177,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
public delegate void AvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID);
|
||||
public event AvatarEnteringNewParcel OnAvatarEnteringNewParcel;
|
||||
|
||||
public delegate void AvatarAppearanceChange(ScenePresence avatar);
|
||||
public event AvatarAppearanceChange OnAvatarAppearanceChange;
|
||||
|
||||
public event Action<ScenePresence> OnSignificantClientMovement;
|
||||
|
||||
public delegate void IncomingInstantMessage(GridInstantMessage message);
|
||||
@@ -188,10 +191,62 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
public event ClientClosed OnClientClosed;
|
||||
|
||||
// Fired when a script is created
|
||||
// The indication that a new script exists in this region.
|
||||
public delegate void NewScript(UUID clientID, SceneObjectPart part, UUID itemID);
|
||||
public event NewScript OnNewScript;
|
||||
public virtual void TriggerNewScript(UUID clientID, SceneObjectPart part, UUID itemID)
|
||||
{
|
||||
NewScript handlerNewScript = OnNewScript;
|
||||
if (handlerNewScript != null)
|
||||
{
|
||||
foreach (NewScript d in handlerNewScript.GetInvocationList())
|
||||
{
|
||||
try
|
||||
{
|
||||
d(clientID, part, itemID);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[EVENT MANAGER]: Delegate for TriggerNewScript failed - continuing. {0} {1}",
|
||||
e.Message, e.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TriggerUpdateScript: triggered after Scene receives client's upload of updated script and stores it as asset
|
||||
// An indication that the script has changed.
|
||||
public delegate void UpdateScript(UUID clientID, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID);
|
||||
public event UpdateScript OnUpdateScript;
|
||||
public virtual void TriggerUpdateScript(UUID clientId, UUID itemId, UUID primId, bool isScriptRunning, UUID newAssetID)
|
||||
{
|
||||
UpdateScript handlerUpdateScript = OnUpdateScript;
|
||||
if (handlerUpdateScript != null)
|
||||
{
|
||||
foreach (UpdateScript d in handlerUpdateScript.GetInvocationList())
|
||||
{
|
||||
try
|
||||
{
|
||||
d(clientId, itemId, primId, isScriptRunning, newAssetID);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[EVENT MANAGER]: Delegate for TriggerUpdateScript failed - continuing. {0} {1}",
|
||||
e.Message, e.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is fired when a scene object property that a script might be interested in (such as color, scale or
|
||||
/// inventory) changes. Only enough information is sent for the LSL changed event
|
||||
/// (see http://lslwiki.net/lslwiki/wakka.php?wakka=changed)
|
||||
/// ScriptChangedEvent is fired when a scene object property that a script might be interested
|
||||
/// in (such as color, scale or inventory) changes. Only enough information sent is for the LSL changed event.
|
||||
/// This is not an indication that the script has changed (see OnUpdateScript for that).
|
||||
/// This event is sent to a script to tell it that some property changed on
|
||||
/// the object the script is in. See http://lslwiki.net/lslwiki/wakka.php?wakka=changed .
|
||||
/// </summary>
|
||||
public event ScriptChangedEvent OnScriptChangedEvent;
|
||||
public delegate void ScriptChangedEvent(uint localID, uint change);
|
||||
@@ -1262,6 +1317,27 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
public void TriggerAvatarAppearanceChanged(ScenePresence avatar)
|
||||
{
|
||||
AvatarAppearanceChange handler = OnAvatarAppearanceChange;
|
||||
if (handler != null)
|
||||
{
|
||||
foreach (AvatarAppearanceChange d in handler.GetInvocationList())
|
||||
{
|
||||
try
|
||||
{
|
||||
d(avatar);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[EVENT MANAGER]: Delegate for TriggerAvatarAppearanceChanged failed - continuing. {0} {1}",
|
||||
e.Message, e.StackTrace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void TriggerIncomingInstantMessage(GridInstantMessage message)
|
||||
{
|
||||
IncomingInstantMessage handlerIncomingInstantMessage = OnIncomingInstantMessage;
|
||||
|
||||
@@ -0,0 +1,742 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
using System.Xml;
|
||||
using OpenSim.Framework.Serialization;
|
||||
using OpenSim.Framework.Serialization.External;
|
||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
||||
|
||||
namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
public class SOPVehicle
|
||||
{
|
||||
public VehicleData vd;
|
||||
|
||||
public Vehicle Type
|
||||
{
|
||||
get { return vd.m_type; }
|
||||
}
|
||||
|
||||
public SOPVehicle()
|
||||
{
|
||||
vd = new VehicleData();
|
||||
ProcessTypeChange(Vehicle.TYPE_NONE); // is needed?
|
||||
}
|
||||
|
||||
public void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
|
||||
{
|
||||
float len;
|
||||
float timestep = 0.01f;
|
||||
switch (pParam)
|
||||
{
|
||||
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
|
||||
if (pValue < 0f) pValue = 0f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
vd.m_angularDeflectionEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
vd.m_angularDeflectionTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
else if (pValue > 120) pValue = 120;
|
||||
vd.m_angularMotorDecayTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
vd.m_angularMotorTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.BANKING_EFFICIENCY:
|
||||
if (pValue < -1f) pValue = -1f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
vd.m_bankingEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.BANKING_MIX:
|
||||
if (pValue < 0f) pValue = 0f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
vd.m_bankingMix = pValue;
|
||||
break;
|
||||
case Vehicle.BANKING_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
vd.m_bankingTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.BUOYANCY:
|
||||
if (pValue < -1f) pValue = -1f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
vd.m_VehicleBuoyancy = pValue;
|
||||
break;
|
||||
case Vehicle.HOVER_EFFICIENCY:
|
||||
if (pValue < 0f) pValue = 0f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
vd.m_VhoverEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.HOVER_HEIGHT:
|
||||
vd.m_VhoverHeight = pValue;
|
||||
break;
|
||||
case Vehicle.HOVER_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
vd.m_VhoverTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
|
||||
if (pValue < 0f) pValue = 0f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
vd.m_linearDeflectionEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
vd.m_linearDeflectionTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
else if (pValue > 120) pValue = 120;
|
||||
vd.m_linearMotorDecayTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
vd.m_linearMotorTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
|
||||
if (pValue < 0f) pValue = 0f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
vd.m_verticalAttractionEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
vd.m_verticalAttractionTimescale = pValue;
|
||||
break;
|
||||
|
||||
// These are vector properties but the engine lets you use a single float value to
|
||||
// set all of the components to the same value
|
||||
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
vd.m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||
vd.m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||
len = vd.m_angularMotorDirection.Length();
|
||||
if (len > 12.566f)
|
||||
vd.m_angularMotorDirection *= (12.566f / len);
|
||||
break;
|
||||
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
vd.m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||
vd.m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||
len = vd.m_linearMotorDirection.Length();
|
||||
if (len > 30.0f)
|
||||
vd.m_linearMotorDirection *= (30.0f / len);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||
vd.m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
|
||||
len = vd.m_linearMotorOffset.Length();
|
||||
if (len > 100.0f)
|
||||
vd.m_linearMotorOffset *= (100.0f / len);
|
||||
break;
|
||||
}
|
||||
}//end ProcessFloatVehicleParam
|
||||
|
||||
public void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue)
|
||||
{
|
||||
float len;
|
||||
float timestep = 0.01f;
|
||||
switch (pParam)
|
||||
{
|
||||
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||
if (pValue.X < timestep) pValue.X = timestep;
|
||||
if (pValue.Y < timestep) pValue.Y = timestep;
|
||||
if (pValue.Z < timestep) pValue.Z = timestep;
|
||||
|
||||
vd.m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||
vd.m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
// Limit requested angular speed to 2 rps= 4 pi rads/sec
|
||||
len = vd.m_angularMotorDirection.Length();
|
||||
if (len > 12.566f)
|
||||
vd.m_angularMotorDirection *= (12.566f / len);
|
||||
break;
|
||||
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||
if (pValue.X < timestep) pValue.X = timestep;
|
||||
if (pValue.Y < timestep) pValue.Y = timestep;
|
||||
if (pValue.Z < timestep) pValue.Z = timestep;
|
||||
vd.m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||
vd.m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
len = vd.m_linearMotorDirection.Length();
|
||||
if (len > 30.0f)
|
||||
vd.m_linearMotorDirection *= (30.0f / len);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||
vd.m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
len = vd.m_linearMotorOffset.Length();
|
||||
if (len > 100.0f)
|
||||
vd.m_linearMotorOffset *= (100.0f / len);
|
||||
break;
|
||||
}
|
||||
}//end ProcessVectorVehicleParam
|
||||
|
||||
public void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
|
||||
{
|
||||
switch (pParam)
|
||||
{
|
||||
case Vehicle.REFERENCE_FRAME:
|
||||
vd.m_referenceFrame = Quaternion.Inverse(pValue);
|
||||
break;
|
||||
}
|
||||
}//end ProcessRotationVehicleParam
|
||||
|
||||
public void ProcessVehicleFlags(int pParam, bool remove)
|
||||
{
|
||||
if (remove)
|
||||
{
|
||||
vd.m_flags &= ~((VehicleFlag)pParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
vd.m_flags |= (VehicleFlag)pParam;
|
||||
}
|
||||
}//end ProcessVehicleFlags
|
||||
|
||||
public void ProcessTypeChange(Vehicle pType)
|
||||
{
|
||||
vd.m_linearMotorDirection = Vector3.Zero;
|
||||
vd.m_angularMotorDirection = Vector3.Zero;
|
||||
vd.m_linearMotorOffset = Vector3.Zero;
|
||||
vd.m_referenceFrame = Quaternion.Identity;
|
||||
|
||||
// Set Defaults For Type
|
||||
vd.m_type = pType;
|
||||
switch (pType)
|
||||
{
|
||||
case Vehicle.TYPE_NONE:
|
||||
vd.m_linearFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||
vd.m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||
vd.m_linearMotorTimescale = 1000;
|
||||
vd.m_linearMotorDecayTimescale = 120;
|
||||
vd.m_angularMotorTimescale = 1000;
|
||||
vd.m_angularMotorDecayTimescale = 1000;
|
||||
vd.m_VhoverHeight = 0;
|
||||
vd.m_VhoverEfficiency = 1;
|
||||
vd.m_VhoverTimescale = 1000;
|
||||
vd.m_VehicleBuoyancy = 0;
|
||||
vd.m_linearDeflectionEfficiency = 0;
|
||||
vd.m_linearDeflectionTimescale = 1000;
|
||||
vd.m_angularDeflectionEfficiency = 0;
|
||||
vd.m_angularDeflectionTimescale = 1000;
|
||||
vd.m_bankingEfficiency = 0;
|
||||
vd.m_bankingMix = 1;
|
||||
vd.m_bankingTimescale = 1000;
|
||||
vd.m_verticalAttractionEfficiency = 0;
|
||||
vd.m_verticalAttractionTimescale = 1000;
|
||||
|
||||
vd.m_flags = (VehicleFlag)0;
|
||||
break;
|
||||
|
||||
case Vehicle.TYPE_SLED:
|
||||
vd.m_linearFrictionTimescale = new Vector3(30, 1, 1000);
|
||||
vd.m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||
vd.m_linearMotorTimescale = 1000;
|
||||
vd.m_linearMotorDecayTimescale = 120;
|
||||
vd.m_angularMotorTimescale = 1000;
|
||||
vd.m_angularMotorDecayTimescale = 120;
|
||||
vd.m_VhoverHeight = 0;
|
||||
vd.m_VhoverEfficiency = 1;
|
||||
vd.m_VhoverTimescale = 10;
|
||||
vd.m_VehicleBuoyancy = 0;
|
||||
vd.m_linearDeflectionEfficiency = 1;
|
||||
vd.m_linearDeflectionTimescale = 1;
|
||||
vd.m_angularDeflectionEfficiency = 0;
|
||||
vd.m_angularDeflectionTimescale = 1000;
|
||||
vd.m_bankingEfficiency = 0;
|
||||
vd.m_bankingMix = 1;
|
||||
vd.m_bankingTimescale = 10;
|
||||
vd.m_flags &=
|
||||
~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
|
||||
vd.m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||
break;
|
||||
case Vehicle.TYPE_CAR:
|
||||
vd.m_linearFrictionTimescale = new Vector3(100, 2, 1000);
|
||||
vd.m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||
vd.m_linearMotorTimescale = 1;
|
||||
vd.m_linearMotorDecayTimescale = 60;
|
||||
vd.m_angularMotorTimescale = 1;
|
||||
vd.m_angularMotorDecayTimescale = 0.8f;
|
||||
vd.m_VhoverHeight = 0;
|
||||
vd.m_VhoverEfficiency = 0;
|
||||
vd.m_VhoverTimescale = 1000;
|
||||
vd.m_VehicleBuoyancy = 0;
|
||||
vd.m_linearDeflectionEfficiency = 1;
|
||||
vd.m_linearDeflectionTimescale = 2;
|
||||
vd.m_angularDeflectionEfficiency = 0;
|
||||
vd.m_angularDeflectionTimescale = 10;
|
||||
vd.m_verticalAttractionEfficiency = 1f;
|
||||
vd.m_verticalAttractionTimescale = 10f;
|
||||
vd.m_bankingEfficiency = -0.2f;
|
||||
vd.m_bankingMix = 1;
|
||||
vd.m_bankingTimescale = 1;
|
||||
vd.m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||
vd.m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY |
|
||||
VehicleFlag.LIMIT_MOTOR_UP | VehicleFlag.HOVER_UP_ONLY);
|
||||
break;
|
||||
case Vehicle.TYPE_BOAT:
|
||||
vd.m_linearFrictionTimescale = new Vector3(10, 3, 2);
|
||||
vd.m_angularFrictionTimescale = new Vector3(10, 10, 10);
|
||||
vd.m_linearMotorTimescale = 5;
|
||||
vd.m_linearMotorDecayTimescale = 60;
|
||||
vd.m_angularMotorTimescale = 4;
|
||||
vd.m_angularMotorDecayTimescale = 4;
|
||||
vd.m_VhoverHeight = 0;
|
||||
vd.m_VhoverEfficiency = 0.5f;
|
||||
vd.m_VhoverTimescale = 2;
|
||||
vd.m_VehicleBuoyancy = 1;
|
||||
vd.m_linearDeflectionEfficiency = 0.5f;
|
||||
vd.m_linearDeflectionTimescale = 3;
|
||||
vd.m_angularDeflectionEfficiency = 0.5f;
|
||||
vd.m_angularDeflectionTimescale = 5;
|
||||
vd.m_verticalAttractionEfficiency = 0.5f;
|
||||
vd.m_verticalAttractionTimescale = 5f;
|
||||
vd.m_bankingEfficiency = -0.3f;
|
||||
vd.m_bankingMix = 0.8f;
|
||||
vd.m_bankingTimescale = 1;
|
||||
vd.m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT |
|
||||
VehicleFlag.HOVER_UP_ONLY |
|
||||
VehicleFlag.LIMIT_ROLL_ONLY);
|
||||
vd.m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
|
||||
VehicleFlag.LIMIT_MOTOR_UP |
|
||||
VehicleFlag.HOVER_WATER_ONLY);
|
||||
break;
|
||||
case Vehicle.TYPE_AIRPLANE:
|
||||
vd.m_linearFrictionTimescale = new Vector3(200, 10, 5);
|
||||
vd.m_angularFrictionTimescale = new Vector3(20, 20, 20);
|
||||
vd.m_linearMotorTimescale = 2;
|
||||
vd.m_linearMotorDecayTimescale = 60;
|
||||
vd.m_angularMotorTimescale = 4;
|
||||
vd.m_angularMotorDecayTimescale = 8;
|
||||
vd.m_VhoverHeight = 0;
|
||||
vd.m_VhoverEfficiency = 0.5f;
|
||||
vd.m_VhoverTimescale = 1000;
|
||||
vd.m_VehicleBuoyancy = 0;
|
||||
vd.m_linearDeflectionEfficiency = 0.5f;
|
||||
vd.m_linearDeflectionTimescale = 0.5f;
|
||||
vd.m_angularDeflectionEfficiency = 1;
|
||||
vd.m_angularDeflectionTimescale = 2;
|
||||
vd.m_verticalAttractionEfficiency = 0.9f;
|
||||
vd.m_verticalAttractionTimescale = 2f;
|
||||
vd.m_bankingEfficiency = 1;
|
||||
vd.m_bankingMix = 0.7f;
|
||||
vd.m_bankingTimescale = 2;
|
||||
vd.m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY |
|
||||
VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT |
|
||||
VehicleFlag.HOVER_UP_ONLY |
|
||||
VehicleFlag.NO_DEFLECTION_UP |
|
||||
VehicleFlag.LIMIT_MOTOR_UP);
|
||||
vd.m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
|
||||
break;
|
||||
case Vehicle.TYPE_BALLOON:
|
||||
vd.m_linearFrictionTimescale = new Vector3(5, 5, 5);
|
||||
vd.m_angularFrictionTimescale = new Vector3(10, 10, 10);
|
||||
vd.m_linearMotorTimescale = 5;
|
||||
vd.m_linearMotorDecayTimescale = 60;
|
||||
vd.m_angularMotorTimescale = 6;
|
||||
vd.m_angularMotorDecayTimescale = 10;
|
||||
vd.m_VhoverHeight = 5;
|
||||
vd.m_VhoverEfficiency = 0.8f;
|
||||
vd.m_VhoverTimescale = 10;
|
||||
vd.m_VehicleBuoyancy = 1;
|
||||
vd.m_linearDeflectionEfficiency = 0;
|
||||
vd.m_linearDeflectionTimescale = 5;
|
||||
vd.m_angularDeflectionEfficiency = 0;
|
||||
vd.m_angularDeflectionTimescale = 5;
|
||||
vd.m_verticalAttractionEfficiency = 0f;
|
||||
vd.m_verticalAttractionTimescale = 1000f;
|
||||
vd.m_bankingEfficiency = 0;
|
||||
vd.m_bankingMix = 0.7f;
|
||||
vd.m_bankingTimescale = 5;
|
||||
vd.m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY |
|
||||
VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_UP_ONLY |
|
||||
VehicleFlag.NO_DEFLECTION_UP |
|
||||
VehicleFlag.LIMIT_MOTOR_UP);
|
||||
vd.m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
public void SetVehicle(PhysicsActor ph)
|
||||
{
|
||||
if (ph == null)
|
||||
return;
|
||||
ph.SetVehicle(vd);
|
||||
}
|
||||
|
||||
private XmlTextWriter writer;
|
||||
|
||||
private void XWint(string name, int i)
|
||||
{
|
||||
writer.WriteElementString(name, i.ToString());
|
||||
}
|
||||
|
||||
private void XWfloat(string name, float f)
|
||||
{
|
||||
writer.WriteElementString(name, f.ToString(Utils.EnUsCulture));
|
||||
}
|
||||
|
||||
private void XWVector(string name, Vector3 vec)
|
||||
{
|
||||
writer.WriteStartElement(name);
|
||||
writer.WriteElementString("X", vec.X.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Y", vec.Y.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Z", vec.Z.ToString(Utils.EnUsCulture));
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
private void XWQuat(string name, Quaternion quat)
|
||||
{
|
||||
writer.WriteStartElement(name);
|
||||
writer.WriteElementString("X", quat.X.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Y", quat.Y.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("Z", quat.Z.ToString(Utils.EnUsCulture));
|
||||
writer.WriteElementString("W", quat.W.ToString(Utils.EnUsCulture));
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
public void ToXml2(XmlTextWriter twriter)
|
||||
{
|
||||
writer = twriter;
|
||||
writer.WriteStartElement("Vehicle");
|
||||
|
||||
XWint("TYPE", (int)vd.m_type);
|
||||
XWint("FLAGS", (int)vd.m_flags);
|
||||
|
||||
// Linear properties
|
||||
XWVector("LMDIR", vd.m_linearMotorDirection);
|
||||
XWVector("LMFTIME", vd.m_linearFrictionTimescale);
|
||||
XWfloat("LMDTIME", vd.m_linearMotorDecayTimescale);
|
||||
XWfloat("LMTIME", vd.m_linearMotorTimescale);
|
||||
XWVector("LMOFF", vd.m_linearMotorOffset);
|
||||
|
||||
//Angular properties
|
||||
XWVector("AMDIR", vd.m_angularMotorDirection);
|
||||
XWfloat("AMTIME", vd.m_angularMotorTimescale);
|
||||
XWfloat("AMDTIME", vd.m_angularMotorDecayTimescale);
|
||||
XWVector("AMFTIME", vd.m_angularFrictionTimescale);
|
||||
|
||||
//Deflection properties
|
||||
XWfloat("ADEFF", vd.m_angularDeflectionEfficiency);
|
||||
XWfloat("ADTIME", vd.m_angularDeflectionTimescale);
|
||||
XWfloat("LDEFF", vd.m_linearDeflectionEfficiency);
|
||||
XWfloat("LDTIME", vd.m_linearDeflectionTimescale);
|
||||
|
||||
//Banking properties
|
||||
XWfloat("BEFF", vd.m_bankingEfficiency);
|
||||
XWfloat("BMIX", vd.m_bankingMix);
|
||||
XWfloat("BTIME", vd.m_bankingTimescale);
|
||||
|
||||
//Hover and Buoyancy properties
|
||||
XWfloat("HHEI", vd.m_VhoverHeight);
|
||||
XWfloat("HEFF", vd.m_VhoverEfficiency);
|
||||
XWfloat("HTIME", vd.m_VhoverTimescale);
|
||||
XWfloat("VBUO", vd.m_VehicleBuoyancy);
|
||||
|
||||
//Attractor properties
|
||||
XWfloat("VAEFF", vd.m_verticalAttractionEfficiency);
|
||||
XWfloat("VATIME", vd.m_verticalAttractionTimescale);
|
||||
|
||||
XWQuat("REF_FRAME", vd.m_referenceFrame);
|
||||
|
||||
writer.WriteEndElement();
|
||||
writer = null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
XmlTextReader reader;
|
||||
|
||||
private int XRint()
|
||||
{
|
||||
return reader.ReadElementContentAsInt();
|
||||
}
|
||||
|
||||
private float XRfloat()
|
||||
{
|
||||
return reader.ReadElementContentAsFloat();
|
||||
}
|
||||
|
||||
public Vector3 XRvector()
|
||||
{
|
||||
Vector3 vec;
|
||||
reader.ReadStartElement();
|
||||
vec.X = reader.ReadElementContentAsFloat();
|
||||
vec.Y = reader.ReadElementContentAsFloat();
|
||||
vec.Z = reader.ReadElementContentAsFloat();
|
||||
reader.ReadEndElement();
|
||||
return vec;
|
||||
}
|
||||
|
||||
public Quaternion XRquat()
|
||||
{
|
||||
Quaternion q;
|
||||
reader.ReadStartElement();
|
||||
q.X = reader.ReadElementContentAsFloat();
|
||||
q.Y = reader.ReadElementContentAsFloat();
|
||||
q.Z = reader.ReadElementContentAsFloat();
|
||||
q.W = reader.ReadElementContentAsFloat();
|
||||
reader.ReadEndElement();
|
||||
return q;
|
||||
}
|
||||
|
||||
public static bool EReadProcessors(
|
||||
Dictionary<string, Action> processors,
|
||||
XmlTextReader xtr)
|
||||
{
|
||||
bool errors = false;
|
||||
|
||||
string nodeName = string.Empty;
|
||||
while (xtr.NodeType != XmlNodeType.EndElement)
|
||||
{
|
||||
nodeName = xtr.Name;
|
||||
|
||||
// m_log.DebugFormat("[ExternalRepresentationUtils]: Processing: {0}", nodeName);
|
||||
|
||||
Action p = null;
|
||||
if (processors.TryGetValue(xtr.Name, out p))
|
||||
{
|
||||
// m_log.DebugFormat("[ExternalRepresentationUtils]: Found {0} processor, nodeName);
|
||||
|
||||
try
|
||||
{
|
||||
p();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
errors = true;
|
||||
if (xtr.NodeType == XmlNodeType.EndElement)
|
||||
xtr.Read();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// m_log.DebugFormat("[LandDataSerializer]: caught unknown element {0}", nodeName);
|
||||
xtr.ReadOuterXml(); // ignore
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void FromXml2(XmlTextReader _reader, out bool errors)
|
||||
{
|
||||
errors = false;
|
||||
reader = _reader;
|
||||
|
||||
Dictionary<string, Action> m_VehicleXmlProcessors
|
||||
= new Dictionary<string, Action>();
|
||||
|
||||
m_VehicleXmlProcessors.Add("TYPE", ProcessXR_type);
|
||||
m_VehicleXmlProcessors.Add("FLAGS", ProcessXR_flags);
|
||||
|
||||
// Linear properties
|
||||
m_VehicleXmlProcessors.Add("LMDIR", ProcessXR_linearMotorDirection);
|
||||
m_VehicleXmlProcessors.Add("LMFTIME", ProcessXR_linearFrictionTimescale);
|
||||
m_VehicleXmlProcessors.Add("LMDTIME", ProcessXR_linearMotorDecayTimescale);
|
||||
m_VehicleXmlProcessors.Add("LMTIME", ProcessXR_linearMotorTimescale);
|
||||
m_VehicleXmlProcessors.Add("LMOFF", ProcessXR_linearMotorOffset);
|
||||
|
||||
//Angular properties
|
||||
m_VehicleXmlProcessors.Add("AMDIR", ProcessXR_angularMotorDirection);
|
||||
m_VehicleXmlProcessors.Add("AMTIME", ProcessXR_angularMotorTimescale);
|
||||
m_VehicleXmlProcessors.Add("AMDTIME", ProcessXR_angularMotorDecayTimescale);
|
||||
m_VehicleXmlProcessors.Add("AMFTIME", ProcessXR_angularFrictionTimescale);
|
||||
|
||||
//Deflection properties
|
||||
m_VehicleXmlProcessors.Add("ADEFF", ProcessXR_angularDeflectionEfficiency);
|
||||
m_VehicleXmlProcessors.Add("ADTIME", ProcessXR_angularDeflectionTimescale);
|
||||
m_VehicleXmlProcessors.Add("LDEFF", ProcessXR_linearDeflectionEfficiency);
|
||||
m_VehicleXmlProcessors.Add("LDTIME", ProcessXR_linearDeflectionTimescale);
|
||||
|
||||
//Banking properties
|
||||
m_VehicleXmlProcessors.Add("BEFF", ProcessXR_bankingEfficiency);
|
||||
m_VehicleXmlProcessors.Add("BMIX", ProcessXR_bankingMix);
|
||||
m_VehicleXmlProcessors.Add("BTIME", ProcessXR_bankingTimescale);
|
||||
|
||||
//Hover and Buoyancy properties
|
||||
m_VehicleXmlProcessors.Add("HHEI", ProcessXR_VhoverHeight);
|
||||
m_VehicleXmlProcessors.Add("HEFF", ProcessXR_VhoverEfficiency);
|
||||
m_VehicleXmlProcessors.Add("HTIME", ProcessXR_VhoverTimescale);
|
||||
|
||||
m_VehicleXmlProcessors.Add("VBUO", ProcessXR_VehicleBuoyancy);
|
||||
|
||||
//Attractor properties
|
||||
m_VehicleXmlProcessors.Add("VAEFF", ProcessXR_verticalAttractionEfficiency);
|
||||
m_VehicleXmlProcessors.Add("VATIME", ProcessXR_verticalAttractionTimescale);
|
||||
|
||||
m_VehicleXmlProcessors.Add("REF_FRAME", ProcessXR_referenceFrame);
|
||||
|
||||
vd = new VehicleData();
|
||||
|
||||
reader.ReadStartElement("Vehicle", String.Empty);
|
||||
|
||||
errors = EReadProcessors(
|
||||
m_VehicleXmlProcessors,
|
||||
reader);
|
||||
|
||||
reader.ReadEndElement();
|
||||
reader = null;
|
||||
}
|
||||
|
||||
private void ProcessXR_type()
|
||||
{
|
||||
vd.m_type = (Vehicle)XRint();
|
||||
}
|
||||
private void ProcessXR_flags()
|
||||
{
|
||||
vd.m_flags = (VehicleFlag)XRint();
|
||||
}
|
||||
// Linear properties
|
||||
private void ProcessXR_linearMotorDirection()
|
||||
{
|
||||
vd.m_linearMotorDirection = XRvector();
|
||||
}
|
||||
|
||||
private void ProcessXR_linearFrictionTimescale()
|
||||
{
|
||||
vd.m_linearFrictionTimescale = XRvector();
|
||||
}
|
||||
|
||||
private void ProcessXR_linearMotorDecayTimescale()
|
||||
{
|
||||
vd.m_linearMotorDecayTimescale = XRfloat();
|
||||
}
|
||||
private void ProcessXR_linearMotorTimescale()
|
||||
{
|
||||
vd.m_linearMotorTimescale = XRfloat();
|
||||
}
|
||||
private void ProcessXR_linearMotorOffset()
|
||||
{
|
||||
vd.m_linearMotorOffset = XRvector();
|
||||
}
|
||||
|
||||
|
||||
//Angular properties
|
||||
private void ProcessXR_angularMotorDirection()
|
||||
{
|
||||
vd.m_angularMotorDirection = XRvector();
|
||||
}
|
||||
private void ProcessXR_angularMotorTimescale()
|
||||
{
|
||||
vd.m_angularMotorTimescale = XRfloat();
|
||||
}
|
||||
private void ProcessXR_angularMotorDecayTimescale()
|
||||
{
|
||||
vd.m_angularMotorDecayTimescale = XRfloat();
|
||||
}
|
||||
private void ProcessXR_angularFrictionTimescale()
|
||||
{
|
||||
vd.m_angularFrictionTimescale = XRvector();
|
||||
}
|
||||
|
||||
//Deflection properties
|
||||
private void ProcessXR_angularDeflectionEfficiency()
|
||||
{
|
||||
vd.m_angularDeflectionEfficiency = XRfloat();
|
||||
}
|
||||
private void ProcessXR_angularDeflectionTimescale()
|
||||
{
|
||||
vd.m_angularDeflectionTimescale = XRfloat();
|
||||
}
|
||||
private void ProcessXR_linearDeflectionEfficiency()
|
||||
{
|
||||
vd.m_linearDeflectionEfficiency = XRfloat();
|
||||
}
|
||||
private void ProcessXR_linearDeflectionTimescale()
|
||||
{
|
||||
vd.m_linearDeflectionTimescale = XRfloat();
|
||||
}
|
||||
|
||||
//Banking properties
|
||||
private void ProcessXR_bankingEfficiency()
|
||||
{
|
||||
vd.m_bankingEfficiency = XRfloat();
|
||||
}
|
||||
private void ProcessXR_bankingMix()
|
||||
{
|
||||
vd.m_bankingMix = XRfloat();
|
||||
}
|
||||
private void ProcessXR_bankingTimescale()
|
||||
{
|
||||
vd.m_bankingTimescale = XRfloat();
|
||||
}
|
||||
|
||||
//Hover and Buoyancy properties
|
||||
private void ProcessXR_VhoverHeight()
|
||||
{
|
||||
vd.m_VhoverHeight = XRfloat();
|
||||
}
|
||||
private void ProcessXR_VhoverEfficiency()
|
||||
{
|
||||
vd.m_VhoverEfficiency = XRfloat();
|
||||
}
|
||||
private void ProcessXR_VhoverTimescale()
|
||||
{
|
||||
vd.m_VhoverTimescale = XRfloat();
|
||||
}
|
||||
|
||||
private void ProcessXR_VehicleBuoyancy()
|
||||
{
|
||||
vd.m_VehicleBuoyancy = XRfloat();
|
||||
}
|
||||
|
||||
//Attractor properties
|
||||
private void ProcessXR_verticalAttractionEfficiency()
|
||||
{
|
||||
vd.m_verticalAttractionEfficiency = XRfloat();
|
||||
}
|
||||
private void ProcessXR_verticalAttractionTimescale()
|
||||
{
|
||||
vd.m_verticalAttractionTimescale = XRfloat();
|
||||
}
|
||||
|
||||
private void ProcessXR_referenceFrame()
|
||||
{
|
||||
vd.m_referenceFrame = XRquat();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -265,6 +265,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
//
|
||||
errors = part.Inventory.CreateScriptInstanceEr(item.ItemID, 0, false, DefaultScriptEngine, 0);
|
||||
}
|
||||
|
||||
// Tell anyone managing scripts that a script has been reloaded/changed
|
||||
EventManager.TriggerUpdateScript(remoteClient.AgentId, itemId, primId, isScriptRunning, item.AssetID);
|
||||
|
||||
part.ParentGroup.ResumeScripts();
|
||||
return errors;
|
||||
}
|
||||
@@ -330,6 +334,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
item.Flags = (item.Flags & ~(uint)255) | (itemUpd.Flags & (uint)255);
|
||||
item.Name = itemUpd.Name;
|
||||
item.Description = itemUpd.Description;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[USER INVENTORY]: itemUpd {0} {1} {2} {3}, item {4} {5} {6} {7}",
|
||||
// itemUpd.NextPermissions, itemUpd.GroupPermissions, itemUpd.EveryOnePermissions, item.Flags,
|
||||
// item.NextPermissions, item.GroupPermissions, item.EveryOnePermissions, item.CurrentPermissions);
|
||||
|
||||
if (item.NextPermissions != (itemUpd.NextPermissions & item.BasePermissions))
|
||||
item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner;
|
||||
item.NextPermissions = itemUpd.NextPermissions & item.BasePermissions;
|
||||
@@ -338,6 +348,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
item.EveryOnePermissions = itemUpd.EveryOnePermissions & item.BasePermissions;
|
||||
if (item.GroupPermissions != (itemUpd.GroupPermissions & item.BasePermissions))
|
||||
item.Flags |= (uint)InventoryItemFlags.ObjectOverwriteGroup;
|
||||
|
||||
// m_log.DebugFormat("[USER INVENTORY]: item.Flags {0}", item.Flags);
|
||||
|
||||
item.GroupPermissions = itemUpd.GroupPermissions & item.BasePermissions;
|
||||
item.GroupID = itemUpd.GroupID;
|
||||
item.GroupOwned = itemUpd.GroupOwned;
|
||||
@@ -1149,8 +1162,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
return;
|
||||
}
|
||||
|
||||
TaskInventoryItem item = part.Inventory.GetInventoryItem(itemId);
|
||||
if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
|
||||
if ((taskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
|
||||
{
|
||||
// If the item to be moved is no copy, we need to be able to
|
||||
// edit the prim.
|
||||
@@ -1634,9 +1646,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// have state in inventory
|
||||
part.Inventory.CreateScriptInstance(copyID, 0, false, DefaultScriptEngine, 0);
|
||||
|
||||
// tell anyone watching that there is a new script in town
|
||||
EventManager.TriggerNewScript(agentID, part, copyID);
|
||||
|
||||
// m_log.InfoFormat("[PRIMINVENTORY]: " +
|
||||
// "Rezzed script {0} into prim local ID {1} for user {2}",
|
||||
// item.inventoryName, localID, remoteClient.Name);
|
||||
|
||||
part.ParentGroup.ResumeScripts();
|
||||
|
||||
return part;
|
||||
@@ -1717,6 +1733,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
part.Inventory.AddInventoryItem(taskItem, false);
|
||||
part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0);
|
||||
|
||||
// tell anyone managing scripts that a new script exists
|
||||
EventManager.TriggerNewScript(agentID, part, taskItem.ItemID);
|
||||
|
||||
part.ParentGroup.ResumeScripts();
|
||||
|
||||
return part;
|
||||
@@ -1945,7 +1965,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
permissionToTake = true;
|
||||
permissionToDelete = true;
|
||||
|
||||
AddReturn(grp.OwnerID, grp.Name, grp.AbsolutePosition, "parcel owner return");
|
||||
AddReturn(grp.OwnerID == grp.GroupID ? grp.LastOwnerID : grp.OwnerID, grp.Name, grp.AbsolutePosition, "parcel owner return");
|
||||
}
|
||||
}
|
||||
else // Auto return passes through here with null agent
|
||||
@@ -2310,7 +2330,24 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_sceneGraph.DelinkObjects(parts);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Link the scene objects containing the indicated parts to a root object.
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="parentPrimId">A root prim id of the object which will be the root prim of the resulting linkset.</param>
|
||||
/// <param name="childPrimIds">A list of child prims for the objects that should be linked in.</param>
|
||||
public void LinkObjects(IClientAPI client, uint parentPrimId, List<uint> childPrimIds)
|
||||
{
|
||||
LinkObjects(client.AgentId, parentPrimId, childPrimIds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Link the scene objects containing the indicated parts to a root object.
|
||||
/// </summary>
|
||||
/// <param name="agentId">The ID of the user linking.</param>
|
||||
/// <param name="parentPrimId">A root prim id of the object which will be the root prim of the resulting linkset.</param>
|
||||
/// <param name="childPrimIds">A list of child prims for the objects that should be linked in.</param>
|
||||
public void LinkObjects(UUID agentId, uint parentPrimId, List<uint> childPrimIds)
|
||||
{
|
||||
List<UUID> owners = new List<UUID>();
|
||||
|
||||
@@ -2323,7 +2360,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Permissions.CanLinkObject(client.AgentId, root.ParentGroup.RootPart.UUID))
|
||||
if (!Permissions.CanLinkObject(agentId, root.ParentGroup.RootPart.UUID))
|
||||
{
|
||||
m_log.DebugFormat("[LINK]: Refusing link. No permissions on root prim");
|
||||
return;
|
||||
@@ -2339,7 +2376,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
if (!owners.Contains(part.OwnerID))
|
||||
owners.Add(part.OwnerID);
|
||||
|
||||
if (Permissions.CanLinkObject(client.AgentId, part.ParentGroup.RootPart.UUID))
|
||||
if (Permissions.CanLinkObject(agentId, part.ParentGroup.RootPart.UUID))
|
||||
children.Add(part);
|
||||
}
|
||||
|
||||
|
||||
@@ -890,16 +890,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
try
|
||||
{
|
||||
ForEachRootScenePresence(delegate(ScenePresence agent)
|
||||
{
|
||||
//agent.ControllingClient.new
|
||||
//this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo());
|
||||
{
|
||||
//agent.ControllingClient.new
|
||||
//this.CommsManager.InterRegion.InformRegionOfChildAgent(otherRegion.RegionHandle, agent.ControllingClient.RequestClientInfo());
|
||||
|
||||
List<ulong> old = new List<ulong>();
|
||||
old.Add(otherRegion.RegionHandle);
|
||||
agent.DropOldNeighbours(old);
|
||||
if (m_teleportModule != null)
|
||||
m_teleportModule.EnableChildAgent(agent, otherRegion);
|
||||
});
|
||||
List<ulong> old = new List<ulong>();
|
||||
old.Add(otherRegion.RegionHandle);
|
||||
agent.DropOldNeighbours(old);
|
||||
if (m_teleportModule != null && agent.PresenceType != PresenceType.Npc)
|
||||
m_teleportModule.EnableChildAgent(agent, otherRegion);
|
||||
});
|
||||
}
|
||||
catch (NullReferenceException)
|
||||
{
|
||||
@@ -907,7 +907,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// This shouldn't happen too often anymore.
|
||||
m_log.Error("[SCENE]: Couldn't inform client of regionup because we got a null reference exception");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1035,10 +1034,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
try
|
||||
{
|
||||
ForEachRootScenePresence(delegate(ScenePresence agent)
|
||||
{
|
||||
if (m_teleportModule != null)
|
||||
m_teleportModule.EnableChildAgent(agent, r);
|
||||
});
|
||||
{
|
||||
if (m_teleportModule != null && agent.PresenceType != PresenceType.Npc)
|
||||
m_teleportModule.EnableChildAgent(agent, r);
|
||||
});
|
||||
}
|
||||
catch (NullReferenceException)
|
||||
{
|
||||
@@ -2404,7 +2403,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </summary>
|
||||
/// <param name="sog"></param>
|
||||
/// <returns></returns>
|
||||
public bool IncomingCreateObject(ISceneObject sog)
|
||||
public bool IncomingCreateObject(Vector3 newPosition, ISceneObject sog)
|
||||
{
|
||||
//m_log.DebugFormat(" >>> IncomingCreateObject(sog) <<< {0} deleted? {1} isAttach? {2}", ((SceneObjectGroup)sog).AbsolutePosition,
|
||||
// ((SceneObjectGroup)sog).IsDeleted, ((SceneObjectGroup)sog).RootPart.IsAttachment);
|
||||
@@ -2420,6 +2419,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
return false;
|
||||
}
|
||||
|
||||
if (newPosition != Vector3.Zero)
|
||||
newObject.RootPart.GroupPosition = newPosition;
|
||||
|
||||
if (!AddSceneObject(newObject))
|
||||
{
|
||||
m_log.DebugFormat("[SCENE]: Problem adding scene object {0} in {1} ", sog.UUID, RegionInfo.RegionName);
|
||||
@@ -3395,8 +3397,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// also return a reason.</returns>
|
||||
public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason, bool requirePresenceLookup)
|
||||
{
|
||||
bool vialogin = ((teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0 ||
|
||||
(teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0);
|
||||
bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 ||
|
||||
(teleportFlags & (uint)TPFlags.ViaHGLogin) != 0);
|
||||
bool viahome = ((teleportFlags & (uint)TPFlags.ViaHome) != 0);
|
||||
bool godlike = ((teleportFlags & (uint)TPFlags.Godlike) != 0);
|
||||
|
||||
reason = String.Empty;
|
||||
|
||||
//Teleport flags:
|
||||
@@ -3408,9 +3413,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
// Don't disable this log message - it's too helpful
|
||||
m_log.DebugFormat(
|
||||
"[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, teleportflags {6}, position {7})",
|
||||
RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
|
||||
agent.AgentID, agent.circuitcode, teleportFlags, agent.startpos);
|
||||
"[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags ({8}), position {9})",
|
||||
RegionInfo.RegionName, (agent.child ? "child" : "root"),agent.firstname, agent.lastname,
|
||||
agent.AgentID, agent.circuitcode, agent.IPAddress, agent.Viewer, ((TPFlags)teleportFlags).ToString(), agent.startpos);
|
||||
|
||||
if (LoginsDisabled)
|
||||
{
|
||||
@@ -3571,6 +3576,29 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
agent.startpos.Z = 720;
|
||||
}
|
||||
}
|
||||
|
||||
// Honor Estate teleport routing via Telehubs excluding ViaHome and GodLike TeleportFlags
|
||||
if (RegionInfo.RegionSettings.TelehubObject != UUID.Zero &&
|
||||
RegionInfo.EstateSettings.AllowDirectTeleport == false &&
|
||||
!viahome && !godlike)
|
||||
{
|
||||
SceneObjectGroup telehub = GetSceneObjectGroup(RegionInfo.RegionSettings.TelehubObject);
|
||||
// Can have multiple SpawnPoints
|
||||
List<SpawnPoint> spawnpoints = RegionInfo.RegionSettings.SpawnPoints();
|
||||
if ( spawnpoints.Count > 1)
|
||||
{
|
||||
// We have multiple SpawnPoints, Route the agent to a random one
|
||||
agent.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count)].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We have a single SpawnPoint and will route the agent to it
|
||||
agent.startpos = spawnpoints[0].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Honor parcel landing type and position.
|
||||
/*
|
||||
ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y);
|
||||
@@ -4406,10 +4434,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <param name="action"></param>
|
||||
public void ForEachRootScenePresence(Action<ScenePresence> action)
|
||||
{
|
||||
if (m_sceneGraph != null)
|
||||
{
|
||||
m_sceneGraph.ForEachAvatar(action);
|
||||
}
|
||||
m_sceneGraph.ForEachAvatar(action);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -4418,10 +4443,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <param name="action"></param>
|
||||
public void ForEachScenePresence(Action<ScenePresence> action)
|
||||
{
|
||||
if (m_sceneGraph != null)
|
||||
{
|
||||
m_sceneGraph.ForEachScenePresence(action);
|
||||
}
|
||||
m_sceneGraph.ForEachScenePresence(action);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -4766,7 +4788,7 @@ Environment.Exit(1);
|
||||
bool wasUsingPhysics = ((jointProxyObject.Flags & PrimFlags.Physics) != 0);
|
||||
if (wasUsingPhysics)
|
||||
{
|
||||
jointProxyObject.UpdatePrimFlags(false, false, true, false); // FIXME: possible deadlock here; check to make sure all the scene alterations set into motion here won't deadlock
|
||||
jointProxyObject.UpdatePrimFlags(false, false, true, false,false); // FIXME: possible deadlock here; check to make sure all the scene alterations set into motion here won't deadlock
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5450,7 +5472,7 @@ Environment.Exit(1);
|
||||
// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget);
|
||||
|
||||
Vector3 agent_control_v3 = new Vector3();
|
||||
presence.HandleMoveToTargetUpdate(ref agent_control_v3);
|
||||
presence.HandleMoveToTargetUpdate(1, ref agent_control_v3);
|
||||
presence.AddNewMovement(agent_control_v3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,16 +156,20 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// that the region position is cached or performance will degrade
|
||||
Utils.LongToUInts(regionHandle, out x, out y);
|
||||
GridRegion dest = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y);
|
||||
bool v = true;
|
||||
if (! simulatorList.Contains(dest.ServerURI))
|
||||
{
|
||||
// we havent seen this simulator before, add it to the list
|
||||
// and send it an update
|
||||
simulatorList.Add(dest.ServerURI);
|
||||
// Let move this to sync. Mono definitely does not like async networking.
|
||||
m_scene.SimulationService.UpdateAgent(dest, cAgentData);
|
||||
|
||||
SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync;
|
||||
d.BeginInvoke(cAgentData, m_regionInfo.ScopeID, dest,
|
||||
SendChildAgentDataUpdateCompleted,
|
||||
d);
|
||||
// Leaving this here as a reminder that we tried, and it sucks.
|
||||
//SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync;
|
||||
//d.BeginInvoke(cAgentData, m_regionInfo.ScopeID, dest,
|
||||
// SendChildAgentDataUpdateCompleted,
|
||||
// d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,7 +406,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_log.ErrorFormat(
|
||||
"[SCENEGRAPH]: Tried to add scene object {0} to {1} with illegal UUID of {2}",
|
||||
sceneObject.Name, m_parentScene.RegionInfo.RegionName, UUID.Zero);
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -415,12 +415,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// m_log.DebugFormat(
|
||||
// "[SCENEGRAPH]: Scene graph for {0} already contains object {1} in AddSceneObject()",
|
||||
// m_parentScene.RegionInfo.RegionName, sceneObject.UUID);
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}",
|
||||
// "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}",
|
||||
// sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName);
|
||||
|
||||
SceneObjectPart[] parts = sceneObject.Parts;
|
||||
@@ -456,7 +456,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
lock (SceneObjectGroupsByFullID)
|
||||
SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
|
||||
|
||||
|
||||
lock (SceneObjectGroupsByFullPartID)
|
||||
{
|
||||
foreach (SceneObjectPart part in parts)
|
||||
@@ -1678,7 +1678,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
if (group != null)
|
||||
{
|
||||
if (m_parentScene.Permissions.CanEditObject(group.UUID,agentID))
|
||||
if (m_parentScene.Permissions.CanEditObject(group.UUID, agentID))
|
||||
{
|
||||
group.UpdateExtraParam(primLocalID, type, inUse, data);
|
||||
}
|
||||
@@ -1695,7 +1695,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
SceneObjectGroup group = GetGroupByPrim(primLocalID);
|
||||
if (group != null)
|
||||
{
|
||||
if (m_parentScene.Permissions.CanEditObject(group.GetPartsFullID(primLocalID), agentID))
|
||||
if (m_parentScene.Permissions.CanEditObject(group.UUID, agentID))
|
||||
{
|
||||
ObjectShapePacket.ObjectDataBlock shapeData = new ObjectShapePacket.ObjectDataBlock();
|
||||
shapeData.ObjectLocalID = shapeBlock.ObjectLocalID;
|
||||
@@ -1751,6 +1751,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
SceneObjectGroup child = children[i].ParentGroup;
|
||||
|
||||
// Don't try and add a group to itself - this will only cause severe problems later on.
|
||||
if (child == parentGroup)
|
||||
continue;
|
||||
|
||||
// Make sure no child prim is set for sale
|
||||
// So that, on delink, no prims are unwittingly
|
||||
// left for sale and sold off
|
||||
@@ -1777,8 +1781,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
// We need to explicitly resend the newly link prim's object properties since no other actions
|
||||
// occur on link to invoke this elsewhere (such as object selection)
|
||||
parentGroup.RootPart.CreateSelected = true;
|
||||
parentGroup.TriggerScriptChangedEvent(Changed.LINK);
|
||||
if (childGroups.Count > 0)
|
||||
{
|
||||
parentGroup.RootPart.CreateSelected = true;
|
||||
parentGroup.TriggerScriptChangedEvent(Changed.LINK);
|
||||
parentGroup.HasGroupChanged = true;
|
||||
parentGroup.ScheduleGroupForFullUpdate();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -269,6 +269,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
public void ApplyNextOwnerPermissions()
|
||||
{
|
||||
// m_log.DebugFormat("[PRIM INVENTORY]: Applying next owner permissions to {0} {1}", Name, UUID);
|
||||
|
||||
SceneObjectPart[] parts = m_parts.GetArray();
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
parts[i].ApplyNextOwnerPermissions();
|
||||
|
||||
@@ -43,6 +43,7 @@ using OpenSim.Region.Framework.Scenes.Serialization;
|
||||
|
||||
namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
|
||||
[Flags]
|
||||
public enum scriptEvents
|
||||
{
|
||||
@@ -461,11 +462,91 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
if (Scene != null)
|
||||
{
|
||||
if ((Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) || Scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W)
|
||||
|| Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S))
|
||||
// if ((Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) || Scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W)
|
||||
// || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S))
|
||||
// && !IsAttachmentCheckFull() && (!Scene.LoadingPrims))
|
||||
if ((Scene.TestBorderCross(val, Cardinals.E) || Scene.TestBorderCross(val, Cardinals.W)
|
||||
|| Scene.TestBorderCross(val, Cardinals.N) || Scene.TestBorderCross(val, Cardinals.S))
|
||||
&& !IsAttachmentCheckFull() && (!Scene.LoadingPrims))
|
||||
{
|
||||
m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
|
||||
IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
|
||||
uint x = 0;
|
||||
uint y = 0;
|
||||
string version = String.Empty;
|
||||
Vector3 newpos = Vector3.Zero;
|
||||
OpenSim.Services.Interfaces.GridRegion destination = null;
|
||||
|
||||
bool canCross = true;
|
||||
foreach (ScenePresence av in m_linkedAvatars)
|
||||
{
|
||||
// We need to cross these agents. First, let's find
|
||||
// out if any of them can't cross for some reason.
|
||||
// We have to deny the crossing entirely if any
|
||||
// of them are banned. Alternatively, we could
|
||||
// unsit banned agents....
|
||||
|
||||
|
||||
// We set the avatar position as being the object
|
||||
// position to get the region to send to
|
||||
if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out x, out y, out version, out newpos)) == null)
|
||||
{
|
||||
canCross = false;
|
||||
break;
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName);
|
||||
}
|
||||
|
||||
if (canCross)
|
||||
{
|
||||
// We unparent the SP quietly so that it won't
|
||||
// be made to stand up
|
||||
foreach (ScenePresence av in m_linkedAvatars)
|
||||
{
|
||||
SceneObjectPart parentPart = m_scene.GetSceneObjectPart(av.ParentID);
|
||||
if (parentPart != null)
|
||||
av.ParentUUID = parentPart.UUID;
|
||||
|
||||
av.ParentID = 0;
|
||||
}
|
||||
|
||||
m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
|
||||
|
||||
// Normalize
|
||||
if (val.X >= Constants.RegionSize)
|
||||
val.X -= Constants.RegionSize;
|
||||
if (val.Y >= Constants.RegionSize)
|
||||
val.Y -= Constants.RegionSize;
|
||||
if (val.X < 0)
|
||||
val.X += Constants.RegionSize;
|
||||
if (val.Y < 0)
|
||||
val.Y += Constants.RegionSize;
|
||||
|
||||
// If it's deleted, crossing was successful
|
||||
if (IsDeleted)
|
||||
{
|
||||
foreach (ScenePresence av in m_linkedAvatars)
|
||||
{
|
||||
m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val);
|
||||
|
||||
av.IsInTransit = true;
|
||||
|
||||
CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync;
|
||||
d.BeginInvoke(av, val, x, y, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (RootPart.PhysActor != null)
|
||||
{
|
||||
RootPart.PhysActor.CrossingFailure();
|
||||
}
|
||||
|
||||
Vector3 oldp = AbsolutePosition;
|
||||
val.X = Util.Clamp<float>(oldp.X, 0.5f, (float)Constants.RegionSize - 0.5f);
|
||||
val.Y = Util.Clamp<float>(oldp.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
|
||||
val.Z = Util.Clamp<float>(oldp.Z, 0.5f, 4096.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -501,7 +582,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
foreach (ScenePresence av in m_linkedAvatars)
|
||||
{
|
||||
SceneObjectPart p = m_scene.GetSceneObjectPart(av.ParentID);
|
||||
if (m_parts.TryGetValue(p.UUID, out p))
|
||||
if (p != null && m_parts.TryGetValue(p.UUID, out p))
|
||||
{
|
||||
Vector3 offset = p.GetWorldPosition() - av.ParentPosition;
|
||||
av.AbsolutePosition += offset;
|
||||
@@ -524,6 +605,29 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector3 Velocity
|
||||
{
|
||||
get { return RootPart.Velocity; }
|
||||
set { RootPart.Velocity = value; }
|
||||
}
|
||||
|
||||
private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
|
||||
{
|
||||
CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState;
|
||||
ScenePresence agent = icon.EndInvoke(iar);
|
||||
|
||||
//// If the cross was successful, this agent is a child agent
|
||||
//if (agent.IsChildAgent)
|
||||
// agent.Reset();
|
||||
//else // Not successful
|
||||
// agent.RestoreInCurrentScene();
|
||||
|
||||
// In any case
|
||||
agent.IsInTransit = false;
|
||||
|
||||
m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname);
|
||||
}
|
||||
|
||||
public override uint LocalId
|
||||
{
|
||||
get { return m_rootPart.LocalId; }
|
||||
@@ -1281,7 +1385,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
m_rootPart.SetParentLocalId(0);
|
||||
AttachmentPoint = (byte)0;
|
||||
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive);
|
||||
// must check if buildind should be true or false here
|
||||
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive,false);
|
||||
HasGroupChanged = true;
|
||||
RootPart.Rezzed = DateTime.Now;
|
||||
RootPart.RemFlag(PrimFlags.TemporaryOnRez);
|
||||
@@ -1580,22 +1685,32 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </summary>
|
||||
public void ApplyPhysics()
|
||||
{
|
||||
// Apply physics to the root prim
|
||||
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive);
|
||||
|
||||
// Apply physics to child prims
|
||||
SceneObjectPart[] parts = m_parts.GetArray();
|
||||
if (parts.Length > 1)
|
||||
{
|
||||
ResetChildPrimPhysicsPositions();
|
||||
|
||||
// Apply physics to the root prim
|
||||
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, true);
|
||||
|
||||
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
{
|
||||
SceneObjectPart part = parts[i];
|
||||
if (part.LocalId != m_rootPart.LocalId)
|
||||
part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive);
|
||||
part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, true);
|
||||
}
|
||||
|
||||
// Hack to get the physics scene geometries in the right spot
|
||||
ResetChildPrimPhysicsPositions();
|
||||
// ResetChildPrimPhysicsPositions();
|
||||
if (m_rootPart.PhysActor != null)
|
||||
{
|
||||
m_rootPart.PhysActor.Building = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Apply physics to the root prim
|
||||
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1667,7 +1782,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
m_log.DebugFormat(
|
||||
"[SCENE OBJECT GROUP]: Returning object {0} due to parcel autoreturn",
|
||||
RootPart.UUID);
|
||||
m_scene.AddReturn(OwnerID, Name, AbsolutePosition, "parcel autoreturn");
|
||||
m_scene.AddReturn(OwnerID == GroupID ? LastOwnerID : OwnerID, Name, AbsolutePosition, "parcel autoreturn");
|
||||
m_scene.DeRezObjects(null, new List<uint>() { RootPart.LocalId }, UUID.Zero,
|
||||
DeRezAction.Return, UUID.Zero);
|
||||
|
||||
@@ -1766,6 +1881,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <returns></returns>
|
||||
public SceneObjectGroup Copy(bool userExposed)
|
||||
{
|
||||
m_dupeInProgress = true;
|
||||
SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone();
|
||||
dupe.m_isBackedUp = false;
|
||||
dupe.m_parts = new MapAndArray<OpenMetaverse.UUID, SceneObjectPart>();
|
||||
@@ -1829,13 +1945,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
pbs,
|
||||
newPart.AbsolutePosition,
|
||||
newPart.Scale,
|
||||
newPart.RotationOffset,
|
||||
//newPart.RotationOffset,
|
||||
newPart.GetWorldRotation(),
|
||||
part.PhysActor.IsPhysical,
|
||||
newPart.LocalId);
|
||||
|
||||
newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true);
|
||||
}
|
||||
}
|
||||
if (dupe.m_rootPart.PhysActor != null && userExposed)
|
||||
dupe.m_rootPart.PhysActor.Building = false; // tell physics to finish building
|
||||
|
||||
if (userExposed)
|
||||
{
|
||||
@@ -1846,6 +1965,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
ScheduleGroupForFullUpdate();
|
||||
}
|
||||
|
||||
m_dupeInProgress = false;
|
||||
return dupe;
|
||||
}
|
||||
|
||||
@@ -2361,6 +2481,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}",
|
||||
// objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID);
|
||||
|
||||
// Linking to ourselves is not a valid operation.
|
||||
if (objectGroup == this)
|
||||
return;
|
||||
|
||||
SceneObjectPart linkPart = objectGroup.m_rootPart;
|
||||
|
||||
Vector3 oldGroupPosition = linkPart.GroupPosition;
|
||||
@@ -2849,12 +2973,31 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
RootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect);
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
{
|
||||
if (parts[i] != RootPart)
|
||||
parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect);
|
||||
}
|
||||
*/
|
||||
if (parts.Length > 1)
|
||||
{
|
||||
m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
|
||||
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
{
|
||||
|
||||
if (parts[i].UUID != m_rootPart.UUID)
|
||||
parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
|
||||
}
|
||||
|
||||
if (m_rootPart.PhysActor != null)
|
||||
m_rootPart.PhysActor.Building = false;
|
||||
}
|
||||
else
|
||||
m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -310,10 +310,16 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
private UUID m_collisionSound;
|
||||
private float m_collisionSoundVolume;
|
||||
|
||||
|
||||
private SOPVehicle m_vehicle = null;
|
||||
|
||||
#endregion Fields
|
||||
|
||||
// ~SceneObjectPart()
|
||||
// {
|
||||
// Console.WriteLine(
|
||||
// "[SCENE OBJECT PART]: Destructor called for {0}, local id {1}, parent {2} {3}",
|
||||
// Name, LocalId, ParentGroup.Name, ParentGroup.LocalId);
|
||||
// m_log.DebugFormat(
|
||||
// "[SCENE OBJECT PART]: Destructor called for {0}, local id {1}, parent {2} {3}",
|
||||
// Name, LocalId, ParentGroup.Name, ParentGroup.LocalId);
|
||||
@@ -1503,7 +1509,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </summary>
|
||||
/// <param name="rootObjectFlags"></param>
|
||||
/// <param name="VolumeDetectActive"></param>
|
||||
public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive)
|
||||
// public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive)
|
||||
public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive, bool building)
|
||||
{
|
||||
if (!ParentGroup.Scene.CollidablePrims)
|
||||
return;
|
||||
@@ -1532,6 +1539,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// or flexible
|
||||
if (!isPhantom && !ParentGroup.IsAttachment && !(Shape.PathCurve == (byte)Extrusion.Flexible))
|
||||
{
|
||||
Vector3 velocity = Velocity;
|
||||
Vector3 rotationalVelocity = AngularVelocity;
|
||||
try
|
||||
{
|
||||
PhysActor = ParentGroup.Scene.PhysicsScene.AddPrimShape(
|
||||
@@ -1539,7 +1548,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
Shape,
|
||||
AbsolutePosition,
|
||||
Scale,
|
||||
RotationOffset,
|
||||
// RotationOffset,
|
||||
GetWorldRotation(), // physics wants world rotation
|
||||
RigidBody,
|
||||
m_localId);
|
||||
}
|
||||
@@ -1554,8 +1564,21 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
PhysActor.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
|
||||
PhysActor.SetMaterial(Material);
|
||||
|
||||
// if root part apply vehicle
|
||||
if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
|
||||
m_vehicle.SetVehicle(PhysActor);
|
||||
|
||||
DoPhysicsPropertyUpdate(RigidBody, true);
|
||||
PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
|
||||
|
||||
Velocity = velocity;
|
||||
AngularVelocity = rotationalVelocity;
|
||||
PhysActor.Velocity = velocity;
|
||||
PhysActor.RotationalVelocity = rotationalVelocity;
|
||||
|
||||
if (!building)
|
||||
PhysActor.Building = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1601,9 +1624,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
dupe.GroupPosition = GroupPosition;
|
||||
dupe.OffsetPosition = OffsetPosition;
|
||||
dupe.RotationOffset = RotationOffset;
|
||||
dupe.Velocity = new Vector3(0, 0, 0);
|
||||
dupe.Acceleration = new Vector3(0, 0, 0);
|
||||
dupe.AngularVelocity = new Vector3(0, 0, 0);
|
||||
dupe.Velocity = Velocity;
|
||||
dupe.Acceleration = Acceleration;
|
||||
dupe.AngularVelocity = AngularVelocity;
|
||||
dupe.Flags = Flags;
|
||||
|
||||
dupe.OwnershipCost = OwnershipCost;
|
||||
@@ -1791,6 +1814,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
if (!isNew)
|
||||
ParentGroup.Scene.RemovePhysicalPrim(1);
|
||||
|
||||
Velocity = new Vector3(0, 0, 0);
|
||||
Acceleration = new Vector3(0, 0, 0);
|
||||
AngularVelocity = new Vector3(0, 0, 0);
|
||||
|
||||
PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
|
||||
PhysActor.OnOutOfBounds -= PhysicsOutOfBounds;
|
||||
PhysActor.delink();
|
||||
@@ -2612,9 +2639,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0);
|
||||
|
||||
if (ParentGroup.Scene.TestBorderCross(newpos, Cardinals.N)
|
||||
| ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
|
||||
| ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
|
||||
| ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
|
||||
|| ParentGroup.Scene.TestBorderCross(newpos, Cardinals.S)
|
||||
|| ParentGroup.Scene.TestBorderCross(newpos, Cardinals.E)
|
||||
|| ParentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
|
||||
{
|
||||
ParentGroup.AbsolutePosition = newpos;
|
||||
return;
|
||||
@@ -3160,17 +3187,74 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
public SOPVehicle sopVehicle
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_vehicle;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_vehicle = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int VehicleType
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_vehicle == null)
|
||||
return (int)Vehicle.TYPE_NONE;
|
||||
else
|
||||
return (int)m_vehicle.Type;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetVehicleType(value);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetVehicleType(int type)
|
||||
{
|
||||
if (PhysActor != null)
|
||||
m_vehicle = null;
|
||||
|
||||
if (type == (int)Vehicle.TYPE_NONE)
|
||||
{
|
||||
if (_parentID ==0 && PhysActor != null)
|
||||
PhysActor.VehicleType = (int)Vehicle.TYPE_NONE;
|
||||
return;
|
||||
}
|
||||
m_vehicle = new SOPVehicle();
|
||||
m_vehicle.ProcessTypeChange((Vehicle)type);
|
||||
{
|
||||
if (_parentID ==0 && PhysActor != null)
|
||||
PhysActor.VehicleType = type;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetVehicleFlags(int param, bool remove)
|
||||
{
|
||||
if (m_vehicle == null)
|
||||
return;
|
||||
|
||||
m_vehicle.ProcessVehicleFlags(param, remove);
|
||||
|
||||
if (_parentID ==0 && PhysActor != null)
|
||||
{
|
||||
PhysActor.VehicleType = type;
|
||||
PhysActor.VehicleFlags(param, remove);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetVehicleFloatParam(int param, float value)
|
||||
{
|
||||
if (PhysActor != null)
|
||||
if (m_vehicle == null)
|
||||
return;
|
||||
|
||||
m_vehicle.ProcessFloatVehicleParam((Vehicle)param, value);
|
||||
|
||||
if (_parentID == 0 && PhysActor != null)
|
||||
{
|
||||
PhysActor.VehicleFloatParam(param, value);
|
||||
}
|
||||
@@ -3178,7 +3262,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
public void SetVehicleVectorParam(int param, Vector3 value)
|
||||
{
|
||||
if (PhysActor != null)
|
||||
if (m_vehicle == null)
|
||||
return;
|
||||
|
||||
m_vehicle.ProcessVectorVehicleParam((Vehicle)param, value);
|
||||
|
||||
if (_parentID == 0 && PhysActor != null)
|
||||
{
|
||||
PhysActor.VehicleVectorParam(param, value);
|
||||
}
|
||||
@@ -3186,7 +3275,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
public void SetVehicleRotationParam(int param, Quaternion rotation)
|
||||
{
|
||||
if (PhysActor != null)
|
||||
if (m_vehicle == null)
|
||||
return;
|
||||
|
||||
m_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
|
||||
|
||||
if (_parentID == 0 && PhysActor != null)
|
||||
{
|
||||
PhysActor.VehicleRotationParam(param, rotation);
|
||||
}
|
||||
@@ -3373,13 +3467,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
hasProfileCut = hasDimple; // is it the same thing?
|
||||
}
|
||||
|
||||
public void SetVehicleFlags(int param, bool remove)
|
||||
{
|
||||
if (PhysActor != null)
|
||||
{
|
||||
PhysActor.VehicleFlags(param, remove);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetGroup(UUID groupID, IClientAPI client)
|
||||
{
|
||||
@@ -4267,7 +4354,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// <param name="SetTemporary"></param>
|
||||
/// <param name="SetPhantom"></param>
|
||||
/// <param name="SetVD"></param>
|
||||
public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD)
|
||||
// public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD)
|
||||
public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
|
||||
{
|
||||
bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
|
||||
bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
|
||||
@@ -4285,6 +4373,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// that...
|
||||
// ... if VD is changed, all others are not.
|
||||
// ... if one of the others is changed, VD is not.
|
||||
// do this first
|
||||
if (building && PhysActor != null && PhysActor.Building != building)
|
||||
PhysActor.Building = building;
|
||||
if (SetVD) // VD is active, special logic applies
|
||||
{
|
||||
// State machine logic for VolumeDetect
|
||||
@@ -4366,11 +4457,17 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
Shape,
|
||||
AbsolutePosition,
|
||||
Scale,
|
||||
RotationOffset,
|
||||
// RotationOffset,
|
||||
GetWorldRotation(), //physics wants world rotation like all other functions send
|
||||
UsePhysics,
|
||||
m_localId);
|
||||
|
||||
PhysActor.SetMaterial(Material);
|
||||
|
||||
// if root part apply vehicle
|
||||
if (m_vehicle != null && LocalId == ParentGroup.RootPart.LocalId)
|
||||
m_vehicle.SetVehicle(PhysActor);
|
||||
|
||||
DoPhysicsPropertyUpdate(UsePhysics, true);
|
||||
|
||||
if (!ParentGroup.IsDeleted)
|
||||
@@ -4446,6 +4543,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
// m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
|
||||
|
||||
// and last in case we have a new actor and not building
|
||||
if (PhysActor != null && PhysActor.Building != building)
|
||||
PhysActor.Building = building;
|
||||
if (ParentGroup != null)
|
||||
{
|
||||
ParentGroup.HasGroupChanged = true;
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis
|
||||
/// issue #1716
|
||||
/// </summary>
|
||||
public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f);
|
||||
public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.4f);
|
||||
|
||||
/// <summary>
|
||||
/// Movement updates for agents in neighboring regions are sent directly to clients.
|
||||
@@ -233,6 +233,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
private bool m_collisionEventFlag = false;
|
||||
private object m_collisionEventLock = new Object();
|
||||
|
||||
private Vector3 m_prevSitOffset;
|
||||
|
||||
protected AvatarAppearance m_appearance;
|
||||
|
||||
public AvatarAppearance Appearance
|
||||
@@ -295,13 +297,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </summary>
|
||||
public PhysicsActor PhysicsActor { get; private set; }
|
||||
|
||||
private byte m_movementflag;
|
||||
|
||||
public byte MovementFlag
|
||||
{
|
||||
set { m_movementflag = value; }
|
||||
get { return m_movementflag; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Record user movement inputs.
|
||||
/// </summary>
|
||||
public byte MovementFlag { get; private set; }
|
||||
|
||||
private bool m_updateflag;
|
||||
|
||||
@@ -647,6 +646,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
private uint m_parentID;
|
||||
|
||||
public UUID ParentUUID
|
||||
{
|
||||
get { return m_parentUUID; }
|
||||
set { m_parentUUID = value; }
|
||||
}
|
||||
private UUID m_parentUUID = UUID.Zero;
|
||||
|
||||
public float Health
|
||||
{
|
||||
get { return m_health; }
|
||||
@@ -868,10 +874,37 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
"[SCENE]: Upgrading child to root agent for {0} in {1}",
|
||||
Name, m_scene.RegionInfo.RegionName);
|
||||
|
||||
//m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count);
|
||||
|
||||
bool wasChild = IsChildAgent;
|
||||
IsChildAgent = false;
|
||||
|
||||
if (ParentUUID != UUID.Zero)
|
||||
{
|
||||
m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
|
||||
SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
|
||||
if (part == null)
|
||||
{
|
||||
m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
|
||||
}
|
||||
else
|
||||
{
|
||||
part.ParentGroup.AddAvatar(UUID);
|
||||
if (part.SitTargetPosition != Vector3.Zero)
|
||||
part.SitTargetAvatar = UUID;
|
||||
ParentPosition = part.GetWorldPosition();
|
||||
ParentID = part.LocalId;
|
||||
m_pos = m_prevSitOffset;
|
||||
pos = ParentPosition;
|
||||
}
|
||||
ParentUUID = UUID.Zero;
|
||||
|
||||
IsChildAgent = false;
|
||||
|
||||
Animator.TrySetMovementAnimation("SIT");
|
||||
}
|
||||
else
|
||||
{
|
||||
IsChildAgent = false;
|
||||
}
|
||||
|
||||
|
||||
IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
|
||||
if (gm != null)
|
||||
@@ -881,62 +914,64 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
|
||||
|
||||
// Moved this from SendInitialData to ensure that Appearance is initialized
|
||||
// before the inventory is processed in MakeRootAgent. This fixes a race condition
|
||||
// related to the handling of attachments
|
||||
//m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
|
||||
if (m_scene.TestBorderCross(pos, Cardinals.E))
|
||||
if (ParentID == 0)
|
||||
{
|
||||
Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
|
||||
pos.X = crossedBorder.BorderLine.Z - 1;
|
||||
// Moved this from SendInitialData to ensure that Appearance is initialized
|
||||
// before the inventory is processed in MakeRootAgent. This fixes a race condition
|
||||
// related to the handling of attachments
|
||||
//m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
|
||||
if (m_scene.TestBorderCross(pos, Cardinals.E))
|
||||
{
|
||||
Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
|
||||
pos.X = crossedBorder.BorderLine.Z - 1;
|
||||
}
|
||||
|
||||
if (m_scene.TestBorderCross(pos, Cardinals.N))
|
||||
{
|
||||
Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
|
||||
pos.Y = crossedBorder.BorderLine.Z - 1;
|
||||
}
|
||||
|
||||
CheckAndAdjustLandingPoint(ref pos);
|
||||
|
||||
if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
|
||||
pos, Name, UUID);
|
||||
|
||||
if (pos.X < 0f) pos.X = 0f;
|
||||
if (pos.Y < 0f) pos.Y = 0f;
|
||||
if (pos.Z < 0f) pos.Z = 0f;
|
||||
}
|
||||
|
||||
float localAVHeight = 1.56f;
|
||||
if (Appearance.AvatarHeight > 0)
|
||||
localAVHeight = Appearance.AvatarHeight;
|
||||
|
||||
float posZLimit = 0;
|
||||
|
||||
if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
|
||||
posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
|
||||
|
||||
float newPosZ = posZLimit + localAVHeight / 2;
|
||||
if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
|
||||
{
|
||||
pos.Z = newPosZ;
|
||||
}
|
||||
AbsolutePosition = pos;
|
||||
|
||||
AddToPhysicalScene(isFlying);
|
||||
|
||||
if (ForceFly)
|
||||
{
|
||||
Flying = true;
|
||||
}
|
||||
else if (FlyDisabled)
|
||||
{
|
||||
Flying = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_scene.TestBorderCross(pos, Cardinals.N))
|
||||
{
|
||||
Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
|
||||
pos.Y = crossedBorder.BorderLine.Z - 1;
|
||||
}
|
||||
|
||||
CheckAndAdjustLandingPoint(ref pos);
|
||||
|
||||
if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
|
||||
pos, Name, UUID);
|
||||
|
||||
if (pos.X < 0f) pos.X = 0f;
|
||||
if (pos.Y < 0f) pos.Y = 0f;
|
||||
if (pos.Z < 0f) pos.Z = 0f;
|
||||
}
|
||||
|
||||
float localAVHeight = 1.56f;
|
||||
if (Appearance.AvatarHeight > 0)
|
||||
localAVHeight = Appearance.AvatarHeight;
|
||||
|
||||
float posZLimit = 0;
|
||||
|
||||
if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
|
||||
posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
|
||||
|
||||
float newPosZ = posZLimit + localAVHeight / 2;
|
||||
if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
|
||||
{
|
||||
pos.Z = newPosZ;
|
||||
}
|
||||
AbsolutePosition = pos;
|
||||
|
||||
AddToPhysicalScene(isFlying);
|
||||
|
||||
if (ForceFly)
|
||||
{
|
||||
Flying = true;
|
||||
}
|
||||
else if (FlyDisabled)
|
||||
{
|
||||
Flying = false;
|
||||
}
|
||||
|
||||
// Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
|
||||
// avatar to return to the standing position in mid-air. On login it looks like this is being sent
|
||||
// elsewhere anyway
|
||||
@@ -954,14 +989,19 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments...");
|
||||
// Resume scripts
|
||||
foreach (SceneObjectGroup sog in m_attachments)
|
||||
{
|
||||
sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
|
||||
sog.ResumeScripts();
|
||||
}
|
||||
Util.FireAndForget(delegate(object x) {
|
||||
foreach (SceneObjectGroup sog in m_attachments)
|
||||
{
|
||||
sog.ScheduleGroupForFullUpdate();
|
||||
sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
|
||||
sog.ResumeScripts();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
SendAvatarDataToAllAgents();
|
||||
|
||||
// send the animations of the other presences to me
|
||||
m_scene.ForEachRootScenePresence(delegate(ScenePresence presence)
|
||||
{
|
||||
@@ -1055,7 +1095,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Do not call this directly. Call Scene.RequestTeleportLocation() instead.
|
||||
/// </summary>
|
||||
/// <param name="pos"></param>
|
||||
public void Teleport(Vector3 pos)
|
||||
@@ -1226,7 +1266,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
{
|
||||
IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
|
||||
if (m_agentTransfer != null)
|
||||
m_agentTransfer.EnableChildAgents(this);
|
||||
Util.FireAndForget(delegate { m_agentTransfer.EnableChildAgents(this); });
|
||||
|
||||
IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
|
||||
if (friendsModule != null)
|
||||
@@ -1529,7 +1569,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
}
|
||||
else if (bAllowUpdateMoveToPosition)
|
||||
{
|
||||
if (HandleMoveToTargetUpdate(ref agent_control_v3))
|
||||
// The UseClientAgentPosition is set if parcel ban is forcing the avatar to move to a
|
||||
// certain position. It's only check for tolerance on returning to that position is 0.2
|
||||
// rather than 1, at which point it removes its force target.
|
||||
if (HandleMoveToTargetUpdate(agentData.UseClientAgentPosition ? 0.2 : 1, ref agent_control_v3))
|
||||
update_movementflag = true;
|
||||
}
|
||||
}
|
||||
@@ -1591,7 +1634,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
/// </remarks>
|
||||
/// <param value="agent_control_v3">Cumulative agent movement that this method will update.</param>
|
||||
/// <returns>True if movement has been updated in some way. False otherwise.</returns>
|
||||
public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3)
|
||||
public bool HandleMoveToTargetUpdate(double tolerance, ref Vector3 agent_control_v3)
|
||||
{
|
||||
// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
|
||||
|
||||
@@ -1608,7 +1651,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
|
||||
|
||||
// Check the error term of the current position in relation to the target position
|
||||
if (distanceToTarget <= 1)
|
||||
if (distanceToTarget <= tolerance)
|
||||
{
|
||||
// We are close enough to the target
|
||||
AbsolutePosition = MoveToPositionTarget;
|
||||
@@ -1784,7 +1827,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, Rotation);
|
||||
|
||||
Vector3 agent_control_v3 = new Vector3();
|
||||
HandleMoveToTargetUpdate(ref agent_control_v3);
|
||||
HandleMoveToTargetUpdate(1, ref agent_control_v3);
|
||||
AddNewMovement(agent_control_v3);
|
||||
}
|
||||
|
||||
@@ -1814,8 +1857,11 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name);
|
||||
|
||||
SitGround = false;
|
||||
|
||||
/* move this down so avatar gets physical in the new position and not where it is siting
|
||||
if (PhysicsActor == null)
|
||||
AddToPhysicalScene(false);
|
||||
*/
|
||||
|
||||
if (ParentID != 0)
|
||||
{
|
||||
@@ -1850,6 +1896,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
ParentPosition = Vector3.Zero;
|
||||
|
||||
ParentID = 0;
|
||||
|
||||
if (PhysicsActor == null)
|
||||
AddToPhysicalScene(false);
|
||||
|
||||
SendAvatarDataToAllAgents();
|
||||
m_requestedSitTargetID = 0;
|
||||
|
||||
@@ -1857,6 +1907,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
|
||||
}
|
||||
|
||||
else if (PhysicsActor == null)
|
||||
AddToPhysicalScene(false);
|
||||
|
||||
Animator.TrySetMovementAnimation("STAND");
|
||||
}
|
||||
|
||||
@@ -2262,7 +2315,27 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
|
||||
//Quaternion result = (sitTargetOrient * vq) * nq;
|
||||
|
||||
m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT;
|
||||
double x, y, z, m;
|
||||
|
||||
Quaternion r = sitTargetOrient;
|
||||
m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
|
||||
|
||||
if (Math.Abs(1.0 - m) > 0.000001)
|
||||
{
|
||||
m = 1.0 / Math.Sqrt(m);
|
||||
r.X *= (float)m;
|
||||
r.Y *= (float)m;
|
||||
r.Z *= (float)m;
|
||||
r.W *= (float)m;
|
||||
}
|
||||
|
||||
x = 2 * (r.X * r.Z + r.Y * r.W);
|
||||
y = 2 * (-r.X * r.W + r.Y * r.Z);
|
||||
z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
|
||||
|
||||
Vector3 up = new Vector3((float)x, (float)y, (float)z);
|
||||
Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f;
|
||||
m_pos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT;
|
||||
Rotation = sitTargetOrient;
|
||||
ParentPosition = part.AbsolutePosition;
|
||||
part.ParentGroup.AddAvatar(UUID);
|
||||
@@ -2748,7 +2821,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
AgentPosition agentpos = new AgentPosition();
|
||||
agentpos.CopyFrom(cadu);
|
||||
|
||||
m_scene.SendOutChildAgentUpdates(agentpos, this);
|
||||
// Let's get this out of the update loop
|
||||
Util.FireAndForget(delegate { m_scene.SendOutChildAgentUpdates(agentpos, this); });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3112,6 +3186,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
cAgent.AlwaysRun = SetAlwaysRun;
|
||||
|
||||
cAgent.Appearance = new AvatarAppearance(Appearance);
|
||||
|
||||
cAgent.ParentPart = ParentUUID;
|
||||
cAgent.SitOffset = m_pos;
|
||||
|
||||
lock (scriptedcontrols)
|
||||
{
|
||||
@@ -3171,6 +3248,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
CameraAtAxis = cAgent.AtAxis;
|
||||
CameraLeftAxis = cAgent.LeftAxis;
|
||||
m_CameraUpAxis = cAgent.UpAxis;
|
||||
ParentUUID = cAgent.ParentPart;
|
||||
m_prevSitOffset = cAgent.SitOffset;
|
||||
|
||||
// When we get to the point of re-computing neighbors everytime this
|
||||
// changes, then start using the agent's drawdistance rather than the
|
||||
@@ -3232,7 +3311,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||
((SceneObjectGroup)so).LocalId = 0;
|
||||
((SceneObjectGroup)so).RootPart.ClearUpdateSchedule();
|
||||
so.SetState(cAgent.AttachmentObjectStates[i++], m_scene);
|
||||
m_scene.IncomingCreateObject(so);
|
||||
m_scene.IncomingCreateObject(Vector3.Zero, so);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using log4net;
|
||||
@@ -349,6 +350,11 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||
|
||||
m_SOPXmlProcessors.Add("Buoyancy", ProcessBuoyancy);
|
||||
m_SOPXmlProcessors.Add("VolumeDetectActive", ProcessVolumeDetectActive);
|
||||
|
||||
//Ubit comented until proper testing
|
||||
m_SOPXmlProcessors.Add("Vehicle", ProcessVehicle);
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region TaskInventoryXmlProcessors initialization
|
||||
@@ -571,15 +577,36 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||
obj.ClickAction = (byte)reader.ReadElementContentAsInt("ClickAction", String.Empty);
|
||||
}
|
||||
|
||||
private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader)
|
||||
private static void ProcessVehicle(SceneObjectPart obj, XmlTextReader reader)
|
||||
{
|
||||
bool errors = false;
|
||||
obj.Shape = ReadShape(reader, "Shape", out errors);
|
||||
SOPVehicle _vehicle = new SOPVehicle();
|
||||
|
||||
_vehicle.FromXml2(reader, out errors);
|
||||
|
||||
if (errors)
|
||||
{
|
||||
obj.sopVehicle = null;
|
||||
m_log.DebugFormat(
|
||||
"[SceneObjectSerializer]: Parsing PrimitiveBaseShape for object part {0} {1} encountered errors. Please see earlier log entries.",
|
||||
"[SceneObjectSerializer]: Parsing Vehicle for object part {0} {1} encountered errors. Please see earlier log entries.",
|
||||
obj.Name, obj.UUID);
|
||||
}
|
||||
else
|
||||
obj.sopVehicle = _vehicle;
|
||||
}
|
||||
|
||||
|
||||
private static void ProcessShape(SceneObjectPart obj, XmlTextReader reader)
|
||||
{
|
||||
List<string> errorNodeNames;
|
||||
obj.Shape = ReadShape(reader, "Shape", out errorNodeNames);
|
||||
|
||||
if (errorNodeNames != null)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[SceneObjectSerializer]: Parsing PrimitiveBaseShape for object part {0} {1} encountered errors in properties {2}.",
|
||||
obj.Name, obj.UUID, string.Join(", ", errorNodeNames.ToArray()));
|
||||
}
|
||||
}
|
||||
|
||||
private static void ProcessScale(SceneObjectPart obj, XmlTextReader reader)
|
||||
@@ -1231,6 +1258,10 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||
writer.WriteElementString("Buoyancy", sop.Buoyancy.ToString());
|
||||
writer.WriteElementString("VolumeDetectActive", sop.VolumeDetectActive.ToString().ToLower());
|
||||
|
||||
//Ubit comented until proper testing
|
||||
if (sop.sopVehicle != null)
|
||||
sop.sopVehicle.ToXml2(writer);
|
||||
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
@@ -1486,7 +1517,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||
m_SOPXmlProcessors,
|
||||
reader,
|
||||
(o, nodeName, e)
|
||||
=> m_log.ErrorFormat(
|
||||
=> m_log.DebugFormat(
|
||||
"[SceneObjectSerializer]: Exception while parsing {0} in object {1} {2}: {3}{4}",
|
||||
((SceneObjectPart)o).Name, ((SceneObjectPart)o).UUID, nodeName, e.Message, e.StackTrace));
|
||||
|
||||
@@ -1529,14 +1560,21 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||
/// </summary>
|
||||
/// <param name="reader"></param>
|
||||
/// <param name="name">The name of the xml element containing the shape</param>
|
||||
/// <param name="errors">true if any errors were encountered during parsing, false otherwise</param>
|
||||
/// <param name="errors">a list containing the failing node names. If no failures then null.</param>
|
||||
/// <returns>The shape parsed</returns>
|
||||
public static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name, out bool errors)
|
||||
public static PrimitiveBaseShape ReadShape(XmlTextReader reader, string name, out List<string> errorNodeNames)
|
||||
{
|
||||
errors = false;
|
||||
List<string> internalErrorNodeNames = null;
|
||||
|
||||
PrimitiveBaseShape shape = new PrimitiveBaseShape();
|
||||
|
||||
if (reader.IsEmptyElement)
|
||||
{
|
||||
reader.Read();
|
||||
errorNodeNames = null;
|
||||
return shape;
|
||||
}
|
||||
|
||||
reader.ReadStartElement(name, String.Empty); // Shape
|
||||
|
||||
ExternalRepresentationUtils.ExecuteReadProcessors(
|
||||
@@ -1544,12 +1582,22 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
|
||||
m_ShapeXmlProcessors,
|
||||
reader,
|
||||
(o, nodeName, e)
|
||||
=> m_log.ErrorFormat(
|
||||
"[SceneObjectSerializer]: Exception while parsing Shape property {0}: {1}{2}",
|
||||
nodeName, e.Message, e.StackTrace));
|
||||
=>
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[SceneObjectSerializer]: Exception while parsing Shape property {0}: {1}{2}",
|
||||
// nodeName, e.Message, e.StackTrace);
|
||||
if (internalErrorNodeNames == null)
|
||||
internalErrorNodeNames = new List<string>();
|
||||
|
||||
internalErrorNodeNames.Add(nodeName);
|
||||
}
|
||||
);
|
||||
|
||||
reader.ReadEndElement(); // Shape
|
||||
|
||||
errorNodeNames = internalErrorNodeNames;
|
||||
|
||||
return shape;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using NUnit.Framework;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
@@ -43,6 +44,42 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||
[TestFixture]
|
||||
public class SceneObjectBasicTests
|
||||
{
|
||||
// [TearDown]
|
||||
// public void TearDown()
|
||||
// {
|
||||
// Console.WriteLine("TearDown");
|
||||
// GC.Collect();
|
||||
// Thread.Sleep(3000);
|
||||
// }
|
||||
|
||||
// public class GcNotify
|
||||
// {
|
||||
// public static AutoResetEvent gcEvent = new AutoResetEvent(false);
|
||||
// private static bool _initialized = false;
|
||||
//
|
||||
// public static void Initialize()
|
||||
// {
|
||||
// if (!_initialized)
|
||||
// {
|
||||
// _initialized = true;
|
||||
// new GcNotify();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private GcNotify(){}
|
||||
//
|
||||
// ~GcNotify()
|
||||
// {
|
||||
// if (!Environment.HasShutdownStarted &&
|
||||
// !AppDomain.CurrentDomain.IsFinalizingForUnload())
|
||||
// {
|
||||
// Console.WriteLine("GcNotify called");
|
||||
// gcEvent.Set();
|
||||
// new GcNotify();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Test adding an object to a scene.
|
||||
/// </summary>
|
||||
@@ -147,11 +184,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests
|
||||
public void TestDeleteSceneObject()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
|
||||
|
||||
TestScene scene = SceneHelpers.SetupScene();
|
||||
SceneObjectPart part = SceneHelpers.AddSceneObject(scene);
|
||||
scene.DeleteSceneObject(part.ParentGroup, false);
|
||||
|
||||
|
||||
SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId);
|
||||
Assert.That(retrievedPart, Is.Null);
|
||||
}
|
||||
|
||||
@@ -39,14 +39,31 @@ using log4net;
|
||||
|
||||
namespace OpenSim.Region.Framework.Scenes.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Linking tests
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class SceneObjectLinkingTests
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// Links to self should be ignored.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestLinkToSelf()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
|
||||
UUID ownerId = TestHelpers.ParseTail(0x1);
|
||||
int nParts = 3;
|
||||
|
||||
TestScene scene = SceneHelpers.SetupScene();
|
||||
SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(nParts, ownerId, "TestLinkToSelf_", 0x10);
|
||||
scene.AddSceneObject(sog1);
|
||||
scene.LinkObjects(ownerId, sog1.LocalId, new List<uint>() { sog1.Parts[1].LocalId });
|
||||
// sog1.LinkToGroup(sog1);
|
||||
|
||||
Assert.That(sog1.Parts.Length, Is.EqualTo(nParts));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLinkDelink2SceneObjects()
|
||||
{
|
||||
|
||||
+3
-3
@@ -63,9 +63,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
// Capability string prefixes
|
||||
private static readonly string m_parcelVoiceInfoRequestPath = "0007/";
|
||||
private static readonly string m_provisionVoiceAccountRequestPath = "0008/";
|
||||
private static readonly string m_chatSessionRequestPath = "0009/";
|
||||
private static readonly string m_parcelVoiceInfoRequestPath = "0207/";
|
||||
private static readonly string m_provisionVoiceAccountRequestPath = "0208/";
|
||||
private static readonly string m_chatSessionRequestPath = "0209/";
|
||||
|
||||
// Control info
|
||||
private static bool m_Enabled = false;
|
||||
|
||||
+64
-9
@@ -30,6 +30,7 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
|
||||
using Nwc.XmlRpc;
|
||||
|
||||
@@ -167,6 +168,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||
|
||||
private bool m_debugEnabled = false;
|
||||
|
||||
private Dictionary<string, bool> m_pendingRequests = new Dictionary<string,bool>();
|
||||
|
||||
private ExpiringCache<string, OSDMap> m_memoryCache;
|
||||
private int m_cacheTimeout = 30;
|
||||
|
||||
@@ -1348,6 +1351,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||
// Immediately forward the request if the cache is disabled.
|
||||
if (m_cacheTimeout == 0)
|
||||
{
|
||||
m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: cache is disabled");
|
||||
return WebUtil.PostToService(m_groupsServerURI, requestArgs);
|
||||
}
|
||||
|
||||
@@ -1355,6 +1359,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||
if (requestArgs["RequestMethod"] == "RemoveGeneric"
|
||||
|| requestArgs["RequestMethod"] == "AddGeneric")
|
||||
{
|
||||
m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: clearing generics cache");
|
||||
|
||||
// Any and all updates cause the cache to clear
|
||||
m_memoryCache.Clear();
|
||||
|
||||
@@ -1366,18 +1372,67 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
|
||||
|
||||
// Create the cache key for the request and see if we have it cached
|
||||
string CacheKey = WebUtil.BuildQueryString(requestArgs);
|
||||
OSDMap response = null;
|
||||
if (!m_memoryCache.TryGetValue(CacheKey, out response))
|
||||
{
|
||||
// if it wasn't in the cache, pass the request to the Simian Grid Services
|
||||
response = WebUtil.PostToService(m_groupsServerURI, requestArgs);
|
||||
|
||||
// and cache the response
|
||||
m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout));
|
||||
// This code uses a leader/follower pattern. On a cache miss, the request is added
|
||||
// to a queue; the first thread to add it to the queue completes the request while
|
||||
// follow on threads busy wait for the results, this situation seems to happen
|
||||
// often when checking permissions
|
||||
while (true)
|
||||
{
|
||||
OSDMap response = null;
|
||||
bool firstRequest = false;
|
||||
|
||||
lock (m_memoryCache)
|
||||
{
|
||||
if (m_memoryCache.TryGetValue(CacheKey, out response))
|
||||
return response;
|
||||
|
||||
if (! m_pendingRequests.ContainsKey(CacheKey))
|
||||
{
|
||||
m_pendingRequests.Add(CacheKey,true);
|
||||
firstRequest = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstRequest)
|
||||
{
|
||||
// if it wasn't in the cache, pass the request to the Simian Grid Services
|
||||
try
|
||||
{
|
||||
response = WebUtil.PostToService(m_groupsServerURI, requestArgs);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.InfoFormat("[SIMIAN GROUPS CONNECTOR] request failed {0}",CacheKey);
|
||||
}
|
||||
|
||||
// and cache the response
|
||||
lock (m_memoryCache)
|
||||
{
|
||||
m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout));
|
||||
m_pendingRequests.Remove(CacheKey);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
Thread.Sleep(50); // waiting for a web request to complete, 50msecs is reasonable
|
||||
}
|
||||
|
||||
// return cached response
|
||||
return response;
|
||||
// if (!m_memoryCache.TryGetValue(CacheKey, out response))
|
||||
// {
|
||||
// m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: query not in the cache");
|
||||
// Util.PrintCallStack();
|
||||
|
||||
// // if it wasn't in the cache, pass the request to the Simian Grid Services
|
||||
// response = WebUtil.PostToService(m_groupsServerURI, requestArgs);
|
||||
|
||||
// // and cache the response
|
||||
// m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout));
|
||||
// }
|
||||
|
||||
// // return cached response
|
||||
// return response;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -230,8 +230,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
|
||||
|
||||
m_scene.EventManager.OnEmptyScriptCompileQueue -= OnEmptyScriptCompileQueue;
|
||||
|
||||
m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}",
|
||||
m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString());
|
||||
// m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}",
|
||||
// m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString());
|
||||
|
||||
m_log.InfoFormat("[RegionReady]: Logins enabled for {0}", m_scene.RegionInfo.RegionName);
|
||||
|
||||
if ( m_uri != string.Empty )
|
||||
{
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||
private readonly string m_firstname;
|
||||
private readonly string m_lastname;
|
||||
private readonly Vector3 m_startPos;
|
||||
private readonly UUID m_uuid = UUID.Random();
|
||||
private UUID m_uuid = UUID.Random();
|
||||
private readonly Scene m_scene;
|
||||
private readonly UUID m_ownerID;
|
||||
|
||||
@@ -444,6 +444,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||
public virtual UUID AgentId
|
||||
{
|
||||
get { return m_uuid; }
|
||||
set { m_uuid = value; }
|
||||
}
|
||||
|
||||
public UUID SessionId
|
||||
|
||||
@@ -96,15 +96,15 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||
if (!m_avatars.ContainsKey(agentId))
|
||||
return false;
|
||||
|
||||
// Delete existing sp attachments
|
||||
scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, false);
|
||||
|
||||
AvatarAppearance npcAppearance = new AvatarAppearance(appearance, true);
|
||||
sp.Appearance = npcAppearance;
|
||||
// Set new sp appearance. Also sends to clients.
|
||||
scene.RequestModuleInterface<IAvatarFactoryModule>().SetAppearance(sp, new AvatarAppearance(appearance, true));
|
||||
|
||||
// Rez needed sp attachments
|
||||
scene.AttachmentsModule.RezAttachments(sp);
|
||||
|
||||
IAvatarFactoryModule module = scene.RequestModuleInterface<IAvatarFactoryModule>();
|
||||
module.SendAppearance(sp.UUID);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -121,8 +121,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||
npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0, int.MaxValue);
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[NPC MODULE]: Creating NPC {0} {1} {2} at {3} in {4}",
|
||||
firstname, lastname, npcAvatar.AgentId, position, scene.RegionInfo.RegionName);
|
||||
"[NPC MODULE]: Creating NPC {0} {1} {2}, owner={3}, senseAsAgent={4} at {5} in {6}",
|
||||
firstname, lastname, npcAvatar.AgentId, owner, senseAsAgent, position, scene.RegionInfo.RegionName);
|
||||
|
||||
AgentCircuitData acd = new AgentCircuitData();
|
||||
acd.AgentID = npcAvatar.AgentId;
|
||||
@@ -155,20 +155,21 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||
"[NPC MODULE]: Successfully retrieved scene presence for NPC {0} {1}", sp.Name, sp.UUID);
|
||||
|
||||
sp.CompleteMovement(npcAvatar, false);
|
||||
m_avatars.Add(npcAvatar.AgentId, npcAvatar);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat("[NPC MODULE]: Could not find scene presence for NPC {0} {1}", sp.Name, sp.UUID);
|
||||
npcAvatar.AgentId = UUID.Zero;
|
||||
}
|
||||
|
||||
m_avatars.Add(npcAvatar.AgentId, npcAvatar);
|
||||
}
|
||||
ev.Set();
|
||||
});
|
||||
|
||||
ev.WaitOne();
|
||||
|
||||
m_log.DebugFormat("[NPC MODULE]: Created NPC with id {0}", npcAvatar.AgentId);
|
||||
// m_log.DebugFormat("[NPC MODULE]: Created NPC with id {0}", npcAvatar.AgentId);
|
||||
|
||||
return npcAvatar.AgentId;
|
||||
}
|
||||
@@ -299,13 +300,16 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||
NPCAvatar av;
|
||||
if (m_avatars.TryGetValue(agentID, out av))
|
||||
{
|
||||
// m_log.DebugFormat("[NPC MODULE]: Found {0} {1} to remove", agentID, av.Name);
|
||||
scene.RemoveClient(agentID, false);
|
||||
m_avatars.Remove(agentID);
|
||||
|
||||
// m_log.DebugFormat("[NPC MODULE]: Removed {0} {1}", agentID, av.Name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[NPC MODULE]: Could not find {0} to remove", agentID);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,9 @@ public class BSPlugin : IPhysicsPlugin
|
||||
{
|
||||
if (_mScene == null)
|
||||
{
|
||||
if (Util.IsWindows())
|
||||
Util.LoadArchSpecificWindowsDll("BulletSim.dll");
|
||||
|
||||
_mScene = new BSScene(sceneIdentifier);
|
||||
}
|
||||
return (_mScene);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1536,7 +1536,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
List<OdePrim> removeprims = null;
|
||||
foreach (OdePrim chr in _activeprims)
|
||||
{
|
||||
if (chr.Body != IntPtr.Zero && d.BodyIsEnabled(chr.Body) && (!chr.m_disabled))
|
||||
if (chr.Body != IntPtr.Zero && d.BodyIsEnabled(chr.Body) && (!chr.m_disabled) && !chr.m_outofBounds)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -1736,6 +1736,23 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
return newPrim;
|
||||
}
|
||||
|
||||
private PhysicsActor AddPrim(String name, Vector3 position, PhysicsActor parent,
|
||||
PrimitiveBaseShape pbs, uint localid, byte[] sdata)
|
||||
{
|
||||
Vector3 pos = position;
|
||||
|
||||
OdePrim newPrim;
|
||||
lock (OdeLock)
|
||||
{
|
||||
newPrim = new OdePrim(name, this, pos, parent, pbs, ode, localid, sdata);
|
||||
lock (_prims)
|
||||
_prims.Add(newPrim);
|
||||
}
|
||||
|
||||
return newPrim;
|
||||
}
|
||||
|
||||
|
||||
public void addActivePrim(OdePrim activatePrim)
|
||||
{
|
||||
// adds active prim.. (ones that should be iterated over in collisions_optimized
|
||||
@@ -1762,6 +1779,17 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
return result;
|
||||
}
|
||||
|
||||
public override PhysicsActor AddPrimShape(string primName, PhysicsActor parent, PrimitiveBaseShape pbs, Vector3 position,
|
||||
uint localid, byte[] sdata)
|
||||
{
|
||||
PhysicsActor result;
|
||||
|
||||
result = AddPrim(primName, position, parent,
|
||||
pbs, localid, sdata);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override float TimeDilation
|
||||
{
|
||||
get { return m_timeDilation; }
|
||||
@@ -3410,13 +3438,13 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
public void SetTerrain(float[] heightMap, Vector3 pOffset)
|
||||
{
|
||||
|
||||
uint regionsize = (uint) Constants.RegionSize; // visible region size eg. 256(M)
|
||||
int regionsize = (int) Constants.RegionSize; // visible region size eg. 256(M)
|
||||
|
||||
uint heightmapWidth = regionsize + 1; // ODE map size 257 x 257 (Meters) (1 extra
|
||||
uint heightmapHeight = regionsize + 1;
|
||||
int heightmapWidth = regionsize + 2; // ODE map size 257 x 257 (Meters) (1 extra
|
||||
int heightmapHeight = regionsize + 2;
|
||||
|
||||
uint heightmapWidthSamples = (uint)regionsize + 2; // Sample file size, 258 x 258 samples
|
||||
uint heightmapHeightSamples = (uint)regionsize + 2;
|
||||
int heightmapWidthSamples = (int)regionsize + 3; // Sample file size, 258 x 258 samples
|
||||
int heightmapHeightSamples = (int)regionsize + 3;
|
||||
|
||||
// Array of height samples for ODE
|
||||
float[] _heightmap;
|
||||
@@ -3432,10 +3460,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
float hfmax = -2000f;
|
||||
float minele = 0.0f; // Dont allow -ve heights
|
||||
|
||||
uint x = 0;
|
||||
uint y = 0;
|
||||
uint xx = 0;
|
||||
uint yy = 0;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int xx = 0;
|
||||
int yy = 0;
|
||||
|
||||
// load the height samples array from the heightMap
|
||||
for ( x = 0; x < heightmapWidthSamples; x++) // 0 to 257
|
||||
@@ -3453,7 +3481,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
// Output x = 0 1 2 3 ..... 255 256 257 258 total out
|
||||
float val= heightMap[(yy * regionsize) + xx]; // input from heightMap, <0-255 * 256> <0-255>
|
||||
if (val < minele) val = minele;
|
||||
_heightmap[x * (regionsize + 2) + y] = val; // samples output to _heightmap, <0-257 * 258> <0-257>
|
||||
_heightmap[x * (heightmapHeightSamples) + y] = val; // samples output to _heightmap, <0-257 * 258> <0-257>
|
||||
hfmin = (val < hfmin) ? val : hfmin;
|
||||
hfmax = (val > hfmax) ? val : hfmax;
|
||||
}
|
||||
@@ -3503,6 +3531,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
|
||||
d.GeomSetRotation(GroundGeom, ref R);
|
||||
d.GeomSetPosition(GroundGeom, (pOffset.X + (regionsize * 0.5f)) - 0.5f, (pOffset.Y + (regionsize * 0.5f)) - 0.5f, 0);
|
||||
// having nsamples = size + 1 center is actually at size/2
|
||||
d.GeomSetPosition(GroundGeom, (pOffset.X + (regionsize * 0.5f)), (pOffset.Y + (regionsize * 0.5f)), 0);
|
||||
IntPtr testGround = IntPtr.Zero;
|
||||
if (RegionTerrain.TryGetValue(pOffset, out testGround))
|
||||
{
|
||||
|
||||
@@ -0,0 +1,353 @@
|
||||
/* Ubit 2012
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// no endian conversion. So can't be use to pass information around diferent cpus with diferent endian
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
|
||||
unsafe public class wstreamer
|
||||
{
|
||||
byte[] buf;
|
||||
int index;
|
||||
byte* src;
|
||||
|
||||
public wstreamer()
|
||||
{
|
||||
buf = new byte[1024];
|
||||
index = 0;
|
||||
}
|
||||
public wstreamer(int size)
|
||||
{
|
||||
buf = new byte[size];
|
||||
index = 0;
|
||||
}
|
||||
|
||||
public byte[] close()
|
||||
{
|
||||
byte[] data = new byte[index];
|
||||
Buffer.BlockCopy(buf, 0, data, 0, index);
|
||||
return data;
|
||||
}
|
||||
|
||||
public void Seek(int pos)
|
||||
{
|
||||
index = pos;
|
||||
}
|
||||
|
||||
public void Seekrel(int pos)
|
||||
{
|
||||
index += pos;
|
||||
}
|
||||
|
||||
public void Wbyte(byte value)
|
||||
{
|
||||
buf[index++] = value;
|
||||
}
|
||||
public void Wshort(short value)
|
||||
{
|
||||
src = (byte*)&value;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
}
|
||||
public void Wushort(ushort value)
|
||||
{
|
||||
src = (byte*)&value;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
}
|
||||
public void Wint(int value)
|
||||
{
|
||||
src = (byte*)&value;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
}
|
||||
public void Wuint(uint value)
|
||||
{
|
||||
src = (byte*)&value;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
}
|
||||
public void Wlong(long value)
|
||||
{
|
||||
src = (byte*)&value;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
}
|
||||
public void Wulong(ulong value)
|
||||
{
|
||||
src = (byte*)&value;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
}
|
||||
|
||||
public void Wfloat(float value)
|
||||
{
|
||||
src = (byte*)&value;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
}
|
||||
|
||||
public void Wdouble(double value)
|
||||
{
|
||||
src = (byte*)&value;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
}
|
||||
|
||||
public void Wvector3(Vector3 value)
|
||||
{
|
||||
src = (byte*)&value.X;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
src = (byte*)&value.Y; // it may have padding ??
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
src = (byte*)&value.Z;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
}
|
||||
public void Wquat(Quaternion value)
|
||||
{
|
||||
src = (byte*)&value.X;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
src = (byte*)&value.Y; // it may have padding ??
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
src = (byte*)&value.Z;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
src = (byte*)&value.W;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src++;
|
||||
buf[index++] = *src;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe public class rstreamer
|
||||
{
|
||||
private byte[] rbuf;
|
||||
private int ptr;
|
||||
private byte* dst;
|
||||
|
||||
public rstreamer(byte[] data)
|
||||
{
|
||||
rbuf = data;
|
||||
ptr = 0;
|
||||
}
|
||||
|
||||
public void close()
|
||||
{
|
||||
}
|
||||
|
||||
public void Seek(int pos)
|
||||
{
|
||||
ptr = pos;
|
||||
}
|
||||
|
||||
public void Seekrel(int pos)
|
||||
{
|
||||
ptr += pos;
|
||||
}
|
||||
|
||||
public byte Rbyte()
|
||||
{
|
||||
return (byte)rbuf[ptr++];
|
||||
}
|
||||
|
||||
public short Rshort()
|
||||
{
|
||||
short v;
|
||||
dst = (byte*)&v;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
return v;
|
||||
}
|
||||
public ushort Rushort()
|
||||
{
|
||||
ushort v;
|
||||
dst = (byte*)&v;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
return v;
|
||||
}
|
||||
public int Rint()
|
||||
{
|
||||
int v;
|
||||
dst = (byte*)&v;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
return v;
|
||||
}
|
||||
public uint Ruint()
|
||||
{
|
||||
uint v;
|
||||
dst = (byte*)&v;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
return v;
|
||||
}
|
||||
public long Rlong()
|
||||
{
|
||||
long v;
|
||||
dst = (byte*)&v;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
return v;
|
||||
}
|
||||
public ulong Rulong()
|
||||
{
|
||||
ulong v;
|
||||
dst = (byte*)&v;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
return v;
|
||||
}
|
||||
public float Rfloat()
|
||||
{
|
||||
float v;
|
||||
dst = (byte*)&v;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
return v;
|
||||
}
|
||||
|
||||
public double Rdouble()
|
||||
{
|
||||
double v;
|
||||
dst = (byte*)&v;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
return v;
|
||||
}
|
||||
|
||||
public Vector3 Rvector3()
|
||||
{
|
||||
Vector3 v;
|
||||
dst = (byte*)&v.X;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
|
||||
dst = (byte*)&v.Y;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
|
||||
dst = (byte*)&v.Z;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
return v;
|
||||
}
|
||||
|
||||
public Quaternion Rquat()
|
||||
{
|
||||
Quaternion v;
|
||||
dst = (byte*)&v.X;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
|
||||
dst = (byte*)&v.Y;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
|
||||
dst = (byte*)&v.Z;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
|
||||
dst = (byte*)&v.W;
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst++ = rbuf[ptr++];
|
||||
*dst = rbuf[ptr++];
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,5 +65,6 @@ namespace OpenSim.Region.Physics.Manager
|
||||
void releasePinned();
|
||||
void Append(IMesh newMesh);
|
||||
void TransformLinear(float[,] matrix, float[] offset);
|
||||
Vector3 GetCentroid();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,17 @@ namespace OpenSim.Region.Physics.Manager
|
||||
}
|
||||
}
|
||||
|
||||
public struct ContactData
|
||||
{
|
||||
public float mu;
|
||||
public float bounce;
|
||||
|
||||
public ContactData(float _mu, float _bounce)
|
||||
{
|
||||
mu = _mu;
|
||||
bounce = _bounce;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Used to pass collision information to OnCollisionUpdate listeners.
|
||||
/// </summary>
|
||||
@@ -135,6 +146,8 @@ namespace OpenSim.Region.Physics.Manager
|
||||
/// </summary>
|
||||
public event CollisionUpdate OnCollisionUpdate;
|
||||
|
||||
public virtual void SetVehicle(object vdata) { }
|
||||
|
||||
public event OutOfBounds OnOutOfBounds;
|
||||
#pragma warning restore 67
|
||||
|
||||
@@ -142,6 +155,13 @@ namespace OpenSim.Region.Physics.Manager
|
||||
{
|
||||
get { return new NullPhysicsActor(); }
|
||||
}
|
||||
|
||||
public virtual bool Building { get; set; }
|
||||
|
||||
public virtual ContactData ContactData
|
||||
{
|
||||
get { return new ContactData(0, 0); }
|
||||
}
|
||||
|
||||
public abstract bool Stopped { get; }
|
||||
|
||||
@@ -195,6 +215,11 @@ namespace OpenSim.Region.Physics.Manager
|
||||
}
|
||||
}
|
||||
|
||||
public virtual byte[] Serialize(bool PhysIsRunning)
|
||||
{
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
public virtual void RaiseOutOfBounds(Vector3 pos)
|
||||
{
|
||||
// Make a temporary copy of the event to avoid possibility of
|
||||
@@ -554,5 +579,6 @@ namespace OpenSim.Region.Physics.Manager
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Nini.Config;
|
||||
using log4net;
|
||||
using log4net;
|
||||
using OpenSim.Framework;
|
||||
|
||||
namespace OpenSim.Region.Physics.Manager
|
||||
{
|
||||
|
||||
@@ -128,6 +128,12 @@ namespace OpenSim.Region.Physics.Manager
|
||||
public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
|
||||
Vector3 size, Quaternion rotation, bool isPhysical, uint localid);
|
||||
|
||||
public virtual PhysicsActor AddPrimShape(string primName, PhysicsActor parent, PrimitiveBaseShape pbs, Vector3 position,
|
||||
uint localid, byte[] sdata)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual float TimeDilation
|
||||
{
|
||||
get { return 1.0f; }
|
||||
@@ -225,7 +231,7 @@ namespace OpenSim.Region.Physics.Manager
|
||||
}
|
||||
|
||||
public virtual void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents) {}
|
||||
|
||||
public virtual void CombineTerrain(float[] heightMap, Vector3 pOffset) {}
|
||||
public virtual void UnCombine(PhysicsScene pScene) {}
|
||||
|
||||
/// <summary>
|
||||
@@ -263,5 +269,13 @@ namespace OpenSim.Region.Physics.Manager
|
||||
{
|
||||
return new List<ContactResult>();
|
||||
}
|
||||
|
||||
public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod){}
|
||||
public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod) { }
|
||||
public virtual List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count)
|
||||
{
|
||||
return new List<ContactResult>();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
*/
|
||||
|
||||
using System;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.Manager
|
||||
{
|
||||
@@ -117,5 +118,47 @@ namespace OpenSim.Region.Physics.Manager
|
||||
NO_DEFLECTION = 16392,
|
||||
LOCK_ROTATION = 32784
|
||||
}
|
||||
|
||||
|
||||
public struct VehicleData
|
||||
{
|
||||
public Vehicle m_type;
|
||||
public VehicleFlag m_flags;
|
||||
|
||||
// Linear properties
|
||||
public Vector3 m_linearMotorDirection;
|
||||
public Vector3 m_linearFrictionTimescale;
|
||||
public float m_linearMotorDecayTimescale;
|
||||
public float m_linearMotorTimescale;
|
||||
public Vector3 m_linearMotorOffset;
|
||||
|
||||
//Angular properties
|
||||
public Vector3 m_angularMotorDirection;
|
||||
public float m_angularMotorTimescale;
|
||||
public float m_angularMotorDecayTimescale;
|
||||
public Vector3 m_angularFrictionTimescale;
|
||||
|
||||
//Deflection properties
|
||||
public float m_angularDeflectionEfficiency;
|
||||
public float m_angularDeflectionTimescale;
|
||||
public float m_linearDeflectionEfficiency;
|
||||
public float m_linearDeflectionTimescale;
|
||||
|
||||
//Banking properties
|
||||
public float m_bankingEfficiency;
|
||||
public float m_bankingMix;
|
||||
public float m_bankingTimescale;
|
||||
|
||||
//Hover and Buoyancy properties
|
||||
public float m_VhoverHeight;
|
||||
public float m_VhoverEfficiency;
|
||||
public float m_VhoverTimescale;
|
||||
public float m_VehicleBuoyancy;
|
||||
|
||||
//Attractor properties
|
||||
public float m_verticalAttractionEfficiency;
|
||||
public float m_verticalAttractionTimescale;
|
||||
|
||||
// Axis
|
||||
public Quaternion m_referenceFrame;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,11 +46,36 @@ namespace OpenSim.Region.Physics.Meshing
|
||||
IntPtr m_indicesPtr = IntPtr.Zero;
|
||||
int m_indexCount = 0;
|
||||
public float[] m_normals;
|
||||
Vector3 _centroid;
|
||||
int _centroidDiv;
|
||||
|
||||
private class vertexcomp : IEqualityComparer<Vertex>
|
||||
{
|
||||
public bool Equals(Vertex v1, Vertex v2)
|
||||
{
|
||||
if (v1.X == v2.X && v1.Y == v2.Y && v1.Z == v2.Z)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
public int GetHashCode(Vertex v)
|
||||
{
|
||||
int a = v.X.GetHashCode();
|
||||
int b = v.Y.GetHashCode();
|
||||
int c = v.Z.GetHashCode();
|
||||
return (a << 16) ^ (b << 8) ^ c;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Mesh()
|
||||
{
|
||||
m_vertices = new Dictionary<Vertex, int>();
|
||||
vertexcomp vcomp = new vertexcomp();
|
||||
|
||||
m_vertices = new Dictionary<Vertex, int>(vcomp);
|
||||
m_triangles = new List<Triangle>();
|
||||
_centroid = Vector3.Zero;
|
||||
_centroidDiv = 0;
|
||||
}
|
||||
|
||||
public Mesh Clone()
|
||||
@@ -61,7 +86,8 @@ namespace OpenSim.Region.Physics.Meshing
|
||||
{
|
||||
result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone()));
|
||||
}
|
||||
|
||||
result._centroid = _centroid;
|
||||
result._centroidDiv = _centroidDiv;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -71,15 +97,57 @@ namespace OpenSim.Region.Physics.Meshing
|
||||
throw new NotSupportedException("Attempt to Add to a pinned Mesh");
|
||||
// If a vertex of the triangle is not yet in the vertices list,
|
||||
// add it and set its index to the current index count
|
||||
// vertex == seems broken
|
||||
// skip colapsed triangles
|
||||
if ((triangle.v1.X == triangle.v2.X && triangle.v1.Y == triangle.v2.Y && triangle.v1.Z == triangle.v2.Z)
|
||||
|| (triangle.v1.X == triangle.v3.X && triangle.v1.Y == triangle.v3.Y && triangle.v1.Z == triangle.v3.Z)
|
||||
|| (triangle.v2.X == triangle.v3.X && triangle.v2.Y == triangle.v3.Y && triangle.v2.Z == triangle.v3.Z)
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_vertices.Count == 0)
|
||||
{
|
||||
_centroidDiv = 0;
|
||||
_centroid = Vector3.Zero;
|
||||
}
|
||||
|
||||
if (!m_vertices.ContainsKey(triangle.v1))
|
||||
{
|
||||
m_vertices[triangle.v1] = m_vertices.Count;
|
||||
_centroid.X += triangle.v1.X;
|
||||
_centroid.Y += triangle.v1.Y;
|
||||
_centroid.Z += triangle.v1.Z;
|
||||
_centroidDiv++;
|
||||
}
|
||||
if (!m_vertices.ContainsKey(triangle.v2))
|
||||
{
|
||||
m_vertices[triangle.v2] = m_vertices.Count;
|
||||
_centroid.X += triangle.v2.X;
|
||||
_centroid.Y += triangle.v2.Y;
|
||||
_centroid.Z += triangle.v2.Z;
|
||||
_centroidDiv++;
|
||||
}
|
||||
if (!m_vertices.ContainsKey(triangle.v3))
|
||||
{
|
||||
m_vertices[triangle.v3] = m_vertices.Count;
|
||||
_centroid.X += triangle.v3.X;
|
||||
_centroid.Y += triangle.v3.Y;
|
||||
_centroid.Z += triangle.v3.Z;
|
||||
_centroidDiv++;
|
||||
}
|
||||
m_triangles.Add(triangle);
|
||||
}
|
||||
|
||||
public Vector3 GetCentroid()
|
||||
{
|
||||
if (_centroidDiv > 0)
|
||||
return new Vector3(_centroid.X / _centroidDiv, _centroid.Y / _centroidDiv, _centroid.Z / _centroidDiv);
|
||||
else
|
||||
return Vector3.Zero;
|
||||
}
|
||||
|
||||
public void CalcNormals()
|
||||
{
|
||||
int iTriangles = m_triangles.Count;
|
||||
|
||||
@@ -74,6 +74,8 @@ namespace OpenSim.Region.Physics.Meshing
|
||||
#endif
|
||||
|
||||
private bool cacheSculptMaps = true;
|
||||
private bool cacheSculptAlphaMaps = true;
|
||||
|
||||
private string decodedSculptMapPath = null;
|
||||
private bool useMeshiesPhysicsMesh = false;
|
||||
|
||||
@@ -87,7 +89,16 @@ namespace OpenSim.Region.Physics.Meshing
|
||||
IConfig mesh_config = config.Configs["Mesh"];
|
||||
|
||||
decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache");
|
||||
|
||||
cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps);
|
||||
|
||||
if (Environment.OSVersion.Platform == PlatformID.Unix)
|
||||
{
|
||||
cacheSculptAlphaMaps = false;
|
||||
}
|
||||
else
|
||||
cacheSculptAlphaMaps = cacheSculptMaps;
|
||||
|
||||
if(mesh_config != null)
|
||||
useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
|
||||
|
||||
@@ -268,15 +279,18 @@ namespace OpenSim.Region.Physics.Meshing
|
||||
{
|
||||
if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, size, lod, out coords, out faces))
|
||||
return null;
|
||||
// Remove the reference to any JPEG2000 sculpt data so it can be GCed
|
||||
// don't loose it
|
||||
// primShape.SculptData = Utils.EmptyBytes;
|
||||
}
|
||||
// primShape.SculptDataLoaded = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, lod, out coords, out faces))
|
||||
return null;
|
||||
}
|
||||
|
||||
// Remove the reference to any JPEG2000 sculpt data so it can be GCed
|
||||
// keep compatible
|
||||
primShape.SculptData = Utils.EmptyBytes;
|
||||
|
||||
int numCoords = coords.Count;
|
||||
@@ -313,7 +327,7 @@ namespace OpenSim.Region.Physics.Meshing
|
||||
private bool GenerateCoordsAndFacesFromPrimMeshData(
|
||||
string primName, PrimitiveBaseShape primShape, Vector3 size, out List<Coord> coords, out List<Face> faces)
|
||||
{
|
||||
m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName);
|
||||
// m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName);
|
||||
|
||||
coords = new List<Coord>();
|
||||
faces = new List<Face>();
|
||||
@@ -321,7 +335,7 @@ namespace OpenSim.Region.Physics.Meshing
|
||||
|
||||
if (primShape.SculptData.Length <= 0)
|
||||
{
|
||||
m_log.Error("[MESH]: asset data is zero length");
|
||||
m_log.ErrorFormat("[MESH]: asset data for {0} is zero length", primName);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -482,7 +496,8 @@ namespace OpenSim.Region.Physics.Meshing
|
||||
|
||||
//idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData);
|
||||
|
||||
if (cacheSculptMaps)
|
||||
if (cacheSculptMaps && (cacheSculptAlphaMaps || (((ImageFlags)(idata.Flags) & ImageFlags.HasAlpha) ==0)))
|
||||
// don't cache images with alpha channel in linux since mono can't load them correctly)
|
||||
{
|
||||
try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); }
|
||||
catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); }
|
||||
|
||||
@@ -58,28 +58,24 @@ namespace PrimMesher
|
||||
if (bmW == 0 || bmH == 0)
|
||||
throw new Exception("SculptMap: bitmap has no data");
|
||||
|
||||
int numLodPixels = lod * 2 * lod * 2; // (32 * 2)^2 = 64^2 pixels for default sculpt map image
|
||||
int numLodPixels = lod * lod; // (32 * 2)^2 = 64^2 pixels for default sculpt map image
|
||||
|
||||
bool smallMap = bmW * bmH <= numLodPixels;
|
||||
bool needsScaling = false;
|
||||
|
||||
bool smallMap = bmW * bmH <= lod * lod;
|
||||
|
||||
width = bmW;
|
||||
height = bmH;
|
||||
while (width * height > numLodPixels)
|
||||
while (width * height > numLodPixels * 4)
|
||||
{
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
needsScaling = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
if (needsScaling)
|
||||
bm = ScaleImage(bm, width, height,
|
||||
System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor);
|
||||
bm = ScaleImage(bm, width, height);
|
||||
}
|
||||
|
||||
catch (Exception e)
|
||||
@@ -87,7 +83,7 @@ namespace PrimMesher
|
||||
throw new Exception("Exception in ScaleImage(): e: " + e.ToString());
|
||||
}
|
||||
|
||||
if (width * height > lod * lod)
|
||||
if (width * height > numLodPixels)
|
||||
{
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
@@ -144,15 +140,17 @@ namespace PrimMesher
|
||||
int rowNdx, colNdx;
|
||||
int smNdx = 0;
|
||||
|
||||
|
||||
for (rowNdx = 0; rowNdx < numRows; rowNdx++)
|
||||
{
|
||||
List<Coord> row = new List<Coord>(numCols);
|
||||
for (colNdx = 0; colNdx < numCols; colNdx++)
|
||||
{
|
||||
|
||||
if (mirror)
|
||||
row.Add(new Coord(-(redBytes[smNdx] * pixScale - 0.5f), (greenBytes[smNdx] * pixScale - 0.5f), blueBytes[smNdx] * pixScale - 0.5f));
|
||||
row.Add(new Coord(-((float)redBytes[smNdx] * pixScale - 0.5f), ((float)greenBytes[smNdx] * pixScale - 0.5f), (float)blueBytes[smNdx] * pixScale - 0.5f));
|
||||
else
|
||||
row.Add(new Coord(redBytes[smNdx] * pixScale - 0.5f, greenBytes[smNdx] * pixScale - 0.5f, blueBytes[smNdx] * pixScale - 0.5f));
|
||||
row.Add(new Coord((float)redBytes[smNdx] * pixScale - 0.5f, (float)greenBytes[smNdx] * pixScale - 0.5f, (float)blueBytes[smNdx] * pixScale - 0.5f));
|
||||
|
||||
++smNdx;
|
||||
}
|
||||
@@ -161,23 +159,39 @@ namespace PrimMesher
|
||||
return rows;
|
||||
}
|
||||
|
||||
private Bitmap ScaleImage(Bitmap srcImage, int destWidth, int destHeight,
|
||||
System.Drawing.Drawing2D.InterpolationMode interpMode)
|
||||
private Bitmap ScaleImage(Bitmap srcImage, int destWidth, int destHeight)
|
||||
{
|
||||
Bitmap scaledImage = new Bitmap(srcImage, destWidth, destHeight);
|
||||
scaledImage.SetResolution(96.0f, 96.0f);
|
||||
|
||||
Graphics grPhoto = Graphics.FromImage(scaledImage);
|
||||
grPhoto.InterpolationMode = interpMode;
|
||||
Bitmap scaledImage = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);
|
||||
|
||||
Color c;
|
||||
float xscale = srcImage.Width / destWidth;
|
||||
float yscale = srcImage.Height / destHeight;
|
||||
|
||||
float sy = 0.5f;
|
||||
for (int y = 0; y < destHeight; y++)
|
||||
{
|
||||
float sx = 0.5f;
|
||||
for (int x = 0; x < destWidth; x++)
|
||||
{
|
||||
try
|
||||
{
|
||||
c = srcImage.GetPixel((int)(sx), (int)(sy));
|
||||
scaledImage.SetPixel(x, y, Color.FromArgb(c.R, c.G, c.B));
|
||||
}
|
||||
catch (IndexOutOfRangeException)
|
||||
{
|
||||
}
|
||||
|
||||
grPhoto.DrawImage(srcImage,
|
||||
new Rectangle(0, 0, destWidth, destHeight),
|
||||
new Rectangle(0, 0, srcImage.Width, srcImage.Height),
|
||||
GraphicsUnit.Pixel);
|
||||
|
||||
grPhoto.Dispose();
|
||||
sx += xscale;
|
||||
}
|
||||
sy += yscale;
|
||||
}
|
||||
srcImage.Dispose();
|
||||
return scaledImage;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -156,6 +156,22 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
internal UUID m_uuid { get; private set; }
|
||||
internal bool bad = false;
|
||||
|
||||
/// <summary>
|
||||
/// ODE Avatar.
|
||||
/// </summary>
|
||||
/// <param name="avName"></param>
|
||||
/// <param name="parent_scene"></param>
|
||||
/// <param name="pos"></param>
|
||||
/// <param name="size"></param>
|
||||
/// <param name="pid_d"></param>
|
||||
/// <param name="pid_p"></param>
|
||||
/// <param name="capsule_radius"></param>
|
||||
/// <param name="tensor"></param>
|
||||
/// <param name="density">
|
||||
/// Only used right now to return information to LSL. Not actually used to set mass in ODE!
|
||||
/// </param>
|
||||
/// <param name="walk_divisor"></param>
|
||||
/// <param name="rundivisor"></param>
|
||||
public OdeCharacter(
|
||||
String avName, OdeScene parent_scene, Vector3 pos, Vector3 size, float pid_d, float pid_p,
|
||||
float capsule_radius, float tensor, float density,
|
||||
@@ -786,6 +802,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
Vector3 vec = Vector3.Zero;
|
||||
d.Vector3 vel = d.BodyGetLinearVel(Body);
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[ODE CHARACTER]: Current velocity in Move() is <{0},{1},{2}>, target {3} for {4}",
|
||||
// vel.X, vel.Y, vel.Z, _target_velocity, Name);
|
||||
|
||||
float movementdivisor = 1f;
|
||||
|
||||
if (!m_alwaysRun)
|
||||
@@ -884,18 +904,20 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
|
||||
if (flying)
|
||||
{
|
||||
// This also acts as anti-gravity so that we hover when flying rather than fall.
|
||||
vec.Z = (_target_velocity.Z - vel.Z) * (PID_D);
|
||||
}
|
||||
}
|
||||
|
||||
if (flying)
|
||||
{
|
||||
// Anti-gravity so that we hover when flying rather than fall.
|
||||
vec.Z += ((-1 * _parent_scene.gravityz) * m_mass);
|
||||
|
||||
//Added for auto fly height. Kitto Flora
|
||||
//d.Vector3 pos = d.BodyGetPosition(Body);
|
||||
float target_altitude = _parent_scene.GetTerrainHeightAtXY(_position.X, _position.Y) + MinimumGroundFlightOffset;
|
||||
|
||||
|
||||
if (_position.Z < target_altitude)
|
||||
{
|
||||
vec.Z += (target_altitude - _position.Z) * PID_P * 5.0f;
|
||||
@@ -921,6 +943,25 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
d.Vector3 newVel = d.BodyGetLinearVel(Body);
|
||||
if (newVel.X >= 256 || newVel.X <= 256 || newVel.Y >= 256 || newVel.Y <= 256 || newVel.Z >= 256 || newVel.Z <= 256)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[ODE CHARACTER]: Limiting falling velocity from {0} to {1} for {2}", newVel.Z, -9.8, Name);
|
||||
|
||||
newVel.X = Util.Clamp<float>(newVel.X, -255f, 255f);
|
||||
newVel.Y = Util.Clamp<float>(newVel.Y, -255f, 255f);
|
||||
|
||||
if (!flying)
|
||||
newVel.Z
|
||||
= Util.Clamp<float>(
|
||||
newVel.Z, -_parent_scene.AvatarTerminalVelocity, _parent_scene.AvatarTerminalVelocity);
|
||||
else
|
||||
newVel.Z = Util.Clamp<float>(newVel.Z, -255f, 255f);
|
||||
|
||||
d.BodySetLinearVel(Body, newVel.X, newVel.Y, newVel.Z);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
/// </summary>
|
||||
public class OdePlugin : IPhysicsPlugin
|
||||
{
|
||||
//private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private OdeScene m_scene;
|
||||
|
||||
@@ -59,13 +59,23 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
if (m_scene == null)
|
||||
{
|
||||
// We do this so that OpenSimulator on Windows loads the correct native ODE library depending on whether
|
||||
// it's running as a 32-bit process or a 64-bit one. By invoking LoadLibary here, later DLLImports
|
||||
// will find it already loaded later on.
|
||||
//
|
||||
// This isn't necessary for other platforms (e.g. Mac OSX and Linux) since the DLL used can be
|
||||
// controlled in Ode.NET.dll.config
|
||||
if (Util.IsWindows())
|
||||
Util.LoadArchSpecificWindowsDll("ode.dll");
|
||||
|
||||
// Initializing ODE only when a scene is created allows alternative ODE plugins to co-habit (according to
|
||||
// http://opensimulator.org/mantis/view.php?id=2750).
|
||||
d.InitODE();
|
||||
|
||||
m_scene = new OdeScene(sceneIdentifier);
|
||||
}
|
||||
return (m_scene);
|
||||
|
||||
return m_scene;
|
||||
}
|
||||
|
||||
public string GetName()
|
||||
|
||||
@@ -144,6 +144,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
public float gravityy = 0f;
|
||||
public float gravityz = -9.8f;
|
||||
|
||||
public float AvatarTerminalVelocity { get; set; }
|
||||
|
||||
private float contactsurfacelayer = 0.001f;
|
||||
|
||||
private int worldHashspaceLow = -4;
|
||||
@@ -459,6 +461,15 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
gravityy = physicsconfig.GetFloat("world_gravityy", 0f);
|
||||
gravityz = physicsconfig.GetFloat("world_gravityz", -9.8f);
|
||||
|
||||
float avatarTerminalVelocity = physicsconfig.GetFloat("avatar_terminal_velocity", 54f);
|
||||
AvatarTerminalVelocity = Util.Clamp<float>(avatarTerminalVelocity, 0, 255f);
|
||||
if (AvatarTerminalVelocity != avatarTerminalVelocity)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[ODE SCENE]: avatar_terminal_velocity of {0} is invalid. Clamping to {1}",
|
||||
avatarTerminalVelocity, AvatarTerminalVelocity);
|
||||
}
|
||||
|
||||
worldHashspaceLow = physicsconfig.GetInt("world_hashspace_size_low", -4);
|
||||
worldHashspaceHigh = physicsconfig.GetInt("world_hashspace_size_high", 128);
|
||||
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Information about this assembly is defined by the following
|
||||
// attributes.
|
||||
//
|
||||
// change them to the information which is associated with the assembly
|
||||
// you compile.
|
||||
|
||||
[assembly : AssemblyTitle("RealPhysXplugin")]
|
||||
[assembly : AssemblyDescription("")]
|
||||
[assembly : AssemblyConfiguration("")]
|
||||
[assembly : AssemblyCompany("http://opensimulator.org")]
|
||||
[assembly : AssemblyProduct("RealPhysXplugin")]
|
||||
[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")]
|
||||
[assembly : AssemblyTrademark("")]
|
||||
[assembly : AssemblyCulture("")]
|
||||
|
||||
// This sets the default COM visibility of types in the assembly to invisible.
|
||||
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
|
||||
|
||||
[assembly : ComVisible(false)]
|
||||
|
||||
// The assembly version has following format :
|
||||
//
|
||||
// Major.Minor.Build.Revision
|
||||
//
|
||||
// You can specify all values by your own or you can build default build and revision
|
||||
// numbers with the '*' character (the default):
|
||||
|
||||
[assembly : AssemblyVersion("0.6.5.*")]
|
||||
@@ -1,349 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
using PhysXWrapper;
|
||||
using Quaternion=OpenMetaverse.Quaternion;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.PhysXPlugin
|
||||
{
|
||||
public class PhysXCharacter : PhysicsActor
|
||||
{
|
||||
private Vector3 _position;
|
||||
private Vector3 _velocity;
|
||||
private Vector3 m_rotationalVelocity = Vector3.Zero;
|
||||
private Vector3 _acceleration;
|
||||
private NxCharacter _character;
|
||||
private bool flying;
|
||||
private bool iscolliding = false;
|
||||
private float gravityAccel;
|
||||
|
||||
public PhysXCharacter(NxCharacter character)
|
||||
{
|
||||
_character = character;
|
||||
}
|
||||
|
||||
public override int PhysicsActorType
|
||||
{
|
||||
get { return (int) ActorTypes.Agent; }
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override bool SetAlwaysRun
|
||||
{
|
||||
get { return false; }
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override uint LocalID
|
||||
{
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override bool Grabbed
|
||||
{
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override bool Selected
|
||||
{
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override float Buoyancy
|
||||
{
|
||||
get { return 0f; }
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override bool FloatOnWater
|
||||
{
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override bool IsPhysical
|
||||
{
|
||||
get { return false; }
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override bool ThrottleUpdates
|
||||
{
|
||||
get { return false; }
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override bool Flying
|
||||
{
|
||||
get { return flying; }
|
||||
set { flying = value; }
|
||||
}
|
||||
|
||||
public override bool IsColliding
|
||||
{
|
||||
get { return iscolliding; }
|
||||
set { iscolliding = value; }
|
||||
}
|
||||
|
||||
public override bool CollidingGround
|
||||
{
|
||||
get { return false; }
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override bool CollidingObj
|
||||
{
|
||||
get { return false; }
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override Vector3 RotationalVelocity
|
||||
{
|
||||
get { return m_rotationalVelocity; }
|
||||
set { m_rotationalVelocity = value; }
|
||||
}
|
||||
|
||||
public override bool Stopped
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override Vector3 Position
|
||||
{
|
||||
get { return _position; }
|
||||
set
|
||||
{
|
||||
_position = value;
|
||||
Vec3 ps = new Vec3();
|
||||
ps.X = value.X;
|
||||
ps.Y = value.Y;
|
||||
ps.Z = value.Z;
|
||||
_character.Position = ps;
|
||||
}
|
||||
}
|
||||
|
||||
public override Vector3 Size
|
||||
{
|
||||
get { return Vector3.Zero; }
|
||||
set { }
|
||||
}
|
||||
|
||||
public override float Mass
|
||||
{
|
||||
get { return 0f; }
|
||||
}
|
||||
|
||||
public override Vector3 Force
|
||||
{
|
||||
get { return Vector3.Zero; }
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override int VehicleType
|
||||
{
|
||||
get { return 0; }
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override void VehicleFloatParam(int param, float value)
|
||||
{
|
||||
}
|
||||
|
||||
public override void VehicleVectorParam(int param, Vector3 value)
|
||||
{
|
||||
}
|
||||
|
||||
public override void VehicleRotationParam(int param, Quaternion rotation)
|
||||
{
|
||||
}
|
||||
|
||||
public override void VehicleFlags(int param, bool remove)
|
||||
{
|
||||
}
|
||||
|
||||
public override void SetVolumeDetect(int param)
|
||||
{
|
||||
}
|
||||
|
||||
public override Vector3 CenterOfMass
|
||||
{
|
||||
get { return Vector3.Zero; }
|
||||
}
|
||||
|
||||
public override Vector3 GeometricCenter
|
||||
{
|
||||
get { return Vector3.Zero; }
|
||||
}
|
||||
|
||||
public override Vector3 Velocity
|
||||
{
|
||||
get { return _velocity; }
|
||||
set { _velocity = value; }
|
||||
}
|
||||
|
||||
public override float CollisionScore
|
||||
{
|
||||
get { return 0f; }
|
||||
set { }
|
||||
}
|
||||
|
||||
public override bool Kinematic
|
||||
{
|
||||
get { return false; }
|
||||
set { }
|
||||
}
|
||||
|
||||
public override Quaternion Orientation
|
||||
{
|
||||
get { return Quaternion.Identity; }
|
||||
set { }
|
||||
}
|
||||
|
||||
public override Vector3 Acceleration
|
||||
{
|
||||
get { return _acceleration; }
|
||||
set { _acceleration = value; }
|
||||
}
|
||||
|
||||
public override void AddForce(Vector3 force, bool pushforce)
|
||||
{
|
||||
}
|
||||
|
||||
public override Vector3 Torque
|
||||
{
|
||||
get { return Vector3.Zero; }
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override void AddAngularForce(Vector3 force, bool pushforce)
|
||||
{
|
||||
}
|
||||
|
||||
public override void link(PhysicsActor obj)
|
||||
{
|
||||
}
|
||||
|
||||
public override void delink()
|
||||
{
|
||||
}
|
||||
|
||||
public override void LockAngularMotion(Vector3 axis)
|
||||
{
|
||||
}
|
||||
|
||||
public override void SetMomentum(Vector3 momentum)
|
||||
{
|
||||
}
|
||||
|
||||
public void Move(float timeStep)
|
||||
{
|
||||
Vec3 vec = new Vec3();
|
||||
vec.X = _velocity.X*timeStep;
|
||||
vec.Y = _velocity.Y*timeStep;
|
||||
if (flying)
|
||||
{
|
||||
vec.Z = (_velocity.Z)*timeStep;
|
||||
}
|
||||
else
|
||||
{
|
||||
gravityAccel += -9.8f;
|
||||
vec.Z = (gravityAccel + _velocity.Z)*timeStep;
|
||||
}
|
||||
int res = _character.Move(vec);
|
||||
if (res == 1)
|
||||
{
|
||||
gravityAccel = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override PrimitiveBaseShape Shape
|
||||
{
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public void UpdatePosition()
|
||||
{
|
||||
Vec3 vec = _character.Position;
|
||||
_position.X = vec.X;
|
||||
_position.Y = vec.Y;
|
||||
_position.Z = vec.Z;
|
||||
}
|
||||
|
||||
public override void CrossingFailure()
|
||||
{
|
||||
}
|
||||
|
||||
public override Vector3 PIDTarget { set { return; } }
|
||||
public override bool PIDActive { set { return; } }
|
||||
public override float PIDTau { set { return; } }
|
||||
|
||||
public override float PIDHoverHeight { set { return; } }
|
||||
public override bool PIDHoverActive { set { return; } }
|
||||
public override PIDHoverType PIDHoverType { set { return; } }
|
||||
public override float PIDHoverTau { set { return; } }
|
||||
|
||||
public override Quaternion APIDTarget
|
||||
{
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override bool APIDActive
|
||||
{
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override float APIDStrength
|
||||
{
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override float APIDDamping
|
||||
{
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override void SubscribeEvents(int ms)
|
||||
{
|
||||
|
||||
}
|
||||
public override void UnSubscribeEvents()
|
||||
{
|
||||
|
||||
}
|
||||
public override bool SubscribedEvents()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,341 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
using PhysXWrapper;
|
||||
using Quaternion=OpenMetaverse.Quaternion;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.PhysXPlugin
|
||||
{
|
||||
public class PhysXPrim : PhysicsActor
|
||||
{
|
||||
private Vector3 _velocity;
|
||||
private Vector3 _acceleration;
|
||||
private Vector3 m_rotationalVelocity;
|
||||
private NxActor _prim;
|
||||
|
||||
public PhysXPrim(NxActor prim)
|
||||
{
|
||||
_velocity = Vector3.Zero;
|
||||
_acceleration = Vector3.Zero;
|
||||
_prim = prim;
|
||||
}
|
||||
|
||||
public override int PhysicsActorType
|
||||
{
|
||||
get { return (int) ActorTypes.Prim; }
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override bool IsPhysical
|
||||
{
|
||||
get { return false; }
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override bool SetAlwaysRun
|
||||
{
|
||||
get { return false; }
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override uint LocalID
|
||||
{
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override bool Grabbed
|
||||
{
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override bool Selected
|
||||
{
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override float Buoyancy
|
||||
{
|
||||
get { return 0f; }
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override bool FloatOnWater
|
||||
{
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override bool ThrottleUpdates
|
||||
{
|
||||
get { return false; }
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override Vector3 RotationalVelocity
|
||||
{
|
||||
get { return m_rotationalVelocity; }
|
||||
set { m_rotationalVelocity = value; }
|
||||
}
|
||||
|
||||
public override bool Flying
|
||||
{
|
||||
get { return false; //no flying prims for you
|
||||
}
|
||||
set { }
|
||||
}
|
||||
|
||||
public override bool IsColliding
|
||||
{
|
||||
get { return false; }
|
||||
set { }
|
||||
}
|
||||
|
||||
public override bool CollidingGround
|
||||
{
|
||||
get { return false; }
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override bool CollidingObj
|
||||
{
|
||||
get { return false; }
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override bool Stopped
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override Vector3 Position
|
||||
{
|
||||
get
|
||||
{
|
||||
Vector3 pos = Vector3.Zero;
|
||||
Vec3 vec = _prim.Position;
|
||||
pos.X = vec.X;
|
||||
pos.Y = vec.Y;
|
||||
pos.Z = vec.Z;
|
||||
return pos;
|
||||
}
|
||||
set
|
||||
{
|
||||
Vector3 vec = value;
|
||||
Vec3 pos = new Vec3();
|
||||
pos.X = vec.X;
|
||||
pos.Y = vec.Y;
|
||||
pos.Z = vec.Z;
|
||||
_prim.Position = pos;
|
||||
}
|
||||
}
|
||||
|
||||
public override PrimitiveBaseShape Shape
|
||||
{
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override Vector3 Velocity
|
||||
{
|
||||
get { return _velocity; }
|
||||
set { _velocity = value; }
|
||||
}
|
||||
|
||||
public override Vector3 Torque
|
||||
{
|
||||
get { return Vector3.Zero; }
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override float CollisionScore
|
||||
{
|
||||
get { return 0f; }
|
||||
set { }
|
||||
}
|
||||
|
||||
public override bool Kinematic
|
||||
{
|
||||
get { return _prim.Kinematic; }
|
||||
set { _prim.Kinematic = value; }
|
||||
}
|
||||
|
||||
public override Quaternion Orientation
|
||||
{
|
||||
get
|
||||
{
|
||||
Quaternion res;
|
||||
PhysXWrapper.Quaternion quat = _prim.GetOrientation();
|
||||
res.W = quat.W;
|
||||
res.X = quat.X;
|
||||
res.Y = quat.Y;
|
||||
res.Z = quat.Z;
|
||||
return res;
|
||||
}
|
||||
set { }
|
||||
}
|
||||
|
||||
public override Vector3 Acceleration
|
||||
{
|
||||
get { return _acceleration; }
|
||||
set { _acceleration = value; }
|
||||
}
|
||||
|
||||
public override void AddForce(Vector3 force, bool pushforce)
|
||||
{
|
||||
}
|
||||
|
||||
public override void AddAngularForce(Vector3 force, bool pushforce)
|
||||
{
|
||||
}
|
||||
|
||||
public override void SetMomentum(Vector3 momentum)
|
||||
{
|
||||
}
|
||||
|
||||
public override Vector3 Size
|
||||
{
|
||||
get { return Vector3.Zero; }
|
||||
set { }
|
||||
}
|
||||
|
||||
public override void link(PhysicsActor obj)
|
||||
{
|
||||
}
|
||||
|
||||
public override void delink()
|
||||
{
|
||||
}
|
||||
|
||||
public override void LockAngularMotion(Vector3 axis)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override float Mass
|
||||
{
|
||||
get { return 0f; }
|
||||
}
|
||||
|
||||
public override Vector3 Force
|
||||
{
|
||||
get { return Vector3.Zero; }
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override int VehicleType
|
||||
{
|
||||
get { return 0; }
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override void VehicleFloatParam(int param, float value)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void VehicleVectorParam(int param, Vector3 value)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void VehicleRotationParam(int param, Quaternion rotation)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void VehicleFlags(int param, bool remove) { }
|
||||
|
||||
public override void SetVolumeDetect(int param)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override Vector3 CenterOfMass
|
||||
{
|
||||
get { return Vector3.Zero; }
|
||||
}
|
||||
|
||||
public override Vector3 GeometricCenter
|
||||
{
|
||||
get { return Vector3.Zero; }
|
||||
}
|
||||
|
||||
public override void CrossingFailure()
|
||||
{
|
||||
}
|
||||
|
||||
public override Vector3 PIDTarget { set { return; } }
|
||||
public override bool PIDActive { set { return; } }
|
||||
public override float PIDTau { set { return; } }
|
||||
|
||||
public override float PIDHoverHeight { set { return; } }
|
||||
public override bool PIDHoverActive { set { return; } }
|
||||
public override PIDHoverType PIDHoverType { set { return; } }
|
||||
public override float PIDHoverTau { set { return; } }
|
||||
|
||||
public override Quaternion APIDTarget
|
||||
{
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override bool APIDActive
|
||||
{
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override float APIDStrength
|
||||
{
|
||||
set { return; }
|
||||
}
|
||||
|
||||
public override float APIDDamping
|
||||
{
|
||||
set { return; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override void SubscribeEvents(int ms)
|
||||
{
|
||||
|
||||
}
|
||||
public override void UnSubscribeEvents()
|
||||
{
|
||||
|
||||
}
|
||||
public override bool SubscribedEvents()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,177 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
using PhysXWrapper;
|
||||
using Quaternion=OpenMetaverse.Quaternion;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.PhysXPlugin
|
||||
{
|
||||
public class PhysXScene : PhysicsScene
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private List<PhysXCharacter> _characters = new List<PhysXCharacter>();
|
||||
private List<PhysXPrim> _prims = new List<PhysXPrim>();
|
||||
private float[] _heightMap = null;
|
||||
private NxPhysicsSDK mySdk;
|
||||
private NxScene scene;
|
||||
|
||||
// protected internal string sceneIdentifier;
|
||||
public PhysXScene(string _sceneIdentifier)
|
||||
{
|
||||
//sceneIdentifier = _sceneIdentifier;
|
||||
|
||||
mySdk = NxPhysicsSDK.CreateSDK();
|
||||
m_log.Info("Sdk created - now creating scene");
|
||||
scene = mySdk.CreateScene();
|
||||
}
|
||||
|
||||
public override void Initialise(IMesher meshmerizer, IConfigSource config)
|
||||
{
|
||||
// Does nothing right now
|
||||
}
|
||||
public override void Dispose()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void SetWaterLevel(float baseheight)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying)
|
||||
{
|
||||
Vec3 pos = new Vec3();
|
||||
pos.X = position.X;
|
||||
pos.Y = position.Y;
|
||||
pos.Z = position.Z;
|
||||
PhysXCharacter act = new PhysXCharacter(scene.AddCharacter(pos));
|
||||
act.Flying = isFlying;
|
||||
act.Position = position;
|
||||
_characters.Add(act);
|
||||
return act;
|
||||
}
|
||||
|
||||
public override void RemovePrim(PhysicsActor prim)
|
||||
{
|
||||
}
|
||||
|
||||
public override void RemoveAvatar(PhysicsActor actor)
|
||||
{
|
||||
}
|
||||
|
||||
private PhysicsActor AddPrim(Vector3 position, Vector3 size, Quaternion rotation)
|
||||
{
|
||||
Vec3 pos = new Vec3();
|
||||
pos.X = position.X;
|
||||
pos.Y = position.Y;
|
||||
pos.Z = position.Z;
|
||||
Vec3 siz = new Vec3();
|
||||
siz.X = size.X;
|
||||
siz.Y = size.Y;
|
||||
siz.Z = size.Z;
|
||||
PhysXPrim act = new PhysXPrim(scene.AddNewBox(pos, siz));
|
||||
_prims.Add(act);
|
||||
return act;
|
||||
}
|
||||
|
||||
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
|
||||
Vector3 size, Quaternion rotation, bool isPhysical, uint localid)
|
||||
{
|
||||
return AddPrim(position, size, rotation);
|
||||
}
|
||||
|
||||
public override void AddPhysicsActorTaint(PhysicsActor prim)
|
||||
{
|
||||
}
|
||||
|
||||
public override float Simulate(float timeStep)
|
||||
{
|
||||
float fps = 0f;
|
||||
try
|
||||
{
|
||||
foreach (PhysXCharacter actor in _characters)
|
||||
{
|
||||
actor.Move(timeStep);
|
||||
}
|
||||
scene.Simulate(timeStep);
|
||||
scene.FetchResults();
|
||||
scene.UpdateControllers();
|
||||
|
||||
foreach (PhysXCharacter actor in _characters)
|
||||
{
|
||||
actor.UpdatePosition();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(e.Message);
|
||||
}
|
||||
return fps;
|
||||
}
|
||||
|
||||
public override void GetResults()
|
||||
{
|
||||
}
|
||||
|
||||
public override bool IsThreaded
|
||||
{
|
||||
// for now we won't be multithreaded
|
||||
get { return (false); }
|
||||
}
|
||||
|
||||
public override void SetTerrain(float[] heightMap)
|
||||
{
|
||||
if (_heightMap != null)
|
||||
{
|
||||
m_log.Debug("PhysX - deleting old terrain");
|
||||
scene.DeleteTerrain();
|
||||
}
|
||||
_heightMap = heightMap;
|
||||
scene.AddTerrain(heightMap);
|
||||
}
|
||||
|
||||
public override void DeleteTerrain()
|
||||
{
|
||||
scene.DeleteTerrain();
|
||||
}
|
||||
|
||||
public override Dictionary<uint, float> GetTopColliders()
|
||||
{
|
||||
Dictionary<uint, float> returncolliders = new Dictionary<uint, float>();
|
||||
return returncolliders;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@
|
||||
*/
|
||||
|
||||
|
||||
// Revision by Ubit 2011
|
||||
// Revision by Ubit 2011/12
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -95,21 +95,12 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
private bool m_iscollidingObj = false;
|
||||
private bool m_alwaysRun = false;
|
||||
private int m_requestedUpdateFrequency = 0;
|
||||
private Vector3 m_taintPosition = Vector3.Zero;
|
||||
private bool m_hasTaintPosition = false;
|
||||
public uint m_localID = 0;
|
||||
public bool m_returnCollisions = false;
|
||||
// taints and their non-tainted counterparts
|
||||
public bool m_isPhysical = false; // the current physical status
|
||||
public bool m_tainted_isPhysical = false; // set when the physical status is tainted (false=not existing in physics engine, true=existing)
|
||||
public float MinimumGroundFlightOffset = 3f;
|
||||
|
||||
|
||||
private Vector3 m_taintForce;
|
||||
private bool m_hasTaintForce;
|
||||
private float m_tainted_CAPSULE_LENGTH; // set when the capsule length changes.
|
||||
|
||||
|
||||
private float m_buoyancy = 0f;
|
||||
|
||||
// private CollisionLocker ode;
|
||||
@@ -135,7 +126,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
public IntPtr Shell = IntPtr.Zero;
|
||||
public IntPtr Amotor = IntPtr.Zero;
|
||||
public d.Mass ShellMass;
|
||||
public bool collidelock = false;
|
||||
// public bool collidelock = false;
|
||||
|
||||
private bool m_haseventsubscription = false;
|
||||
public int m_eventsubscription = 0;
|
||||
@@ -151,15 +142,13 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
m_uuid = UUID.Random();
|
||||
|
||||
m_hasTaintPosition = false;
|
||||
|
||||
if (pos.IsFinite())
|
||||
{
|
||||
if (pos.Z > 9999999f)
|
||||
if (pos.Z > 99999f)
|
||||
{
|
||||
pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
|
||||
}
|
||||
if (pos.Z < -90000f)
|
||||
if (pos.Z < -100f) // shouldn't this be 0 ?
|
||||
{
|
||||
pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
|
||||
}
|
||||
@@ -187,15 +176,12 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
|
||||
CAPSULE_LENGTH = size.Z * 1.15f - CAPSULE_RADIUS * 2.0f;
|
||||
//m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString());
|
||||
m_tainted_CAPSULE_LENGTH = CAPSULE_LENGTH;
|
||||
|
||||
m_isPhysical = false; // current status: no ODE information exists
|
||||
m_tainted_isPhysical = true; // new tainted status: need to create ODE information
|
||||
|
||||
m_hasTaintForce = false;
|
||||
_parent_scene.AddPhysicsActorTaint(this);
|
||||
|
||||
m_name = avName;
|
||||
|
||||
AddChange(changes.Add, null);
|
||||
}
|
||||
|
||||
public override int PhysicsActorType
|
||||
@@ -402,16 +388,11 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
|
||||
}
|
||||
if (value.Z < -90000f)
|
||||
if (value.Z < -100f)
|
||||
{
|
||||
value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5;
|
||||
}
|
||||
|
||||
m_taintPosition.X = value.X;
|
||||
m_taintPosition.Y = value.Y;
|
||||
m_taintPosition.Z = value.Z;
|
||||
m_hasTaintPosition = true;
|
||||
_parent_scene.AddPhysicsActorTaint(this);
|
||||
AddChange(changes.Position, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -440,11 +421,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
if (value.IsFinite())
|
||||
{
|
||||
m_pidControllerActive = true;
|
||||
|
||||
Vector3 SetSize = value;
|
||||
m_tainted_CAPSULE_LENGTH = SetSize.Z *1.15f - CAPSULE_RADIUS * 2.0f;
|
||||
_parent_scene.AddPhysicsActorTaint(this);
|
||||
AddChange(changes.Size, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -460,129 +437,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
/// <param name="npositionY"></param>
|
||||
/// <param name="npositionZ"></param>
|
||||
|
||||
// WARNING: This MUST NOT be called outside of ProcessTaints, else we can have unsynchronized access
|
||||
// to ODE internals. ProcessTaints is called from within thread-locked Simulate(), so it is the only
|
||||
// place that is safe to call this routine AvatarGeomAndBodyCreation.
|
||||
private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ)
|
||||
{
|
||||
_parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace);
|
||||
if (CAPSULE_LENGTH <= 0)
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!");
|
||||
CAPSULE_LENGTH = 0.01f;
|
||||
|
||||
}
|
||||
|
||||
if (CAPSULE_RADIUS <= 0)
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!");
|
||||
CAPSULE_RADIUS = 0.01f;
|
||||
|
||||
}
|
||||
Shell = d.CreateCapsule(_parent_scene.ActiveSpace, CAPSULE_RADIUS, CAPSULE_LENGTH);
|
||||
|
||||
d.GeomSetCategoryBits(Shell, (int)m_collisionCategories);
|
||||
d.GeomSetCollideBits(Shell, (int)m_collisionFlags);
|
||||
|
||||
d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH);
|
||||
|
||||
m_mass = ShellMass.mass; // update mass
|
||||
|
||||
// rescale PID parameters
|
||||
PID_D = _parent_scene.avPIDD;
|
||||
PID_P = _parent_scene.avPIDP;
|
||||
|
||||
// rescale PID parameters so that this aren't affected by mass
|
||||
// and so don't get unstable for some masses
|
||||
// also scale by ode time step so you don't need to refix them
|
||||
|
||||
PID_D /= 50 * 80; //scale to original mass of around 80 and 50 ODE fps
|
||||
PID_D *= m_mass / _parent_scene.ODE_STEPSIZE;
|
||||
PID_P /= 50 * 80;
|
||||
PID_P *= m_mass / _parent_scene.ODE_STEPSIZE;
|
||||
|
||||
Body = d.BodyCreate(_parent_scene.world);
|
||||
|
||||
d.BodySetAutoDisableFlag(Body, false);
|
||||
d.BodySetPosition(Body, npositionX, npositionY, npositionZ);
|
||||
|
||||
_position.X = npositionX;
|
||||
_position.Y = npositionY;
|
||||
_position.Z = npositionZ;
|
||||
|
||||
m_hasTaintPosition = false;
|
||||
|
||||
d.BodySetMass(Body, ref ShellMass);
|
||||
d.GeomSetBody(Shell, Body);
|
||||
|
||||
// The purpose of the AMotor here is to keep the avatar's physical
|
||||
// surrogate from rotating while moving
|
||||
Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero);
|
||||
d.JointAttach(Amotor, Body, IntPtr.Zero);
|
||||
|
||||
d.JointSetAMotorMode(Amotor, 0);
|
||||
d.JointSetAMotorNumAxes(Amotor, 3);
|
||||
d.JointSetAMotorAxis(Amotor, 0, 0 , 1, 0, 0);
|
||||
d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0);
|
||||
d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1);
|
||||
|
||||
d.JointSetAMotorAngle(Amotor, 0, 0);
|
||||
d.JointSetAMotorAngle(Amotor, 1, 0);
|
||||
d.JointSetAMotorAngle(Amotor, 2, 0);
|
||||
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM, 0f); // make it HARD
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM2, 0f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM3, 0f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.StopERP, 0.8f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.StopERP2, 0.8f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.StopERP3, 0.8f);
|
||||
|
||||
// These lowstops and high stops are effectively (no wiggle room)
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -1e-5f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 1e-5f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -1e-5f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 1e-5f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -1e-5f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 1e-5f);
|
||||
|
||||
d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel, 0);
|
||||
d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel2, 0);
|
||||
d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel3, 0);
|
||||
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.FMax, 5e6f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.FMax2, 5e6f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.FMax3, 5e6f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the avatar body and geom
|
||||
|
||||
private void AvatarGeomAndBodyDestroy()
|
||||
{
|
||||
// Kill the Amotor
|
||||
if (Amotor != IntPtr.Zero)
|
||||
{
|
||||
d.JointDestroy(Amotor);
|
||||
Amotor = IntPtr.Zero;
|
||||
}
|
||||
|
||||
if (Body != IntPtr.Zero)
|
||||
{
|
||||
//kill the body
|
||||
d.BodyDestroy(Body);
|
||||
Body = IntPtr.Zero;
|
||||
}
|
||||
|
||||
//kill the Geometry
|
||||
if (Shell != IntPtr.Zero)
|
||||
{
|
||||
_parent_scene.geom_name_map.Remove(Shell);
|
||||
_parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace);
|
||||
d.GeomDestroy(Shell);
|
||||
_parent_scene.geom_name_map.Remove(Shell);
|
||||
Shell = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
//
|
||||
/// <summary>
|
||||
/// Uses the capped cyllinder volume formula to calculate the avatar's mass.
|
||||
@@ -705,8 +559,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
if (value.IsFinite())
|
||||
{
|
||||
m_pidControllerActive = true;
|
||||
_target_velocity = value;
|
||||
AddChange(changes.Velocity, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -738,9 +591,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
get { return Quaternion.Identity; }
|
||||
set
|
||||
{
|
||||
//Matrix3 or = Orientation.ToRotationMatrix();
|
||||
//d.Matrix3 ord = new d.Matrix3(or.m00, or.m10, or.m20, or.m01, or.m11, or.m21, or.m02, or.m12, or.m22);
|
||||
//d.BodySetRotation(Body, ref ord);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -767,17 +617,11 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
if (pushforce)
|
||||
{
|
||||
m_pidControllerActive = false;
|
||||
m_taintForce = force / _parent_scene.ODE_STEPSIZE;
|
||||
m_hasTaintForce = true;
|
||||
_parent_scene.AddPhysicsActorTaint(this);
|
||||
AddChange(changes.Force, force * m_density / _parent_scene.ODE_STEPSIZE / 28f);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pidControllerActive = true;
|
||||
_target_velocity.X += force.X;
|
||||
_target_velocity.Y += force.Y;
|
||||
_target_velocity.Z += force.Z;
|
||||
AddChange(changes.Velocity, force);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -797,6 +641,128 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
}
|
||||
|
||||
|
||||
// WARNING: This MUST NOT be called outside of ProcessTaints, else we can have unsynchronized access
|
||||
// to ODE internals. ProcessTaints is called from within thread-locked Simulate(), so it is the only
|
||||
// place that is safe to call this routine AvatarGeomAndBodyCreation.
|
||||
private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ)
|
||||
{
|
||||
_parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace);
|
||||
if (CAPSULE_LENGTH <= 0)
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!");
|
||||
CAPSULE_LENGTH = 0.01f;
|
||||
|
||||
}
|
||||
|
||||
if (CAPSULE_RADIUS <= 0)
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!");
|
||||
CAPSULE_RADIUS = 0.01f;
|
||||
|
||||
}
|
||||
Shell = d.CreateCapsule(_parent_scene.ActiveSpace, CAPSULE_RADIUS, CAPSULE_LENGTH);
|
||||
|
||||
d.GeomSetCategoryBits(Shell, (int)m_collisionCategories);
|
||||
d.GeomSetCollideBits(Shell, (int)m_collisionFlags);
|
||||
|
||||
d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH);
|
||||
|
||||
m_mass = ShellMass.mass; // update mass
|
||||
|
||||
// rescale PID parameters
|
||||
PID_D = _parent_scene.avPIDD;
|
||||
PID_P = _parent_scene.avPIDP;
|
||||
|
||||
// rescale PID parameters so that this aren't affected by mass
|
||||
// and so don't get unstable for some masses
|
||||
// also scale by ode time step so you don't need to refix them
|
||||
|
||||
PID_D /= 50 * 80; //scale to original mass of around 80 and 50 ODE fps
|
||||
PID_D *= m_mass / _parent_scene.ODE_STEPSIZE;
|
||||
PID_P /= 50 * 80;
|
||||
PID_P *= m_mass / _parent_scene.ODE_STEPSIZE;
|
||||
|
||||
Body = d.BodyCreate(_parent_scene.world);
|
||||
|
||||
d.BodySetAutoDisableFlag(Body, false);
|
||||
d.BodySetPosition(Body, npositionX, npositionY, npositionZ);
|
||||
|
||||
_position.X = npositionX;
|
||||
_position.Y = npositionY;
|
||||
_position.Z = npositionZ;
|
||||
|
||||
d.BodySetMass(Body, ref ShellMass);
|
||||
d.GeomSetBody(Shell, Body);
|
||||
|
||||
// The purpose of the AMotor here is to keep the avatar's physical
|
||||
// surrogate from rotating while moving
|
||||
Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero);
|
||||
d.JointAttach(Amotor, Body, IntPtr.Zero);
|
||||
|
||||
d.JointSetAMotorMode(Amotor, 0);
|
||||
d.JointSetAMotorNumAxes(Amotor, 3);
|
||||
d.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0);
|
||||
d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0);
|
||||
d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1);
|
||||
|
||||
d.JointSetAMotorAngle(Amotor, 0, 0);
|
||||
d.JointSetAMotorAngle(Amotor, 1, 0);
|
||||
d.JointSetAMotorAngle(Amotor, 2, 0);
|
||||
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM, 0f); // make it HARD
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM2, 0f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM3, 0f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.StopERP, 0.8f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.StopERP2, 0.8f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.StopERP3, 0.8f);
|
||||
|
||||
// These lowstops and high stops are effectively (no wiggle room)
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -1e-5f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 1e-5f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -1e-5f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 1e-5f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -1e-5f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 1e-5f);
|
||||
|
||||
d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel, 0);
|
||||
d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel2, 0);
|
||||
d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel3, 0);
|
||||
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.FMax, 5e6f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.FMax2, 5e6f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.FMax3, 5e6f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the avatar body and geom
|
||||
|
||||
private void AvatarGeomAndBodyDestroy()
|
||||
{
|
||||
// Kill the Amotor
|
||||
if (Amotor != IntPtr.Zero)
|
||||
{
|
||||
d.JointDestroy(Amotor);
|
||||
Amotor = IntPtr.Zero;
|
||||
}
|
||||
|
||||
if (Body != IntPtr.Zero)
|
||||
{
|
||||
//kill the body
|
||||
d.BodyDestroy(Body);
|
||||
Body = IntPtr.Zero;
|
||||
}
|
||||
|
||||
//kill the Geometry
|
||||
if (Shell != IntPtr.Zero)
|
||||
{
|
||||
_parent_scene.geom_name_map.Remove(Shell);
|
||||
_parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace);
|
||||
d.GeomDestroy(Shell);
|
||||
_parent_scene.geom_name_map.Remove(Shell);
|
||||
Shell = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called from Simulate
|
||||
/// This is the avatar's movement control + PID Controller
|
||||
@@ -1135,8 +1101,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
/// </summary>
|
||||
public void Destroy()
|
||||
{
|
||||
m_tainted_isPhysical = false;
|
||||
_parent_scene.AddPhysicsActorTaint(this);
|
||||
AddChange(changes.Remove, null);
|
||||
}
|
||||
|
||||
public override void CrossingFailure()
|
||||
@@ -1206,12 +1171,11 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
return m_haseventsubscription;
|
||||
}
|
||||
|
||||
public void ProcessTaints(float timestep)
|
||||
private void changePhysicsStatus(bool NewStatus)
|
||||
{
|
||||
|
||||
if (m_tainted_isPhysical != m_isPhysical)
|
||||
if (NewStatus != m_isPhysical)
|
||||
{
|
||||
if (m_tainted_isPhysical)
|
||||
if (NewStatus)
|
||||
{
|
||||
// Create avatar capsule and related ODE data
|
||||
if ((Shell != IntPtr.Zero))
|
||||
@@ -1236,60 +1200,246 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
AvatarGeomAndBodyDestroy();
|
||||
}
|
||||
|
||||
m_isPhysical = m_tainted_isPhysical;
|
||||
m_isPhysical = NewStatus;
|
||||
}
|
||||
|
||||
if (m_tainted_CAPSULE_LENGTH != CAPSULE_LENGTH)
|
||||
{
|
||||
if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero)
|
||||
{
|
||||
AvatarGeomAndBodyDestroy();
|
||||
|
||||
m_pidControllerActive = true;
|
||||
|
||||
float prevCapsule = CAPSULE_LENGTH;
|
||||
CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH;
|
||||
|
||||
AvatarGeomAndBodyCreation(_position.X, _position.Y,
|
||||
_position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2));
|
||||
|
||||
Velocity = Vector3.Zero;
|
||||
|
||||
_parent_scene.geom_name_map[Shell] = m_name;
|
||||
_parent_scene.actor_name_map[Shell] = (PhysicsActor)this;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: trying to change capsule size, but the following ODE data is missing - "
|
||||
+ (Shell == IntPtr.Zero ? "Shell " : "")
|
||||
+ (Body == IntPtr.Zero ? "Body " : "")
|
||||
+ (Amotor == IntPtr.Zero ? "Amotor " : ""));
|
||||
}
|
||||
}
|
||||
|
||||
if (m_hasTaintPosition)
|
||||
{
|
||||
if (Body != IntPtr.Zero)
|
||||
d.BodySetPosition(Body, m_taintPosition.X, m_taintPosition.Y, m_taintPosition.Z);
|
||||
|
||||
_position.X = m_taintPosition.X;
|
||||
_position.Y = m_taintPosition.Y;
|
||||
_position.Z = m_taintPosition.Z;
|
||||
m_hasTaintPosition = false;
|
||||
}
|
||||
|
||||
if (m_hasTaintForce)
|
||||
{
|
||||
if (Body != IntPtr.Zero)
|
||||
{
|
||||
if(m_taintForce.X !=0f || m_taintForce.Y !=0f || m_taintForce.Z !=0)
|
||||
d.BodyAddForce(Body, m_taintForce.X, m_taintForce.Y, m_taintForce.Z);
|
||||
m_hasTaintForce = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void changeAdd()
|
||||
{
|
||||
changePhysicsStatus(true);
|
||||
}
|
||||
|
||||
private void changeRemove()
|
||||
{
|
||||
changePhysicsStatus(false);
|
||||
}
|
||||
|
||||
private void changeShape(PrimitiveBaseShape arg)
|
||||
{
|
||||
}
|
||||
|
||||
private void changeSize(Vector3 Size)
|
||||
{
|
||||
if (Size.IsFinite())
|
||||
{
|
||||
float caplen = Size.Z;
|
||||
|
||||
caplen = caplen * 1.15f - CAPSULE_RADIUS * 2.0f;
|
||||
|
||||
if (caplen != CAPSULE_LENGTH)
|
||||
{
|
||||
if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero)
|
||||
{
|
||||
AvatarGeomAndBodyDestroy();
|
||||
|
||||
float prevCapsule = CAPSULE_LENGTH;
|
||||
CAPSULE_LENGTH = caplen;
|
||||
|
||||
AvatarGeomAndBodyCreation(_position.X, _position.Y,
|
||||
_position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2));
|
||||
|
||||
Velocity = Vector3.Zero;
|
||||
|
||||
_parent_scene.geom_name_map[Shell] = m_name;
|
||||
_parent_scene.actor_name_map[Shell] = (PhysicsActor)this;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: trying to change capsule size, but the following ODE data is missing - "
|
||||
+ (Shell == IntPtr.Zero ? "Shell " : "")
|
||||
+ (Body == IntPtr.Zero ? "Body " : "")
|
||||
+ (Amotor == IntPtr.Zero ? "Amotor " : ""));
|
||||
}
|
||||
}
|
||||
|
||||
m_pidControllerActive = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: Got a NaN Size from Scene on a Character");
|
||||
}
|
||||
}
|
||||
|
||||
private void changePosition( Vector3 newPos)
|
||||
{
|
||||
if (Body != IntPtr.Zero)
|
||||
d.BodySetPosition(Body, newPos.X, newPos.Y, newPos.Z);
|
||||
_position = newPos;
|
||||
}
|
||||
|
||||
private void changeOrientation(Quaternion newOri)
|
||||
{
|
||||
}
|
||||
|
||||
private void changeVelocity(Vector3 newVel)
|
||||
{
|
||||
m_pidControllerActive = true;
|
||||
_target_velocity = newVel;
|
||||
}
|
||||
|
||||
private void changeSetTorque(Vector3 newTorque)
|
||||
{
|
||||
}
|
||||
|
||||
private void changeAddForce(Vector3 newForce)
|
||||
{
|
||||
}
|
||||
|
||||
private void changeAddAngularForce(Vector3 arg)
|
||||
{
|
||||
}
|
||||
|
||||
private void changeAngularLock(Vector3 arg)
|
||||
{
|
||||
}
|
||||
|
||||
private void changeFloatOnWater(bool arg)
|
||||
{
|
||||
}
|
||||
|
||||
private void changeVolumedetetion(bool arg)
|
||||
{
|
||||
}
|
||||
|
||||
private void changeSelectedStatus(bool arg)
|
||||
{
|
||||
}
|
||||
|
||||
private void changeDisable(bool arg)
|
||||
{
|
||||
}
|
||||
|
||||
private void changeBuilding(bool arg)
|
||||
{
|
||||
}
|
||||
|
||||
private void changeForce(Vector3 newForce)
|
||||
{
|
||||
m_pidControllerActive = false;
|
||||
if (Body != IntPtr.Zero)
|
||||
{
|
||||
if (newForce.X != 0f || newForce.Y != 0f || newForce.Z != 0)
|
||||
d.BodyAddForce(Body, newForce.X, newForce.Y, newForce.Z);
|
||||
}
|
||||
}
|
||||
|
||||
private void donullchange()
|
||||
{
|
||||
}
|
||||
|
||||
public bool DoAChange(changes what, object arg)
|
||||
{
|
||||
if (Shell == IntPtr.Zero && what != changes.Add && what != changes.Remove)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// nasty switch
|
||||
switch (what)
|
||||
{
|
||||
case changes.Add:
|
||||
changeAdd();
|
||||
break;
|
||||
case changes.Remove:
|
||||
changeRemove();
|
||||
break;
|
||||
|
||||
case changes.Position:
|
||||
changePosition((Vector3)arg);
|
||||
break;
|
||||
|
||||
case changes.Orientation:
|
||||
changeOrientation((Quaternion)arg);
|
||||
break;
|
||||
|
||||
case changes.PosOffset:
|
||||
donullchange();
|
||||
break;
|
||||
|
||||
case changes.OriOffset:
|
||||
donullchange();
|
||||
break;
|
||||
|
||||
case changes.Velocity:
|
||||
changeVelocity((Vector3)arg);
|
||||
break;
|
||||
|
||||
// case changes.Acceleration:
|
||||
// changeacceleration((Vector3)arg);
|
||||
// break;
|
||||
// case changes.AngVelocity:
|
||||
// changeangvelocity((Vector3)arg);
|
||||
// break;
|
||||
|
||||
case changes.Force:
|
||||
changeForce((Vector3)arg);
|
||||
break;
|
||||
|
||||
case changes.Torque:
|
||||
changeSetTorque((Vector3)arg);
|
||||
break;
|
||||
|
||||
case changes.AddForce:
|
||||
changeAddForce((Vector3)arg);
|
||||
break;
|
||||
|
||||
case changes.AddAngForce:
|
||||
changeAddAngularForce((Vector3)arg);
|
||||
break;
|
||||
|
||||
case changes.AngLock:
|
||||
changeAngularLock((Vector3)arg);
|
||||
break;
|
||||
|
||||
case changes.Size:
|
||||
changeSize((Vector3)arg);
|
||||
break;
|
||||
/* not in use for now
|
||||
case changes.Shape:
|
||||
changeShape((PrimitiveBaseShape)arg);
|
||||
break;
|
||||
|
||||
case changes.CollidesWater:
|
||||
changeFloatOnWater((bool)arg);
|
||||
break;
|
||||
|
||||
case changes.VolumeDtc:
|
||||
changeVolumedetetion((bool)arg);
|
||||
break;
|
||||
|
||||
case changes.Physical:
|
||||
changePhysicsStatus((bool)arg);
|
||||
break;
|
||||
|
||||
case changes.Selected:
|
||||
changeSelectedStatus((bool)arg);
|
||||
break;
|
||||
|
||||
case changes.disabled:
|
||||
changeDisable((bool)arg);
|
||||
break;
|
||||
|
||||
case changes.building:
|
||||
changeBuilding((bool)arg);
|
||||
break;
|
||||
*/
|
||||
case changes.Null:
|
||||
donullchange();
|
||||
break;
|
||||
|
||||
default:
|
||||
donullchange();
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void AddChange(changes what, object arg)
|
||||
{
|
||||
_parent_scene.AddChange((PhysicsActor)this, what, arg);
|
||||
}
|
||||
|
||||
|
||||
internal void AddCollisionFrameTime(int p)
|
||||
{
|
||||
// protect it from overflow crashing
|
||||
|
||||
@@ -1,630 +0,0 @@
|
||||
/*
|
||||
* Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces
|
||||
* ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
|
||||
* ODEPrim.cs contains methods dealing with Prim editing, Prim
|
||||
* characteristics and Kinetic motion.
|
||||
* ODEDynamics.cs contains methods dealing with Prim Physical motion
|
||||
* (dynamics) and the associated settings. Old Linear and angular
|
||||
* motors for dynamic motion have been replace with MoveLinear()
|
||||
* and MoveAngular(); 'Physical' is used only to switch ODE dynamic
|
||||
* simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
|
||||
* switch between 'VEHICLE' parameter use and general dynamics
|
||||
* settings use.
|
||||
*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using Ode.NET;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
|
||||
namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
public class ODEDynamics
|
||||
{
|
||||
public Vehicle Type
|
||||
{
|
||||
get { return m_type; }
|
||||
}
|
||||
|
||||
public IntPtr Body
|
||||
{
|
||||
get { return m_body; }
|
||||
}
|
||||
|
||||
private int frcount = 0; // Used to limit dynamics debug output to
|
||||
// every 100th frame
|
||||
|
||||
// private OdeScene m_parentScene = null;
|
||||
private IntPtr m_body = IntPtr.Zero;
|
||||
private IntPtr m_jointGroup = IntPtr.Zero;
|
||||
private IntPtr m_aMotor = IntPtr.Zero;
|
||||
|
||||
|
||||
// Vehicle properties
|
||||
private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind
|
||||
// private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier
|
||||
private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings:
|
||||
// HOVER_TERRAIN_ONLY
|
||||
// HOVER_GLOBAL_HEIGHT
|
||||
// NO_DEFLECTION_UP
|
||||
// HOVER_WATER_ONLY
|
||||
// HOVER_UP_ONLY
|
||||
// LIMIT_MOTOR_UP
|
||||
// LIMIT_ROLL_ONLY
|
||||
|
||||
// Linear properties
|
||||
private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time
|
||||
private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL
|
||||
private Vector3 m_dir = Vector3.Zero; // velocity applied to body
|
||||
private Vector3 m_linearFrictionTimescale = Vector3.Zero;
|
||||
private float m_linearMotorDecayTimescale = 0;
|
||||
private float m_linearMotorTimescale = 0;
|
||||
private Vector3 m_lastLinearVelocityVector = Vector3.Zero;
|
||||
// private bool m_LinearMotorSetLastFrame = false;
|
||||
// private Vector3 m_linearMotorOffset = Vector3.Zero;
|
||||
|
||||
//Angular properties
|
||||
private Vector3 m_angularMotorDirection = Vector3.Zero;
|
||||
private Vector3 m_angularMotorDirectionLASTSET = Vector3.Zero;
|
||||
private Vector3 m_angularFrictionTimescale = Vector3.Zero;
|
||||
private float m_angularMotorDecayTimescale = 0;
|
||||
private float m_angularMotorTimescale = 0;
|
||||
private Vector3 m_lastAngularVelocityVector = Vector3.Zero;
|
||||
|
||||
//Deflection properties
|
||||
// private float m_angularDeflectionEfficiency = 0;
|
||||
// private float m_angularDeflectionTimescale = 0;
|
||||
// private float m_linearDeflectionEfficiency = 0;
|
||||
// private float m_linearDeflectionTimescale = 0;
|
||||
|
||||
//Banking properties
|
||||
// private float m_bankingEfficiency = 0;
|
||||
// private float m_bankingMix = 0;
|
||||
// private float m_bankingTimescale = 0;
|
||||
|
||||
//Hover and Buoyancy properties
|
||||
private float m_VhoverHeight = 0f;
|
||||
private float m_VhoverEfficiency = 0f;
|
||||
private float m_VhoverTimescale = 0f;
|
||||
private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
|
||||
private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle.
|
||||
// Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
|
||||
// KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
|
||||
// Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
|
||||
|
||||
//Attractor properties
|
||||
private float m_verticalAttractionEfficiency = 0;
|
||||
private float m_verticalAttractionTimescale = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
|
||||
{
|
||||
switch (pParam)
|
||||
{
|
||||
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
// m_angularDeflectionEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
// m_angularDeflectionTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
m_angularMotorDecayTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
m_angularMotorTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.BANKING_EFFICIENCY:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
// m_bankingEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.BANKING_MIX:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
// m_bankingMix = pValue;
|
||||
break;
|
||||
case Vehicle.BANKING_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
// m_bankingTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.BUOYANCY:
|
||||
if (pValue < -1f) pValue = -1f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
m_VehicleBuoyancy = pValue;
|
||||
break;
|
||||
case Vehicle.HOVER_EFFICIENCY:
|
||||
if (pValue < 0f) pValue = 0f;
|
||||
if (pValue > 1f) pValue = 1f;
|
||||
m_VhoverEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.HOVER_HEIGHT:
|
||||
m_VhoverHeight = pValue;
|
||||
break;
|
||||
case Vehicle.HOVER_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
m_VhoverTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
// m_linearDeflectionEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
// m_linearDeflectionTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
m_linearMotorDecayTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
m_linearMotorTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
|
||||
if (pValue < 0.0f) pValue = 0.0f;
|
||||
if (pValue > 1.0f) pValue = 1.0f;
|
||||
m_verticalAttractionEfficiency = pValue;
|
||||
break;
|
||||
case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
|
||||
if (pValue < 0.01f) pValue = 0.01f;
|
||||
m_verticalAttractionTimescale = pValue;
|
||||
break;
|
||||
|
||||
// These are vector properties but the engine lets you use a single float value to
|
||||
// set all of the components to the same value
|
||||
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||
m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||
m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||
m_angularMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue);
|
||||
break;
|
||||
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||
m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||
m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||
m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||
// m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}//end ProcessFloatVehicleParam
|
||||
|
||||
internal void ProcessVectorVehicleParam(Vehicle pParam, PhysicsVector pValue)
|
||||
{
|
||||
switch (pParam)
|
||||
{
|
||||
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||
m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||
m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
m_angularMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
break;
|
||||
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||
m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||
m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||
// m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||
break;
|
||||
}
|
||||
|
||||
}//end ProcessVectorVehicleParam
|
||||
|
||||
internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
|
||||
{
|
||||
switch (pParam)
|
||||
{
|
||||
case Vehicle.REFERENCE_FRAME:
|
||||
// m_referenceFrame = pValue;
|
||||
break;
|
||||
}
|
||||
|
||||
}//end ProcessRotationVehicleParam
|
||||
|
||||
internal void ProcessTypeChange(Vehicle pType)
|
||||
{
|
||||
Console.WriteLine("ProcessTypeChange to " + pType);
|
||||
|
||||
// Set Defaults For Type
|
||||
m_type = pType;
|
||||
switch (pType)
|
||||
{
|
||||
case Vehicle.TYPE_SLED:
|
||||
m_linearFrictionTimescale = new Vector3(30, 1, 1000);
|
||||
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||
m_linearMotorDirection = Vector3.Zero;
|
||||
m_linearMotorTimescale = 1000;
|
||||
m_linearMotorDecayTimescale = 120;
|
||||
m_angularMotorDirection = Vector3.Zero;
|
||||
m_angularMotorTimescale = 1000;
|
||||
m_angularMotorDecayTimescale = 120;
|
||||
m_VhoverHeight = 0;
|
||||
m_VhoverEfficiency = 1;
|
||||
m_VhoverTimescale = 10;
|
||||
m_VehicleBuoyancy = 0;
|
||||
// m_linearDeflectionEfficiency = 1;
|
||||
// m_linearDeflectionTimescale = 1;
|
||||
// m_angularDeflectionEfficiency = 1;
|
||||
// m_angularDeflectionTimescale = 1000;
|
||||
// m_bankingEfficiency = 0;
|
||||
// m_bankingMix = 1;
|
||||
// m_bankingTimescale = 10;
|
||||
// m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &=
|
||||
~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
|
||||
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||
break;
|
||||
case Vehicle.TYPE_CAR:
|
||||
m_linearFrictionTimescale = new Vector3(100, 2, 1000);
|
||||
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||
m_linearMotorDirection = Vector3.Zero;
|
||||
m_linearMotorTimescale = 1;
|
||||
m_linearMotorDecayTimescale = 60;
|
||||
m_angularMotorDirection = Vector3.Zero;
|
||||
m_angularMotorTimescale = 1;
|
||||
m_angularMotorDecayTimescale = 0.8f;
|
||||
m_VhoverHeight = 0;
|
||||
m_VhoverEfficiency = 0;
|
||||
m_VhoverTimescale = 1000;
|
||||
m_VehicleBuoyancy = 0;
|
||||
// // m_linearDeflectionEfficiency = 1;
|
||||
// // m_linearDeflectionTimescale = 2;
|
||||
// // m_angularDeflectionEfficiency = 0;
|
||||
// m_angularDeflectionTimescale = 10;
|
||||
m_verticalAttractionEfficiency = 1;
|
||||
m_verticalAttractionTimescale = 10;
|
||||
// m_bankingEfficiency = -0.2f;
|
||||
// m_bankingMix = 1;
|
||||
// m_bankingTimescale = 1;
|
||||
// m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_UP_ONLY |
|
||||
VehicleFlag.LIMIT_MOTOR_UP);
|
||||
break;
|
||||
case Vehicle.TYPE_BOAT:
|
||||
m_linearFrictionTimescale = new Vector3(10, 3, 2);
|
||||
m_angularFrictionTimescale = new Vector3(10,10,10);
|
||||
m_linearMotorDirection = Vector3.Zero;
|
||||
m_linearMotorTimescale = 5;
|
||||
m_linearMotorDecayTimescale = 60;
|
||||
m_angularMotorDirection = Vector3.Zero;
|
||||
m_angularMotorTimescale = 4;
|
||||
m_angularMotorDecayTimescale = 4;
|
||||
m_VhoverHeight = 0;
|
||||
m_VhoverEfficiency = 0.5f;
|
||||
m_VhoverTimescale = 2;
|
||||
m_VehicleBuoyancy = 1;
|
||||
// m_linearDeflectionEfficiency = 0.5f;
|
||||
// m_linearDeflectionTimescale = 3;
|
||||
// m_angularDeflectionEfficiency = 0.5f;
|
||||
// m_angularDeflectionTimescale = 5;
|
||||
m_verticalAttractionEfficiency = 0.5f;
|
||||
m_verticalAttractionTimescale = 5;
|
||||
// m_bankingEfficiency = -0.3f;
|
||||
// m_bankingMix = 0.8f;
|
||||
// m_bankingTimescale = 1;
|
||||
// m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.LIMIT_ROLL_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
|
||||
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY |
|
||||
VehicleFlag.LIMIT_MOTOR_UP);
|
||||
break;
|
||||
case Vehicle.TYPE_AIRPLANE:
|
||||
m_linearFrictionTimescale = new Vector3(200, 10, 5);
|
||||
m_angularFrictionTimescale = new Vector3(20, 20, 20);
|
||||
m_linearMotorDirection = Vector3.Zero;
|
||||
m_linearMotorTimescale = 2;
|
||||
m_linearMotorDecayTimescale = 60;
|
||||
m_angularMotorDirection = Vector3.Zero;
|
||||
m_angularMotorTimescale = 4;
|
||||
m_angularMotorDecayTimescale = 4;
|
||||
m_VhoverHeight = 0;
|
||||
m_VhoverEfficiency = 0.5f;
|
||||
m_VhoverTimescale = 1000;
|
||||
m_VehicleBuoyancy = 0;
|
||||
// m_linearDeflectionEfficiency = 0.5f;
|
||||
// m_linearDeflectionTimescale = 3;
|
||||
// m_angularDeflectionEfficiency = 1;
|
||||
// m_angularDeflectionTimescale = 2;
|
||||
m_verticalAttractionEfficiency = 0.9f;
|
||||
m_verticalAttractionTimescale = 2;
|
||||
// m_bankingEfficiency = 1;
|
||||
// m_bankingMix = 0.7f;
|
||||
// m_bankingTimescale = 2;
|
||||
// m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
|
||||
break;
|
||||
case Vehicle.TYPE_BALLOON:
|
||||
m_linearFrictionTimescale = new Vector3(5, 5, 5);
|
||||
m_angularFrictionTimescale = new Vector3(10, 10, 10);
|
||||
m_linearMotorDirection = Vector3.Zero;
|
||||
m_linearMotorTimescale = 5;
|
||||
m_linearMotorDecayTimescale = 60;
|
||||
m_angularMotorDirection = Vector3.Zero;
|
||||
m_angularMotorTimescale = 6;
|
||||
m_angularMotorDecayTimescale = 10;
|
||||
m_VhoverHeight = 5;
|
||||
m_VhoverEfficiency = 0.8f;
|
||||
m_VhoverTimescale = 10;
|
||||
m_VehicleBuoyancy = 1;
|
||||
// m_linearDeflectionEfficiency = 0;
|
||||
// m_linearDeflectionTimescale = 5;
|
||||
// m_angularDeflectionEfficiency = 0;
|
||||
// m_angularDeflectionTimescale = 5;
|
||||
m_verticalAttractionEfficiency = 1;
|
||||
m_verticalAttractionTimescale = 1000;
|
||||
// m_bankingEfficiency = 0;
|
||||
// m_bankingMix = 0.7f;
|
||||
// m_bankingTimescale = 5;
|
||||
// m_referenceFrame = Quaternion.Identity;
|
||||
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||
VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||
break;
|
||||
|
||||
}
|
||||
}//end SetDefaultsForType
|
||||
|
||||
internal void Enable(IntPtr pBody, OdeScene pParentScene)
|
||||
{
|
||||
//Console.WriteLine("Enable m_type=" + m_type + " m_VehicleBuoyancy=" + m_VehicleBuoyancy);
|
||||
if (m_type == Vehicle.TYPE_NONE)
|
||||
return;
|
||||
|
||||
m_body = pBody;
|
||||
//KF: This used to set up the linear and angular joints
|
||||
}
|
||||
|
||||
internal void Step(float pTimestep, OdeScene pParentScene)
|
||||
{
|
||||
if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE)
|
||||
return;
|
||||
frcount++; // used to limit debug comment output
|
||||
if (frcount > 100)
|
||||
frcount = 0;
|
||||
|
||||
MoveLinear(pTimestep, pParentScene);
|
||||
MoveAngular(pTimestep);
|
||||
}// end Step
|
||||
|
||||
private void MoveLinear(float pTimestep, OdeScene _pParentScene)
|
||||
{
|
||||
if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) // requested m_linearMotorDirection is significant
|
||||
{
|
||||
if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
|
||||
|
||||
// add drive to body
|
||||
Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep);
|
||||
m_lastLinearVelocityVector += (addAmount*10); // lastLinearVelocityVector is the current body velocity vector?
|
||||
|
||||
// This will work temporarily, but we really need to compare speed on an axis
|
||||
// KF: Limit body velocity to applied velocity?
|
||||
if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X))
|
||||
m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X;
|
||||
if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y))
|
||||
m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y;
|
||||
if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z))
|
||||
m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z;
|
||||
|
||||
// decay applied velocity
|
||||
Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep)));
|
||||
//Console.WriteLine("decay: " + decayfraction);
|
||||
m_linearMotorDirection -= m_linearMotorDirection * decayfraction;
|
||||
//Console.WriteLine("actual: " + m_linearMotorDirection);
|
||||
}
|
||||
else
|
||||
{ // requested is not significant
|
||||
// if what remains of applied is small, zero it.
|
||||
if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f))
|
||||
m_lastLinearVelocityVector = Vector3.Zero;
|
||||
}
|
||||
|
||||
|
||||
// convert requested object velocity to world-referenced vector
|
||||
m_dir = m_lastLinearVelocityVector;
|
||||
d.Quaternion rot = d.BodyGetQuaternion(Body);
|
||||
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
|
||||
m_dir *= rotq; // apply obj rotation to velocity vector
|
||||
|
||||
// add Gravity andBuoyancy
|
||||
// KF: So far I have found no good method to combine a script-requested
|
||||
// .Z velocity and gravity. Therefore only 0g will used script-requested
|
||||
// .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only.
|
||||
Vector3 grav = Vector3.Zero;
|
||||
if(m_VehicleBuoyancy < 1.0f)
|
||||
{
|
||||
// There is some gravity, make a gravity force vector
|
||||
// that is applied after object velocity.
|
||||
d.Mass objMass;
|
||||
d.BodyGetMass(Body, out objMass);
|
||||
// m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
|
||||
grav.Z = _pParentScene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy);
|
||||
// Preserve the current Z velocity
|
||||
d.Vector3 vel_now = d.BodyGetLinearVel(Body);
|
||||
m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity
|
||||
} // else its 1.0, no gravity.
|
||||
|
||||
// Check if hovering
|
||||
if( (m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
|
||||
{
|
||||
// We should hover, get the target height
|
||||
d.Vector3 pos = d.BodyGetPosition(Body);
|
||||
if((m_flags & VehicleFlag.HOVER_WATER_ONLY) == VehicleFlag.HOVER_WATER_ONLY)
|
||||
{
|
||||
m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight;
|
||||
}
|
||||
else if((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) == VehicleFlag.HOVER_TERRAIN_ONLY)
|
||||
{
|
||||
m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
|
||||
}
|
||||
else if((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == VehicleFlag.HOVER_GLOBAL_HEIGHT)
|
||||
{
|
||||
m_VhoverTargetHeight = m_VhoverHeight;
|
||||
}
|
||||
|
||||
if((m_flags & VehicleFlag.HOVER_UP_ONLY) == VehicleFlag.HOVER_UP_ONLY)
|
||||
{
|
||||
// If body is aready heigher, use its height as target height
|
||||
if(pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
|
||||
}
|
||||
|
||||
// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped
|
||||
// m_VhoverTimescale = 0f; // time to acheive height
|
||||
// pTimestep is time since last frame,in secs
|
||||
float herr0 = pos.Z - m_VhoverTargetHeight;
|
||||
//if(frcount == 0) Console.WriteLine("herr0=" + herr0);
|
||||
// Replace Vertical speed with correction figure if significant
|
||||
if(Math.Abs(herr0) > 0.01f )
|
||||
{
|
||||
d.Mass objMass;
|
||||
d.BodyGetMass(Body, out objMass);
|
||||
m_dir.Z = - ( (herr0 * pTimestep * 50.0f) / m_VhoverTimescale);
|
||||
// m_VhoverEfficiency is not yet implemented
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dir.Z = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply velocity
|
||||
d.BodySetLinearVel(Body, m_dir.X, m_dir.Y, m_dir.Z);
|
||||
//if(frcount == 0) Console.WriteLine("Move " + Body + ":"+ m_dir.X + " " + m_dir.Y + " " + m_dir.Z);
|
||||
// apply gravity force
|
||||
d.BodyAddForce(Body, grav.X, grav.Y, grav.Z);
|
||||
//if(frcount == 0) Console.WriteLine("Force " + Body + ":" + grav.X + " " + grav.Y + " " + grav.Z);
|
||||
|
||||
|
||||
// apply friction
|
||||
Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep);
|
||||
m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount;
|
||||
} // end MoveLinear()
|
||||
|
||||
private void MoveAngular(float pTimestep)
|
||||
{
|
||||
|
||||
// m_angularMotorDirection is the latest value from the script, and is decayed here
|
||||
// m_angularMotorDirectionLASTSET is the latest value from the script
|
||||
// m_lastAngularVelocityVector is what is being applied to the Body, varied up and down here
|
||||
|
||||
if (!m_angularMotorDirection.ApproxEquals(Vector3.Zero, 0.01f))
|
||||
{
|
||||
if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
|
||||
// ramp up to new value
|
||||
Vector3 addAmount = m_angularMotorDirection / (m_angularMotorTimescale / pTimestep);
|
||||
m_lastAngularVelocityVector += (addAmount * 10f);
|
||||
//if(frcount == 0) Console.WriteLine("add: " + addAmount);
|
||||
|
||||
// limit applied value to what was set by script
|
||||
// This will work temporarily, but we really need to compare speed on an axis
|
||||
if (Math.Abs(m_lastAngularVelocityVector.X) > Math.Abs(m_angularMotorDirectionLASTSET.X))
|
||||
m_lastAngularVelocityVector.X = m_angularMotorDirectionLASTSET.X;
|
||||
if (Math.Abs(m_lastAngularVelocityVector.Y) > Math.Abs(m_angularMotorDirectionLASTSET.Y))
|
||||
m_lastAngularVelocityVector.Y = m_angularMotorDirectionLASTSET.Y;
|
||||
if (Math.Abs(m_lastAngularVelocityVector.Z) > Math.Abs(m_angularMotorDirectionLASTSET.Z))
|
||||
m_lastAngularVelocityVector.Z = m_angularMotorDirectionLASTSET.Z;
|
||||
|
||||
// decay the requested value
|
||||
Vector3 decayfraction = ((Vector3.One / (m_angularMotorDecayTimescale / pTimestep)));
|
||||
//Console.WriteLine("decay: " + decayfraction);
|
||||
m_angularMotorDirection -= m_angularMotorDirection * decayfraction;
|
||||
//Console.WriteLine("actual: " + m_linearMotorDirection);
|
||||
}
|
||||
// KF: m_lastAngularVelocityVector is rotational speed in rad/sec ?
|
||||
|
||||
// Vertical attractor section
|
||||
|
||||
// d.Mass objMass;
|
||||
// d.BodyGetMass(Body, out objMass);
|
||||
// float servo = 100f * objMass.mass * m_verticalAttractionEfficiency / (m_verticalAttractionTimescale * pTimestep);
|
||||
float servo = 0.1f * m_verticalAttractionEfficiency / (m_verticalAttractionTimescale * pTimestep);
|
||||
// get present body rotation
|
||||
d.Quaternion rot = d.BodyGetQuaternion(Body);
|
||||
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W);
|
||||
// make a vector pointing up
|
||||
Vector3 verterr = Vector3.Zero;
|
||||
verterr.Z = 1.0f;
|
||||
// rotate it to Body Angle
|
||||
verterr = verterr * rotq;
|
||||
// verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1.
|
||||
// As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go
|
||||
// negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body.
|
||||
if (verterr.Z < 0.0f)
|
||||
{
|
||||
verterr.X = 2.0f - verterr.X;
|
||||
verterr.Y = 2.0f - verterr.Y;
|
||||
}
|
||||
// Error is 0 (no error) to +/- 2 (max error)
|
||||
// scale it by servo
|
||||
verterr = verterr * servo;
|
||||
|
||||
// rotate to object frame
|
||||
// verterr = verterr * rotq;
|
||||
|
||||
// As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so
|
||||
// Change Body angular velocity X based on Y, and Y based on X. Z is not changed.
|
||||
m_lastAngularVelocityVector.X += verterr.Y;
|
||||
m_lastAngularVelocityVector.Y -= verterr.X;
|
||||
/*
|
||||
if(frcount == 0)
|
||||
{
|
||||
// Console.WriteLine("AngleMotor " + m_lastAngularVelocityVector);
|
||||
Console.WriteLine(String.Format("VA Body:{0} servo:{1} err:<{2},{3},{4}> VAE:{5}",
|
||||
Body, servo, verterr.X, verterr.Y, verterr.Z, m_verticalAttractionEfficiency));
|
||||
}
|
||||
*/
|
||||
d.BodySetAngularVel (Body, m_lastAngularVelocityVector.X, m_lastAngularVelocityVector.Y, m_lastAngularVelocityVector.Z);
|
||||
// apply friction
|
||||
Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep);
|
||||
m_lastAngularVelocityVector -= m_lastAngularVelocityVector * decayamount;
|
||||
|
||||
} //end MoveAngular
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,8 @@
|
||||
* settings use.
|
||||
*/
|
||||
|
||||
// Ubit 2012
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
@@ -57,24 +59,15 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
get { return m_type; }
|
||||
}
|
||||
|
||||
// private OdeScene m_parentScene = null;
|
||||
// private IntPtr m_aMotor = IntPtr.Zero;
|
||||
|
||||
|
||||
private OdePrim rootPrim;
|
||||
private OdeScene _pParentScene;
|
||||
|
||||
|
||||
|
||||
|
||||
private Vector3 refUpAxis = new Vector3(0, 0, 1);
|
||||
private Vector3 refAtAxis = new Vector3(1, 0, 0);
|
||||
|
||||
|
||||
// Vehicle properties
|
||||
private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier
|
||||
private Quaternion m_RollreferenceFrame = Quaternion.Identity; // what hell is this ?
|
||||
|
||||
private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind
|
||||
|
||||
private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier
|
||||
private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings:
|
||||
// HOVER_TERRAIN_ONLY
|
||||
// HOVER_GLOBAL_HEIGHT
|
||||
@@ -84,7 +77,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
// LIMIT_MOTOR_UP
|
||||
// LIMIT_ROLL_ONLY
|
||||
private Vector3 m_BlockingEndPoint = Vector3.Zero; // not sl
|
||||
private Quaternion m_RollreferenceFrame = Quaternion.Identity;
|
||||
|
||||
// Linear properties
|
||||
private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time
|
||||
@@ -116,7 +108,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
private float m_VhoverHeight = 0f;
|
||||
private float m_VhoverEfficiency = 0f;
|
||||
private float m_VhoverTimescale = 1000f;
|
||||
private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
|
||||
private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle.
|
||||
// Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
|
||||
// KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
|
||||
@@ -126,9 +117,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
private float m_verticalAttractionEfficiency = 1.0f; // damped
|
||||
private float m_verticalAttractionTimescale = 1000f; // Timescale > 300 means no vert attractor.
|
||||
|
||||
// special contact data for vehicles
|
||||
public ContactData VehiculeContactData = new ContactData(0f, 0.1f);
|
||||
|
||||
// auxiliar
|
||||
private Vector3 m_dir = Vector3.Zero; // velocity applied to body
|
||||
|
||||
@@ -160,7 +148,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
m_angularDeflectionTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
// if (pValue < timestep) pValue = timestep;
|
||||
// try to make impulses to work a bit better
|
||||
if (pValue < 0.5f) pValue = 0.5f;
|
||||
else if (pValue > 120) pValue = 120;
|
||||
m_angularMotorDecayTimescale = pValue * invtimestep;
|
||||
break;
|
||||
@@ -209,7 +199,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
m_linearDeflectionTimescale = pValue;
|
||||
break;
|
||||
case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
|
||||
if (pValue < timestep) pValue = timestep;
|
||||
// if (pValue < timestep) pValue = timestep;
|
||||
// try to make impulses to work a bit better
|
||||
if (pValue < 0.5f) pValue = 0.5f;
|
||||
else if (pValue > 120) pValue = 120;
|
||||
m_linearMotorDecayTimescale = pValue * invtimestep;
|
||||
break;
|
||||
@@ -267,7 +259,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
float timestep = _pParentScene.ODE_STEPSIZE;
|
||||
switch (pParam)
|
||||
{
|
||||
|
||||
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||
if (pValue.X < timestep) pValue.X = timestep;
|
||||
if (pValue.Y < timestep) pValue.Y = timestep;
|
||||
@@ -571,7 +562,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
return vec;
|
||||
}
|
||||
|
||||
|
||||
public static void GetRollPitch(Quaternion rot, out float roll, out float pitch)
|
||||
{
|
||||
// assuming rot is normalised
|
||||
@@ -613,52 +603,47 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
|
||||
d.Vector3 dvtmp;
|
||||
Vector3 tmpV;
|
||||
Vector3 curVel; // velocity in world
|
||||
Vector3 curAngVel; // angular velocity in world
|
||||
Vector3 force = Vector3.Zero; // actually linear aceleration until mult by mass in world frame
|
||||
Vector3 torque = Vector3.Zero;// actually angular aceleration until mult by Inertia in vehicle frame
|
||||
d.Vector3 dtorque = new d.Vector3();
|
||||
|
||||
dvtmp = d.BodyGetLinearVel(Body);
|
||||
Vector3 curVel;
|
||||
curVel.X = dvtmp.X;
|
||||
curVel.Y = dvtmp.Y;
|
||||
curVel.Z = dvtmp.Z;
|
||||
Vector3 curLocalVel = curVel * irotq; // current velocity in local
|
||||
|
||||
dvtmp = d.BodyGetAngularVel(Body);
|
||||
Vector3 curAngVel;
|
||||
curAngVel.X = dvtmp.X;
|
||||
curAngVel.Y = dvtmp.Y;
|
||||
curAngVel.Z = dvtmp.Z;
|
||||
Vector3 curLocalAngVel = curAngVel * irotq; // current velocity in local
|
||||
|
||||
Vector3 force = Vector3.Zero; // actually linear aceleration until mult by mass in world frame
|
||||
Vector3 torque = Vector3.Zero;// actually angular aceleration until mult by Inertia in object frame
|
||||
d.Vector3 dtorque = new d.Vector3();// actually angular aceleration until mult by Inertia in object frame
|
||||
|
||||
bool doathing = false;
|
||||
Vector3 curLocalAngVel = curAngVel * irotq; // current angular velocity in local
|
||||
|
||||
// linear motor
|
||||
if (m_lmEfect > 0.01 && m_linearMotorTimescale < 1000)
|
||||
{
|
||||
tmpV = m_linearMotorDirection - curLocalVel; // velocity error
|
||||
if (tmpV.LengthSquared() > 1e-6f)
|
||||
tmpV *= m_lmEfect / m_linearMotorTimescale; // error to correct in this timestep
|
||||
tmpV *= rotq; // to world
|
||||
|
||||
if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0)
|
||||
tmpV.Z = 0;
|
||||
|
||||
if (m_linearMotorOffset.X != 0 || m_linearMotorOffset.Y != 0 || m_linearMotorOffset.Z != 0)
|
||||
{
|
||||
tmpV = tmpV * (m_lmEfect / m_linearMotorTimescale); // error to correct in this timestep
|
||||
tmpV *= rotq; // to world
|
||||
|
||||
if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0)
|
||||
tmpV.Z = 0;
|
||||
|
||||
if (m_linearMotorOffset.X != 0 && m_linearMotorOffset.Y != 0 && m_linearMotorOffset.Z != 0)
|
||||
{
|
||||
// have offset, do it now
|
||||
tmpV *= rootPrim.Mass;
|
||||
d.BodyAddForceAtRelPos(Body, tmpV.X, tmpV.Y, tmpV.Z, m_linearMotorOffset.X, m_linearMotorOffset.Y, m_linearMotorOffset.Z);
|
||||
}
|
||||
else
|
||||
{
|
||||
force.X += tmpV.X;
|
||||
force.Y += tmpV.Y;
|
||||
force.Z += tmpV.Z;
|
||||
}
|
||||
// have offset, do it now
|
||||
tmpV *= rootPrim.Mass;
|
||||
d.BodyAddForceAtRelPos(Body, tmpV.X, tmpV.Y, tmpV.Z, m_linearMotorOffset.X, m_linearMotorOffset.Y, m_linearMotorOffset.Z);
|
||||
}
|
||||
m_lmEfect *= (1 - 1.0f / m_linearMotorDecayTimescale);
|
||||
else
|
||||
{
|
||||
force.X += tmpV.X;
|
||||
force.Y += tmpV.Y;
|
||||
force.Z += tmpV.Z;
|
||||
}
|
||||
m_lmEfect *= (1.0f - 1.0f / m_linearMotorDecayTimescale);
|
||||
}
|
||||
else
|
||||
m_lmEfect = 0;
|
||||
@@ -719,30 +704,35 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
if (m_linearDeflectionEfficiency > 0)
|
||||
{
|
||||
float len = curVel.Length();
|
||||
Vector3 atAxis = refAtAxis;
|
||||
atAxis *= rotq; // at axis rotated to world
|
||||
atAxis = Xrot(rotq);
|
||||
tmpV = atAxis * len;
|
||||
tmpV -= curVel; // velocity error
|
||||
tmpV *= (m_linearDeflectionEfficiency / m_linearDeflectionTimescale); // error to correct in this timestep
|
||||
force.X += tmpV.X;
|
||||
force.Y += tmpV.Y;
|
||||
if((m_flags & VehicleFlag.NO_DEFLECTION_UP) ==0)
|
||||
force.Z += tmpV.Z;
|
||||
Vector3 atAxis;
|
||||
atAxis = Xrot(rotq); // where are we pointing to
|
||||
atAxis *= len; // make it same size as world velocity vector
|
||||
tmpV = -atAxis; // oposite direction
|
||||
atAxis -= curVel; // error to one direction
|
||||
len = atAxis.LengthSquared();
|
||||
tmpV -= curVel; // error to oposite
|
||||
float lens = tmpV.LengthSquared();
|
||||
if (len > 0.01 || lens > 0.01) // do nothing if close enougth
|
||||
{
|
||||
if (len < lens)
|
||||
tmpV = atAxis;
|
||||
|
||||
tmpV *= (m_linearDeflectionEfficiency / m_linearDeflectionTimescale); // error to correct in this timestep
|
||||
force.X += tmpV.X;
|
||||
force.Y += tmpV.Y;
|
||||
if ((m_flags & VehicleFlag.NO_DEFLECTION_UP) == 0)
|
||||
force.Z += tmpV.Z;
|
||||
}
|
||||
}
|
||||
|
||||
// angular motor
|
||||
if (m_amEfect > 0.01 && m_angularMotorTimescale < 1000)
|
||||
{
|
||||
tmpV = m_angularMotorDirection - curLocalAngVel; // velocity error
|
||||
if (tmpV.LengthSquared() > 1e-6f)
|
||||
{
|
||||
tmpV = tmpV * (m_amEfect / m_angularMotorTimescale); // error to correct in this timestep
|
||||
tmpV *= m_referenceFrame; // to object
|
||||
dtorque.X += tmpV.X;
|
||||
dtorque.Y += tmpV.Y;
|
||||
dtorque.Z += tmpV.Z;
|
||||
}
|
||||
tmpV *= m_amEfect / m_angularMotorTimescale; // error to correct in this timestep
|
||||
torque.X += tmpV.X;
|
||||
torque.Y += tmpV.Y;
|
||||
torque.Z += tmpV.Z;
|
||||
m_amEfect *= (1 - 1.0f / m_angularMotorDecayTimescale);
|
||||
}
|
||||
else
|
||||
@@ -751,234 +741,90 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
// angular friction
|
||||
if (curLocalAngVel.X != 0 || curLocalAngVel.Y != 0 || curLocalAngVel.Z != 0)
|
||||
{
|
||||
tmpV.X = -curLocalAngVel.X / m_angularFrictionTimescale.X;
|
||||
tmpV.Y = -curLocalAngVel.Y / m_angularFrictionTimescale.Y;
|
||||
tmpV.Z = -curLocalAngVel.Z / m_angularFrictionTimescale.Z;
|
||||
tmpV *= m_referenceFrame; // to object
|
||||
dtorque.X += tmpV.X;
|
||||
dtorque.Y += tmpV.Y;
|
||||
dtorque.Z += tmpV.Z;
|
||||
torque.X -= curLocalAngVel.X / m_angularFrictionTimescale.X;
|
||||
torque.Y -= curLocalAngVel.Y / m_angularFrictionTimescale.Y;
|
||||
torque.Z -= curLocalAngVel.Z / m_angularFrictionTimescale.Z;
|
||||
}
|
||||
|
||||
// angular deflection
|
||||
if (m_angularDeflectionEfficiency > 0)
|
||||
{
|
||||
doathing = false;
|
||||
float ftmp = m_angularDeflectionEfficiency / m_angularDeflectionTimescale / m_angularDeflectionTimescale /_pParentScene.ODE_STEPSIZE;
|
||||
tmpV.X = 0;
|
||||
if (Math.Abs(curLocalVel.Z) > 0.01)
|
||||
{
|
||||
tmpV.Y = -(float)Math.Atan2(curLocalVel.Z, curLocalVel.X) * ftmp;
|
||||
doathing = true;
|
||||
}
|
||||
Vector3 dirv;
|
||||
|
||||
if (curLocalVel.X > 0.01f)
|
||||
dirv = curLocalVel;
|
||||
else if (curLocalVel.X < -0.01f)
|
||||
// use oposite
|
||||
dirv = -curLocalVel;
|
||||
else
|
||||
tmpV.Y = 0;
|
||||
if (Math.Abs(curLocalVel.Y) > 0.01)
|
||||
{
|
||||
tmpV.Z = (float)Math.Atan2(curLocalVel.Y, curLocalVel.X) * ftmp;
|
||||
doathing = true;
|
||||
// make it fall into small positive x case
|
||||
dirv.X = 0.01f;
|
||||
dirv.Y = curLocalVel.Y;
|
||||
dirv.Z = curLocalVel.Z;
|
||||
}
|
||||
else
|
||||
tmpV.Z = 0;
|
||||
|
||||
if (doathing)
|
||||
float ftmp = m_angularDeflectionEfficiency / m_angularDeflectionTimescale;
|
||||
|
||||
if (Math.Abs(dirv.Z) > 0.01)
|
||||
{
|
||||
tmpV *= m_referenceFrame; // to object
|
||||
dtorque.X += tmpV.X;
|
||||
dtorque.Y += tmpV.Y;
|
||||
dtorque.Z += tmpV.Z;
|
||||
torque.Y += - (float)Math.Atan2(dirv.Z, dirv.X) * ftmp;
|
||||
}
|
||||
|
||||
if (Math.Abs(dirv.Y) > 0.01)
|
||||
{
|
||||
torque.Z += (float)Math.Atan2(dirv.Y, dirv.X) * ftmp;
|
||||
}
|
||||
}
|
||||
|
||||
// vertical atractor
|
||||
if (m_verticalAttractionTimescale < 300)
|
||||
{
|
||||
doathing = false;
|
||||
float roll;
|
||||
float pitch;
|
||||
|
||||
GetRollPitch(rotq, out roll, out pitch);
|
||||
|
||||
GetRollPitch(irotq, out roll, out pitch);
|
||||
|
||||
float ftmp = 1.0f / m_verticalAttractionTimescale / m_verticalAttractionTimescale / _pParentScene.ODE_STEPSIZE;
|
||||
float ftmp2 = m_verticalAttractionEfficiency / _pParentScene.ODE_STEPSIZE;
|
||||
|
||||
if (Math.Abs(roll) > 0.01) // roll
|
||||
{
|
||||
tmpV.X = -roll * ftmp;
|
||||
tmpV.X -= curLocalAngVel.X * ftmp2;
|
||||
doathing = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmpV.X = 0;
|
||||
torque.X -= -roll * ftmp + curLocalAngVel.X * ftmp2;
|
||||
}
|
||||
|
||||
if (Math.Abs(pitch) > 0.01 && ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) == 0)) // pitch
|
||||
{
|
||||
tmpV.Y = -pitch * ftmp;
|
||||
tmpV.Y -= curLocalAngVel.Y * ftmp2;
|
||||
doathing = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmpV.Y = 0;
|
||||
torque.Y -= -pitch * ftmp + curLocalAngVel.Y * ftmp2;
|
||||
}
|
||||
|
||||
tmpV.Z = 0;
|
||||
|
||||
if (m_bankingEfficiency == 0 || Math.Abs(roll) < 0.01)
|
||||
tmpV.Z = 0;
|
||||
else
|
||||
if (m_bankingEfficiency != 0 && Math.Abs(roll) > 0.01)
|
||||
{
|
||||
float broll = -roll * m_bankingEfficiency; ;
|
||||
float broll = roll * m_bankingEfficiency; ;
|
||||
if (m_bankingMix != 0)
|
||||
{
|
||||
float vfact = m_bankingMix * Math.Abs(curLocalVel.X) / 10.0f;
|
||||
if (vfact < m_bankingMix)
|
||||
float vfact = Math.Abs(curLocalVel.X) / 10.0f;
|
||||
if (vfact > 1.0f) vfact = 1.0f;
|
||||
if (curLocalVel.X >= 0)
|
||||
broll *= ((1 - m_bankingMix) + vfact);
|
||||
else
|
||||
broll *= -((1 - m_bankingMix) + vfact);
|
||||
}
|
||||
broll = (broll - curLocalAngVel.Z) / m_bankingTimescale;
|
||||
// torque.Z += broll;
|
||||
|
||||
tmpV.Z = (broll - curLocalAngVel.Z) / m_bankingTimescale;
|
||||
doathing = true;
|
||||
}
|
||||
// make z rot be in world Z not local as seems to be in sl
|
||||
tmpV.X = 0;
|
||||
tmpV.Y = 0;
|
||||
tmpV.Z = broll;
|
||||
tmpV *= irotq;
|
||||
|
||||
if (doathing)
|
||||
{
|
||||
|
||||
tmpV *= m_referenceFrame; // to object
|
||||
dtorque.X += tmpV.X;
|
||||
dtorque.Y += tmpV.Y;
|
||||
dtorque.Z += tmpV.Z;
|
||||
torque.X += tmpV.X;
|
||||
torque.Y += tmpV.Y;
|
||||
torque.Z += tmpV.Z;
|
||||
}
|
||||
}
|
||||
/*
|
||||
d.Vector3 pos = d.BodyGetPosition(Body);
|
||||
// Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f);
|
||||
Vector3 posChange = new Vector3();
|
||||
posChange.X = pos.X - m_lastPositionVector.X;
|
||||
posChange.Y = pos.Y - m_lastPositionVector.Y;
|
||||
posChange.Z = pos.Z - m_lastPositionVector.Z;
|
||||
double Zchange = Math.Abs(posChange.Z);
|
||||
if (m_BlockingEndPoint != Vector3.Zero)
|
||||
{
|
||||
if (pos.X >= (m_BlockingEndPoint.X - (float)1))
|
||||
{
|
||||
pos.X -= posChange.X + 1;
|
||||
d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
|
||||
}
|
||||
if (pos.Y >= (m_BlockingEndPoint.Y - (float)1))
|
||||
{
|
||||
pos.Y -= posChange.Y + 1;
|
||||
d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
|
||||
}
|
||||
if (pos.Z >= (m_BlockingEndPoint.Z - (float)1))
|
||||
{
|
||||
pos.Z -= posChange.Z + 1;
|
||||
d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
|
||||
}
|
||||
if (pos.X <= 0)
|
||||
{
|
||||
pos.X += posChange.X + 1;
|
||||
d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
|
||||
}
|
||||
if (pos.Y <= 0)
|
||||
{
|
||||
pos.Y += posChange.Y + 1;
|
||||
d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
|
||||
}
|
||||
}
|
||||
if (pos.Z < _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y))
|
||||
{
|
||||
pos.Z = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + 2;
|
||||
d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
|
||||
}
|
||||
|
||||
}
|
||||
if ((m_flags & (VehicleFlag.NO_X)) != 0)
|
||||
{
|
||||
m_dir.X = 0;
|
||||
}
|
||||
if ((m_flags & (VehicleFlag.NO_Y)) != 0)
|
||||
{
|
||||
m_dir.Y = 0;
|
||||
}
|
||||
if ((m_flags & (VehicleFlag.NO_Z)) != 0)
|
||||
{
|
||||
m_dir.Z = 0;
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
// angular part
|
||||
/*
|
||||
|
||||
// Get what the body is doing, this includes 'external' influences
|
||||
/*
|
||||
Vector3 angularVelocity = Vector3.Zero;
|
||||
|
||||
// Vertical attractor section
|
||||
Vector3 vertattr = Vector3.Zero;
|
||||
|
||||
if (m_verticalAttractionTimescale < 300)
|
||||
{
|
||||
float VAservo = 0.2f / m_verticalAttractionTimescale;
|
||||
// get present body rotation
|
||||
// make a vector pointing up
|
||||
Vector3 verterr = Vector3.Zero;
|
||||
verterr.Z = 1.0f;
|
||||
// rotate it to Body Angle
|
||||
verterr = verterr * rotq;
|
||||
// verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1.
|
||||
// As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go
|
||||
// negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body.
|
||||
if (verterr.Z < 0.0f)
|
||||
{
|
||||
verterr.X = 2.0f - verterr.X;
|
||||
verterr.Y = 2.0f - verterr.Y;
|
||||
}
|
||||
// Error is 0 (no error) to +/- 2 (max error)
|
||||
// scale it by VAservo
|
||||
verterr = verterr * VAservo;
|
||||
//if (frcount == 0) Console.WriteLine("VAerr=" + verterr);
|
||||
|
||||
// As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so
|
||||
// Change Body angular velocity X based on Y, and Y based on X. Z is not changed.
|
||||
vertattr.X = verterr.Y;
|
||||
vertattr.Y = - verterr.X;
|
||||
vertattr.Z = 0f;
|
||||
|
||||
// scaling appears better usingsquare-law
|
||||
float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency);
|
||||
vertattr.X += bounce * angularVelocity.X;
|
||||
vertattr.Y += bounce * angularVelocity.Y;
|
||||
|
||||
} // else vertical attractor is off
|
||||
|
||||
// m_lastVertAttractor = vertattr;
|
||||
|
||||
// Bank section tba
|
||||
// Deflection section tba
|
||||
|
||||
// Sum velocities
|
||||
m_lastAngularVelocity = angularVelocity + vertattr; // + bank + deflection
|
||||
|
||||
if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
|
||||
{
|
||||
m_lastAngularVelocity.X = 0;
|
||||
m_lastAngularVelocity.Y = 0;
|
||||
}
|
||||
|
||||
if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
|
||||
{
|
||||
if (!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
|
||||
}
|
||||
*/
|
||||
|
||||
d.Mass dmass;
|
||||
d.BodyGetMass(Body,out dmass);
|
||||
|
||||
@@ -988,48 +834,16 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
d.BodySetForce(Body, force.X, force.Y, force.Z);
|
||||
}
|
||||
|
||||
if (dtorque.X != 0 || dtorque.Y != 0 || dtorque.Z != 0)
|
||||
if (torque.X != 0 || torque.Y != 0 || torque.Z != 0)
|
||||
{
|
||||
torque *= m_referenceFrame; // to object frame
|
||||
dtorque.X = torque.X;
|
||||
dtorque.Y = torque.Y;
|
||||
dtorque.Z = torque.Z;
|
||||
|
||||
d.MultiplyM3V3(out dvtmp, ref dmass.I, ref dtorque);
|
||||
d.BodyAddRelTorque(Body, dvtmp.X, dvtmp.Y, dvtmp.Z); // add torque in object frame
|
||||
}
|
||||
|
||||
//end MoveAngular
|
||||
|
||||
// limit rotations
|
||||
/*
|
||||
bool changed = false;
|
||||
|
||||
if (m_RollreferenceFrame != Quaternion.Identity)
|
||||
{
|
||||
if (rotq.X >= m_RollreferenceFrame.X)
|
||||
{
|
||||
rot.X = rotq.X - (m_RollreferenceFrame.X / 2);
|
||||
}
|
||||
if (rotq.Y >= m_RollreferenceFrame.Y)
|
||||
{
|
||||
rot.Y = rotq.Y - (m_RollreferenceFrame.Y / 2);
|
||||
}
|
||||
if (rotq.X <= -m_RollreferenceFrame.X)
|
||||
{
|
||||
rot.X = rotq.X + (m_RollreferenceFrame.X / 2);
|
||||
}
|
||||
if (rotq.Y <= -m_RollreferenceFrame.Y)
|
||||
{
|
||||
rot.Y = rotq.Y + (m_RollreferenceFrame.Y / 2);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0)
|
||||
{
|
||||
rot.X = 0;
|
||||
rot.Y = 0;
|
||||
changed = true;
|
||||
}
|
||||
if (changed)
|
||||
d.BodySetQuaternion(Body, ref rot);
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Revision 2011 by Ubit Umarov
|
||||
/* Revision 2011/12 by Ubit Umarov
|
||||
*
|
||||
*
|
||||
*/
|
||||
@@ -190,7 +190,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
public ODEDynamics m_vehicle;
|
||||
|
||||
internal int m_material = (int)Material.Wood;
|
||||
protected ContactData primContactData = new ContactData { mu = 0f, bounce = 0.1f};
|
||||
protected ContactData primContactData = new ContactData { mu = 0f, bounce = 0.1f };
|
||||
|
||||
/// <summary>
|
||||
/// Is this prim subject to physics? Even if not, it's still solid for collision purposes.
|
||||
@@ -209,7 +209,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
AddChange(changes.Physical, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override bool Building // this is not reliable for internal use
|
||||
{
|
||||
get { return m_building; }
|
||||
@@ -225,23 +225,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
get
|
||||
{
|
||||
/*
|
||||
ODEDynamics v;
|
||||
if(childPrim && _parent !=null)
|
||||
{
|
||||
v =((OdePrim)_parent).m_vehicle;
|
||||
if(v != null && v.Type != Vehicle.TYPE_NONE)
|
||||
return v.VehiculeContactData;
|
||||
return primContactData;
|
||||
}
|
||||
|
||||
if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
|
||||
return m_vehicle.VehiculeContactData;
|
||||
*/
|
||||
return primContactData;
|
||||
return primContactData;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override int PhysicsActorType
|
||||
{
|
||||
get { return (int)ActorTypes.Prim; }
|
||||
@@ -276,11 +263,11 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
set
|
||||
{
|
||||
if(value)
|
||||
if (value)
|
||||
m_isSelected = value;
|
||||
AddChange(changes.Selected, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Flying
|
||||
{
|
||||
@@ -400,10 +387,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void SetVolumeDetect(int param)
|
||||
{
|
||||
AddChange(changes.VolumeDtc,(param != 0));
|
||||
AddChange(changes.VolumeDtc, (param != 0));
|
||||
}
|
||||
|
||||
public override Vector3 GeometricCenter
|
||||
@@ -483,14 +469,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
// client object interpolation works a 'little' better
|
||||
if (_zeroFlag)
|
||||
return Vector3.Zero;
|
||||
/*
|
||||
Vector3 returnVelocity = Vector3.Zero;
|
||||
returnVelocity.X = (m_lastVelocity.X + _velocity.X) / 2;
|
||||
returnVelocity.Y = (m_lastVelocity.Y + _velocity.Y) / 2;
|
||||
returnVelocity.Z = (m_lastVelocity.Z + _velocity.Z) / 2;
|
||||
|
||||
return returnVelocity;
|
||||
*/
|
||||
return _velocity;
|
||||
}
|
||||
set
|
||||
@@ -498,7 +476,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
if (value.IsFinite())
|
||||
{
|
||||
AddChange(changes.Velocity, value);
|
||||
// _velocity = value;
|
||||
// _velocity = value;
|
||||
|
||||
}
|
||||
else
|
||||
@@ -548,7 +526,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
get
|
||||
{
|
||||
if (givefakeori>0)
|
||||
if (givefakeori > 0)
|
||||
return fakeori;
|
||||
else
|
||||
|
||||
@@ -603,7 +581,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override float Buoyancy
|
||||
{
|
||||
get { return m_buoyancy; }
|
||||
@@ -652,6 +630,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
|
||||
public override int VehicleType
|
||||
{
|
||||
// we may need to put a fake on this
|
||||
get
|
||||
{
|
||||
if (m_vehicle == null)
|
||||
@@ -661,53 +640,42 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
}
|
||||
set
|
||||
{
|
||||
if (m_vehicle == null)
|
||||
{
|
||||
if (value != (int)Vehicle.TYPE_NONE)
|
||||
{
|
||||
m_vehicle = new ODEDynamics(this);
|
||||
m_vehicle.ProcessTypeChange((Vehicle)value);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_vehicle.ProcessTypeChange((Vehicle)value);
|
||||
AddChange(changes.VehicleType, value);
|
||||
}
|
||||
}
|
||||
|
||||
public override void VehicleFloatParam(int param, float value)
|
||||
{
|
||||
if (m_vehicle == null)
|
||||
return;
|
||||
m_vehicle.ProcessFloatVehicleParam((Vehicle)param, value);
|
||||
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
|
||||
d.BodyEnable(Body);
|
||||
strVehicleFloatParam fp = new strVehicleFloatParam();
|
||||
fp.param = param;
|
||||
fp.value = value;
|
||||
AddChange(changes.VehicleFloatParam, fp);
|
||||
}
|
||||
|
||||
public override void VehicleVectorParam(int param, Vector3 value)
|
||||
{
|
||||
if (m_vehicle == null)
|
||||
return;
|
||||
m_vehicle.ProcessVectorVehicleParam((Vehicle)param, value);
|
||||
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
|
||||
d.BodyEnable(Body);
|
||||
strVehicleVectorParam fp = new strVehicleVectorParam();
|
||||
fp.param = param;
|
||||
fp.value = value;
|
||||
AddChange(changes.VehicleVectorParam, fp);
|
||||
}
|
||||
|
||||
public override void VehicleRotationParam(int param, Quaternion rotation)
|
||||
public override void VehicleRotationParam(int param, Quaternion value)
|
||||
{
|
||||
strVehicleQuatParam fp = new strVehicleQuatParam();
|
||||
fp.param = param;
|
||||
fp.value = value;
|
||||
AddChange(changes.VehicleVectorParam, fp);
|
||||
}
|
||||
|
||||
public override void VehicleFlags(int param, bool value)
|
||||
{
|
||||
if (m_vehicle == null)
|
||||
return;
|
||||
m_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
|
||||
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
|
||||
d.BodyEnable(Body);
|
||||
}
|
||||
|
||||
public override void VehicleFlags(int param, bool remove)
|
||||
{
|
||||
if (m_vehicle == null)
|
||||
return;
|
||||
m_vehicle.ProcessVehicleFlags(param, remove);
|
||||
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
|
||||
d.BodyEnable(Body);
|
||||
strVehicleBoolParam bp = new strVehicleBoolParam();
|
||||
bp.param = param;
|
||||
bp.value = value;
|
||||
AddChange(changes.VehicleFlags, bp);
|
||||
}
|
||||
|
||||
public void SetAcceleration(Vector3 accel)
|
||||
@@ -829,7 +797,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size,
|
||||
Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
|
||||
{
|
||||
@@ -866,7 +834,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
if (size.Z <= 0) size.Z = 0.01f;
|
||||
|
||||
_size = size;
|
||||
|
||||
|
||||
|
||||
if (!QuaternionIsFinite(rotation))
|
||||
{
|
||||
@@ -1023,7 +991,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
if (_parent != null)
|
||||
{
|
||||
OdePrim parent = (OdePrim)_parent;
|
||||
parent.ChildDelink(this,false);
|
||||
parent.ChildDelink(this, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1055,9 +1023,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
return false;
|
||||
}
|
||||
|
||||
// primOOBoffset = mesh.GetCentroid();
|
||||
// hasOOBoffsetFromMesh = true;
|
||||
hasOOBoffsetFromMesh = false;
|
||||
primOOBoffset = mesh.GetCentroid();
|
||||
hasOOBoffsetFromMesh = true;
|
||||
|
||||
_triMeshData = d.GeomTriMeshDataCreate();
|
||||
|
||||
@@ -1094,23 +1061,23 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
_parent_scene.geom_name_map[prim_geom] = Name;
|
||||
_parent_scene.actor_name_map[prim_geom] = this;
|
||||
|
||||
/*
|
||||
if (childPrim)
|
||||
{
|
||||
if (_parent != null && _parent is OdePrim)
|
||||
{
|
||||
OdePrim parent = (OdePrim)_parent;
|
||||
//Console.WriteLine("SetGeom calls ChildSetGeom");
|
||||
parent.ChildSetGeom(this);
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
if (childPrim)
|
||||
{
|
||||
if (_parent != null && _parent is OdePrim)
|
||||
{
|
||||
OdePrim parent = (OdePrim)_parent;
|
||||
//Console.WriteLine("SetGeom calls ChildSetGeom");
|
||||
parent.ChildSetGeom(this);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
else
|
||||
m_log.Warn("Setting bad Geom");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create a geometry for the given mesh in the given target space.
|
||||
/// </summary>
|
||||
@@ -1129,10 +1096,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
|
||||
if (_parent_scene.needsMeshing(_pbs))
|
||||
{
|
||||
haveMesh = setMesh(_parent_scene); // this will give a mesh to non trivial known prims
|
||||
haveMesh = setMesh(_parent_scene); // this will give a mesh to non trivial known prims
|
||||
}
|
||||
|
||||
if(!haveMesh)
|
||||
if (!haveMesh)
|
||||
{
|
||||
if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1
|
||||
&& _size.X == _size.Y && _size.Y == _size.Z)
|
||||
@@ -1187,7 +1154,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
// catch (System.AccessViolationException)
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction failed for {0} exception {1}", Name,e);
|
||||
m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction failed for {0} exception {1}", Name, e);
|
||||
}
|
||||
|
||||
prim_geom = IntPtr.Zero;
|
||||
@@ -1198,7 +1165,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
}
|
||||
Body = IntPtr.Zero;
|
||||
hasOOBoffsetFromMesh = false;
|
||||
// CalcPrimBodyData();
|
||||
CalcPrimBodyData();
|
||||
}
|
||||
|
||||
private void ChildSetGeom(OdePrim odePrim)
|
||||
@@ -1223,7 +1190,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero)
|
||||
{
|
||||
/*
|
||||
if (m_targetSpace != _parent_scene.ActiveSpace)
|
||||
{
|
||||
m_targetSpace = _parent_scene.ActiveSpace;
|
||||
@@ -1238,7 +1204,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
}
|
||||
d.SpaceAdd(m_targetSpace, prim_geom);
|
||||
}
|
||||
*/
|
||||
d.GeomEnable(prim_geom);
|
||||
foreach (OdePrim prm in childrenPrim)
|
||||
d.GeomEnable(prm.prim_geom);
|
||||
@@ -1256,7 +1221,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero)
|
||||
{
|
||||
/*
|
||||
if (m_targetSpace == _parent_scene.ActiveSpace)
|
||||
{
|
||||
foreach (OdePrim prm in childrenPrim)
|
||||
@@ -1270,7 +1234,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
d.SpaceRemove(m_targetSpace, prim_geom);
|
||||
m_targetSpace = IntPtr.Zero;
|
||||
}
|
||||
*/
|
||||
d.GeomDisable(prim_geom);
|
||||
foreach (OdePrim prm in childrenPrim)
|
||||
d.GeomDisable(prm.prim_geom);
|
||||
@@ -1531,7 +1494,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
}
|
||||
|
||||
#region Mass Calculation
|
||||
|
||||
|
||||
private float CalculatePrimVolume()
|
||||
{
|
||||
float volume = _size.X * _size.Y * _size.Z; // default
|
||||
@@ -1890,7 +1853,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
if (prm.prim_geom != IntPtr.Zero)
|
||||
d.GeomSetBody(prm.prim_geom, IntPtr.Zero);
|
||||
if(prm.Body != prim.Body)
|
||||
if (prm.Body != prim.Body)
|
||||
prm.DestroyBody(); // don't loose bodies around
|
||||
prm.Body = IntPtr.Zero;
|
||||
}
|
||||
@@ -2062,21 +2025,18 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
SetInStaticSpace(this);
|
||||
}
|
||||
|
||||
m_building = false; // REMOVE THIS LATER
|
||||
|
||||
|
||||
if (m_isphysical && Body == IntPtr.Zero)
|
||||
{
|
||||
/*
|
||||
if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
|
||||
{
|
||||
changeShape(_pbs);
|
||||
}
|
||||
else
|
||||
{
|
||||
*/
|
||||
MakeBody();
|
||||
// }
|
||||
/*
|
||||
if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
|
||||
{
|
||||
changeShape(_pbs);
|
||||
}
|
||||
else
|
||||
{
|
||||
*/
|
||||
MakeBody();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2119,7 +2079,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
{
|
||||
if (NewParent != _parent)
|
||||
{
|
||||
(_parent as OdePrim).ChildDelink(this,false); // for now...
|
||||
(_parent as OdePrim).ChildDelink(this, false); // for now...
|
||||
childPrim = false;
|
||||
|
||||
if (NewParent != null)
|
||||
@@ -2135,7 +2095,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
|
||||
private void Stop()
|
||||
{
|
||||
if(!childPrim)
|
||||
if (!childPrim)
|
||||
{
|
||||
m_force = Vector3.Zero;
|
||||
m_forceacc = Vector3.Zero;
|
||||
@@ -2143,7 +2103,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
_torque = Vector3.Zero;
|
||||
_velocity = Vector3.Zero;
|
||||
_acceleration = Vector3.Zero;
|
||||
m_rotationalVelocity = Vector3.Zero;
|
||||
m_rotationalVelocity = Vector3.Zero;
|
||||
_target_velocity = Vector3.Zero;
|
||||
if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE)
|
||||
m_vehicle.Stop();
|
||||
@@ -2155,7 +2115,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
d.BodySetTorque(Body, 0f, 0f, 0f);
|
||||
d.BodySetLinearVel(Body, 0f, 0f, 0f);
|
||||
d.BodySetAngularVel(Body, 0f, 0f, 0f);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2241,7 +2201,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
givefakepos--;
|
||||
if (givefakepos < 0)
|
||||
givefakepos = 0;
|
||||
// changeSelectedStatus();
|
||||
// changeSelectedStatus();
|
||||
resetCollisionAccounting();
|
||||
}
|
||||
|
||||
@@ -2386,17 +2346,17 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
|
||||
if (!childPrim)
|
||||
{
|
||||
if (NewStatus)
|
||||
if (NewStatus)
|
||||
{
|
||||
if (Body == IntPtr.Zero)
|
||||
{
|
||||
/*
|
||||
if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
|
||||
{
|
||||
changeShape(_pbs);
|
||||
}
|
||||
else
|
||||
*/
|
||||
/*
|
||||
if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
|
||||
{
|
||||
changeShape(_pbs);
|
||||
}
|
||||
else
|
||||
*/
|
||||
{
|
||||
MakeBody();
|
||||
}
|
||||
@@ -2407,13 +2367,14 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
if (Body != IntPtr.Zero)
|
||||
{
|
||||
// UpdateChildsfromgeom();
|
||||
/* if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
|
||||
{
|
||||
changeShape(_pbs);
|
||||
}
|
||||
else
|
||||
*/
|
||||
DestroyBody();
|
||||
/* if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
|
||||
{
|
||||
changeShape(_pbs);
|
||||
}
|
||||
else
|
||||
*/
|
||||
DestroyBody();
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2422,7 +2383,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
}
|
||||
|
||||
private void changeprimsizeshape()
|
||||
{
|
||||
{
|
||||
OdePrim parent = (OdePrim)_parent;
|
||||
|
||||
bool chp = childPrim;
|
||||
@@ -2614,6 +2575,57 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
}
|
||||
}
|
||||
|
||||
private void changeVehicleType(int value)
|
||||
{
|
||||
if (m_vehicle == null)
|
||||
{
|
||||
if (value != (int)Vehicle.TYPE_NONE)
|
||||
{
|
||||
m_vehicle = new ODEDynamics(this);
|
||||
m_vehicle.ProcessTypeChange((Vehicle)value);
|
||||
}
|
||||
}
|
||||
else
|
||||
m_vehicle.ProcessTypeChange((Vehicle)value);
|
||||
}
|
||||
|
||||
private void changeVehicleFloatParam(strVehicleFloatParam fp)
|
||||
{
|
||||
if (m_vehicle == null)
|
||||
return;
|
||||
|
||||
m_vehicle.ProcessFloatVehicleParam((Vehicle)fp.param, fp.value);
|
||||
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
|
||||
d.BodyEnable(Body);
|
||||
}
|
||||
|
||||
private void changeVehicleVectorParam(strVehicleVectorParam vp)
|
||||
{
|
||||
if (m_vehicle == null)
|
||||
return;
|
||||
m_vehicle.ProcessVectorVehicleParam((Vehicle)vp.param, vp.value);
|
||||
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
|
||||
d.BodyEnable(Body);
|
||||
}
|
||||
|
||||
private void changeVehicleRotationParam(strVehicleQuatParam qp)
|
||||
{
|
||||
if (m_vehicle == null)
|
||||
return;
|
||||
m_vehicle.ProcessRotationVehicleParam((Vehicle)qp.param, qp.value);
|
||||
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
|
||||
d.BodyEnable(Body);
|
||||
}
|
||||
|
||||
private void changeVehicleFlags(strVehicleBoolParam bp)
|
||||
{
|
||||
if (m_vehicle == null)
|
||||
return;
|
||||
m_vehicle.ProcessVehicleFlags(bp.param, bp.value);
|
||||
if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body))
|
||||
d.BodyEnable(Body);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void Move()
|
||||
@@ -2621,10 +2633,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
if (!childPrim && m_isphysical && Body != IntPtr.Zero &&
|
||||
!m_disabled && !m_isSelected && d.BodyIsEnabled(Body) && !m_building) // KF: Only move root prims.
|
||||
{
|
||||
// if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); // KF add 161009
|
||||
// if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); // KF add 161009
|
||||
|
||||
float timestep = _parent_scene.ODE_STEPSIZE;
|
||||
|
||||
|
||||
float fx = 0;
|
||||
float fy = 0;
|
||||
float fz = 0;
|
||||
@@ -2636,13 +2648,13 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
}
|
||||
else
|
||||
{
|
||||
float m_mass = _mass;
|
||||
|
||||
float m_mass = _mass;
|
||||
|
||||
// fz = 0f;
|
||||
//m_log.Info(m_collisionFlags.ToString());
|
||||
if (m_usePID)
|
||||
{
|
||||
|
||||
|
||||
// If the PID Controller isn't active then we set our force
|
||||
// calculating base velocity to the current position
|
||||
|
||||
@@ -2800,7 +2812,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
fz += m_forceacc.Z;
|
||||
|
||||
m_forceacc = Vector3.Zero;
|
||||
|
||||
|
||||
//m_log.Info("[OBJPID]: X:" + fx.ToString() + " Y:" + fy.ToString() + " Z:" + fz.ToString());
|
||||
if (fx != 0 || fy != 0 || fz != 0)
|
||||
{
|
||||
@@ -2876,10 +2888,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
bool lastZeroFlag = _zeroFlag;
|
||||
|
||||
d.Vector3 lpos;
|
||||
d.GeomCopyPosition(prim_geom,out lpos); // root position that is seem by rest of simulator
|
||||
|
||||
d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator
|
||||
|
||||
// we need to use root position since that's all the rest of scene uses
|
||||
if ( lpos.X < 0f || lpos.X > _parent_scene.WorldExtents.X
|
||||
if (lpos.X < 0f || lpos.X > _parent_scene.WorldExtents.X
|
||||
|| lpos.Y < 0f || lpos.Y > _parent_scene.WorldExtents.Y
|
||||
)
|
||||
{
|
||||
@@ -3142,10 +3154,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
if (_parent != null)
|
||||
{
|
||||
OdePrim parent = (OdePrim)_parent;
|
||||
parent.ChildRemove(this,false);
|
||||
parent.ChildRemove(this, false);
|
||||
}
|
||||
else
|
||||
ChildRemove(this,false);
|
||||
ChildRemove(this, false);
|
||||
|
||||
RemoveGeom();
|
||||
m_targetSpace = IntPtr.Zero;
|
||||
@@ -3182,12 +3194,12 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
changevelocity((Vector3)arg);
|
||||
break;
|
||||
|
||||
// case changes.Acceleration:
|
||||
// changeacceleration((Vector3)arg);
|
||||
// break;
|
||||
// case changes.AngVelocity:
|
||||
// changeangvelocity((Vector3)arg);
|
||||
// break;
|
||||
// case changes.Acceleration:
|
||||
// changeacceleration((Vector3)arg);
|
||||
// break;
|
||||
// case changes.AngVelocity:
|
||||
// changeangvelocity((Vector3)arg);
|
||||
// break;
|
||||
|
||||
case changes.Force:
|
||||
changeForce((Vector3)arg);
|
||||
@@ -3214,7 +3226,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
break;
|
||||
|
||||
case changes.Shape:
|
||||
changeShape((PrimitiveBaseShape) arg);
|
||||
changeShape((PrimitiveBaseShape)arg);
|
||||
break;
|
||||
|
||||
case changes.CollidesWater:
|
||||
@@ -3234,13 +3246,33 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
break;
|
||||
|
||||
case changes.disabled:
|
||||
changeDisable((bool) arg);
|
||||
changeDisable((bool)arg);
|
||||
break;
|
||||
|
||||
case changes.building:
|
||||
changeBuilding((bool)arg);
|
||||
break;
|
||||
|
||||
case changes.VehicleType:
|
||||
changeVehicleType((int)arg);
|
||||
break;
|
||||
|
||||
case changes.VehicleFlags:
|
||||
changeVehicleFlags((strVehicleBoolParam) arg);
|
||||
break;
|
||||
|
||||
case changes.VehicleFloatParam:
|
||||
changeVehicleFloatParam((strVehicleFloatParam) arg);
|
||||
break;
|
||||
|
||||
case changes.VehicleVectorParam:
|
||||
changeVehicleVectorParam((strVehicleVectorParam) arg);
|
||||
break;
|
||||
|
||||
case changes.VehicleRotationParam:
|
||||
changeVehicleRotationParam((strVehicleQuatParam) arg);
|
||||
break;
|
||||
|
||||
case changes.Null:
|
||||
donullchange();
|
||||
break;
|
||||
@@ -3254,7 +3286,32 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
|
||||
public void AddChange(changes what, object arg)
|
||||
{
|
||||
_parent_scene.AddChange(this, what, arg);
|
||||
_parent_scene.AddChange((PhysicsActor) this, what, arg);
|
||||
}
|
||||
|
||||
|
||||
private struct strVehicleBoolParam
|
||||
{
|
||||
public int param;
|
||||
public bool value;
|
||||
}
|
||||
|
||||
private struct strVehicleFloatParam
|
||||
{
|
||||
public int param;
|
||||
public float value;
|
||||
}
|
||||
|
||||
private struct strVehicleQuatParam
|
||||
{
|
||||
public int param;
|
||||
public Quaternion value;
|
||||
}
|
||||
|
||||
private struct strVehicleVectorParam
|
||||
{
|
||||
public int param;
|
||||
public Vector3 value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* based on:
|
||||
* Ode.NET - .NET bindings for ODE
|
||||
@@ -59,6 +60,7 @@ namespace OdeAPI
|
||||
{
|
||||
public static dReal Infinity = dReal.MaxValue;
|
||||
public static int NTotalBodies = 0;
|
||||
public static int NTotalGeoms = 0;
|
||||
|
||||
#region Flags and Enumerations
|
||||
|
||||
@@ -420,7 +422,7 @@ namespace OdeAPI
|
||||
|
||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCreate"), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr BodyiCreate(IntPtr world);
|
||||
public static IntPtr BodyCreate(IntPtr world)
|
||||
public static IntPtr BodyCreate(IntPtr world)
|
||||
{
|
||||
NTotalBodies++;
|
||||
return BodyiCreate(world);
|
||||
@@ -689,22 +691,52 @@ namespace OdeAPI
|
||||
public static extern IntPtr ConnectingJoint(IntPtr j1, IntPtr j2);
|
||||
|
||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateBox"), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateBox(IntPtr space, dReal lx, dReal ly, dReal lz);
|
||||
public static extern IntPtr CreateiBox(IntPtr space, dReal lx, dReal ly, dReal lz);
|
||||
public static IntPtr CreateBox(IntPtr space, dReal lx, dReal ly, dReal lz)
|
||||
{
|
||||
NTotalGeoms++;
|
||||
return CreateiBox(space, lx, ly, lz);
|
||||
}
|
||||
|
||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateCapsule"), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateCapsule(IntPtr space, dReal radius, dReal length);
|
||||
public static extern IntPtr CreateiCapsule(IntPtr space, dReal radius, dReal length);
|
||||
public static IntPtr CreateCapsule(IntPtr space, dReal radius, dReal length)
|
||||
{
|
||||
NTotalGeoms++;
|
||||
return CreateiCapsule(space, radius, length);
|
||||
}
|
||||
|
||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateConvex"), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateConvex(IntPtr space, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons);
|
||||
public static extern IntPtr CreateiConvex(IntPtr space, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons);
|
||||
public static IntPtr CreateConvex(IntPtr space, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons)
|
||||
{
|
||||
NTotalGeoms++;
|
||||
return CreateiConvex(space, planes, planeCount, points, pointCount, polygons);
|
||||
}
|
||||
|
||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateCylinder"), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateCylinder(IntPtr space, dReal radius, dReal length);
|
||||
public static extern IntPtr CreateiCylinder(IntPtr space, dReal radius, dReal length);
|
||||
public static IntPtr CreateCylinder(IntPtr space, dReal radius, dReal length)
|
||||
{
|
||||
NTotalGeoms++;
|
||||
return CreateiCylinder(space, radius, length);
|
||||
}
|
||||
|
||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateHeightfield"), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateHeightfield(IntPtr space, IntPtr data, int bPlaceable);
|
||||
public static extern IntPtr CreateiHeightfield(IntPtr space, IntPtr data, int bPlaceable);
|
||||
public static IntPtr CreateHeightfield(IntPtr space, IntPtr data, int bPlaceable)
|
||||
{
|
||||
NTotalGeoms++;
|
||||
return CreateiHeightfield(space, data, bPlaceable);
|
||||
}
|
||||
|
||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeom"), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateGeom(int classnum);
|
||||
public static extern IntPtr CreateiGeom(int classnum);
|
||||
public static IntPtr CreateGeom(int classnum)
|
||||
{
|
||||
NTotalGeoms++;
|
||||
return CreateiGeom(classnum);
|
||||
}
|
||||
|
||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeomClass"), SuppressUnmanagedCodeSecurity]
|
||||
public static extern int CreateGeomClass(ref GeomClass classptr);
|
||||
@@ -713,19 +745,39 @@ namespace OdeAPI
|
||||
public static extern IntPtr CreateGeomTransform(IntPtr space);
|
||||
|
||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreatePlane"), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreatePlane(IntPtr space, dReal a, dReal b, dReal c, dReal d);
|
||||
public static extern IntPtr CreateiPlane(IntPtr space, dReal a, dReal b, dReal c, dReal d);
|
||||
public static IntPtr CreatePlane(IntPtr space, dReal a, dReal b, dReal c, dReal d)
|
||||
{
|
||||
NTotalGeoms++;
|
||||
return CreateiPlane(space, a, b, c, d);
|
||||
}
|
||||
|
||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateRay"), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateRay(IntPtr space, dReal length);
|
||||
public static extern IntPtr CreateiRay(IntPtr space, dReal length);
|
||||
public static IntPtr CreateRay(IntPtr space, dReal length)
|
||||
{
|
||||
NTotalGeoms++;
|
||||
return CreateiRay(space, length);
|
||||
}
|
||||
|
||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateSphere"), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateSphere(IntPtr space, dReal radius);
|
||||
public static extern IntPtr CreateiSphere(IntPtr space, dReal radius);
|
||||
public static IntPtr CreateSphere(IntPtr space, dReal radius)
|
||||
{
|
||||
NTotalGeoms++;
|
||||
return CreateiSphere(space, radius);
|
||||
}
|
||||
|
||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateTriMesh"), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateTriMesh(IntPtr space, IntPtr data,
|
||||
public static extern IntPtr CreateiTriMesh(IntPtr space, IntPtr data,
|
||||
TriCallback callback, TriArrayCallback arrayCallback, TriRayCallback rayCallback);
|
||||
|
||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dDot"), SuppressUnmanagedCodeSecurity]
|
||||
public static IntPtr CreateTriMesh(IntPtr space, IntPtr data,
|
||||
TriCallback callback, TriArrayCallback arrayCallback, TriRayCallback rayCallback)
|
||||
{
|
||||
NTotalGeoms++;
|
||||
return CreateiTriMesh(space, data, callback, arrayCallback, rayCallback);
|
||||
}
|
||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dDot"), SuppressUnmanagedCodeSecurity]
|
||||
public static extern dReal Dot(ref dReal X0, ref dReal X1, int n);
|
||||
|
||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dDQfromW"), SuppressUnmanagedCodeSecurity]
|
||||
@@ -798,7 +850,13 @@ namespace OdeAPI
|
||||
public static extern void GeomCylinderSetParams(IntPtr geom, dReal radius, dReal length);
|
||||
|
||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomDestroy"), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void GeomDestroy(IntPtr geom);
|
||||
public static extern void GeomiDestroy(IntPtr geom);
|
||||
public static void GeomDestroy(IntPtr geom)
|
||||
{
|
||||
NTotalGeoms--;
|
||||
GeomiDestroy(geom);
|
||||
}
|
||||
|
||||
|
||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomDisable"), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void GeomDisable(IntPtr geom);
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
//#define USE_DRAWSTUFF
|
||||
//#define SPAM
|
||||
|
||||
using System;
|
||||
@@ -38,9 +37,6 @@ using System.Diagnostics;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OdeAPI;
|
||||
#if USE_DRAWSTUFF
|
||||
using ODEDrawstuff;
|
||||
#endif
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
using OpenMetaverse;
|
||||
@@ -136,12 +132,18 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
disabled,
|
||||
building,
|
||||
|
||||
VehicleType,
|
||||
VehicleFloatParam,
|
||||
VehicleVectorParam,
|
||||
VehicleRotationParam,
|
||||
VehicleFlags,
|
||||
|
||||
Null //keep this last used do dim the methods array. does nothing but pulsing the prim
|
||||
}
|
||||
|
||||
public struct ODEchangeitem
|
||||
{
|
||||
public OdePrim prim;
|
||||
public PhysicsActor actor;
|
||||
public OdeCharacter character;
|
||||
public changes what;
|
||||
public Object arg;
|
||||
@@ -181,7 +183,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
public float gravityy = 0f;
|
||||
public float gravityz = -9.8f;
|
||||
|
||||
|
||||
private float waterlevel = 0f;
|
||||
private int framecount = 0;
|
||||
|
||||
@@ -223,10 +224,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
private readonly HashSet<OdePrim> _prims = new HashSet<OdePrim>();
|
||||
private readonly HashSet<OdePrim> _activeprims = new HashSet<OdePrim>();
|
||||
|
||||
private readonly Object _taintedCharacterLock = new Object();
|
||||
private readonly HashSet<OdeCharacter> _taintedCharacterH = new HashSet<OdeCharacter>(); // faster verification of repeated character taints
|
||||
private readonly Queue<OdeCharacter> _taintedCharacterQ = new Queue<OdeCharacter>(); // character taints
|
||||
|
||||
public OpenSim.Framework.LocklessQueue<ODEchangeitem> ChangesQueue = new OpenSim.Framework.LocklessQueue<ODEchangeitem>();
|
||||
|
||||
/// <summary>
|
||||
@@ -365,31 +362,11 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
//contactgroup
|
||||
|
||||
d.WorldSetAutoDisableFlag(world, false);
|
||||
#if USE_DRAWSTUFF
|
||||
|
||||
Thread viewthread = new Thread(new ParameterizedThreadStart(startvisualization));
|
||||
viewthread.Start();
|
||||
#endif
|
||||
}
|
||||
|
||||
_watermap = new float[258 * 258];
|
||||
}
|
||||
|
||||
#if USE_DRAWSTUFF
|
||||
public void startvisualization(object o)
|
||||
{
|
||||
ds.Functions fn;
|
||||
fn.version = ds.VERSION;
|
||||
fn.start = new ds.CallbackFunction(start);
|
||||
fn.step = new ds.CallbackFunction(step);
|
||||
fn.command = new ds.CallbackFunction(command);
|
||||
fn.stop = null;
|
||||
fn.path_to_textures = "./textures";
|
||||
string[] args = new string[0];
|
||||
ds.SimulationLoop(args.Length, args, 352, 288, ref fn);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initialize the mesh plugin
|
||||
// public override void Initialise(IMesher meshmerizer, IConfigSource config, RegionInfo region )
|
||||
public override void Initialise(IMesher meshmerizer, IConfigSource config)
|
||||
@@ -1552,23 +1529,15 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
return true;
|
||||
}
|
||||
|
||||
public void AddChange(OdePrim prim, changes what, Object arg)
|
||||
{
|
||||
ODEchangeitem item = new ODEchangeitem();
|
||||
item.prim = prim;
|
||||
item.what = what;
|
||||
item.arg = arg;
|
||||
ChangesQueue.Enqueue(item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called to queue a change to a prim
|
||||
/// Called to queue a change to a actor
|
||||
/// to use in place of old taint mechanism so changes do have a time sequence
|
||||
/// </summary>
|
||||
public void AddChange(OdeCharacter character, changes what, Object arg)
|
||||
|
||||
public void AddChange(PhysicsActor actor, changes what, Object arg)
|
||||
{
|
||||
ODEchangeitem item = new ODEchangeitem();
|
||||
item.character = character;
|
||||
item.actor = actor;
|
||||
item.what = what;
|
||||
item.arg = arg;
|
||||
ChangesQueue.Enqueue(item);
|
||||
@@ -1582,34 +1551,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
/// <param name="prim"></param>
|
||||
public override void AddPhysicsActorTaint(PhysicsActor prim)
|
||||
{
|
||||
if (prim is OdePrim)
|
||||
{
|
||||
/* OdePrim taintedprim = ((OdePrim) prim);
|
||||
lock (_taintedPrimLock)
|
||||
{
|
||||
if (!(_taintedPrimH.Contains(taintedprim)))
|
||||
{
|
||||
_taintedPrimH.Add(taintedprim); // HashSet for searching
|
||||
_taintedPrimQ.Enqueue(taintedprim); // List for ordered readout
|
||||
}
|
||||
}
|
||||
*/
|
||||
return;
|
||||
}
|
||||
else if (prim is OdeCharacter)
|
||||
{
|
||||
OdeCharacter taintedchar = ((OdeCharacter)prim);
|
||||
lock (_taintedCharacterLock)
|
||||
{
|
||||
if (!(_taintedCharacterH.Contains(taintedchar)))
|
||||
{
|
||||
_taintedCharacterH.Add(taintedchar);
|
||||
_taintedCharacterQ.Enqueue(taintedchar);
|
||||
if (taintedchar.bad)
|
||||
m_log.DebugFormat("[PHYSICS]: Added BAD actor {0} to tainted actors", taintedchar.m_uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1681,25 +1622,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
// clear pointer/counter to contacts to pass into joints
|
||||
m_global_contactcount = 0;
|
||||
|
||||
// do characters requested changes
|
||||
|
||||
OdeCharacter character;
|
||||
int numtaints;
|
||||
lock (_taintedCharacterLock)
|
||||
{
|
||||
numtaints = _taintedCharacterQ.Count;
|
||||
// if (numtaints > 50)
|
||||
// numtaints = 50;
|
||||
while (numtaints > 0)
|
||||
{
|
||||
character = _taintedCharacterQ.Dequeue();
|
||||
character.ProcessTaints(ODE_STEPSIZE);
|
||||
_taintedCharacterH.Remove(character);
|
||||
numtaints--;
|
||||
}
|
||||
}
|
||||
// do other objects requested changes
|
||||
|
||||
ODEchangeitem item;
|
||||
|
||||
if(ChangesQueue.Count >0)
|
||||
@@ -1710,14 +1632,19 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
|
||||
while(ChangesQueue.Dequeue(out item))
|
||||
{
|
||||
if (item.prim != null)
|
||||
if (item.actor != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (item.prim.DoAChange(item.what, item.arg))
|
||||
RemovePrimThreadLocked(item.prim);
|
||||
if (item.actor is OdeCharacter)
|
||||
((OdeCharacter)item.actor).DoAChange(item.what, item.arg);
|
||||
else if (((OdePrim)item.actor).DoAChange(item.what, item.arg))
|
||||
RemovePrimThreadLocked((OdePrim)item.actor);
|
||||
}
|
||||
catch { };
|
||||
catch
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: doChange failed for a actor");
|
||||
};
|
||||
}
|
||||
ttmp = Util.EnvironmentTickCountSubtract(ttmpstart);
|
||||
if (ttmp > 20)
|
||||
@@ -1860,6 +1787,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
int nstaticgeoms = d.SpaceGetNumGeoms(StaticSpace);
|
||||
int ntopgeoms = d.SpaceGetNumGeoms(TopSpace);
|
||||
int nbodies = d.NTotalBodies;
|
||||
int ngeoms = d.NTotalGeoms;
|
||||
|
||||
// Finished with all sim stepping. If requested, dump world state to file for debugging.
|
||||
// TODO: This call to the export function is already inside lock (OdeLock) - but is an extra lock needed?
|
||||
@@ -2608,134 +2536,5 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||
}
|
||||
return new List<ContactResult>();
|
||||
}
|
||||
|
||||
#if USE_DRAWSTUFF
|
||||
// Keyboard callback
|
||||
public void command(int cmd)
|
||||
{
|
||||
IntPtr geom;
|
||||
d.Mass mass;
|
||||
d.Vector3 sides = new d.Vector3(d.RandReal() * 0.5f + 0.1f, d.RandReal() * 0.5f + 0.1f, d.RandReal() * 0.5f + 0.1f);
|
||||
|
||||
|
||||
|
||||
Char ch = Char.ToLower((Char)cmd);
|
||||
switch ((Char)ch)
|
||||
{
|
||||
case 'w':
|
||||
try
|
||||
{
|
||||
Vector3 rotate = (new Vector3(1, 0, 0) * Quaternion.CreateFromEulers(hpr.Z * Utils.DEG_TO_RAD, hpr.Y * Utils.DEG_TO_RAD, hpr.X * Utils.DEG_TO_RAD));
|
||||
|
||||
xyz.X += rotate.X; xyz.Y += rotate.Y; xyz.Z += rotate.Z;
|
||||
ds.SetViewpoint(ref xyz, ref hpr);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{ hpr.X = 0; }
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
hpr.X++;
|
||||
ds.SetViewpoint(ref xyz, ref hpr);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
try
|
||||
{
|
||||
Vector3 rotate2 = (new Vector3(-1, 0, 0) * Quaternion.CreateFromEulers(hpr.Z * Utils.DEG_TO_RAD, hpr.Y * Utils.DEG_TO_RAD, hpr.X * Utils.DEG_TO_RAD));
|
||||
|
||||
xyz.X += rotate2.X; xyz.Y += rotate2.Y; xyz.Z += rotate2.Z;
|
||||
ds.SetViewpoint(ref xyz, ref hpr);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{ hpr.X = 0; }
|
||||
break;
|
||||
case 'd':
|
||||
hpr.X--;
|
||||
ds.SetViewpoint(ref xyz, ref hpr);
|
||||
break;
|
||||
case 'r':
|
||||
xyz.Z++;
|
||||
ds.SetViewpoint(ref xyz, ref hpr);
|
||||
break;
|
||||
case 'f':
|
||||
xyz.Z--;
|
||||
ds.SetViewpoint(ref xyz, ref hpr);
|
||||
break;
|
||||
case 'e':
|
||||
xyz.Y++;
|
||||
ds.SetViewpoint(ref xyz, ref hpr);
|
||||
break;
|
||||
case 'q':
|
||||
xyz.Y--;
|
||||
ds.SetViewpoint(ref xyz, ref hpr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void step(int pause)
|
||||
{
|
||||
|
||||
ds.SetColor(1.0f, 1.0f, 0.0f);
|
||||
ds.SetTexture(ds.Texture.Wood);
|
||||
lock (_prims)
|
||||
{
|
||||
foreach (OdePrim prm in _prims)
|
||||
{
|
||||
//IntPtr body = d.GeomGetBody(prm.prim_geom);
|
||||
if (prm.prim_geom != IntPtr.Zero)
|
||||
{
|
||||
d.Vector3 pos;
|
||||
d.GeomCopyPosition(prm.prim_geom, out pos);
|
||||
//d.BodyCopyPosition(body, out pos);
|
||||
|
||||
d.Matrix3 R;
|
||||
d.GeomCopyRotation(prm.prim_geom, out R);
|
||||
//d.BodyCopyRotation(body, out R);
|
||||
|
||||
|
||||
d.Vector3 sides = new d.Vector3();
|
||||
sides.X = prm.Size.X;
|
||||
sides.Y = prm.Size.Y;
|
||||
sides.Z = prm.Size.Z;
|
||||
|
||||
ds.DrawBox(ref pos, ref R, ref sides);
|
||||
}
|
||||
}
|
||||
}
|
||||
ds.SetColor(1.0f, 0.0f, 0.0f);
|
||||
lock (_characters)
|
||||
{
|
||||
foreach (OdeCharacter chr in _characters)
|
||||
{
|
||||
if (chr.Shell != IntPtr.Zero)
|
||||
{
|
||||
IntPtr body = d.GeomGetBody(chr.Shell);
|
||||
|
||||
d.Vector3 pos;
|
||||
d.GeomCopyPosition(chr.Shell, out pos);
|
||||
//d.BodyCopyPosition(body, out pos);
|
||||
|
||||
d.Matrix3 R;
|
||||
d.GeomCopyRotation(chr.Shell, out R);
|
||||
//d.BodyCopyRotation(body, out R);
|
||||
|
||||
ds.DrawCapsule(ref pos, ref R, chr.Size.Z, 0.35f);
|
||||
d.Vector3 sides = new d.Vector3();
|
||||
sides.X = 0.5f;
|
||||
sides.Y = 0.5f;
|
||||
sides.Z = 0.5f;
|
||||
|
||||
ds.DrawBox(ref pos, ref R, ref sides);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void start(int unused)
|
||||
{
|
||||
ds.SetViewpoint(ref xyz, ref hpr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright ODE
|
||||
* Ode.NET - .NET bindings for ODE
|
||||
* Jason Perkins (starkos@industriousone.com)
|
||||
* Licensed under the New BSD
|
||||
* Part of the OpenDynamicsEngine
|
||||
Open Dynamics Engine
|
||||
Copyright (c) 2001-2007, Russell L. Smith.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
Neither the names of ODE's copyright owner nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using OdeAPI;
|
||||
|
||||
namespace ODEDrawstuff
|
||||
{
|
||||
/*#if dDOUBLE
|
||||
using dReal = System.Double;
|
||||
#else
|
||||
*/
|
||||
using dReal = System.Single;
|
||||
//#endif
|
||||
|
||||
public static class ds
|
||||
{
|
||||
public const int VERSION = 2;
|
||||
|
||||
public enum Texture
|
||||
{
|
||||
None,
|
||||
Wood
|
||||
}
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void CallbackFunction(int arg);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Functions
|
||||
{
|
||||
public int version;
|
||||
public CallbackFunction start;
|
||||
public CallbackFunction step;
|
||||
public CallbackFunction command;
|
||||
public CallbackFunction stop;
|
||||
public string path_to_textures;
|
||||
}
|
||||
|
||||
[DllImport("drawstuff", EntryPoint = "dsDrawBox")]
|
||||
public static extern void DrawBox(ref d.Vector3 pos, ref d.Matrix3 R, ref d.Vector3 sides);
|
||||
|
||||
[DllImport("drawstuff", EntryPoint = "dsDrawCapsule")]
|
||||
public static extern void DrawCapsule(ref d.Vector3 pos, ref d.Matrix3 R, dReal length, dReal radius);
|
||||
|
||||
[DllImport("drawstuff", EntryPoint = "dsDrawConvex")]
|
||||
public static extern void DrawConvex(ref d.Vector3 pos, ref d.Matrix3 R, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons);
|
||||
|
||||
[DllImport("drawstuff", EntryPoint = "dsSetColor")]
|
||||
public static extern void SetColor(float red, float green, float blue);
|
||||
|
||||
[DllImport("drawstuff", EntryPoint = "dsSetTexture")]
|
||||
public static extern void SetTexture(Texture texture);
|
||||
|
||||
[DllImport("drawstuff", EntryPoint = "dsSetViewpoint")]
|
||||
public static extern void SetViewpoint(ref d.Vector3 xyz, ref d.Vector3 hpr);
|
||||
|
||||
[DllImport("drawstuff", EntryPoint = "dsSimulationLoop")]
|
||||
public static extern void SimulationLoop(int argc, string[] argv, int window_width, int window_height, ref Functions fn);
|
||||
}
|
||||
}
|
||||
@@ -2177,6 +2177,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
return real_vec;
|
||||
}
|
||||
|
||||
public LSL_Integer llSetRegionPos(LSL_Vector pos)
|
||||
{
|
||||
return new LSL_Integer(SetRegionPos(m_host, pos));
|
||||
}
|
||||
|
||||
protected int SetRegionPos(SceneObjectPart part, LSL_Vector targetPos)
|
||||
{
|
||||
if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
|
||||
return 0;
|
||||
|
||||
SceneObjectGroup grp = part.ParentGroup;
|
||||
|
||||
if (grp.IsAttachment)
|
||||
return 0;
|
||||
|
||||
if (grp.RootPart.PhysActor != null && grp.RootPart.PhysActor.IsPhysical)
|
||||
return 0;
|
||||
|
||||
if (targetPos.x < -10.0f || targetPos.x >= (float)Constants.RegionSize || targetPos.y < -10.0f || targetPos.y >= (float)Constants.RegionSize || targetPos.z < 0 || targetPos.z >= 4096.0f)
|
||||
return 0;
|
||||
|
||||
float constrainedX = (float)targetPos.x;
|
||||
float constrainedY = (float)targetPos.y;
|
||||
|
||||
if (constrainedX < 0.0f)
|
||||
constrainedX = 0.0f;
|
||||
if (constrainedY < 0.0f)
|
||||
constrainedY = 0.0f;
|
||||
if (constrainedX >= (float)Constants.RegionSize)
|
||||
constrainedX = (float)Constants.RegionSize - 0.1f;
|
||||
if (constrainedY >= (float)Constants.RegionSize)
|
||||
constrainedY = (float)Constants.RegionSize -0.1f;
|
||||
|
||||
float ground = World.GetGroundHeight(constrainedX, constrainedY);
|
||||
|
||||
if (targetPos.z < ground)
|
||||
targetPos.z = ground;
|
||||
|
||||
Vector3 dest = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z);
|
||||
|
||||
if (!World.Permissions.CanObjectEntry(grp.UUID, false, dest))
|
||||
return 0;
|
||||
|
||||
grp.UpdateGroupPosition(dest);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
|
||||
{
|
||||
if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
|
||||
@@ -2185,10 +2233,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
LSL_Vector currentPos = GetPartLocalPos(part);
|
||||
LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
|
||||
|
||||
|
||||
if (part.ParentGroup.RootPart == part)
|
||||
{
|
||||
SceneObjectGroup parent = part.ParentGroup;
|
||||
parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z));
|
||||
Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
|
||||
if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
|
||||
return;
|
||||
Util.FireAndForget(delegate(object x) {
|
||||
parent.UpdateGroupPosition(dest);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4184,7 +4238,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
// Single prim
|
||||
if (m_host.LinkNum == 0)
|
||||
{
|
||||
if (linknum == 0)
|
||||
if (linknum == 0 || linknum == ScriptBaseClass.LINK_ROOT)
|
||||
return m_host.Name;
|
||||
else
|
||||
return UUID.Zero.ToString();
|
||||
@@ -5707,7 +5761,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
public LSL_Integer llGetRegionAgentCount()
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
return new LSL_Integer(World.GetRootAgentCount());
|
||||
|
||||
int count = 0;
|
||||
World.ForEachRootScenePresence(delegate(ScenePresence sp) {
|
||||
count++;
|
||||
});
|
||||
|
||||
return new LSL_Integer(count);
|
||||
}
|
||||
|
||||
public LSL_Vector llGetRegionCorner()
|
||||
@@ -7540,27 +7600,59 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
|
||||
int remain = rules.Length - idx;
|
||||
|
||||
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case (int)ScriptBaseClass.PRIM_POSITION:
|
||||
if (remain < 1)
|
||||
return;
|
||||
LSL_Vector v;
|
||||
v = rules.GetVector3Item(idx++);
|
||||
av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
|
||||
av.SendAvatarDataToAllAgents();
|
||||
{
|
||||
if (remain < 1)
|
||||
return;
|
||||
LSL_Vector v;
|
||||
v = rules.GetVector3Item(idx++);
|
||||
|
||||
SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
|
||||
if (part == null)
|
||||
break;
|
||||
|
||||
LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
|
||||
LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
|
||||
if (llGetLinkNumber() > 1)
|
||||
{
|
||||
localRot = llGetLocalRot();
|
||||
localPos = llGetLocalPos();
|
||||
}
|
||||
|
||||
v -= localPos;
|
||||
v /= localRot;
|
||||
|
||||
LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
|
||||
|
||||
v = v + 2 * sitOffset;
|
||||
|
||||
av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
|
||||
av.SendAvatarDataToAllAgents();
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case (int)ScriptBaseClass.PRIM_ROTATION:
|
||||
if (remain < 1)
|
||||
return;
|
||||
LSL_Rotation r;
|
||||
r = rules.GetQuaternionItem(idx++);
|
||||
av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
|
||||
av.SendAvatarDataToAllAgents();
|
||||
{
|
||||
if (remain < 1)
|
||||
return;
|
||||
|
||||
LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
|
||||
LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
|
||||
if (llGetLinkNumber() > 1)
|
||||
{
|
||||
localRot = llGetLocalRot();
|
||||
localPos = llGetLocalPos();
|
||||
}
|
||||
|
||||
LSL_Rotation r;
|
||||
r = rules.GetQuaternionItem(idx++);
|
||||
r = r * llGetRootRotation() / localRot;
|
||||
av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
|
||||
av.SendAvatarDataToAllAgents();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -7973,7 +8065,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
if (part.ParentGroup.RootPart == part)
|
||||
{
|
||||
SceneObjectGroup parent = part.ParentGroup;
|
||||
parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
|
||||
Util.FireAndForget(delegate(object x) {
|
||||
parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -7990,7 +8084,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
if (part.ParentGroup.RootPart == part)
|
||||
{
|
||||
SceneObjectGroup parent = part.ParentGroup;
|
||||
parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
|
||||
Util.FireAndForget(delegate(object x) {
|
||||
parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -2254,7 +2254,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
firstname, lastname, position, notecard,
|
||||
(options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
|
||||
false);
|
||||
// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) == 0);
|
||||
// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
|
||||
}
|
||||
|
||||
private LSL_Key NpcCreate(
|
||||
@@ -2634,7 +2634,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||
UUID npcID = new UUID(npc.m_string);
|
||||
|
||||
if (module.CheckPermissions(npcID, m_host.OwnerID))
|
||||
AvatarPlayAnimation(npcID.ToString(), animation);
|
||||
AvatarStopAnimation(npcID.ToString(), animation);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ using System.Collections.Generic;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using log4net;
|
||||
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.ScriptEngine.Shared;
|
||||
@@ -41,6 +40,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
|
||||
{
|
||||
public class SensorRepeat
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public AsyncCommandManager m_CmdManager;
|
||||
|
||||
public SensorRepeat(AsyncCommandManager CmdManager)
|
||||
@@ -450,17 +451,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
|
||||
Vector3 toRegionPos;
|
||||
double dis;
|
||||
|
||||
Action<ScenePresence> senseEntity = new Action<ScenePresence>(delegate(ScenePresence presence)
|
||||
Action<ScenePresence> senseEntity = new Action<ScenePresence>(presence =>
|
||||
{
|
||||
if ((ts.type & NPC) == 0
|
||||
&& presence.PresenceType == PresenceType.Npc
|
||||
&& !npcModule.GetNPC(presence.UUID, presence.Scene).SenseAsAgent)
|
||||
return;
|
||||
// m_log.DebugFormat(
|
||||
// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
|
||||
// presence.Name, presence.PresenceType, ts.name, ts.type);
|
||||
|
||||
if ((ts.type & AGENT) == 0
|
||||
&& (presence.PresenceType == PresenceType.User
|
||||
|| npcModule.GetNPC(presence.UUID, presence.Scene).SenseAsAgent))
|
||||
return;
|
||||
if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
|
||||
{
|
||||
INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene);
|
||||
if (npcData == null || !npcData.SenseAsAgent)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[SENSOR REPEAT]: Discarding NPC {0} from agent sense sweep for script item id {1}",
|
||||
// presence.Name, ts.itemID);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ts.type & AGENT) == 0)
|
||||
{
|
||||
if (presence.PresenceType == PresenceType.User)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene);
|
||||
if (npcData != null && npcData.SenseAsAgent)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[SENSOR REPEAT]: Discarding NPC {0} from non-agent sense sweep for script item id {1}",
|
||||
// presence.Name, ts.itemID);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0)
|
||||
return;
|
||||
|
||||
@@ -346,6 +346,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
||||
void llSetParcelMusicURL(string url);
|
||||
void llSetPayPrice(int price, LSL_List quick_pay_buttons);
|
||||
void llSetPos(LSL_Vector pos);
|
||||
LSL_Integer llSetRegionPos(LSL_Vector pos);
|
||||
LSL_Integer llSetPrimMediaParams(int face, LSL_List rules);
|
||||
void llSetPrimitiveParams(LSL_List rules);
|
||||
void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
|
||||
|
||||
@@ -1580,6 +1580,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||
m_LSL_Functions.llSetPos(pos);
|
||||
}
|
||||
|
||||
public LSL_Integer llSetRegionPos(LSL_Vector pos)
|
||||
{
|
||||
return m_LSL_Functions.llSetRegionPos(pos);
|
||||
}
|
||||
|
||||
public void llSetPrimitiveParams(LSL_List rules)
|
||||
{
|
||||
m_LSL_Functions.llSetPrimitiveParams(rules);
|
||||
|
||||
@@ -538,6 +538,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||
|
||||
public bool Stop(int timeout)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[SCRIPT INSTANCE]: Stopping script {0} {1} with timeout {2}", ScriptName, ItemID, timeout);
|
||||
|
||||
IScriptWorkItem result;
|
||||
|
||||
lock (m_EventQueue)
|
||||
@@ -772,7 +775,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// m_log.DebugFormat("[SCRIPT] Exception: {0}", e.Message);
|
||||
// m_log.DebugFormat(
|
||||
// "[SCRIPT] Exception in script {0} {1}: {2}{3}",
|
||||
// ScriptName, ItemID, e.Message, e.StackTrace);
|
||||
|
||||
m_InEvent = false;
|
||||
m_CurrentEvent = String.Empty;
|
||||
|
||||
|
||||
@@ -301,7 +301,7 @@ namespace OpenSim.Region.UserStatistics
|
||||
|
||||
public void OnRegisterCaps(UUID agentID, Caps caps)
|
||||
{
|
||||
m_log.DebugFormat("[VC]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps);
|
||||
m_log.DebugFormat("[WEB STATS MODULE]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps);
|
||||
string capsPath = "/CAPS/VS/" + UUID.Random();
|
||||
caps.RegisterHandler("ViewerStats",
|
||||
new RestStreamHandler("POST", capsPath,
|
||||
@@ -462,7 +462,7 @@ namespace OpenSim.Region.UserStatistics
|
||||
|
||||
if (!m_sessions.ContainsKey(agentID))
|
||||
{
|
||||
m_log.Warn("[VS]: no session for stat disclosure");
|
||||
m_log.Warn("[WEB STATS MODULE]: no session for stat disclosure");
|
||||
return new UserSessionID();
|
||||
}
|
||||
uid = m_sessions[agentID];
|
||||
@@ -667,14 +667,13 @@ namespace OpenSim.Region.UserStatistics
|
||||
{
|
||||
updatecmd.ExecuteNonQuery();
|
||||
}
|
||||
catch
|
||||
(SqliteExecutionException)
|
||||
catch (SqliteExecutionException)
|
||||
{
|
||||
m_log.Warn("[WEBSTATS]: failed to write stats to storage Execution Exception");
|
||||
m_log.Warn("[WEB STATS MODULE]: failed to write stats to storage Execution Exception");
|
||||
}
|
||||
catch (SqliteSyntaxException)
|
||||
{
|
||||
m_log.Warn("[WEBSTATS]: failed to write stats to storage SQL Syntax Exception");
|
||||
m_log.Warn("[WEB STATS MODULE]: failed to write stats to storage SQL Syntax Exception");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -136,6 +136,8 @@ namespace OpenSim.Server.Handlers.Simulation
|
||||
int x = 0, y = 0;
|
||||
UUID uuid = UUID.Zero;
|
||||
string regionname = string.Empty;
|
||||
Vector3 newPosition = Vector3.Zero;
|
||||
|
||||
if (args.ContainsKey("destination_x") && args["destination_x"] != null)
|
||||
Int32.TryParse(args["destination_x"].AsString(), out x);
|
||||
if (args.ContainsKey("destination_y") && args["destination_y"] != null)
|
||||
@@ -144,6 +146,8 @@ namespace OpenSim.Server.Handlers.Simulation
|
||||
UUID.TryParse(args["destination_uuid"].AsString(), out uuid);
|
||||
if (args.ContainsKey("destination_name") && args["destination_name"] != null)
|
||||
regionname = args["destination_name"].ToString();
|
||||
if (args.ContainsKey("new_position") && args["new_position"] != null)
|
||||
Vector3.TryParse(args["new_position"], out newPosition);
|
||||
|
||||
GridRegion destination = new GridRegion();
|
||||
destination.RegionID = uuid;
|
||||
@@ -199,7 +203,7 @@ namespace OpenSim.Server.Handlers.Simulation
|
||||
try
|
||||
{
|
||||
// This is the meaning of POST object
|
||||
result = CreateObject(destination, sog);
|
||||
result = CreateObject(destination, newPosition, sog);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -211,9 +215,9 @@ namespace OpenSim.Server.Handlers.Simulation
|
||||
}
|
||||
|
||||
// subclasses can override this
|
||||
protected virtual bool CreateObject(GridRegion destination, ISceneObject sog)
|
||||
protected virtual bool CreateObject(GridRegion destination, Vector3 newPosition, ISceneObject sog)
|
||||
{
|
||||
return m_SimulationService.CreateObject(destination, sog, false);
|
||||
return m_SimulationService.CreateObject(destination, newPosition, sog, false);
|
||||
}
|
||||
|
||||
protected virtual void DoObjectPut(Hashtable request, Hashtable responsedata, UUID regionID)
|
||||
|
||||
@@ -220,7 +220,7 @@ namespace OpenSim.Services.Connectors.Friends
|
||||
public bool Delete(Dictionary<string, object> sendData, string PrincipalID, string Friend)
|
||||
{
|
||||
string reply = string.Empty;
|
||||
string uri = m_ServerURI = "/friends";
|
||||
string uri = m_ServerURI + "/friends";
|
||||
try
|
||||
{
|
||||
reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, ServerUtils.BuildQueryString(sendData));
|
||||
|
||||
@@ -153,6 +153,7 @@ namespace OpenSim.Services.Connectors.Simulation
|
||||
return UpdateAgent(destination, (IAgentData)data, 200000); // yes, 200 seconds
|
||||
}
|
||||
|
||||
private ExpiringCache<string, bool> _failedSims = new ExpiringCache<string, bool>();
|
||||
/// <summary>
|
||||
/// Send updated position information about an agent in this region to a neighbor
|
||||
/// This operation may be called very frequently if an avatar is moving about in
|
||||
@@ -160,6 +161,10 @@ namespace OpenSim.Services.Connectors.Simulation
|
||||
/// </summary>
|
||||
public bool UpdateAgent(GridRegion destination, AgentPosition data)
|
||||
{
|
||||
bool v = true;
|
||||
if (_failedSims.TryGetValue(destination.ServerURI, out v))
|
||||
return false;
|
||||
|
||||
// The basic idea of this code is that the first thread that needs to
|
||||
// send an update for a specific avatar becomes the worker for any subsequent
|
||||
// requests until there are no more outstanding requests. Further, only send the most
|
||||
@@ -183,9 +188,10 @@ namespace OpenSim.Services.Connectors.Simulation
|
||||
// Otherwise update the reference and start processing
|
||||
m_updateAgentQueue[uri] = data;
|
||||
}
|
||||
|
||||
|
||||
AgentPosition pos = null;
|
||||
while (true)
|
||||
bool success = true;
|
||||
while (success)
|
||||
{
|
||||
lock (m_updateAgentQueue)
|
||||
{
|
||||
@@ -205,11 +211,16 @@ namespace OpenSim.Services.Connectors.Simulation
|
||||
}
|
||||
}
|
||||
|
||||
UpdateAgent(destination, (IAgentData)pos, 10000);
|
||||
success = UpdateAgent(destination, (IAgentData)pos, 10000);
|
||||
}
|
||||
|
||||
// unreachable
|
||||
// return true;
|
||||
// we get here iff success == false
|
||||
// blacklist sim for 2 minutes
|
||||
lock (m_updateAgentQueue)
|
||||
{
|
||||
_failedSims.AddOrUpdate(destination.ServerURI, true, 120);
|
||||
m_updateAgentQueue.Remove(uri);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -409,7 +420,7 @@ namespace OpenSim.Services.Connectors.Simulation
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public bool CreateObject(GridRegion destination, ISceneObject sog, bool isLocalCall)
|
||||
public bool CreateObject(GridRegion destination, Vector3 newPosition, ISceneObject sog, bool isLocalCall)
|
||||
{
|
||||
// m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: CreateObject start");
|
||||
|
||||
@@ -422,6 +433,7 @@ namespace OpenSim.Services.Connectors.Simulation
|
||||
args["sog"] = OSD.FromString(sog.ToXml2());
|
||||
args["extra"] = OSD.FromString(sog.ExtraToXmlString());
|
||||
args["modified"] = OSD.FromBoolean(sog.HasGroupChanged);
|
||||
args["new_position"] = newPosition.ToString();
|
||||
|
||||
string state = sog.GetStateSnapshot();
|
||||
if (state.Length > 0)
|
||||
@@ -433,11 +445,14 @@ namespace OpenSim.Services.Connectors.Simulation
|
||||
args["destination_name"] = OSD.FromString(destination.RegionName);
|
||||
args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
|
||||
|
||||
WebUtil.PostToService(uri, args, 40000);
|
||||
OSDMap response = WebUtil.PostToService(uri, args, 40000);
|
||||
if (response["Success"] == "False")
|
||||
return false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.WarnFormat("[REMOTE SIMULATION CONNECTOR] CreateObject failed with exception; {0}",e.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -188,9 +188,9 @@ namespace OpenSim.Services.HypergridService
|
||||
string authURL = string.Empty;
|
||||
if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
|
||||
authURL = aCircuit.ServiceURLs["HomeURI"].ToString();
|
||||
m_log.InfoFormat("[GATEKEEPER SERVICE]: Login request for {0} {1} @ {2} ({3}) at {4} using viewer {5}, channel {6}, IP {7}, Mac {8}, Id0 {9}",
|
||||
m_log.InfoFormat("[GATEKEEPER SERVICE]: Login request for {0} {1} @ {2} ({3}) at {4} using viewer {5}, channel {6}, IP {7}, Mac {8}, Id0 {9} Teleport Flags {10}",
|
||||
aCircuit.firstname, aCircuit.lastname, authURL, aCircuit.AgentID, destination.RegionName,
|
||||
aCircuit.Viewer, aCircuit.Channel, aCircuit.IPAddress, aCircuit.Mac, aCircuit.Id0);
|
||||
aCircuit.Viewer, aCircuit.Channel, aCircuit.IPAddress, aCircuit.Mac, aCircuit.Id0, aCircuit.teleportFlags.ToString());
|
||||
|
||||
//
|
||||
// Check client
|
||||
@@ -315,6 +315,10 @@ namespace OpenSim.Services.HypergridService
|
||||
// Finally launch the agent at the destination
|
||||
//
|
||||
Constants.TeleportFlags loginFlag = isFirstLogin ? Constants.TeleportFlags.ViaLogin : Constants.TeleportFlags.ViaHGLogin;
|
||||
|
||||
// Preserve our TeleportFlags we have gathered so-far
|
||||
loginFlag |= (Constants.TeleportFlags) aCircuit.teleportFlags;
|
||||
|
||||
m_log.DebugFormat("[GATEKEEPER SERVICE]: launching agent {0}", loginFlag);
|
||||
return m_SimulationService.CreateAgent(destination, aCircuit, (uint)loginFlag, out reason);
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace OpenSim.Services.Interfaces
|
||||
/// <param name="sog"></param>
|
||||
/// <param name="isLocalCall"></param>
|
||||
/// <returns></returns>
|
||||
bool CreateObject(GridRegion destination, ISceneObject sog, bool isLocalCall);
|
||||
bool CreateObject(GridRegion destination, Vector3 newPosition, ISceneObject sog, bool isLocalCall);
|
||||
|
||||
/// <summary>
|
||||
/// Create an object from the user's inventory in the destination region.
|
||||
|
||||
@@ -472,6 +472,7 @@ namespace OpenSim.Services.LLLoginService
|
||||
|
||||
position = pinfo.HomePosition;
|
||||
lookAt = pinfo.HomeLookAt;
|
||||
flags |= TeleportFlags.ViaHome;
|
||||
}
|
||||
|
||||
if (tryDefaults)
|
||||
@@ -760,6 +761,7 @@ namespace OpenSim.Services.LLLoginService
|
||||
{
|
||||
circuitCode = (uint)Util.RandomClass.Next(); ;
|
||||
aCircuit = MakeAgent(destination, account, avatar, session, secureSession, circuitCode, position, clientIP.Address.ToString(), viewer, channel, mac, id0);
|
||||
aCircuit.teleportFlags |= (uint)flags;
|
||||
success = LaunchAgentIndirectly(gatekeeper, destination, aCircuit, clientIP, out reason);
|
||||
if (!success && m_GridService != null)
|
||||
{
|
||||
|
||||
@@ -50,7 +50,8 @@ namespace OpenSim.Tests.Common.Mock
|
||||
|
||||
~TestScene()
|
||||
{
|
||||
Console.WriteLine("TestScene destructor called for {0}", RegionInfo.RegionName);
|
||||
//Console.WriteLine("TestScene destructor called for {0}", RegionInfo.RegionName);
|
||||
Console.WriteLine("TestScene destructor called");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using NUnit.Framework;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications;
|
||||
using OpenSim.Region.CoreModules.Avatar.Attachments;
|
||||
using OpenSim.Region.CoreModules.Avatar.AvatarFactory;
|
||||
using OpenSim.Region.CoreModules.Framework.InventoryAccess;
|
||||
using OpenSim.Region.CoreModules.Framework.UserManagement;
|
||||
using OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.OptionalModules.World.NPC;
|
||||
using OpenSim.Services.AvatarService;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
|
||||
namespace OpenSim.Tests.Torture
|
||||
{
|
||||
/// <summary>
|
||||
/// NPC torture tests
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Don't rely on the numbers given by these tests - they will vary a lot depending on what is already cached,
|
||||
/// how much memory is free, etc. In some cases, later larger tests will apparently take less time than smaller
|
||||
/// earlier tests.
|
||||
/// </remarks>
|
||||
[TestFixture]
|
||||
public class NPCTortureTests
|
||||
{
|
||||
private TestScene scene;
|
||||
private AvatarFactoryModule afm;
|
||||
private UserManagementModule umm;
|
||||
private AttachmentsModule am;
|
||||
|
||||
[TestFixtureSetUp]
|
||||
public void FixtureInit()
|
||||
{
|
||||
// Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
|
||||
Util.FireAndForgetMethod = FireAndForgetMethod.None;
|
||||
}
|
||||
|
||||
[TestFixtureTearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
// We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
|
||||
// threads. Possibly, later tests should be rewritten not to worry about such things.
|
||||
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void Init()
|
||||
{
|
||||
IConfigSource config = new IniConfigSource();
|
||||
config.AddConfig("NPC");
|
||||
config.Configs["NPC"].Set("Enabled", "true");
|
||||
config.AddConfig("Modules");
|
||||
config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
|
||||
|
||||
afm = new AvatarFactoryModule();
|
||||
umm = new UserManagementModule();
|
||||
am = new AttachmentsModule();
|
||||
|
||||
scene = SceneHelpers.SetupScene();
|
||||
SceneHelpers.SetupSceneModules(scene, config, afm, umm, am, new BasicInventoryAccessModule(), new NPCModule());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddRemove100NPCs()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
TestAddRemoveNPCs(100);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddRemove1000NPCs()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
TestAddRemoveNPCs(1000);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddRemove2000NPCs()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
TestAddRemoveNPCs(2000);
|
||||
}
|
||||
|
||||
private void TestAddRemoveNPCs(int numberOfNpcs)
|
||||
{
|
||||
ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
|
||||
// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
|
||||
|
||||
// 8 is the index of the first baked texture in AvatarAppearance
|
||||
UUID originalFace8TextureId = TestHelpers.ParseTail(0x10);
|
||||
Primitive.TextureEntry originalTe = new Primitive.TextureEntry(UUID.Zero);
|
||||
Primitive.TextureEntryFace originalTef = originalTe.CreateFace(8);
|
||||
originalTef.TextureID = originalFace8TextureId;
|
||||
|
||||
// We also need to add the texture to the asset service, otherwise the AvatarFactoryModule will tell
|
||||
// ScenePresence.SendInitialData() to reset our entire appearance.
|
||||
scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId));
|
||||
|
||||
afm.SetAppearance(sp, originalTe, null);
|
||||
|
||||
INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
|
||||
|
||||
List<UUID> npcs = new List<UUID>();
|
||||
|
||||
long startGcMemory = GC.GetTotalMemory(true);
|
||||
Stopwatch sw = new Stopwatch();
|
||||
sw.Start();
|
||||
|
||||
for (int i = 0; i < numberOfNpcs; i++)
|
||||
{
|
||||
npcs.Add(
|
||||
npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, scene, sp.Appearance));
|
||||
}
|
||||
|
||||
for (int i = 0; i < numberOfNpcs; i++)
|
||||
{
|
||||
Assert.That(npcs[i], Is.Not.Null);
|
||||
|
||||
ScenePresence npc = scene.GetScenePresence(npcs[i]);
|
||||
Assert.That(npc, Is.Not.Null);
|
||||
}
|
||||
|
||||
for (int i = 0; i < numberOfNpcs; i++)
|
||||
{
|
||||
Assert.That(npcModule.DeleteNPC(npcs[i], scene), Is.True);
|
||||
ScenePresence npc = scene.GetScenePresence(npcs[i]);
|
||||
Assert.That(npc, Is.Null);
|
||||
}
|
||||
|
||||
sw.Stop();
|
||||
|
||||
long endGcMemory = GC.GetTotalMemory(true);
|
||||
|
||||
Console.WriteLine("Took {0} ms", sw.ElapsedMilliseconds);
|
||||
Console.WriteLine(
|
||||
"End {0} MB, Start {1} MB, Diff {2} MB",
|
||||
endGcMemory / 1024 / 1024,
|
||||
startGcMemory / 1024 / 1024,
|
||||
(endGcMemory - startGcMemory) / 1024 / 1024);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,13 @@ namespace OpenSim.Tests.Torture
|
||||
[TestFixture]
|
||||
public class ObjectTortureTests
|
||||
{
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
}
|
||||
|
||||
// [Test]
|
||||
// public void Test0000Clean()
|
||||
// {
|
||||
@@ -141,8 +148,18 @@ namespace OpenSim.Tests.Torture
|
||||
string.Format("Object {0} could not be retrieved", i));
|
||||
}
|
||||
|
||||
// This does not work to fire the SceneObjectGroup destructors - something else is hanging on to them.
|
||||
// scene.DeleteAllSceneObjects();
|
||||
// When a scene object is added to a scene, it is placed in the update list for sending to viewers
|
||||
// (though in this case we have none). When it is deleted, it is not removed from the update which is
|
||||
// fine since it will later be ignored.
|
||||
//
|
||||
// However, that means that we need to manually run an update here to clear out that list so that deleted
|
||||
// objects will be clean up by the garbage collector before the next stress test is run.
|
||||
scene.Update();
|
||||
|
||||
// Currently, we need to do this in order to garbage collect the scene objects ready for the next test run.
|
||||
// However, what we really need to do is find out why the entire scene is not garbage collected in
|
||||
// teardown.
|
||||
scene.DeleteAllSceneObjects();
|
||||
|
||||
Console.WriteLine(
|
||||
"Took {0}ms, {1}MB ({2} - {3}) to create {4} objects each containing {5} prim(s)",
|
||||
|
||||
@@ -484,7 +484,6 @@
|
||||
;; such as the Meta7 viewer.
|
||||
;; It has no ill effect on viewers which do not support server-side
|
||||
;; windlight settings.
|
||||
;; Currently we only have support for MySQL databases.
|
||||
; enable_windlight = false
|
||||
|
||||
|
||||
@@ -573,10 +572,15 @@
|
||||
; DeleteScriptsOnStartup = true
|
||||
|
||||
;; Set this to true (the default) to load each script into a separate
|
||||
;; AppDomain. Setting this to false will load all script assemblies into the
|
||||
;; current AppDomain, which will reduce the per-script overhead at the
|
||||
;; expense of reduced security and the inability to garbage collect the
|
||||
;; script assemblies
|
||||
;; AppDomain.
|
||||
;;
|
||||
;; Setting this to false will load all script assemblies into the
|
||||
;; current AppDomain, which will significantly improve script loading times.
|
||||
;; It will also reduce initial per-script memory overhead.
|
||||
;;
|
||||
;; However, setting this to false will also prevent script DLLs from being unloaded from memory if the script is deleted.
|
||||
;; This may cause an OutOfMemory problem over time when avatars with scripted attachments move in and out of the region.
|
||||
;; Some Windows users have also reported script loading problems when AppDomainLoading = false
|
||||
; AppDomainLoading = true
|
||||
|
||||
;# {DefaultCompileLanguage} {Enabled:true} {Default script language?} {lsl vb cs} lsl
|
||||
|
||||
@@ -655,6 +655,11 @@
|
||||
world_gravityy = 0
|
||||
world_gravityz = -9.8
|
||||
|
||||
; Terminal velocity of a falling avatar
|
||||
; This is the same http://en.wikipedia.org/wiki/Terminal_velocity#Examples
|
||||
; Max value is 255, min value is 0
|
||||
avatar_terminal_velocity = 54
|
||||
|
||||
; World Step size. (warning these are dangerous. Changing these will probably cause your scene to explode dramatically)
|
||||
; reference: fps = (0.089/ODE_STEPSIZE) * 1000;
|
||||
world_stepsize = 0.0178
|
||||
@@ -1065,7 +1070,6 @@
|
||||
[LightShare]
|
||||
; This enables the transmission of Windlight scenes to supporting clients, such as the Meta7 viewer.
|
||||
; It has no ill effect on viewers which do not support server-side windlight settings.
|
||||
; Currently we only have support for MySQL databases.
|
||||
enable_windlight = false
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user