Merge branch 'ubitwork' of ssh://3dhosting.de/var/git/careminster into ubitwork
commit
d09fa0d76e
|
@ -91,6 +91,7 @@ what it is today.
|
||||||
* Fly-Man
|
* Fly-Man
|
||||||
* Flyte Xevious
|
* Flyte Xevious
|
||||||
* Garmin Kawaguichi
|
* Garmin Kawaguichi
|
||||||
|
* Gryc Ueusp
|
||||||
* Imaze Rhiano
|
* Imaze Rhiano
|
||||||
* Intimidated
|
* Intimidated
|
||||||
* Jeremy Bongio (IBM)
|
* Jeremy Bongio (IBM)
|
||||||
|
|
|
@ -2207,5 +2207,18 @@ VALUES
|
||||||
{
|
{
|
||||||
return new UUID[0];
|
return new UUID[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SaveExtra(UUID regionID, string name, string value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveExtra(UUID regionID, string name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, string> GetExtra(UUID regionID)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2094,5 +2094,74 @@ namespace OpenSim.Data.MySQL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SaveExtra(UUID regionID, string name, string val)
|
||||||
|
{
|
||||||
|
lock (m_dbLock)
|
||||||
|
{
|
||||||
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
|
{
|
||||||
|
dbcon.Open();
|
||||||
|
|
||||||
|
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||||
|
{
|
||||||
|
cmd.CommandText = "replace into regionextra values (?RegionID, ?Name, ?value)";
|
||||||
|
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||||
|
cmd.Parameters.AddWithValue("?Name", name);
|
||||||
|
cmd.Parameters.AddWithValue("?value", val);
|
||||||
|
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveExtra(UUID regionID, string name)
|
||||||
|
{
|
||||||
|
lock (m_dbLock)
|
||||||
|
{
|
||||||
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
|
{
|
||||||
|
dbcon.Open();
|
||||||
|
|
||||||
|
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||||
|
{
|
||||||
|
cmd.CommandText = "delete from regionextra where RegionID=?RegionID and Name=?Name";
|
||||||
|
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||||
|
cmd.Parameters.AddWithValue("?Name", name);
|
||||||
|
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, string> GetExtra(UUID regionID)
|
||||||
|
{
|
||||||
|
Dictionary<string, string> ret = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
lock (m_dbLock)
|
||||||
|
{
|
||||||
|
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||||
|
{
|
||||||
|
dbcon.Open();
|
||||||
|
|
||||||
|
using (MySqlCommand cmd = dbcon.CreateCommand())
|
||||||
|
{
|
||||||
|
cmd.CommandText = "select * from regionextra where RegionID=?RegionID";
|
||||||
|
cmd.Parameters.AddWithValue("?RegionID", regionID.ToString());
|
||||||
|
using (IDataReader r = cmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (r.Read())
|
||||||
|
{
|
||||||
|
ret[r["Name"].ToString()] = r["value"].ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -895,3 +895,10 @@ CREATE TABLE `regionenvironment` (
|
||||||
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
|
:VERSION 45
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
CREATE TABLE `regionextra` (`RegionID` char(36) not null, `Name` varchar(32) not null, `value` text, primary key(`RegionID`, `Name`));
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
|
@ -156,5 +156,18 @@ namespace OpenSim.Data.Null
|
||||||
{
|
{
|
||||||
return new UUID[0];
|
return new UUID[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SaveExtra(UUID regionID, string name, string value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveExtra(UUID regionID, string name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, string> GetExtra(UUID regionID)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2894,5 +2894,18 @@ namespace OpenSim.Data.SQLite
|
||||||
{
|
{
|
||||||
return new UUID[0];
|
return new UUID[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SaveExtra(UUID regionID, string name, string value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveExtra(UUID regionID, string name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, string> GetExtra(UUID regionID)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -678,6 +678,8 @@ namespace OpenSim.Framework.Console
|
||||||
{
|
{
|
||||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
public event OnOutputDelegate OnOutput;
|
||||||
|
|
||||||
public ICommands Commands { get; private set; }
|
public ICommands Commands { get; private set; }
|
||||||
|
|
||||||
public CommandConsole(string defaultPrompt) : base(defaultPrompt)
|
public CommandConsole(string defaultPrompt) : base(defaultPrompt)
|
||||||
|
@ -697,6 +699,13 @@ namespace OpenSim.Framework.Console
|
||||||
Output(s);
|
Output(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void FireOnOutput(string text)
|
||||||
|
{
|
||||||
|
OnOutputDelegate onOutput = OnOutput;
|
||||||
|
if (onOutput != null)
|
||||||
|
onOutput(text);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Display a command prompt on the console and wait for user input
|
/// Display a command prompt on the console and wait for user input
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -319,6 +319,8 @@ namespace OpenSim.Framework.Console
|
||||||
|
|
||||||
public override void Output(string text, string level)
|
public override void Output(string text, string level)
|
||||||
{
|
{
|
||||||
|
FireOnOutput(text);
|
||||||
|
|
||||||
lock (m_commandLine)
|
lock (m_commandLine)
|
||||||
{
|
{
|
||||||
if (m_cursorYPosition == -1)
|
if (m_cursorYPosition == -1)
|
||||||
|
@ -509,4 +511,4 @@ namespace OpenSim.Framework.Console
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,8 @@ namespace OpenSim.Framework.Console
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MockConsole : ICommandConsole
|
public class MockConsole : ICommandConsole
|
||||||
{
|
{
|
||||||
|
public event OnOutputDelegate OnOutput;
|
||||||
|
|
||||||
private MockCommands m_commands = new MockCommands();
|
private MockCommands m_commands = new MockCommands();
|
||||||
|
|
||||||
public ICommands Commands { get { return m_commands; } }
|
public ICommands Commands { get { return m_commands; } }
|
||||||
|
@ -76,4 +78,4 @@ namespace OpenSim.Framework.Console
|
||||||
public string[] Resolve(string[] cmd) { return null; }
|
public string[] Resolve(string[] cmd) { return null; }
|
||||||
public XmlElement GetXml(XmlDocument doc) { return null; }
|
public XmlElement GetXml(XmlDocument doc) { return null; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,6 +100,7 @@ namespace OpenSim.Framework.Console
|
||||||
m_LineNumber++;
|
m_LineNumber++;
|
||||||
m_Scrollback.Add(String.Format("{0}", m_LineNumber)+":"+level+":"+text);
|
m_Scrollback.Add(String.Format("{0}", m_LineNumber)+":"+level+":"+text);
|
||||||
}
|
}
|
||||||
|
FireOnOutput(text.Trim());
|
||||||
System.Console.WriteLine(text.Trim());
|
System.Console.WriteLine(text.Trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ namespace OpenSim.Framework
|
||||||
public delegate void ObjectDrop(uint localID, IClientAPI remoteClient);
|
public delegate void ObjectDrop(uint localID, IClientAPI remoteClient);
|
||||||
|
|
||||||
public delegate void UpdatePrimFlags(
|
public delegate void UpdatePrimFlags(
|
||||||
uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom,ExtraPhysicsData PhysData, IClientAPI remoteClient);
|
uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom, ExtraPhysicsData PhysData, IClientAPI remoteClient);
|
||||||
|
|
||||||
public delegate void UpdatePrimTexture(uint localID, byte[] texture, IClientAPI remoteClient);
|
public delegate void UpdatePrimTexture(uint localID, byte[] texture, IClientAPI remoteClient);
|
||||||
|
|
||||||
|
|
|
@ -74,8 +74,12 @@ namespace OpenSim.Framework
|
||||||
XmlElement GetXml(XmlDocument doc);
|
XmlElement GetXml(XmlDocument doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public delegate void OnOutputDelegate(string message);
|
||||||
|
|
||||||
public interface ICommandConsole : IConsole
|
public interface ICommandConsole : IConsole
|
||||||
{
|
{
|
||||||
|
event OnOutputDelegate OnOutput;
|
||||||
|
|
||||||
ICommands Commands { get; }
|
ICommands Commands { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -87,4 +91,4 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
string ReadLine(string p, bool isCommand, bool e);
|
string ReadLine(string p, bool isCommand, bool e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,6 +97,32 @@ namespace OpenSim.Framework.Monitoring
|
||||||
/// /summary>
|
/// /summary>
|
||||||
public static event Action<ThreadWatchdogInfo> OnWatchdogTimeout;
|
public static event Action<ThreadWatchdogInfo> OnWatchdogTimeout;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is this watchdog active?
|
||||||
|
/// </summary>
|
||||||
|
public static bool Enabled
|
||||||
|
{
|
||||||
|
get { return m_enabled; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat("[MEMORY WATCHDOG]: Setting MemoryWatchdog.Enabled to {0}", value);
|
||||||
|
|
||||||
|
if (value == m_enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_enabled = value;
|
||||||
|
|
||||||
|
if (m_enabled)
|
||||||
|
{
|
||||||
|
// Set now so we don't get alerted on the first run
|
||||||
|
LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_watchdogTimer.Enabled = m_enabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static bool m_enabled;
|
||||||
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
private static Dictionary<int, ThreadWatchdogInfo> m_threads;
|
private static Dictionary<int, ThreadWatchdogInfo> m_threads;
|
||||||
private static System.Timers.Timer m_watchdogTimer;
|
private static System.Timers.Timer m_watchdogTimer;
|
||||||
|
@ -115,11 +141,6 @@ namespace OpenSim.Framework.Monitoring
|
||||||
m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS);
|
m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS);
|
||||||
m_watchdogTimer.AutoReset = false;
|
m_watchdogTimer.AutoReset = false;
|
||||||
m_watchdogTimer.Elapsed += WatchdogTimerElapsed;
|
m_watchdogTimer.Elapsed += WatchdogTimerElapsed;
|
||||||
|
|
||||||
// Set now so we don't get alerted on the first run
|
|
||||||
LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue;
|
|
||||||
|
|
||||||
m_watchdogTimer.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -93,6 +93,8 @@ namespace OpenSim.Framework.Serialization.External
|
||||||
"MediaURL", (ld, xtr) => ld.MediaURL = xtr.ReadElementString("MediaURL"));
|
"MediaURL", (ld, xtr) => ld.MediaURL = xtr.ReadElementString("MediaURL"));
|
||||||
m_ldProcessors.Add(
|
m_ldProcessors.Add(
|
||||||
"MusicURL", (ld, xtr) => ld.MusicURL = xtr.ReadElementString("MusicURL"));
|
"MusicURL", (ld, xtr) => ld.MusicURL = xtr.ReadElementString("MusicURL"));
|
||||||
|
m_ldProcessors.Add(
|
||||||
|
"OwnerID", (ld, xtr) => ld.OwnerID = UUID.Parse(xtr.ReadElementString("OwnerID")));
|
||||||
|
|
||||||
m_ldProcessors.Add(
|
m_ldProcessors.Add(
|
||||||
"ParcelAccessList", ProcessParcelAccessList);
|
"ParcelAccessList", ProcessParcelAccessList);
|
||||||
|
@ -186,7 +188,16 @@ namespace OpenSim.Framework.Serialization.External
|
||||||
return landData;
|
return landData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Serialize(LandData landData)
|
/// <summary>
|
||||||
|
/// Serialize land data
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='landData'></param>
|
||||||
|
/// <param name='options'>
|
||||||
|
/// Serialization options.
|
||||||
|
/// Can be null if there are no options.
|
||||||
|
/// "wipe-owners" will write UUID.Zero rather than the ownerID so that a later reload loads all parcels with the estate owner as the owner
|
||||||
|
/// </param>
|
||||||
|
public static string Serialize(LandData landData, Dictionary<string, object> options)
|
||||||
{
|
{
|
||||||
StringWriter sw = new StringWriter();
|
StringWriter sw = new StringWriter();
|
||||||
XmlTextWriter xtw = new XmlTextWriter(sw);
|
XmlTextWriter xtw = new XmlTextWriter(sw);
|
||||||
|
@ -215,7 +226,14 @@ namespace OpenSim.Framework.Serialization.External
|
||||||
xtw.WriteElementString("MediaID", landData.MediaID.ToString());
|
xtw.WriteElementString("MediaID", landData.MediaID.ToString());
|
||||||
xtw.WriteElementString("MediaURL", landData.MediaURL);
|
xtw.WriteElementString("MediaURL", landData.MediaURL);
|
||||||
xtw.WriteElementString("MusicURL", landData.MusicURL);
|
xtw.WriteElementString("MusicURL", landData.MusicURL);
|
||||||
xtw.WriteElementString("OwnerID", landData.OwnerID.ToString());
|
|
||||||
|
UUID ownerIdToWrite;
|
||||||
|
if (options != null && options.ContainsKey("wipe-owners"))
|
||||||
|
ownerIdToWrite = UUID.Zero;
|
||||||
|
else
|
||||||
|
ownerIdToWrite = landData.OwnerID;
|
||||||
|
|
||||||
|
xtw.WriteElementString("OwnerID", ownerIdToWrite.ToString());
|
||||||
|
|
||||||
xtw.WriteStartElement("ParcelAccessList");
|
xtw.WriteStartElement("ParcelAccessList");
|
||||||
foreach (LandAccessEntry pal in landData.ParcelAccessList)
|
foreach (LandAccessEntry pal in landData.ParcelAccessList)
|
||||||
|
|
|
@ -42,22 +42,23 @@ namespace OpenSim.Framework.Serialization.Tests
|
||||||
private LandData land;
|
private LandData land;
|
||||||
private LandData landWithParcelAccessList;
|
private LandData landWithParcelAccessList;
|
||||||
|
|
||||||
private static string preSerialized = "<?xml version=\"1.0\" encoding=\"utf-16\"?>\n<LandData>\n <Area>128</Area>\n <AuctionID>0</AuctionID>\n <AuthBuyerID>00000000-0000-0000-0000-000000000000</AuthBuyerID>\n <Category>10</Category>\n <ClaimDate>0</ClaimDate>\n <ClaimPrice>0</ClaimPrice>\n <GlobalID>54ff9641-dd40-4a2c-b1f1-47dd3af24e50</GlobalID>\n <GroupID>d740204e-bbbf-44aa-949d-02c7d739f6a5</GroupID>\n <IsGroupOwned>False</IsGroupOwned>\n <Bitmap>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</Bitmap>\n <Description>land data to test LandDataSerializer</Description>\n <Flags>536870944</Flags>\n <LandingType>2</LandingType>\n <Name>LandDataSerializerTest Land</Name>\n <Status>0</Status>\n <LocalID>0</LocalID>\n <MediaAutoScale>1</MediaAutoScale>\n <MediaID>d4452578-2f25-4b97-a81b-819af559cfd7</MediaID>\n <MediaURL>http://videos.opensimulator.org/bumblebee.mp4</MediaURL>\n <MusicURL />\n <OwnerID>1b8eedf9-6d15-448b-8015-24286f1756bf</OwnerID>\n <ParcelAccessList />\n <PassHours>0</PassHours>\n <PassPrice>0</PassPrice>\n <SalePrice>0</SalePrice>\n <SnapshotID>00000000-0000-0000-0000-000000000000</SnapshotID>\n <UserLocation><0, 0, 0></UserLocation>\n <UserLookAt><0, 0, 0></UserLookAt>\n <Dwell>0</Dwell>\n <OtherCleanTime>0</OtherCleanTime>\n</LandData>";
|
// private static string preSerialized = "<?xml version=\"1.0\" encoding=\"utf-16\"?>\n<LandData>\n <Area>128</Area>\n <AuctionID>0</AuctionID>\n <AuthBuyerID>00000000-0000-0000-0000-000000000000</AuthBuyerID>\n <Category>10</Category>\n <ClaimDate>0</ClaimDate>\n <ClaimPrice>0</ClaimPrice>\n <GlobalID>54ff9641-dd40-4a2c-b1f1-47dd3af24e50</GlobalID>\n <GroupID>d740204e-bbbf-44aa-949d-02c7d739f6a5</GroupID>\n <IsGroupOwned>False</IsGroupOwned>\n <Bitmap>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</Bitmap>\n <Description>land data to test LandDataSerializer</Description>\n <Flags>536870944</Flags>\n <LandingType>2</LandingType>\n <Name>LandDataSerializerTest Land</Name>\n <Status>0</Status>\n <LocalID>0</LocalID>\n <MediaAutoScale>1</MediaAutoScale>\n <MediaID>d4452578-2f25-4b97-a81b-819af559cfd7</MediaID>\n <MediaURL>http://videos.opensimulator.org/bumblebee.mp4</MediaURL>\n <MusicURL />\n <OwnerID>1b8eedf9-6d15-448b-8015-24286f1756bf</OwnerID>\n <ParcelAccessList />\n <PassHours>0</PassHours>\n <PassPrice>0</PassPrice>\n <SalePrice>0</SalePrice>\n <SnapshotID>00000000-0000-0000-0000-000000000000</SnapshotID>\n <UserLocation><0, 0, 0></UserLocation>\n <UserLookAt><0, 0, 0></UserLookAt>\n <Dwell>0</Dwell>\n <OtherCleanTime>0</OtherCleanTime>\n</LandData>";
|
||||||
private static string preSerializedWithParcelAccessList = "<?xml version=\"1.0\" encoding=\"utf-16\"?>\n<LandData>\n <Area>128</Area>\n <AuctionID>0</AuctionID>\n <AuthBuyerID>00000000-0000-0000-0000-000000000000</AuthBuyerID>\n <Category>10</Category>\n <ClaimDate>0</ClaimDate>\n <ClaimPrice>0</ClaimPrice>\n <GlobalID>54ff9641-dd40-4a2c-b1f1-47dd3af24e50</GlobalID>\n <GroupID>d740204e-bbbf-44aa-949d-02c7d739f6a5</GroupID>\n <IsGroupOwned>False</IsGroupOwned>\n <Bitmap>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</Bitmap>\n <Description>land data to test LandDataSerializer</Description>\n <Flags>536870944</Flags>\n <LandingType>2</LandingType>\n <Name>LandDataSerializerTest Land</Name>\n <Status>0</Status>\n <LocalID>0</LocalID>\n <MediaAutoScale>1</MediaAutoScale>\n <MediaID>d4452578-2f25-4b97-a81b-819af559cfd7</MediaID>\n <MediaURL>http://videos.opensimulator.org/bumblebee.mp4</MediaURL>\n <MusicURL />\n <OwnerID>1b8eedf9-6d15-448b-8015-24286f1756bf</OwnerID>\n <ParcelAccessList>\n <ParcelAccessEntry>\n <AgentID>62d65d45-c91a-4f77-862c-46557d978b6c</AgentID>\n <Time>0</Time>\n <AccessList>2</AccessList>\n </ParcelAccessEntry>\n <ParcelAccessEntry>\n <AgentID>ec2a8d18-2378-4fe0-8b68-2a31b57c481e</AgentID>\n <Time>0</Time>\n <AccessList>1</AccessList>\n </ParcelAccessEntry>\n </ParcelAccessList>\n <PassHours>0</PassHours>\n <PassPrice>0</PassPrice>\n <SalePrice>0</SalePrice>\n <SnapshotID>00000000-0000-0000-0000-000000000000</SnapshotID>\n <UserLocation><0, 0, 0></UserLocation>\n <UserLookAt><0, 0, 0></UserLookAt>\n <Dwell>0</Dwell>\n <OtherCleanTime>0</OtherCleanTime>\n</LandData>";
|
private static string preSerializedWithParcelAccessList
|
||||||
|
= "<?xml version=\"1.0\" encoding=\"utf-16\"?>\n<LandData>\n <Area>128</Area>\n <AuctionID>0</AuctionID>\n <AuthBuyerID>00000000-0000-0000-0000-000000000000</AuthBuyerID>\n <Category>10</Category>\n <ClaimDate>0</ClaimDate>\n <ClaimPrice>0</ClaimPrice>\n <GlobalID>54ff9641-dd40-4a2c-b1f1-47dd3af24e50</GlobalID>\n <GroupID>d740204e-bbbf-44aa-949d-02c7d739f6a5</GroupID>\n <IsGroupOwned>False</IsGroupOwned>\n <Bitmap>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</Bitmap>\n <Description>land data to test LandDataSerializer</Description>\n <Flags>536870944</Flags>\n <LandingType>2</LandingType>\n <Name>LandDataSerializerTest Land</Name>\n <Status>0</Status>\n <LocalID>0</LocalID>\n <MediaAutoScale>1</MediaAutoScale>\n <MediaID>d4452578-2f25-4b97-a81b-819af559cfd7</MediaID>\n <MediaURL>http://videos.opensimulator.org/bumblebee.mp4</MediaURL>\n <MusicURL />\n <OwnerID>1b8eedf9-6d15-448b-8015-24286f1756bf</OwnerID>\n <ParcelAccessList>\n <ParcelAccessEntry>\n <AgentID>62d65d45-c91a-4f77-862c-46557d978b6c</AgentID>\n <Time>0</Time>\n <AccessList>2</AccessList>\n </ParcelAccessEntry>\n <ParcelAccessEntry>\n <AgentID>ec2a8d18-2378-4fe0-8b68-2a31b57c481e</AgentID>\n <Time>0</Time>\n <AccessList>1</AccessList>\n </ParcelAccessEntry>\n </ParcelAccessList>\n <PassHours>0</PassHours>\n <PassPrice>0</PassPrice>\n <SalePrice>0</SalePrice>\n <SnapshotID>00000000-0000-0000-0000-000000000000</SnapshotID>\n <UserLocation><0, 0, 0></UserLocation>\n <UserLookAt><0, 0, 0></UserLookAt>\n <Dwell>0</Dwell>\n <OtherCleanTime>0</OtherCleanTime>\n</LandData>";
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void setup()
|
public void setup()
|
||||||
{
|
{
|
||||||
// setup LandData object
|
// setup LandData object
|
||||||
this.land = new LandData();
|
this.land = new LandData();
|
||||||
this.land.AABBMax = new Vector3(0, 0, 0);
|
this.land.AABBMax = new Vector3(1, 2, 3);
|
||||||
this.land.AABBMin = new Vector3(128, 128, 128);
|
this.land.AABBMin = new Vector3(129, 130, 131);
|
||||||
this.land.Area = 128;
|
this.land.Area = 128;
|
||||||
this.land.AuctionID = 0;
|
this.land.AuctionID = 4;
|
||||||
this.land.AuthBuyerID = new UUID();
|
this.land.AuthBuyerID = new UUID("7176df0c-6c50-45db-8a37-5e78be56a0cd");
|
||||||
this.land.Category = ParcelCategory.Residential;
|
this.land.Category = ParcelCategory.Residential;
|
||||||
this.land.ClaimDate = 0;
|
this.land.ClaimDate = 1;
|
||||||
this.land.ClaimPrice = 0;
|
this.land.ClaimPrice = 2;
|
||||||
this.land.GlobalID = new UUID("54ff9641-dd40-4a2c-b1f1-47dd3af24e50");
|
this.land.GlobalID = new UUID("54ff9641-dd40-4a2c-b1f1-47dd3af24e50");
|
||||||
this.land.GroupID = new UUID("d740204e-bbbf-44aa-949d-02c7d739f6a5");
|
this.land.GroupID = new UUID("d740204e-bbbf-44aa-949d-02c7d739f6a5");
|
||||||
this.land.Description = "land data to test LandDataSerializer";
|
this.land.Description = "land data to test LandDataSerializer";
|
||||||
|
@ -65,7 +66,7 @@ namespace OpenSim.Framework.Serialization.Tests
|
||||||
this.land.LandingType = (byte)LandingType.Direct;
|
this.land.LandingType = (byte)LandingType.Direct;
|
||||||
this.land.Name = "LandDataSerializerTest Land";
|
this.land.Name = "LandDataSerializerTest Land";
|
||||||
this.land.Status = ParcelStatus.Leased;
|
this.land.Status = ParcelStatus.Leased;
|
||||||
this.land.LocalID = 0;
|
this.land.LocalID = 1;
|
||||||
this.land.MediaAutoScale = (byte)0x01;
|
this.land.MediaAutoScale = (byte)0x01;
|
||||||
this.land.MediaID = new UUID("d4452578-2f25-4b97-a81b-819af559cfd7");
|
this.land.MediaID = new UUID("d4452578-2f25-4b97-a81b-819af559cfd7");
|
||||||
this.land.MediaURL = "http://videos.opensimulator.org/bumblebee.mp4";
|
this.land.MediaURL = "http://videos.opensimulator.org/bumblebee.mp4";
|
||||||
|
@ -90,26 +91,26 @@ namespace OpenSim.Framework.Serialization.Tests
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Test the LandDataSerializer.Serialize() method
|
/// Test the LandDataSerializer.Serialize() method
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Test]
|
// [Test]
|
||||||
public void LandDataSerializerSerializeTest()
|
// public void LandDataSerializerSerializeTest()
|
||||||
{
|
// {
|
||||||
TestHelpers.InMethod();
|
// TestHelpers.InMethod();
|
||||||
|
//
|
||||||
string serialized = LandDataSerializer.Serialize(this.land).Replace("\r\n", "\n");
|
// string serialized = LandDataSerializer.Serialize(this.land).Replace("\r\n", "\n");
|
||||||
Assert.That(serialized.Length > 0, "Serialize(LandData) returned empty string");
|
// Assert.That(serialized.Length > 0, "Serialize(LandData) returned empty string");
|
||||||
|
//
|
||||||
// adding a simple boolean variable because resharper nUnit integration doesn't like this
|
// // adding a simple boolean variable because resharper nUnit integration doesn't like this
|
||||||
// XML data in the Assert.That statement. Not sure why.
|
// // XML data in the Assert.That statement. Not sure why.
|
||||||
bool result = (serialized == preSerialized);
|
// bool result = (serialized == preSerialized);
|
||||||
Assert.That(result, "result of Serialize LandData does not match expected result");
|
// Assert.That(result, "result of Serialize LandData does not match expected result");
|
||||||
|
//
|
||||||
string serializedWithParcelAccessList = LandDataSerializer.Serialize(this.landWithParcelAccessList).Replace("\r\n", "\n");
|
// string serializedWithParcelAccessList = LandDataSerializer.Serialize(this.landWithParcelAccessList).Replace("\r\n", "\n");
|
||||||
Assert.That(serializedWithParcelAccessList.Length > 0,
|
// Assert.That(serializedWithParcelAccessList.Length > 0,
|
||||||
"Serialize(LandData) returned empty string for LandData object with ParcelAccessList");
|
// "Serialize(LandData) returned empty string for LandData object with ParcelAccessList");
|
||||||
result = (serializedWithParcelAccessList == preSerializedWithParcelAccessList);
|
// result = (serializedWithParcelAccessList == preSerializedWithParcelAccessList);
|
||||||
Assert.That(result,
|
// Assert.That(result,
|
||||||
"result of Serialize(LandData) does not match expected result (pre-serialized with parcel access list");
|
// "result of Serialize(LandData) does not match expected result (pre-serialized with parcel access list");
|
||||||
}
|
// }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Test the LandDataSerializer.Deserialize() method
|
/// Test the LandDataSerializer.Deserialize() method
|
||||||
|
@ -120,10 +121,28 @@ namespace OpenSim.Framework.Serialization.Tests
|
||||||
TestHelpers.InMethod();
|
TestHelpers.InMethod();
|
||||||
// log4net.Config.XmlConfigurator.Configure();
|
// log4net.Config.XmlConfigurator.Configure();
|
||||||
|
|
||||||
LandData ld = LandDataSerializer.Deserialize(LandDataSerializerTest.preSerialized);
|
LandData ld = LandDataSerializer.Deserialize(LandDataSerializer.Serialize(this.land, null));
|
||||||
Assert.That(ld != null, "Deserialize(string) returned null");
|
Assert.That(ld, Is.Not.Null, "Deserialize(string) returned null");
|
||||||
Assert.That(ld.GlobalID == this.land.GlobalID, "Reified LandData.GlobalID != original LandData.GlobalID");
|
// Assert.That(ld.AABBMax, Is.EqualTo(land.AABBMax));
|
||||||
Assert.That(ld.Name == this.land.Name, "Reified LandData.Name != original LandData.Name");
|
// Assert.That(ld.AABBMin, Is.EqualTo(land.AABBMin));
|
||||||
|
Assert.That(ld.Area, Is.EqualTo(land.Area));
|
||||||
|
Assert.That(ld.AuctionID, Is.EqualTo(land.AuctionID));
|
||||||
|
Assert.That(ld.AuthBuyerID, Is.EqualTo(land.AuthBuyerID));
|
||||||
|
Assert.That(ld.Category, Is.EqualTo(land.Category));
|
||||||
|
Assert.That(ld.ClaimDate, Is.EqualTo(land.ClaimDate));
|
||||||
|
Assert.That(ld.ClaimPrice, Is.EqualTo(land.ClaimPrice));
|
||||||
|
Assert.That(ld.GlobalID, Is.EqualTo(land.GlobalID), "Reified LandData.GlobalID != original LandData.GlobalID");
|
||||||
|
Assert.That(ld.GroupID, Is.EqualTo(land.GroupID));
|
||||||
|
Assert.That(ld.Description, Is.EqualTo(land.Description));
|
||||||
|
Assert.That(ld.Flags, Is.EqualTo(land.Flags));
|
||||||
|
Assert.That(ld.LandingType, Is.EqualTo(land.LandingType));
|
||||||
|
Assert.That(ld.Name, Is.EqualTo(land.Name), "Reified LandData.Name != original LandData.Name");
|
||||||
|
Assert.That(ld.Status, Is.EqualTo(land.Status));
|
||||||
|
Assert.That(ld.LocalID, Is.EqualTo(land.LocalID));
|
||||||
|
Assert.That(ld.MediaAutoScale, Is.EqualTo(land.MediaAutoScale));
|
||||||
|
Assert.That(ld.MediaID, Is.EqualTo(land.MediaID));
|
||||||
|
Assert.That(ld.MediaURL, Is.EqualTo(land.MediaURL));
|
||||||
|
Assert.That(ld.OwnerID, Is.EqualTo(land.OwnerID));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|
|
@ -294,14 +294,13 @@ namespace OpenSim
|
||||||
"save oar [-h|--home=<url>] [--noassets] [--publish] [--perm=<permissions>] [<OAR path>]",
|
"save oar [-h|--home=<url>] [--noassets] [--publish] [--perm=<permissions>] [<OAR path>]",
|
||||||
"Save a region's data to an OAR archive.",
|
"Save a region's data to an OAR archive.",
|
||||||
// "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
|
// "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
|
||||||
"-h|--home=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
|
"-h|--home=<url> adds the url of the profile service to the saved user information.\n"
|
||||||
+ "--noassets stops assets being saved to the OAR." + Environment.NewLine
|
+ "--noassets stops assets being saved to the OAR.\n"
|
||||||
+ "--publish saves an OAR stripped of owner and last owner information." + Environment.NewLine
|
+ "--publish saves an OAR stripped of owner and last owner information.\n"
|
||||||
+ " on reload, the estate owner will be the owner of all objects" + Environment.NewLine
|
+ " on reload, the estate owner will be the owner of all objects\n"
|
||||||
+ " this is useful if you're making oars generally available that might be reloaded to the same grid from which you published" + Environment.NewLine
|
+ " this is useful if you're making oars generally available that might be reloaded to the same grid from which you published\n"
|
||||||
+ " this option is EXPERIMENTAL" + Environment.NewLine
|
+ "--perm=<permissions> stops objects with insufficient permissions from being saved to the OAR.\n"
|
||||||
+ "--perm=<permissions> stops objects with insufficient permissions from being saved to the OAR." + Environment.NewLine
|
+ " <permissions> can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer\n"
|
||||||
+ " <permissions> can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer" + Environment.NewLine
|
|
||||||
+ "The OAR path must be a filesystem path."
|
+ "The OAR path must be a filesystem path."
|
||||||
+ " If this is not given then the oar is saved to region.oar in the current directory.",
|
+ " If this is not given then the oar is saved to region.oar in the current directory.",
|
||||||
SaveOar);
|
SaveOar);
|
||||||
|
|
|
@ -320,8 +320,13 @@ namespace OpenSim
|
||||||
m_httpServerPort = m_networkServersInfo.HttpListenerPort;
|
m_httpServerPort = m_networkServersInfo.HttpListenerPort;
|
||||||
SceneManager.OnRestartSim += handleRestartRegion;
|
SceneManager.OnRestartSim += handleRestartRegion;
|
||||||
|
|
||||||
// Only start the memory watchdog once all regions are ready
|
// Only enable the watchdogs when all regions are ready. Otherwise we get false positives when cpu is
|
||||||
SceneManager.OnRegionsReadyStatusChange += sm => MemoryWatchdog.Enabled = sm.AllRegionsReady;
|
// heavily used during initial startup.
|
||||||
|
//
|
||||||
|
// FIXME: It's also possible that region ready status should be flipped during an OAR load since this
|
||||||
|
// also makes heavy use of the CPU.
|
||||||
|
SceneManager.OnRegionsReadyStatusChange
|
||||||
|
+= sm => { MemoryWatchdog.Enabled = sm.AllRegionsReady; Watchdog.Enabled = sm.AllRegionsReady; };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -126,9 +126,14 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
IConfig sconfig = config.Configs["Startup"];
|
IConfig sconfig = config.Configs["Startup"];
|
||||||
if (sconfig != null)
|
if (sconfig != null)
|
||||||
{
|
{
|
||||||
m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
|
|
||||||
m_levelUpload = sconfig.GetInt("LevelUpload", 0);
|
m_levelUpload = sconfig.GetInt("LevelUpload", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IConfig appearanceConfig = config.Configs["Appearance"];
|
||||||
|
if (appearanceConfig != null)
|
||||||
|
{
|
||||||
|
m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_assetService = m_Scene.AssetService;
|
m_assetService = m_Scene.AssetService;
|
||||||
|
|
|
@ -0,0 +1,234 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.IO;
|
||||||
|
using System.Web;
|
||||||
|
using log4net;
|
||||||
|
using Nini.Config;
|
||||||
|
using Mono.Addins;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenMetaverse.StructuredData;
|
||||||
|
using OpenMetaverse.Imaging;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Console;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using Caps = OpenSim.Framework.Capabilities.Caps;
|
||||||
|
using OpenSim.Capabilities.Handlers;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
{
|
||||||
|
|
||||||
|
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RegionConsoleModule")]
|
||||||
|
public class RegionConsoleModule : INonSharedRegionModule, IRegionConsole
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log =
|
||||||
|
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private Scene m_scene;
|
||||||
|
private IEventQueue m_eventQueue;
|
||||||
|
private Commands m_commands = new Commands();
|
||||||
|
public ICommands Commands { get { return m_commands; } }
|
||||||
|
|
||||||
|
public void Initialise(IConfigSource source)
|
||||||
|
{
|
||||||
|
m_commands.AddCommand( "Help", false, "help", "help [<item>]", "Display help on a particular command or on a list of commands in a category", Help);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRegion(Scene s)
|
||||||
|
{
|
||||||
|
m_scene = s;
|
||||||
|
m_scene.RegisterModuleInterface<IRegionConsole>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveRegion(Scene s)
|
||||||
|
{
|
||||||
|
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
|
||||||
|
m_scene = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegionLoaded(Scene s)
|
||||||
|
{
|
||||||
|
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
|
||||||
|
m_eventQueue = m_scene.RequestModuleInterface<IEventQueue>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PostInitialise()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close() { }
|
||||||
|
|
||||||
|
public string Name { get { return "RegionConsoleModule"; } }
|
||||||
|
|
||||||
|
public Type ReplaceableInterface
|
||||||
|
{
|
||||||
|
get { return null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterCaps(UUID agentID, Caps caps)
|
||||||
|
{
|
||||||
|
if (!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(agentID))
|
||||||
|
return;
|
||||||
|
|
||||||
|
UUID capID = UUID.Random();
|
||||||
|
|
||||||
|
m_log.DebugFormat("[REGION CONSOLE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
|
||||||
|
caps.RegisterHandler(
|
||||||
|
"SimConsoleAsync",
|
||||||
|
new ConsoleHandler("/CAPS/" + capID + "/", "SimConsoleAsync", agentID, this, m_scene));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendConsoleOutput(UUID agentID, string message)
|
||||||
|
{
|
||||||
|
OSD osd = OSD.FromString(message);
|
||||||
|
|
||||||
|
m_eventQueue.Enqueue(EventQueueHelper.BuildEvent("SimConsoleResponse", osd), agentID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RunCommand(string command, UUID invokerID)
|
||||||
|
{
|
||||||
|
string[] parts = Parser.Parse(command);
|
||||||
|
Array.Resize(ref parts, parts.Length + 1);
|
||||||
|
parts[parts.Length - 1] = invokerID.ToString();
|
||||||
|
|
||||||
|
if (m_commands.Resolve(parts).Length == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Help(string module, string[] cmd)
|
||||||
|
{
|
||||||
|
UUID agentID = new UUID(cmd[cmd.Length - 1]);
|
||||||
|
Array.Resize(ref cmd, cmd.Length - 1);
|
||||||
|
|
||||||
|
List<string> help = Commands.GetHelp(cmd);
|
||||||
|
|
||||||
|
string reply = String.Empty;
|
||||||
|
|
||||||
|
foreach (string s in help)
|
||||||
|
{
|
||||||
|
reply += s + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
SendConsoleOutput(agentID, reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddCommand(string module, bool shared, string command, string help, string longhelp, CommandDelegate fn)
|
||||||
|
{
|
||||||
|
m_commands.AddCommand(module, shared, command, help, longhelp, fn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ConsoleHandler : BaseStreamHandler
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log =
|
||||||
|
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private RegionConsoleModule m_consoleModule;
|
||||||
|
private UUID m_agentID;
|
||||||
|
private bool m_isGod;
|
||||||
|
private Scene m_scene;
|
||||||
|
private bool m_consoleIsOn = false;
|
||||||
|
|
||||||
|
public ConsoleHandler(string path, string name, UUID agentID, RegionConsoleModule module, Scene scene)
|
||||||
|
:base("POST", path, name, agentID.ToString())
|
||||||
|
{
|
||||||
|
m_agentID = agentID;
|
||||||
|
m_consoleModule = module;
|
||||||
|
m_scene = scene;
|
||||||
|
|
||||||
|
m_isGod = m_scene.Permissions.IsGod(agentID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override byte[] Handle(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
||||||
|
{
|
||||||
|
StreamReader reader = new StreamReader(request);
|
||||||
|
string message = reader.ReadToEnd();
|
||||||
|
|
||||||
|
OSD osd = OSDParser.DeserializeLLSDXml(message);
|
||||||
|
|
||||||
|
string cmd = osd.AsString();
|
||||||
|
if (cmd == "set console on")
|
||||||
|
{
|
||||||
|
if (m_isGod)
|
||||||
|
{
|
||||||
|
MainConsole.Instance.OnOutput += ConsoleSender;
|
||||||
|
m_consoleIsOn = true;
|
||||||
|
m_consoleModule.SendConsoleOutput(m_agentID, "Console is now on");
|
||||||
|
}
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
else if (cmd == "set console off")
|
||||||
|
{
|
||||||
|
MainConsole.Instance.OnOutput -= ConsoleSender;
|
||||||
|
m_consoleIsOn = false;
|
||||||
|
m_consoleModule.SendConsoleOutput(m_agentID, "Console is now off");
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_consoleIsOn == false && m_consoleModule.RunCommand(osd.AsString().Trim(), m_agentID))
|
||||||
|
return new byte[0];
|
||||||
|
|
||||||
|
if (m_isGod && m_consoleIsOn)
|
||||||
|
{
|
||||||
|
MainConsole.Instance.RunCommand(osd.AsString().Trim());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_consoleModule.SendConsoleOutput(m_agentID, "Unknown command");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConsoleSender(string text)
|
||||||
|
{
|
||||||
|
m_consoleModule.SendConsoleOutput(m_agentID, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnMakeChildAgent(ScenePresence presence)
|
||||||
|
{
|
||||||
|
if (presence.UUID == m_agentID)
|
||||||
|
{
|
||||||
|
MainConsole.Instance.OnOutput -= ConsoleSender;
|
||||||
|
m_consoleIsOn = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -66,9 +66,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
public void Initialise(IConfigSource source)
|
public void Initialise(IConfigSource source)
|
||||||
{
|
{
|
||||||
IConfig sconfig = source.Configs["Startup"];
|
IConfig appearanceConfig = source.Configs["Appearance"];
|
||||||
if (sconfig != null)
|
if (appearanceConfig != null)
|
||||||
m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
|
m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddRegion(Scene s)
|
public void AddRegion(Scene s)
|
||||||
|
|
|
@ -284,7 +284,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
sp.ClearAttachments();
|
sp.ClearAttachments();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData)
|
public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool useAttachData, bool temp)
|
||||||
{
|
{
|
||||||
lock (sp.AttachmentsSyncLock)
|
lock (sp.AttachmentsSyncLock)
|
||||||
{
|
{
|
||||||
|
@ -361,7 +361,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
group.AbsolutePosition = attachPos;
|
group.AbsolutePosition = attachPos;
|
||||||
|
|
||||||
if (sp.PresenceType != PresenceType.Npc)
|
if (sp.PresenceType != PresenceType.Npc)
|
||||||
UpdateUserInventoryWithAttachment(sp, group, attachmentPt);
|
UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp);
|
||||||
|
|
||||||
AttachToAgent(sp, group, attachmentPt, attachPos, silent);
|
AttachToAgent(sp, group, attachmentPt, attachPos, silent);
|
||||||
}
|
}
|
||||||
|
@ -369,7 +369,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt)
|
private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp)
|
||||||
{
|
{
|
||||||
// Remove any previous attachments
|
// Remove any previous attachments
|
||||||
List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
|
List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
|
||||||
|
@ -379,18 +379,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
{
|
{
|
||||||
if (attachments[0].FromItemID != UUID.Zero)
|
if (attachments[0].FromItemID != UUID.Zero)
|
||||||
DetachSingleAttachmentToInvInternal(sp, attachments[0]);
|
DetachSingleAttachmentToInvInternal(sp, attachments[0]);
|
||||||
else
|
// Error logging commented because UUID.Zero now means temp attachment
|
||||||
m_log.WarnFormat(
|
// else
|
||||||
"[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!",
|
// m_log.WarnFormat(
|
||||||
attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name);
|
// "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!",
|
||||||
|
// attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the new attachment to inventory if we don't already have it.
|
// Add the new attachment to inventory if we don't already have it.
|
||||||
UUID newAttachmentItemID = group.FromItemID;
|
if (!temp)
|
||||||
if (newAttachmentItemID == UUID.Zero)
|
{
|
||||||
newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
|
UUID newAttachmentItemID = group.FromItemID;
|
||||||
|
if (newAttachmentItemID == UUID.Zero)
|
||||||
|
newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
|
||||||
|
|
||||||
ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
|
ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
|
public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
|
||||||
|
@ -474,6 +478,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
|
|
||||||
UUID inventoryID = so.FromItemID;
|
UUID inventoryID = so.FromItemID;
|
||||||
|
|
||||||
|
// As per Linden spec, drop is disabled for temp attachs
|
||||||
|
if (inventoryID == UUID.Zero)
|
||||||
|
return;
|
||||||
|
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}",
|
// "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}",
|
||||||
// so.Name, so.LocalId, inventoryID);
|
// so.Name, so.LocalId, inventoryID);
|
||||||
|
@ -484,7 +492,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
so.PrimCount, sp.UUID, sp.AbsolutePosition))
|
so.PrimCount, sp.UUID, sp.AbsolutePosition))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool changed = sp.Appearance.DetachAttachment(inventoryID);
|
bool changed = false;
|
||||||
|
if (inventoryID != UUID.Zero)
|
||||||
|
changed = sp.Appearance.DetachAttachment(inventoryID);
|
||||||
if (changed && m_scene.AvatarFactory != null)
|
if (changed && m_scene.AvatarFactory != null)
|
||||||
m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
|
m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
|
||||||
|
|
||||||
|
@ -516,6 +526,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
|
|
||||||
public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so)
|
public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so)
|
||||||
{
|
{
|
||||||
|
// As per Linden spec, detach (take) is disabled for temp attachs
|
||||||
|
if (so.FromItemID == UUID.Zero)
|
||||||
|
return;
|
||||||
|
|
||||||
lock (sp.AttachmentsSyncLock)
|
lock (sp.AttachmentsSyncLock)
|
||||||
{
|
{
|
||||||
// Save avatar attachment information
|
// Save avatar attachment information
|
||||||
|
@ -589,6 +603,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
/// <param name="saveAllScripted"></param>
|
/// <param name="saveAllScripted"></param>
|
||||||
private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, string scriptedState)
|
private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, string scriptedState)
|
||||||
{
|
{
|
||||||
|
if (grp.FromItemID == UUID.Zero)
|
||||||
|
{
|
||||||
|
// We can't save temp attachments
|
||||||
|
grp.HasGroupChanged = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Saving attachments for NPCs messes them up for the real owner!
|
// Saving attachments for NPCs messes them up for the real owner!
|
||||||
INPCModule module = m_scene.RequestModuleInterface<INPCModule>();
|
INPCModule module = m_scene.RequestModuleInterface<INPCModule>();
|
||||||
if (module != null)
|
if (module != null)
|
||||||
|
@ -845,7 +866,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
// This will throw if the attachment fails
|
// This will throw if the attachment fails
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
AttachObject(sp, objatt, attachmentPt, false, false);
|
AttachObject(sp, objatt, attachmentPt, false, false, false);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -1005,7 +1026,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||||
AttachmentPt &= 0x7f;
|
AttachmentPt &= 0x7f;
|
||||||
|
|
||||||
// Calls attach with a Zero position
|
// Calls attach with a Zero position
|
||||||
if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true))
|
if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true, false))
|
||||||
{
|
{
|
||||||
// m_log.Debug(
|
// m_log.Debug(
|
||||||
// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
|
// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
|
||||||
|
|
|
@ -189,7 +189,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||||
|
|
||||||
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
|
SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
|
||||||
|
|
||||||
scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false);
|
scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false);
|
||||||
|
|
||||||
// Check status on scene presence
|
// Check status on scene presence
|
||||||
Assert.That(sp.HasAttachments(), Is.True);
|
Assert.That(sp.HasAttachments(), Is.True);
|
||||||
|
@ -243,7 +243,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||||
sp2.AbsolutePosition = new Vector3(0, 0, 0);
|
sp2.AbsolutePosition = new Vector3(0, 0, 0);
|
||||||
sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero);
|
sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero);
|
||||||
|
|
||||||
scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false);
|
scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false, false);
|
||||||
|
|
||||||
Assert.That(sp.HasAttachments(), Is.False);
|
Assert.That(sp.HasAttachments(), Is.False);
|
||||||
Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
|
Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
|
||||||
|
|
|
@ -66,11 +66,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
scene.RegisterModuleInterface<IAvatarFactoryModule>(this);
|
scene.RegisterModuleInterface<IAvatarFactoryModule>(this);
|
||||||
scene.EventManager.OnNewClient += SubscribeToClientEvents;
|
scene.EventManager.OnNewClient += SubscribeToClientEvents;
|
||||||
|
|
||||||
IConfig sconfig = config.Configs["Startup"];
|
IConfig appearanceConfig = config.Configs["Appearance"];
|
||||||
if (sconfig != null)
|
if (appearanceConfig != null)
|
||||||
{
|
{
|
||||||
m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime)));
|
m_savetime = Convert.ToInt32(appearanceConfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime)));
|
||||||
m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime)));
|
m_sendtime = Convert.ToInt32(appearanceConfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime)));
|
||||||
// m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime);
|
// m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -596,9 +596,14 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "R":
|
case "R":
|
||||||
Font anewFont = new Font(myFont, FontStyle.Regular);
|
// We need to place this newFont inside its own context so that the .NET compiler
|
||||||
myFont.Dispose();
|
// doesn't complain about a redefinition of an existing newFont, even though there is none
|
||||||
myFont = anewFont;
|
// The mono compiler doesn't produce this error.
|
||||||
|
{
|
||||||
|
Font newFont = new Font(myFont, FontStyle.Regular);
|
||||||
|
myFont.Dispose();
|
||||||
|
myFont = newFont;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -768,4 +773,4 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,6 +137,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authentication
|
||||||
|
|
||||||
#region IAuthenticationService
|
#region IAuthenticationService
|
||||||
|
|
||||||
|
public string Authenticate(UUID principalID, string password, int lifetime, out UUID realID)
|
||||||
|
{
|
||||||
|
// Not implemented at the regions
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
public string Authenticate(UUID principalID, string password, int lifetime)
|
public string Authenticate(UUID principalID, string password, int lifetime)
|
||||||
{
|
{
|
||||||
// Not implemented at the regions
|
// Not implemented at the regions
|
||||||
|
|
|
@ -124,7 +124,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||||
LandData landData = lo.LandData;
|
LandData landData = lo.LandData;
|
||||||
string landDataPath = String.Format("{0}{1}.xml", ArchiveConstants.LANDDATA_PATH,
|
string landDataPath = String.Format("{0}{1}.xml", ArchiveConstants.LANDDATA_PATH,
|
||||||
landData.GlobalID.ToString());
|
landData.GlobalID.ToString());
|
||||||
m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData));
|
m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData, m_options));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.InfoFormat("[ARCHIVER]: Adding terrain information to archive.");
|
m_log.InfoFormat("[ARCHIVER]: Adding terrain information to archive.");
|
||||||
|
|
|
@ -84,7 +84,7 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
/// <param name="AttachmentPt"></param>
|
/// <param name="AttachmentPt"></param>
|
||||||
/// <param name="silent"></param>
|
/// <param name="silent"></param>
|
||||||
/// <returns>true if the object was successfully attached, false otherwise</returns>
|
/// <returns>true if the object was successfully attached, false otherwise</returns>
|
||||||
bool AttachObject(IScenePresence sp, SceneObjectGroup grp, uint AttachmentPt, bool silent, bool useAttachmentInfo);
|
bool AttachObject(IScenePresence sp, SceneObjectGroup grp, uint AttachmentPt, bool silent, bool useAttachmentInfo, bool temp);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rez an attachment from user inventory and change inventory status to match.
|
/// Rez an attachment from user inventory and change inventory status to match.
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Framework.Interfaces
|
||||||
|
{
|
||||||
|
public interface IRegionConsole
|
||||||
|
{
|
||||||
|
bool RunCommand(string command, UUID invokerID);
|
||||||
|
void SendConsoleOutput(UUID agentID, string message);
|
||||||
|
void AddCommand(string module, bool shared, string command, string help, string longhelp, CommandDelegate fn);
|
||||||
|
}
|
||||||
|
}
|
|
@ -117,5 +117,11 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
void RemoveRegionEnvironmentSettings(UUID regionUUID);
|
void RemoveRegionEnvironmentSettings(UUID regionUUID);
|
||||||
|
|
||||||
UUID[] GetObjectIDs(UUID regionID);
|
UUID[] GetObjectIDs(UUID regionID);
|
||||||
|
|
||||||
|
void SaveExtra(UUID regionID, string name, string value);
|
||||||
|
|
||||||
|
void RemoveExtra(UUID regionID, string name);
|
||||||
|
|
||||||
|
Dictionary<string, string> GetExtra(UUID regionID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,6 +128,12 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
/// <param name="regionUUID">the region UUID</param>
|
/// <param name="regionUUID">the region UUID</param>
|
||||||
void RemoveRegionEnvironmentSettings(UUID regionUUID);
|
void RemoveRegionEnvironmentSettings(UUID regionUUID);
|
||||||
|
|
||||||
|
void SaveExtra(UUID regionID, string name, string val);
|
||||||
|
|
||||||
|
void RemoveExtra(UUID regionID, string name);
|
||||||
|
|
||||||
|
Dictionary<string, string> GetExtra(UUID regionID);
|
||||||
|
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -217,6 +217,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public event NewScript OnNewScript;
|
public event NewScript OnNewScript;
|
||||||
|
|
||||||
|
public delegate void ExtraSettingChangedDelegate(Scene scene, string name, string value);
|
||||||
|
public event ExtraSettingChangedDelegate OnExtraSettingChanged;
|
||||||
|
|
||||||
public virtual void TriggerNewScript(UUID clientID, SceneObjectPart part, UUID itemID)
|
public virtual void TriggerNewScript(UUID clientID, SceneObjectPart part, UUID itemID)
|
||||||
{
|
{
|
||||||
NewScript handlerNewScript = OnNewScript;
|
NewScript handlerNewScript = OnNewScript;
|
||||||
|
@ -2616,5 +2619,25 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void TriggerExtraSettingChanged(Scene scene, string name, string val)
|
||||||
|
{
|
||||||
|
ExtraSettingChangedDelegate handler = OnExtraSettingChanged;
|
||||||
|
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
foreach (ExtraSettingChangedDelegate d in handler.GetInvocationList())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
d(scene, name, val);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("[EVENT MANAGER]: Delegate for ExtraSettingChanged failed - continuing {0} - {1}",
|
||||||
|
e.Message, e.StackTrace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,6 +177,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
protected ICapabilitiesModule m_capsModule;
|
protected ICapabilitiesModule m_capsModule;
|
||||||
protected IGroupsModule m_groupsModule;
|
protected IGroupsModule m_groupsModule;
|
||||||
|
|
||||||
|
private Dictionary<string, string> m_extraSettings;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Current scene frame number
|
/// Current scene frame number
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -658,6 +660,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// FIXME: It shouldn't be up to the database plugins to create this data - we should do it when a new
|
// FIXME: It shouldn't be up to the database plugins to create this data - we should do it when a new
|
||||||
// region is set up and avoid these gyrations.
|
// region is set up and avoid these gyrations.
|
||||||
RegionSettings rs = simDataService.LoadRegionSettings(RegionInfo.RegionID);
|
RegionSettings rs = simDataService.LoadRegionSettings(RegionInfo.RegionID);
|
||||||
|
m_extraSettings = simDataService.GetExtra(RegionInfo.RegionID);
|
||||||
|
|
||||||
bool updatedTerrainTextures = false;
|
bool updatedTerrainTextures = false;
|
||||||
if (rs.TerrainTexture1 == UUID.Zero)
|
if (rs.TerrainTexture1 == UUID.Zero)
|
||||||
{
|
{
|
||||||
|
@ -842,7 +846,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_update_presences = startupConfig.GetInt( "UpdateAgentsEveryNFrames", m_update_presences);
|
m_update_presences = startupConfig.GetInt( "UpdateAgentsEveryNFrames", m_update_presences);
|
||||||
m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain);
|
m_update_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain);
|
||||||
m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning);
|
m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning);
|
||||||
SendPeriodicAppearanceUpdates = startupConfig.GetBoolean("SendPeriodicAppearanceUpdates", SendPeriodicAppearanceUpdates);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -850,6 +853,14 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_log.Error("[SCENE]: Failed to load StartupConfig: " + e.ToString());
|
m_log.Error("[SCENE]: Failed to load StartupConfig: " + e.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Ultimately this should be in a module.
|
||||||
|
IConfig appearanceConfig = m_config.Configs["Appearance"];
|
||||||
|
if (appearanceConfig != null)
|
||||||
|
{
|
||||||
|
SendPeriodicAppearanceUpdates
|
||||||
|
= appearanceConfig.GetBoolean("ResendAppearanceUpdates", SendPeriodicAppearanceUpdates);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion Region Config
|
#endregion Region Config
|
||||||
|
|
||||||
#region Interest Management
|
#region Interest Management
|
||||||
|
@ -2748,7 +2759,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
|
RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
|
||||||
|
|
||||||
if (AttachmentsModule != null)
|
if (AttachmentsModule != null)
|
||||||
AttachmentsModule.AttachObject(sp, grp, 0, false, false);
|
AttachmentsModule.AttachObject(sp, grp, 0, false, false, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -5843,5 +5854,44 @@ Environment.Exit(1);
|
||||||
|
|
||||||
callback(asset);
|
callback(asset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string GetExtraSetting(string name)
|
||||||
|
{
|
||||||
|
string val;
|
||||||
|
|
||||||
|
if (!m_extraSettings.TryGetValue(name, out val))
|
||||||
|
return String.Empty;
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StoreExtraSetting(string name, string val)
|
||||||
|
{
|
||||||
|
string oldVal;
|
||||||
|
|
||||||
|
if (m_extraSettings.TryGetValue(name, out oldVal))
|
||||||
|
{
|
||||||
|
if (oldVal == val)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_extraSettings[name] = val;
|
||||||
|
|
||||||
|
m_SimulationDataService.SaveExtra(RegionInfo.RegionID, name, val);
|
||||||
|
|
||||||
|
m_eventManager.TriggerExtraSettingChanged(this, name, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveExtraSetting(string name)
|
||||||
|
{
|
||||||
|
if (!m_extraSettings.ContainsKey(name))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_extraSettings.Remove(name);
|
||||||
|
|
||||||
|
m_SimulationDataService.RemoveExtra(RegionInfo.RegionID, name);
|
||||||
|
|
||||||
|
m_eventManager.TriggerExtraSettingChanged(this, name, String.Empty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1793,7 +1793,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
parentGroup.areUpdatesSuspended = true;
|
|
||||||
|
|
||||||
List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
|
List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
|
||||||
|
|
||||||
|
@ -1850,7 +1849,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
SceneObjectGroupsByLocalPartID[part.LocalId] = parentGroup;
|
SceneObjectGroupsByLocalPartID[part.LocalId] = parentGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
parentGroup.areUpdatesSuspended = false;
|
|
||||||
parentGroup.HasGroupChanged = true;
|
parentGroup.HasGroupChanged = true;
|
||||||
parentGroup.ProcessBackup(m_parentScene.SimulationDataService, true);
|
parentGroup.ProcessBackup(m_parentScene.SimulationDataService, true);
|
||||||
parentGroup.ScheduleGroupForFullUpdate();
|
parentGroup.ScheduleGroupForFullUpdate();
|
||||||
|
@ -1896,7 +1894,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
SceneObjectGroup group = part.ParentGroup;
|
SceneObjectGroup group = part.ParentGroup;
|
||||||
if (!affectedGroups.Contains(group))
|
if (!affectedGroups.Contains(group))
|
||||||
{
|
{
|
||||||
group.areUpdatesSuspended = true;
|
|
||||||
affectedGroups.Add(group);
|
affectedGroups.Add(group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1922,7 +1919,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// However, editing linked parts and unlinking may be different
|
// However, editing linked parts and unlinking may be different
|
||||||
//
|
//
|
||||||
SceneObjectGroup group = root.ParentGroup;
|
SceneObjectGroup group = root.ParentGroup;
|
||||||
group.areUpdatesSuspended = true;
|
|
||||||
|
|
||||||
List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts);
|
List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts);
|
||||||
int numChildren = newSet.Count;
|
int numChildren = newSet.Count;
|
||||||
|
@ -1945,7 +1941,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
group.DelinkFromGroup(p, sendEventsToRemainder);
|
group.DelinkFromGroup(p, sendEventsToRemainder);
|
||||||
if (numChildren > 2)
|
if (numChildren > 2)
|
||||||
{
|
{
|
||||||
p.ParentGroup.areUpdatesSuspended = true;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1980,7 +1975,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
foreach (SceneObjectPart newChild in newSet)
|
foreach (SceneObjectPart newChild in newSet)
|
||||||
newChild.ClearUpdateSchedule();
|
newChild.ClearUpdateSchedule();
|
||||||
|
|
||||||
newRoot.ParentGroup.areUpdatesSuspended = true;
|
|
||||||
LinkObjects(newRoot, newSet);
|
LinkObjects(newRoot, newSet);
|
||||||
if (!affectedGroups.Contains(newRoot.ParentGroup))
|
if (!affectedGroups.Contains(newRoot.ParentGroup))
|
||||||
affectedGroups.Add(newRoot.ParentGroup);
|
affectedGroups.Add(newRoot.ParentGroup);
|
||||||
|
@ -1998,7 +1992,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_parentScene.SimulationDataService.RemoveObject(g.UUID, m_parentScene.RegionInfo.RegionID);
|
m_parentScene.SimulationDataService.RemoveObject(g.UUID, m_parentScene.RegionInfo.RegionID);
|
||||||
g.TriggerScriptChangedEvent(Changed.LINK);
|
g.TriggerScriptChangedEvent(Changed.LINK);
|
||||||
g.HasGroupChanged = true; // Persist
|
g.HasGroupChanged = true; // Persist
|
||||||
g.areUpdatesSuspended = false;
|
|
||||||
g.ScheduleGroupForFullUpdate();
|
g.ScheduleGroupForFullUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,25 +113,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
private long m_maxPersistTime = 0;
|
private long m_maxPersistTime = 0;
|
||||||
private long m_minPersistTime = 0;
|
private long m_minPersistTime = 0;
|
||||||
private Random m_rand;
|
private Random m_rand;
|
||||||
private bool m_suspendUpdates;
|
|
||||||
private List<ScenePresence> m_linkedAvatars = new List<ScenePresence>();
|
private List<ScenePresence> m_linkedAvatars = new List<ScenePresence>();
|
||||||
|
|
||||||
public bool areUpdatesSuspended
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return m_suspendUpdates;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
m_suspendUpdates = value;
|
|
||||||
if (!value)
|
|
||||||
{
|
|
||||||
QueueForUpdateCheck();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This indicates whether the object has changed such that it needs to be repersisted to permenant storage
|
/// This indicates whether the object has changed such that it needs to be repersisted to permenant storage
|
||||||
/// (the database).
|
/// (the database).
|
||||||
|
@ -951,7 +934,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// its existing localID and UUID.
|
/// its existing localID and UUID.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name='part'>Root part for this scene object.</param>
|
/// <param name='part'>Root part for this scene object.</param>
|
||||||
public SceneObjectGroup(SceneObjectPart part)
|
public SceneObjectGroup(SceneObjectPart part) : this()
|
||||||
{
|
{
|
||||||
SetRootPart(part);
|
SetRootPart(part);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,189 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using log4net;
|
||||||
|
using Mono.Addins;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Console;
|
||||||
|
using OpenSim.Framework.Monitoring;
|
||||||
|
using OpenSim.Region.ClientStack.LindenUDP;
|
||||||
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.OptionalModules.Avatar.Attachments
|
||||||
|
{
|
||||||
|
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "TempAttachmentsModule")]
|
||||||
|
public class TempAttachmentsModule : INonSharedRegionModule
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private Scene m_scene;
|
||||||
|
private IRegionConsole m_console;
|
||||||
|
|
||||||
|
public void Initialise(IConfigSource configSource)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRegion(Scene scene)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveRegion(Scene scene)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegionLoaded(Scene scene)
|
||||||
|
{
|
||||||
|
m_scene = scene;
|
||||||
|
|
||||||
|
IScriptModuleComms comms = scene.RequestModuleInterface<IScriptModuleComms>();
|
||||||
|
if (comms != null)
|
||||||
|
{
|
||||||
|
comms.RegisterScriptInvocation( this, "llAttachToAvatarTemp");
|
||||||
|
m_log.DebugFormat("[TEMP ATTACHS]: Registered script functions");
|
||||||
|
m_console = scene.RequestModuleInterface<IRegionConsole>();
|
||||||
|
|
||||||
|
if (m_console != null)
|
||||||
|
{
|
||||||
|
m_console.AddCommand("TempATtachModule", false, "set auto_grant_attach_perms", "set auto_grant_attach_perms true|false", "Allow objects owned by the region owner os estate managers to obtain attach permissions without asking the user", SetAutoGrantAttachPerms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("[TEMP ATTACHS]: Failed to register script functions");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type ReplaceableInterface
|
||||||
|
{
|
||||||
|
get { return null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return "TempAttachmentsModule"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SendConsoleOutput(UUID agentID, string text)
|
||||||
|
{
|
||||||
|
if (m_console == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_console.SendConsoleOutput(agentID, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetAutoGrantAttachPerms(string module, string[] parms)
|
||||||
|
{
|
||||||
|
UUID agentID = new UUID(parms[parms.Length - 1]);
|
||||||
|
Array.Resize(ref parms, parms.Length - 1);
|
||||||
|
|
||||||
|
if (parms.Length != 3)
|
||||||
|
{
|
||||||
|
SendConsoleOutput(agentID, "Command parameter error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string val = parms[2];
|
||||||
|
if (val != "true" && val != "false")
|
||||||
|
{
|
||||||
|
SendConsoleOutput(agentID, "Command parameter error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_scene.StoreExtraSetting("auto_grant_attach_perms", val);
|
||||||
|
|
||||||
|
SendConsoleOutput(agentID, String.Format("auto_grant_attach_perms set to {0}", val));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void llAttachToAvatarTemp(UUID host, UUID script, int attachmentPoint)
|
||||||
|
{
|
||||||
|
SceneObjectPart hostPart = m_scene.GetSceneObjectPart(host);
|
||||||
|
|
||||||
|
if (hostPart == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (hostPart.ParentGroup.IsAttachment)
|
||||||
|
return;
|
||||||
|
|
||||||
|
IAttachmentsModule attachmentsModule = m_scene.RequestModuleInterface<IAttachmentsModule>();
|
||||||
|
if (attachmentsModule == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
TaskInventoryItem item = hostPart.Inventory.GetInventoryItem(script);
|
||||||
|
if (item == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((item.PermsMask & 32) == 0) // PERMISSION_ATTACH
|
||||||
|
return;
|
||||||
|
|
||||||
|
ScenePresence target;
|
||||||
|
if (!m_scene.TryGetScenePresence(item.PermsGranter, out target))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (target.UUID != hostPart.ParentGroup.OwnerID)
|
||||||
|
{
|
||||||
|
uint effectivePerms = hostPart.ParentGroup.GetEffectivePermissions();
|
||||||
|
|
||||||
|
if ((effectivePerms & (uint)PermissionMask.Transfer) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hostPart.ParentGroup.SetOwnerId(target.UUID);
|
||||||
|
hostPart.ParentGroup.SetRootPartOwner(hostPart.ParentGroup.RootPart, target.UUID, target.ControllingClient.ActiveGroupId);
|
||||||
|
|
||||||
|
if (m_scene.Permissions.PropagatePermissions())
|
||||||
|
{
|
||||||
|
foreach (SceneObjectPart child in hostPart.ParentGroup.Parts)
|
||||||
|
{
|
||||||
|
child.Inventory.ChangeInventoryOwner(target.UUID);
|
||||||
|
child.TriggerScriptChangedEvent(Changed.OWNER);
|
||||||
|
child.ApplyNextOwnerPermissions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hostPart.ParentGroup.RootPart.ObjectSaleType = 0;
|
||||||
|
hostPart.ParentGroup.RootPart.SalePrice = 10;
|
||||||
|
|
||||||
|
hostPart.ParentGroup.HasGroupChanged = true;
|
||||||
|
hostPart.ParentGroup.RootPart.SendPropertiesToClient(target.ControllingClient);
|
||||||
|
hostPart.ParentGroup.RootPart.ScheduleFullUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -469,8 +469,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
|
||||||
avatarName = avatar.Name;
|
avatarName = avatar.Name;
|
||||||
|
|
||||||
m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: scene = {0}, agentID = {1}", scene, agentID);
|
m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: scene = {0}, agentID = {1}", scene, agentID);
|
||||||
m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}",
|
// m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}",
|
||||||
request, path, param);
|
// request, path, param);
|
||||||
|
|
||||||
XmlElement resp;
|
XmlElement resp;
|
||||||
bool retry = false;
|
bool retry = false;
|
||||||
|
@ -577,7 +577,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
|
||||||
|
|
||||||
string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse);
|
string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse);
|
||||||
|
|
||||||
m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: avatar \"{0}\": {1}", avatarName, r);
|
// m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: avatar \"{0}\": {1}", avatarName, r);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -625,8 +625,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
|
||||||
// voice channel
|
// voice channel
|
||||||
LandData land = scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
|
LandData land = scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y);
|
||||||
|
|
||||||
m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}",
|
// m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}",
|
||||||
scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param);
|
// scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param);
|
||||||
// m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: avatar \"{0}\": location: {1} {2} {3}",
|
// m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: avatar \"{0}\": location: {1} {2} {3}",
|
||||||
// avatarName, avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z);
|
// avatarName, avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z);
|
||||||
|
|
||||||
|
@ -656,8 +656,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
|
||||||
parcelVoiceInfo = new LLSDParcelVoiceInfoResponse(scene.RegionInfo.RegionName, land.LocalID, creds);
|
parcelVoiceInfo = new LLSDParcelVoiceInfoResponse(scene.RegionInfo.RegionName, land.LocalID, creds);
|
||||||
string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo);
|
string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo);
|
||||||
|
|
||||||
m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": {4}",
|
// m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": {4}",
|
||||||
scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, r);
|
// scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, r);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -684,11 +684,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
|
||||||
public string ChatSessionRequest(Scene scene, string request, string path, string param,
|
public string ChatSessionRequest(Scene scene, string request, string path, string param,
|
||||||
UUID agentID, Caps caps)
|
UUID agentID, Caps caps)
|
||||||
{
|
{
|
||||||
ScenePresence avatar = scene.GetScenePresence(agentID);
|
// ScenePresence avatar = scene.GetScenePresence(agentID);
|
||||||
string avatarName = avatar.Name;
|
// string avatarName = avatar.Name;
|
||||||
|
|
||||||
m_log.DebugFormat("[VivoxVoice][CHATSESSION]: avatar \"{0}\": request: {1}, path: {2}, param: {3}",
|
// m_log.DebugFormat("[VivoxVoice][CHATSESSION]: avatar \"{0}\": request: {1}, path: {2}, param: {3}",
|
||||||
avatarName, request, path, param);
|
// avatarName, request, path, param);
|
||||||
return "<llsd>true</llsd>";
|
return "<llsd>true</llsd>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1119,7 +1119,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Otherwise prepare the request
|
// Otherwise prepare the request
|
||||||
m_log.DebugFormat("[VivoxVoice] Sending request <{0}>", requrl);
|
// m_log.DebugFormat("[VivoxVoice] Sending request <{0}>", requrl);
|
||||||
|
|
||||||
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requrl);
|
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requrl);
|
||||||
HttpWebResponse rsp = null;
|
HttpWebResponse rsp = null;
|
||||||
|
|
|
@ -124,9 +124,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, owner, senseAsAgent, scene);
|
NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, owner, senseAsAgent, scene);
|
||||||
npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0, int.MaxValue);
|
npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0, int.MaxValue);
|
||||||
|
|
||||||
m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
"[NPC MODULE]: Creating NPC {0} {1} {2}, owner={3}, senseAsAgent={4} at {5} in {6}",
|
// "[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);
|
// firstname, lastname, npcAvatar.AgentId, owner, senseAsAgent, position, scene.RegionInfo.RegionName);
|
||||||
|
|
||||||
AgentCircuitData acd = new AgentCircuitData();
|
AgentCircuitData acd = new AgentCircuitData();
|
||||||
acd.AgentID = npcAvatar.AgentId;
|
acd.AgentID = npcAvatar.AgentId;
|
||||||
|
@ -157,7 +157,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
{
|
{
|
||||||
sp.CompleteMovement(npcAvatar, false);
|
sp.CompleteMovement(npcAvatar, false);
|
||||||
m_avatars.Add(npcAvatar.AgentId, npcAvatar);
|
m_avatars.Add(npcAvatar.AgentId, npcAvatar);
|
||||||
m_log.DebugFormat("[NPC MODULE]: Created NPC {0} {1}", npcAvatar.AgentId, sp.Name);
|
// m_log.DebugFormat("[NPC MODULE]: Created NPC {0} {1}", npcAvatar.AgentId, sp.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ev.Set();
|
ev.Set();
|
||||||
|
@ -177,16 +177,17 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
if (m_avatars.ContainsKey(agentID))
|
if (m_avatars.ContainsKey(agentID))
|
||||||
{
|
{
|
||||||
ScenePresence sp;
|
ScenePresence sp;
|
||||||
scene.TryGetScenePresence(agentID, out sp);
|
if (scene.TryGetScenePresence(agentID, out sp))
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[NPC MODULE]: Moving {0} to {1} in {2}, noFly {3}, landAtTarget {4}",
|
||||||
|
// sp.Name, pos, scene.RegionInfo.RegionName, noFly, landAtTarget);
|
||||||
|
|
||||||
m_log.DebugFormat(
|
sp.MoveToTarget(pos, noFly, landAtTarget);
|
||||||
"[NPC MODULE]: Moving {0} to {1} in {2}, noFly {3}, landAtTarget {4}",
|
sp.SetAlwaysRun = running;
|
||||||
sp.Name, pos, scene.RegionInfo.RegionName, noFly, landAtTarget);
|
|
||||||
|
return true;
|
||||||
sp.MoveToTarget(pos, noFly, landAtTarget);
|
}
|
||||||
sp.SetAlwaysRun = running;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,12 +201,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
if (m_avatars.ContainsKey(agentID))
|
if (m_avatars.ContainsKey(agentID))
|
||||||
{
|
{
|
||||||
ScenePresence sp;
|
ScenePresence sp;
|
||||||
scene.TryGetScenePresence(agentID, out sp);
|
if (scene.TryGetScenePresence(agentID, out sp))
|
||||||
|
{
|
||||||
|
sp.Velocity = Vector3.Zero;
|
||||||
|
sp.ResetMoveToTarget();
|
||||||
|
|
||||||
sp.Velocity = Vector3.Zero;
|
return true;
|
||||||
sp.ResetMoveToTarget();
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,9 +225,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
{
|
{
|
||||||
if (m_avatars.ContainsKey(agentID))
|
if (m_avatars.ContainsKey(agentID))
|
||||||
{
|
{
|
||||||
ScenePresence sp;
|
|
||||||
scene.TryGetScenePresence(agentID, out sp);
|
|
||||||
|
|
||||||
m_avatars[agentID].Say(channel, text);
|
m_avatars[agentID].Say(channel, text);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -241,9 +240,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
{
|
{
|
||||||
if (m_avatars.ContainsKey(agentID))
|
if (m_avatars.ContainsKey(agentID))
|
||||||
{
|
{
|
||||||
ScenePresence sp;
|
|
||||||
scene.TryGetScenePresence(agentID, out sp);
|
|
||||||
|
|
||||||
m_avatars[agentID].Shout(channel, text);
|
m_avatars[agentID].Shout(channel, text);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -260,11 +256,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
if (m_avatars.ContainsKey(agentID))
|
if (m_avatars.ContainsKey(agentID))
|
||||||
{
|
{
|
||||||
ScenePresence sp;
|
ScenePresence sp;
|
||||||
scene.TryGetScenePresence(agentID, out sp);
|
if (scene.TryGetScenePresence(agentID, out sp))
|
||||||
sp.HandleAgentRequestSit(m_avatars[agentID], agentID, partID, Vector3.Zero);
|
{
|
||||||
// sp.HandleAgentSit(m_avatars[agentID], agentID);
|
sp.HandleAgentRequestSit(m_avatars[agentID], agentID, partID, Vector3.Zero);
|
||||||
|
// sp.HandleAgentSit(m_avatars[agentID], agentID);
|
||||||
return true;
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,9 +275,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
{
|
{
|
||||||
if (m_avatars.ContainsKey(agentID))
|
if (m_avatars.ContainsKey(agentID))
|
||||||
{
|
{
|
||||||
ScenePresence sp;
|
|
||||||
scene.TryGetScenePresence(agentID, out sp);
|
|
||||||
|
|
||||||
m_avatars[agentID].Whisper(channel, text);
|
m_avatars[agentID].Whisper(channel, text);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -296,10 +291,12 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
if (m_avatars.ContainsKey(agentID))
|
if (m_avatars.ContainsKey(agentID))
|
||||||
{
|
{
|
||||||
ScenePresence sp;
|
ScenePresence sp;
|
||||||
scene.TryGetScenePresence(agentID, out sp);
|
if (scene.TryGetScenePresence(agentID, out sp))
|
||||||
sp.StandUp();
|
{
|
||||||
|
sp.StandUp();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,6 +309,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
{
|
{
|
||||||
if (m_avatars.ContainsKey(agentID))
|
if (m_avatars.ContainsKey(agentID))
|
||||||
return m_avatars[agentID].Touch(objectID);
|
return m_avatars[agentID].Touch(objectID);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -322,9 +320,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
{
|
{
|
||||||
NPCAvatar av;
|
NPCAvatar av;
|
||||||
if (m_avatars.TryGetValue(agentID, out av))
|
if (m_avatars.TryGetValue(agentID, out av))
|
||||||
{
|
|
||||||
return av.OwnerID;
|
return av.OwnerID;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return UUID.Zero;
|
return UUID.Zero;
|
||||||
|
@ -352,7 +348,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
scene.RemoveClient(agentID, false);
|
scene.RemoveClient(agentID, false);
|
||||||
m_avatars.Remove(agentID);
|
m_avatars.Remove(agentID);
|
||||||
|
|
||||||
m_log.DebugFormat("[NPC MODULE]: Removed NPC {0} {1}", agentID, av.Name);
|
// m_log.DebugFormat("[NPC MODULE]: Removed NPC {0} {1}", agentID, av.Name);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
/*
|
||||||
|
* 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 copyrightD
|
||||||
|
* 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.Text;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
|
{
|
||||||
|
|
||||||
|
public class BS6DofConstraint : BSConstraint
|
||||||
|
{
|
||||||
|
// Create a btGeneric6DofConstraint
|
||||||
|
public BS6DofConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
|
||||||
|
Vector3 frame1, Quaternion frame1rot,
|
||||||
|
Vector3 frame2, Quaternion frame2rot,
|
||||||
|
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
|
||||||
|
{
|
||||||
|
m_world = world;
|
||||||
|
m_body1 = obj1;
|
||||||
|
m_body2 = obj2;
|
||||||
|
m_constraint = new BulletConstraint(
|
||||||
|
BulletSimAPI.Create6DofConstraint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr,
|
||||||
|
frame1, frame1rot,
|
||||||
|
frame2, frame2rot,
|
||||||
|
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies));
|
||||||
|
m_enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BS6DofConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
|
||||||
|
Vector3 joinPoint,
|
||||||
|
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
|
||||||
|
{
|
||||||
|
m_world = world;
|
||||||
|
m_body1 = obj1;
|
||||||
|
m_body2 = obj2;
|
||||||
|
m_constraint = new BulletConstraint(
|
||||||
|
BulletSimAPI.Create6DofConstraintToPoint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr,
|
||||||
|
joinPoint,
|
||||||
|
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies));
|
||||||
|
m_enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetFrames(Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
if (m_enabled)
|
||||||
|
{
|
||||||
|
BulletSimAPI.SetFrames2(m_constraint.Ptr, frameA, frameArot, frameB, frameBrot);
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetCFMAndERP(float cfm, float erp)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
if (m_enabled)
|
||||||
|
{
|
||||||
|
BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL);
|
||||||
|
BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL);
|
||||||
|
BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL);
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool UseFrameOffset(bool useOffset)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
float onOff = useOffset ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse;
|
||||||
|
if (m_enabled)
|
||||||
|
ret = BulletSimAPI.UseFrameOffset2(m_constraint.Ptr, onOff);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TranslationalLimitMotor(bool enable, float targetVelocity, float maxMotorForce)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
float onOff = enable ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse;
|
||||||
|
if (m_enabled)
|
||||||
|
ret = BulletSimAPI.TranslationalLimitMotor2(m_constraint.Ptr, onOff, targetVelocity, maxMotorForce);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SetBreakingImpulseThreshold(float threshold)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
if (m_enabled)
|
||||||
|
ret = BulletSimAPI.SetBreakingImpulseThreshold2(m_constraint.Ptr, threshold);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,6 +40,7 @@ public class BSCharacter : PhysicsActor
|
||||||
private static readonly string LogHeader = "[BULLETS CHAR]";
|
private static readonly string LogHeader = "[BULLETS CHAR]";
|
||||||
|
|
||||||
private BSScene _scene;
|
private BSScene _scene;
|
||||||
|
public BSScene Scene { get { return _scene; } }
|
||||||
private String _avName;
|
private String _avName;
|
||||||
// private bool _stopped;
|
// private bool _stopped;
|
||||||
private Vector3 _size;
|
private Vector3 _size;
|
||||||
|
@ -73,6 +74,12 @@ public class BSCharacter : PhysicsActor
|
||||||
private bool _kinematic;
|
private bool _kinematic;
|
||||||
private float _buoyancy;
|
private float _buoyancy;
|
||||||
|
|
||||||
|
private BulletBody m_body;
|
||||||
|
public BulletBody Body {
|
||||||
|
get { return m_body; }
|
||||||
|
set { m_body = value; }
|
||||||
|
}
|
||||||
|
|
||||||
private int _subscribedEventsMs = 0;
|
private int _subscribedEventsMs = 0;
|
||||||
private int _nextCollisionOkTime = 0;
|
private int _nextCollisionOkTime = 0;
|
||||||
|
|
||||||
|
@ -95,7 +102,9 @@ public class BSCharacter : PhysicsActor
|
||||||
_orientation = Quaternion.Identity;
|
_orientation = Quaternion.Identity;
|
||||||
_velocity = Vector3.Zero;
|
_velocity = Vector3.Zero;
|
||||||
_buoyancy = ComputeBuoyancyFromFlying(isFlying);
|
_buoyancy = ComputeBuoyancyFromFlying(isFlying);
|
||||||
_scale = new Vector3(1f, 1f, 1f);
|
// The dimensions of the avatar capsule are kept in the scale.
|
||||||
|
// Physics creates a unit capsule which is scaled by the physics engine.
|
||||||
|
_scale = new Vector3(_scene.Params.avatarCapsuleRadius, _scene.Params.avatarCapsuleRadius, size.Z);
|
||||||
_density = _scene.Params.avatarDensity;
|
_density = _scene.Params.avatarDensity;
|
||||||
ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale
|
ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale
|
||||||
|
|
||||||
|
@ -113,9 +122,13 @@ public class BSCharacter : PhysicsActor
|
||||||
shapeData.Restitution = _scene.Params.avatarRestitution;
|
shapeData.Restitution = _scene.Params.avatarRestitution;
|
||||||
|
|
||||||
// do actual create at taint time
|
// do actual create at taint time
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSCharacter.create", delegate()
|
||||||
{
|
{
|
||||||
BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData);
|
BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData);
|
||||||
|
|
||||||
|
m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
|
||||||
|
// avatars get all collisions no matter what
|
||||||
|
BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -124,7 +137,8 @@ public class BSCharacter : PhysicsActor
|
||||||
// called when this character is being destroyed and the resources should be released
|
// called when this character is being destroyed and the resources should be released
|
||||||
public void Destroy()
|
public void Destroy()
|
||||||
{
|
{
|
||||||
_scene.TaintedObject(delegate()
|
// DetailLog("{0},BSCharacter.Destroy", LocalID);
|
||||||
|
_scene.TaintedObject("BSCharacter.destroy", delegate()
|
||||||
{
|
{
|
||||||
BulletSimAPI.DestroyObject(_scene.WorldID, _localID);
|
BulletSimAPI.DestroyObject(_scene.WorldID, _localID);
|
||||||
});
|
});
|
||||||
|
@ -138,9 +152,28 @@ public class BSCharacter : PhysicsActor
|
||||||
public override bool Stopped {
|
public override bool Stopped {
|
||||||
get { return false; }
|
get { return false; }
|
||||||
}
|
}
|
||||||
public override Vector3 Size {
|
public override Vector3 Size {
|
||||||
get { return _size; }
|
get
|
||||||
set { _size = value;
|
{
|
||||||
|
// Avatar capsule size is kept in the scale parameter.
|
||||||
|
return new Vector3(_scale.X * 2, _scale.Y * 2, _scale.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
set {
|
||||||
|
// When an avatar's size is set, only the height is changed
|
||||||
|
// and that really only depends on the radius.
|
||||||
|
_size = value;
|
||||||
|
_scale.Z = (_size.Z * 1.15f) - (_scale.X + _scale.Y);
|
||||||
|
|
||||||
|
// TODO: something has to be done with the avatar's vertical position
|
||||||
|
|
||||||
|
ComputeAvatarVolumeAndMass();
|
||||||
|
|
||||||
|
_scene.TaintedObject("BSCharacter.setSize", delegate()
|
||||||
|
{
|
||||||
|
BulletSimAPI.SetObjectScaleMass(_scene.WorldID, LocalID, _scale, _mass, true);
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public override PrimitiveBaseShape Shape {
|
public override PrimitiveBaseShape Shape {
|
||||||
|
@ -172,12 +205,37 @@ public class BSCharacter : PhysicsActor
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
_position = value;
|
_position = value;
|
||||||
_scene.TaintedObject(delegate()
|
PositionSanityCheck();
|
||||||
|
|
||||||
|
_scene.TaintedObject("BSCharacter.setPosition", delegate()
|
||||||
{
|
{
|
||||||
|
DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||||
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
|
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check that the current position is sane and, if not, modify the position to make it so.
|
||||||
|
// Check for being below terrain and being out of bounds.
|
||||||
|
// Returns 'true' of the position was made sane by some action.
|
||||||
|
private bool PositionSanityCheck()
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
// If below the ground, move the avatar up
|
||||||
|
float terrainHeight = Scene.GetTerrainHeightAtXYZ(_position);
|
||||||
|
if (_position.Z < terrainHeight)
|
||||||
|
{
|
||||||
|
DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||||
|
_position.Z = terrainHeight + 2.0f;
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: check for out of bounds
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
public override float Mass {
|
public override float Mass {
|
||||||
get {
|
get {
|
||||||
return _mass;
|
return _mass;
|
||||||
|
@ -188,9 +246,10 @@ public class BSCharacter : PhysicsActor
|
||||||
set {
|
set {
|
||||||
_force = value;
|
_force = value;
|
||||||
// m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force);
|
// m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force);
|
||||||
_scene.TaintedObject(delegate()
|
Scene.TaintedObject("BSCharacter.SetForce", delegate()
|
||||||
{
|
{
|
||||||
BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
|
DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force);
|
||||||
|
BulletSimAPI.SetObjectForce(Scene.WorldID, LocalID, _force);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,8 +273,9 @@ public class BSCharacter : PhysicsActor
|
||||||
set {
|
set {
|
||||||
_velocity = value;
|
_velocity = value;
|
||||||
// m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity);
|
// m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity);
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSCharacter.setVelocity", delegate()
|
||||||
{
|
{
|
||||||
|
DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity);
|
||||||
BulletSimAPI.SetObjectVelocity(_scene.WorldID, _localID, _velocity);
|
BulletSimAPI.SetObjectVelocity(_scene.WorldID, _localID, _velocity);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -239,7 +299,7 @@ public class BSCharacter : PhysicsActor
|
||||||
set {
|
set {
|
||||||
_orientation = value;
|
_orientation = value;
|
||||||
// m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation);
|
// m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation);
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSCharacter.setOrientation", delegate()
|
||||||
{
|
{
|
||||||
// _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
|
// _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
|
||||||
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
|
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
|
||||||
|
@ -259,9 +319,12 @@ public class BSCharacter : PhysicsActor
|
||||||
public override bool Flying {
|
public override bool Flying {
|
||||||
get { return _flying; }
|
get { return _flying; }
|
||||||
set {
|
set {
|
||||||
_flying = value;
|
if (_flying != value)
|
||||||
// simulate flying by changing the effect of gravity
|
{
|
||||||
this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
|
_flying = value;
|
||||||
|
// simulate flying by changing the effect of gravity
|
||||||
|
this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private float ComputeBuoyancyFromFlying(bool ifFlying) {
|
private float ComputeBuoyancyFromFlying(bool ifFlying) {
|
||||||
|
@ -303,8 +366,9 @@ public class BSCharacter : PhysicsActor
|
||||||
public override float Buoyancy {
|
public override float Buoyancy {
|
||||||
get { return _buoyancy; }
|
get { return _buoyancy; }
|
||||||
set { _buoyancy = value;
|
set { _buoyancy = value;
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSCharacter.setBuoyancy", delegate()
|
||||||
{
|
{
|
||||||
|
DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
|
||||||
BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy);
|
BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -349,9 +413,10 @@ public class BSCharacter : PhysicsActor
|
||||||
_force.Y += force.Y;
|
_force.Y += force.Y;
|
||||||
_force.Z += force.Z;
|
_force.Z += force.Z;
|
||||||
// m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force);
|
// m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force);
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSCharacter.AddForce", delegate()
|
||||||
{
|
{
|
||||||
BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
|
DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force);
|
||||||
|
BulletSimAPI.AddObjectForce2(Body.Ptr, _force);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -369,11 +434,25 @@ public class BSCharacter : PhysicsActor
|
||||||
// Turn on collision events at a rate no faster than one every the given milliseconds
|
// Turn on collision events at a rate no faster than one every the given milliseconds
|
||||||
public override void SubscribeEvents(int ms) {
|
public override void SubscribeEvents(int ms) {
|
||||||
_subscribedEventsMs = ms;
|
_subscribedEventsMs = ms;
|
||||||
_nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs; // make first collision happen
|
if (ms > 0)
|
||||||
|
{
|
||||||
|
// make sure first collision happens
|
||||||
|
_nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs;
|
||||||
|
|
||||||
|
Scene.TaintedObject("BSCharacter.SubscribeEvents", delegate()
|
||||||
|
{
|
||||||
|
BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Stop collision events
|
// Stop collision events
|
||||||
public override void UnSubscribeEvents() {
|
public override void UnSubscribeEvents() {
|
||||||
_subscribedEventsMs = 0;
|
_subscribedEventsMs = 0;
|
||||||
|
// Avatars get all their collision events
|
||||||
|
// Scene.TaintedObject("BSCharacter.UnSubscribeEvents", delegate()
|
||||||
|
// {
|
||||||
|
// BulletSimAPI.RemoveFromCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
// Return 'true' if someone has subscribed to events
|
// Return 'true' if someone has subscribed to events
|
||||||
public override bool SubscribedEvents() {
|
public override bool SubscribedEvents() {
|
||||||
|
@ -385,9 +464,15 @@ public class BSCharacter : PhysicsActor
|
||||||
{
|
{
|
||||||
_avatarVolume = (float)(
|
_avatarVolume = (float)(
|
||||||
Math.PI
|
Math.PI
|
||||||
* _scene.Params.avatarCapsuleRadius * _scale.X
|
* _scale.X
|
||||||
* _scene.Params.avatarCapsuleRadius * _scale.Y
|
* _scale.Y // the area of capsule cylinder
|
||||||
* _scene.Params.avatarCapsuleHeight * _scale.Z);
|
* _scale.Z // times height of capsule cylinder
|
||||||
|
+ 1.33333333f
|
||||||
|
* Math.PI
|
||||||
|
* _scale.X
|
||||||
|
* Math.Min(_scale.X, _scale.Y)
|
||||||
|
* _scale.Y // plus the volume of the capsule end caps
|
||||||
|
);
|
||||||
_mass = _density * _avatarVolume;
|
_mass = _density * _avatarVolume;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,43 +480,19 @@ public class BSCharacter : PhysicsActor
|
||||||
// the world that things have changed.
|
// the world that things have changed.
|
||||||
public void UpdateProperties(EntityProperties entprop)
|
public void UpdateProperties(EntityProperties entprop)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
bool changed = false;
|
|
||||||
// we assign to the local variables so the normal set action does not happen
|
|
||||||
if (_position != entprop.Position) {
|
|
||||||
_position = entprop.Position;
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
if (_orientation != entprop.Rotation) {
|
|
||||||
_orientation = entprop.Rotation;
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
if (_velocity != entprop.Velocity) {
|
|
||||||
_velocity = entprop.Velocity;
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
if (_acceleration != entprop.Acceleration) {
|
|
||||||
_acceleration = entprop.Acceleration;
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
if (_rotationalVelocity != entprop.RotationalVelocity) {
|
|
||||||
_rotationalVelocity = entprop.RotationalVelocity;
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
if (changed) {
|
|
||||||
// m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
|
|
||||||
// Avatar movement is not done by generating this event. There is code in the heartbeat
|
|
||||||
// loop that updates avatars.
|
|
||||||
// base.RequestPhysicsterseUpdate();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
_position = entprop.Position;
|
_position = entprop.Position;
|
||||||
_orientation = entprop.Rotation;
|
_orientation = entprop.Rotation;
|
||||||
_velocity = entprop.Velocity;
|
_velocity = entprop.Velocity;
|
||||||
_acceleration = entprop.Acceleration;
|
_acceleration = entprop.Acceleration;
|
||||||
_rotationalVelocity = entprop.RotationalVelocity;
|
_rotationalVelocity = entprop.RotationalVelocity;
|
||||||
// Avatars don't report theirr changes the usual way. Changes are checked for in the heartbeat loop.
|
// Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
|
||||||
// base.RequestPhysicsterseUpdate();
|
// base.RequestPhysicsterseUpdate();
|
||||||
|
|
||||||
|
/*
|
||||||
|
DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
|
||||||
|
LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,
|
||||||
|
entprop.Acceleration, entprop.RotationalVelocity);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called by the scene when a collision with this object is reported
|
// Called by the scene when a collision with this object is reported
|
||||||
|
@ -448,6 +509,7 @@ public class BSCharacter : PhysicsActor
|
||||||
{
|
{
|
||||||
_collidingGroundStep = _scene.SimulationStep;
|
_collidingGroundStep = _scene.SimulationStep;
|
||||||
}
|
}
|
||||||
|
// DetailLog("{0},BSCharacter.Collison,call,with={1}", LocalID, collidingWith);
|
||||||
|
|
||||||
// throttle collisions to the rate specified in the subscription
|
// throttle collisions to the rate specified in the subscription
|
||||||
if (_subscribedEventsMs != 0) {
|
if (_subscribedEventsMs != 0) {
|
||||||
|
@ -476,9 +538,17 @@ public class BSCharacter : PhysicsActor
|
||||||
if (collisionCollection == null)
|
if (collisionCollection == null)
|
||||||
collisionCollection = new CollisionEventUpdate();
|
collisionCollection = new CollisionEventUpdate();
|
||||||
base.SendCollisionUpdate(collisionCollection);
|
base.SendCollisionUpdate(collisionCollection);
|
||||||
collisionCollection.Clear();
|
// If there were any collisions in the collection, make sure we don't use the
|
||||||
|
// same instance next time.
|
||||||
|
if (collisionCollection.Count > 0)
|
||||||
|
collisionCollection = null;
|
||||||
// End kludge
|
// End kludge
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Invoke the detailed logger and output something if it's enabled.
|
||||||
|
private void DetailLog(string msg, params Object[] args)
|
||||||
|
{
|
||||||
|
Scene.PhysicsLogging.Write(msg, args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,35 +32,26 @@ using OpenMetaverse;
|
||||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
{
|
{
|
||||||
|
|
||||||
public class BSConstraint : IDisposable
|
public abstract class BSConstraint : IDisposable
|
||||||
{
|
{
|
||||||
private BulletSim m_world;
|
protected BulletSim m_world;
|
||||||
private BulletBody m_body1;
|
protected BulletBody m_body1;
|
||||||
private BulletBody m_body2;
|
protected BulletBody m_body2;
|
||||||
private BulletConstraint m_constraint;
|
protected BulletConstraint m_constraint;
|
||||||
private bool m_enabled = false;
|
protected bool m_enabled = false;
|
||||||
|
|
||||||
public BSConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
|
public BSConstraint()
|
||||||
Vector3 frame1, Quaternion frame1rot,
|
|
||||||
Vector3 frame2, Quaternion frame2rot
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
m_world = world;
|
|
||||||
m_body1 = obj1;
|
|
||||||
m_body2 = obj2;
|
|
||||||
m_constraint = new BulletConstraint(BulletSimAPI.CreateConstraint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr,
|
|
||||||
frame1, frame1rot,
|
|
||||||
frame2, frame2rot,
|
|
||||||
true /*useLinearReferenceFrameA*/, true /*disableCollisionsBetweenLinkedBodies*/));
|
|
||||||
m_enabled = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public virtual void Dispose()
|
||||||
{
|
{
|
||||||
if (m_enabled)
|
if (m_enabled)
|
||||||
{
|
{
|
||||||
// BulletSimAPI.RemoveConstraint(m_world.ID, m_body1.ID, m_body2.ID);
|
// BulletSimAPI.RemoveConstraint(m_world.ID, m_body1.ID, m_body2.ID);
|
||||||
BulletSimAPI.DestroyConstraint2(m_world.Ptr, m_constraint.Ptr);
|
bool success = BulletSimAPI.DestroyConstraint2(m_world.Ptr, m_constraint.Ptr);
|
||||||
|
m_world.scene.DetailLog("{0},BSConstraint.Dispose,taint,body1={1},body2={2},success={3}", BSScene.DetailLogZero, m_body1.ID, m_body2.ID, success);
|
||||||
|
m_constraint.Ptr = System.IntPtr.Zero;
|
||||||
m_enabled = false;
|
m_enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,7 +59,7 @@ public class BSConstraint : IDisposable
|
||||||
public BulletBody Body1 { get { return m_body1; } }
|
public BulletBody Body1 { get { return m_body1; } }
|
||||||
public BulletBody Body2 { get { return m_body2; } }
|
public BulletBody Body2 { get { return m_body2; } }
|
||||||
|
|
||||||
public bool SetLinearLimits(Vector3 low, Vector3 high)
|
public virtual bool SetLinearLimits(Vector3 low, Vector3 high)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
if (m_enabled)
|
if (m_enabled)
|
||||||
|
@ -76,7 +67,7 @@ public class BSConstraint : IDisposable
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SetAngularLimits(Vector3 low, Vector3 high)
|
public virtual bool SetAngularLimits(Vector3 low, Vector3 high)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
if (m_enabled)
|
if (m_enabled)
|
||||||
|
@ -84,42 +75,38 @@ public class BSConstraint : IDisposable
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SetCFMAndERP(float cfm, float erp)
|
public virtual bool CalculateTransforms()
|
||||||
{
|
|
||||||
bool ret = true;
|
|
||||||
BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_CFM, cfm, ConstraintParamAxis.AXIS_ALL);
|
|
||||||
BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_STOP_ERP, erp, ConstraintParamAxis.AXIS_ALL);
|
|
||||||
BulletSimAPI.SetConstraintParam2(m_constraint.Ptr, ConstraintParams.BT_CONSTRAINT_CFM, cfm, ConstraintParamAxis.AXIS_ALL);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool UseFrameOffset(bool useOffset)
|
|
||||||
{
|
|
||||||
bool ret = false;
|
|
||||||
float onOff = useOffset ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse;
|
|
||||||
if (m_enabled)
|
|
||||||
ret = BulletSimAPI.UseFrameOffset2(m_constraint.Ptr, onOff);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TranslationalLimitMotor(bool enable, float targetVelocity, float maxMotorForce)
|
|
||||||
{
|
|
||||||
bool ret = false;
|
|
||||||
float onOff = enable ? ConfigurationParameters.numericTrue : ConfigurationParameters.numericFalse;
|
|
||||||
if (m_enabled)
|
|
||||||
ret = BulletSimAPI.TranslationalLimitMotor2(m_constraint.Ptr, onOff, targetVelocity, maxMotorForce);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CalculateTransforms()
|
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
if (m_enabled)
|
if (m_enabled)
|
||||||
{
|
{
|
||||||
|
// Recompute the internal transforms
|
||||||
BulletSimAPI.CalculateTransforms2(m_constraint.Ptr);
|
BulletSimAPI.CalculateTransforms2(m_constraint.Ptr);
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset this constraint making sure it has all its internal structures
|
||||||
|
// recomputed and is enabled and ready to go.
|
||||||
|
public virtual bool RecomputeConstraintVariables(float mass)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
if (m_enabled)
|
||||||
|
{
|
||||||
|
ret = CalculateTransforms();
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
// m_world.scene.PhysicsLogging.Write("{0},BSConstraint.RecomputeConstraintVariables,taint,enabling,A={1},B={2}",
|
||||||
|
// BSScene.DetailLogZero, Body1.ID, Body2.ID);
|
||||||
|
BulletSimAPI.SetConstraintEnable2(m_constraint.Ptr, m_world.scene.NumericBool(true));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_world.scene.Logger.ErrorFormat("[BULLETSIM CONSTRAINT] CalculateTransforms failed. A={0}, B={1}", Body1.ID, Body2.ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,29 +56,25 @@ public class BSConstraintCollection : IDisposable
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
foreach (BSConstraint cons in m_constraints)
|
lock (m_constraints)
|
||||||
{
|
{
|
||||||
cons.Dispose();
|
foreach (BSConstraint cons in m_constraints)
|
||||||
|
{
|
||||||
|
cons.Dispose();
|
||||||
|
}
|
||||||
|
m_constraints.Clear();
|
||||||
}
|
}
|
||||||
m_constraints.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public BSConstraint CreateConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
|
|
||||||
Vector3 frame1, Quaternion frame1rot,
|
|
||||||
Vector3 frame2, Quaternion frame2rot)
|
|
||||||
{
|
|
||||||
BSConstraint constrain = new BSConstraint(world, obj1, obj2, frame1, frame1rot, frame2, frame2rot);
|
|
||||||
|
|
||||||
this.AddConstraint(constrain);
|
|
||||||
return constrain;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AddConstraint(BSConstraint cons)
|
public bool AddConstraint(BSConstraint cons)
|
||||||
{
|
{
|
||||||
// There is only one constraint between any bodies. Remove any old just to make sure.
|
lock (m_constraints)
|
||||||
RemoveAndDestroyConstraint(cons.Body1, cons.Body2);
|
{
|
||||||
|
// There is only one constraint between any bodies. Remove any old just to make sure.
|
||||||
|
RemoveAndDestroyConstraint(cons.Body1, cons.Body2);
|
||||||
|
|
||||||
m_constraints.Add(cons);
|
m_constraints.Add(cons);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -92,16 +88,19 @@ public class BSConstraintCollection : IDisposable
|
||||||
|
|
||||||
uint lookingID1 = body1.ID;
|
uint lookingID1 = body1.ID;
|
||||||
uint lookingID2 = body2.ID;
|
uint lookingID2 = body2.ID;
|
||||||
ForEachConstraint(delegate(BSConstraint constrain)
|
lock (m_constraints)
|
||||||
{
|
{
|
||||||
if ((constrain.Body1.ID == lookingID1 && constrain.Body2.ID == lookingID2)
|
foreach (BSConstraint constrain in m_constraints)
|
||||||
|| (constrain.Body1.ID == lookingID2 && constrain.Body2.ID == lookingID1))
|
|
||||||
{
|
{
|
||||||
foundConstraint = constrain;
|
if ((constrain.Body1.ID == lookingID1 && constrain.Body2.ID == lookingID2)
|
||||||
found = true;
|
|| (constrain.Body1.ID == lookingID2 && constrain.Body2.ID == lookingID1))
|
||||||
|
{
|
||||||
|
foundConstraint = constrain;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return found;
|
}
|
||||||
});
|
|
||||||
returnConstraint = foundConstraint;
|
returnConstraint = foundConstraint;
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
@ -111,24 +110,35 @@ public class BSConstraintCollection : IDisposable
|
||||||
// Return 'true' if a constraint was found and destroyed.
|
// Return 'true' if a constraint was found and destroyed.
|
||||||
public bool RemoveAndDestroyConstraint(BulletBody body1, BulletBody body2)
|
public bool RemoveAndDestroyConstraint(BulletBody body1, BulletBody body2)
|
||||||
{
|
{
|
||||||
// return BulletSimAPI.RemoveConstraint(m_world.ID, obj1.ID, obj2.ID);
|
|
||||||
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
BSConstraint constrain;
|
lock (m_constraints)
|
||||||
|
|
||||||
if (this.TryGetConstraint(body1, body2, out constrain))
|
|
||||||
{
|
{
|
||||||
// remove the constraint from our collection
|
BSConstraint constrain;
|
||||||
m_constraints.Remove(constrain);
|
if (this.TryGetConstraint(body1, body2, out constrain))
|
||||||
// tell the engine that all its structures need to be freed
|
{
|
||||||
constrain.Dispose();
|
// remove the constraint from our collection
|
||||||
// we destroyed something
|
RemoveAndDestroyConstraint(constrain);
|
||||||
ret = true;
|
ret = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The constraint MUST exist in the collection
|
||||||
|
public bool RemoveAndDestroyConstraint(BSConstraint constrain)
|
||||||
|
{
|
||||||
|
lock (m_constraints)
|
||||||
|
{
|
||||||
|
// remove the constraint from our collection
|
||||||
|
m_constraints.Remove(constrain);
|
||||||
|
}
|
||||||
|
// tell the engine that all its structures need to be freed
|
||||||
|
constrain.Dispose();
|
||||||
|
// we destroyed something
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Remove all constraints that reference the passed body.
|
// Remove all constraints that reference the passed body.
|
||||||
// Return 'true' if any constraints were destroyed.
|
// Return 'true' if any constraints were destroyed.
|
||||||
public bool RemoveAndDestroyConstraint(BulletBody body1)
|
public bool RemoveAndDestroyConstraint(BulletBody body1)
|
||||||
|
@ -137,16 +147,15 @@ public class BSConstraintCollection : IDisposable
|
||||||
|
|
||||||
List<BSConstraint> toRemove = new List<BSConstraint>();
|
List<BSConstraint> toRemove = new List<BSConstraint>();
|
||||||
uint lookingID = body1.ID;
|
uint lookingID = body1.ID;
|
||||||
ForEachConstraint(delegate(BSConstraint constrain)
|
|
||||||
{
|
|
||||||
if (constrain.Body1.ID == lookingID || constrain.Body2.ID == lookingID)
|
|
||||||
{
|
|
||||||
toRemove.Add(constrain);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
lock (m_constraints)
|
lock (m_constraints)
|
||||||
{
|
{
|
||||||
|
foreach (BSConstraint constrain in m_constraints)
|
||||||
|
{
|
||||||
|
if (constrain.Body1.ID == lookingID || constrain.Body2.ID == lookingID)
|
||||||
|
{
|
||||||
|
toRemove.Add(constrain);
|
||||||
|
}
|
||||||
|
}
|
||||||
foreach (BSConstraint constrain in toRemove)
|
foreach (BSConstraint constrain in toRemove)
|
||||||
{
|
{
|
||||||
m_constraints.Remove(constrain);
|
m_constraints.Remove(constrain);
|
||||||
|
@ -158,27 +167,16 @@ public class BSConstraintCollection : IDisposable
|
||||||
|
|
||||||
public bool RecalculateAllConstraints()
|
public bool RecalculateAllConstraints()
|
||||||
{
|
{
|
||||||
foreach (BSConstraint constrain in m_constraints)
|
bool ret = false;
|
||||||
{
|
|
||||||
constrain.CalculateTransforms();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lock the constraint list and loop through it.
|
|
||||||
// The constraint action returns 'true' if it wants the loop aborted.
|
|
||||||
private void ForEachConstraint(ConstraintAction action)
|
|
||||||
{
|
|
||||||
lock (m_constraints)
|
lock (m_constraints)
|
||||||
{
|
{
|
||||||
foreach (BSConstraint constrain in m_constraints)
|
foreach (BSConstraint constrain in m_constraints)
|
||||||
{
|
{
|
||||||
if (action(constrain))
|
constrain.CalculateTransforms();
|
||||||
break;
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -613,7 +613,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
MoveAngular(pTimestep);
|
MoveAngular(pTimestep);
|
||||||
LimitRotation(pTimestep);
|
LimitRotation(pTimestep);
|
||||||
|
|
||||||
DetailLog("{0},Dynamics,done,pos={1},force={2},velocity={3},angvel={4}",
|
DetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
|
||||||
m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity);
|
m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity);
|
||||||
}// end Step
|
}// end Step
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* 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 copyrightD
|
||||||
|
* 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.Text;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
|
{
|
||||||
|
|
||||||
|
class BSHingeConstraint : BSConstraint
|
||||||
|
{
|
||||||
|
public BSHingeConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
|
||||||
|
Vector3 pivotInA, Vector3 pivotInB,
|
||||||
|
Vector3 axisInA, Vector3 axisInB,
|
||||||
|
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
|
||||||
|
{
|
||||||
|
m_world = world;
|
||||||
|
m_body1 = obj1;
|
||||||
|
m_body2 = obj2;
|
||||||
|
m_constraint = new BulletConstraint(
|
||||||
|
BulletSimAPI.CreateHingeConstraint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr,
|
||||||
|
pivotInA, pivotInB,
|
||||||
|
axisInA, axisInB,
|
||||||
|
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies));
|
||||||
|
m_enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -37,10 +37,12 @@ public class BSLinkset
|
||||||
private static string LogHeader = "[BULLETSIM LINKSET]";
|
private static string LogHeader = "[BULLETSIM LINKSET]";
|
||||||
|
|
||||||
private BSPrim m_linksetRoot;
|
private BSPrim m_linksetRoot;
|
||||||
public BSPrim Root { get { return m_linksetRoot; } }
|
public BSPrim LinksetRoot { get { return m_linksetRoot; } }
|
||||||
|
|
||||||
private BSScene m_scene;
|
private BSScene m_physicsScene;
|
||||||
|
public BSScene PhysicsScene { get { return m_physicsScene; } }
|
||||||
|
|
||||||
|
// The children under the root in this linkset
|
||||||
private List<BSPrim> m_children;
|
private List<BSPrim> m_children;
|
||||||
|
|
||||||
// We lock the diddling of linkset classes to prevent any badness.
|
// We lock the diddling of linkset classes to prevent any badness.
|
||||||
|
@ -72,7 +74,7 @@ public class BSLinkset
|
||||||
public BSLinkset(BSScene scene, BSPrim parent)
|
public BSLinkset(BSScene scene, BSPrim parent)
|
||||||
{
|
{
|
||||||
// A simple linkset of one (no children)
|
// A simple linkset of one (no children)
|
||||||
m_scene = scene;
|
m_physicsScene = scene;
|
||||||
m_linksetRoot = parent;
|
m_linksetRoot = parent;
|
||||||
m_children = new List<BSPrim>();
|
m_children = new List<BSPrim>();
|
||||||
m_mass = parent.MassRaw;
|
m_mass = parent.MassRaw;
|
||||||
|
@ -80,16 +82,19 @@ public class BSLinkset
|
||||||
|
|
||||||
// Link to a linkset where the child knows the parent.
|
// Link to a linkset where the child knows the parent.
|
||||||
// Parent changing should not happen so do some sanity checking.
|
// Parent changing should not happen so do some sanity checking.
|
||||||
// We return the parent's linkset so the child can track it's membership.
|
// We return the parent's linkset so the child can track its membership.
|
||||||
public BSLinkset AddMeToLinkset(BSPrim child, BSPrim parent)
|
public BSLinkset AddMeToLinkset(BSPrim child)
|
||||||
{
|
{
|
||||||
lock (m_linksetActivityLock)
|
lock (m_linksetActivityLock)
|
||||||
{
|
{
|
||||||
parent.Linkset.AddChildToLinkset(child);
|
AddChildToLinkset(child);
|
||||||
}
|
}
|
||||||
return parent.Linkset;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove a child from a linkset.
|
||||||
|
// Returns a new linkset for the child which is a linkset of one (just the
|
||||||
|
// orphened child).
|
||||||
public BSLinkset RemoveMeFromLinkset(BSPrim child)
|
public BSLinkset RemoveMeFromLinkset(BSPrim child)
|
||||||
{
|
{
|
||||||
lock (m_linksetActivityLock)
|
lock (m_linksetActivityLock)
|
||||||
|
@ -101,7 +106,7 @@ public class BSLinkset
|
||||||
{
|
{
|
||||||
// Note that we don't do a foreach because the remove routine
|
// Note that we don't do a foreach because the remove routine
|
||||||
// takes it out of the list.
|
// takes it out of the list.
|
||||||
RemoveChildFromLinkset(m_children[0]);
|
RemoveChildFromOtherLinkset(m_children[0]);
|
||||||
}
|
}
|
||||||
m_children.Clear(); // just to make sure
|
m_children.Clear(); // just to make sure
|
||||||
}
|
}
|
||||||
|
@ -113,63 +118,17 @@ public class BSLinkset
|
||||||
}
|
}
|
||||||
|
|
||||||
// The child is down to a linkset of just itself
|
// The child is down to a linkset of just itself
|
||||||
return new BSLinkset(m_scene, child);
|
return new BSLinkset(PhysicsScene, child);
|
||||||
}
|
}
|
||||||
|
|
||||||
// An existing linkset had one of its members rebuilt or something.
|
|
||||||
// Go through the linkset and rebuild the pointers to the bodies of the linkset members.
|
|
||||||
public BSLinkset RefreshLinkset(BSPrim requestor)
|
|
||||||
{
|
|
||||||
BSLinkset ret = requestor.Linkset;
|
|
||||||
|
|
||||||
lock (m_linksetActivityLock)
|
|
||||||
{
|
|
||||||
System.IntPtr aPtr = BulletSimAPI.GetBodyHandle2(m_scene.World.Ptr, m_linksetRoot.LocalID);
|
|
||||||
if (aPtr == System.IntPtr.Zero)
|
|
||||||
{
|
|
||||||
// That's odd. We can't find the root of the linkset.
|
|
||||||
// The linkset is somehow dead. The requestor is now a member of a linkset of one.
|
|
||||||
DetailLog("{0},RefreshLinkset.RemoveRoot,child={1}", m_linksetRoot.LocalID, m_linksetRoot.LocalID);
|
|
||||||
ret = RemoveMeFromLinkset(m_linksetRoot);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Reconstruct the pointer to the body of the linkset root.
|
|
||||||
DetailLog("{0},RefreshLinkset.RebuildRoot,rootID={1},ptr={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, aPtr);
|
|
||||||
m_linksetRoot.Body = new BulletBody(m_linksetRoot.LocalID, aPtr);
|
|
||||||
|
|
||||||
List<BSPrim> toRemove = new List<BSPrim>();
|
|
||||||
foreach (BSPrim bsp in m_children)
|
|
||||||
{
|
|
||||||
aPtr = BulletSimAPI.GetBodyHandle2(m_scene.World.Ptr, bsp.LocalID);
|
|
||||||
if (aPtr == System.IntPtr.Zero)
|
|
||||||
{
|
|
||||||
toRemove.Add(bsp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Reconstruct the pointer to the body of the linkset root.
|
|
||||||
DetailLog("{0},RefreshLinkset.RebuildChild,rootID={1},ptr={2}", bsp.LocalID, m_linksetRoot.LocalID, aPtr);
|
|
||||||
bsp.Body = new BulletBody(bsp.LocalID, aPtr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach (BSPrim bsp in toRemove)
|
|
||||||
{
|
|
||||||
RemoveChildFromLinkset(bsp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Return 'true' if the passed object is the root object of this linkset
|
// Return 'true' if the passed object is the root object of this linkset
|
||||||
public bool IsRoot(BSPrim requestor)
|
public bool IsRoot(BSPrim requestor)
|
||||||
{
|
{
|
||||||
return (requestor.LocalID == m_linksetRoot.LocalID);
|
return (requestor.LocalID == m_linksetRoot.LocalID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int NumberOfChildren { get { return m_children.Count; } }
|
||||||
|
|
||||||
// Return 'true' if this linkset has any children (more than the root member)
|
// Return 'true' if this linkset has any children (more than the root member)
|
||||||
public bool HasAnyChildren { get { return (m_children.Count > 0); } }
|
public bool HasAnyChildren { get { return (m_children.Count > 0); } }
|
||||||
|
|
||||||
|
@ -177,12 +136,15 @@ public class BSLinkset
|
||||||
public bool HasChild(BSPrim child)
|
public bool HasChild(BSPrim child)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
foreach (BSPrim bp in m_children)
|
lock (m_linksetActivityLock)
|
||||||
{
|
{
|
||||||
if (child.LocalID == bp.LocalID)
|
foreach (BSPrim bp in m_children)
|
||||||
{
|
{
|
||||||
ret = true;
|
if (child.LocalID == bp.LocalID)
|
||||||
break;
|
{
|
||||||
|
ret = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -203,12 +165,16 @@ public class BSLinkset
|
||||||
OMV.Vector3 com = m_linksetRoot.Position * m_linksetRoot.MassRaw;
|
OMV.Vector3 com = m_linksetRoot.Position * m_linksetRoot.MassRaw;
|
||||||
float totalMass = m_linksetRoot.MassRaw;
|
float totalMass = m_linksetRoot.MassRaw;
|
||||||
|
|
||||||
foreach (BSPrim bp in m_children)
|
lock (m_linksetActivityLock)
|
||||||
{
|
{
|
||||||
com += bp.Position * bp.MassRaw;
|
foreach (BSPrim bp in m_children)
|
||||||
totalMass += bp.MassRaw;
|
{
|
||||||
|
com += bp.Position * bp.MassRaw;
|
||||||
|
totalMass += bp.MassRaw;
|
||||||
|
}
|
||||||
|
if (totalMass != 0f)
|
||||||
|
com /= totalMass;
|
||||||
}
|
}
|
||||||
com /= totalMass;
|
|
||||||
|
|
||||||
return com;
|
return com;
|
||||||
}
|
}
|
||||||
|
@ -217,135 +183,237 @@ public class BSLinkset
|
||||||
{
|
{
|
||||||
OMV.Vector3 com = m_linksetRoot.Position;
|
OMV.Vector3 com = m_linksetRoot.Position;
|
||||||
|
|
||||||
foreach (BSPrim bp in m_children)
|
lock (m_linksetActivityLock)
|
||||||
{
|
{
|
||||||
com += bp.Position * bp.MassRaw;
|
foreach (BSPrim bp in m_children)
|
||||||
|
{
|
||||||
|
com += bp.Position * bp.MassRaw;
|
||||||
|
}
|
||||||
|
com /= (m_children.Count + 1);
|
||||||
}
|
}
|
||||||
com /= m_children.Count + 1;
|
|
||||||
|
|
||||||
return com;
|
return com;
|
||||||
}
|
}
|
||||||
|
|
||||||
// I am the root of a linkset and a new child is being added
|
// When physical properties are changed the linkset needs to recalculate
|
||||||
public void AddChildToLinkset(BSPrim pchild)
|
// its internal properties.
|
||||||
|
public void Refresh(BSPrim requestor)
|
||||||
|
{
|
||||||
|
// If there are no children, there aren't any constraints to recompute
|
||||||
|
if (!HasAnyChildren)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Only the root does the recomputation
|
||||||
|
if (IsRoot(requestor))
|
||||||
|
{
|
||||||
|
PhysicsScene.TaintedObject("BSLinkSet.Refresh", delegate()
|
||||||
|
{
|
||||||
|
RecomputeLinksetConstraintVariables();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call each of the constraints that make up this linkset and recompute the
|
||||||
|
// various transforms and variables. Used when objects are added or removed
|
||||||
|
// from a linkset to make sure the constraints know about the new mass and
|
||||||
|
// geometry.
|
||||||
|
// Must only be called at taint time!!
|
||||||
|
private bool RecomputeLinksetConstraintVariables()
|
||||||
|
{
|
||||||
|
float linksetMass = LinksetMass;
|
||||||
|
lock (m_linksetActivityLock)
|
||||||
|
{
|
||||||
|
foreach (BSPrim child in m_children)
|
||||||
|
{
|
||||||
|
BSConstraint constrain;
|
||||||
|
if (m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.Body, child.Body, out constrain))
|
||||||
|
{
|
||||||
|
// DetailLog("{0},BSLinkset.RecomputeLinksetConstraintVariables,taint,child={1},mass={2},A={3},B={4}",
|
||||||
|
// LinksetRoot.LocalID, child.LocalID, linksetMass, constrain.Body1.ID, constrain.Body2.ID);
|
||||||
|
constrain.RecomputeConstraintVariables(linksetMass);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Non-fatal error that can happen when children are being added to the linkset but
|
||||||
|
// their constraints have not been created yet.
|
||||||
|
// Caused by the fact that m_children is built at run time but building constraints
|
||||||
|
// happens at taint time.
|
||||||
|
// m_physicsScene.Logger.ErrorFormat("[BULLETSIM LINKSET] RecomputeLinksetConstraintVariables: constraint not found for root={0}, child={1}",
|
||||||
|
// m_linksetRoot.Body.ID, child.Body.ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// I am the root of a linkset and a new child is being added
|
||||||
|
// Called while LinkActivity is locked.
|
||||||
|
private void AddChildToLinkset(BSPrim child)
|
||||||
{
|
{
|
||||||
BSPrim child = pchild;
|
|
||||||
if (!HasChild(child))
|
if (!HasChild(child))
|
||||||
{
|
{
|
||||||
m_children.Add(child);
|
m_children.Add(child);
|
||||||
|
|
||||||
m_scene.TaintedObject(delegate()
|
BSPrim rootx = LinksetRoot; // capture the root as of now
|
||||||
|
BSPrim childx = child;
|
||||||
|
m_physicsScene.TaintedObject("AddChildToLinkset", delegate()
|
||||||
{
|
{
|
||||||
DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID);
|
// DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID);
|
||||||
DetailLog("{0},AddChildToLinkset,child={1}", m_linksetRoot.LocalID, pchild.LocalID);
|
// DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
|
||||||
PhysicallyLinkAChildToRoot(pchild); // build the physical binding between me and the child
|
PhysicallyLinkAChildToRoot(rootx, childx); // build the physical binding between me and the child
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Forcefully removing a child from a linkset.
|
||||||
|
// This is not being called by the child so we have to make sure the child doesn't think
|
||||||
|
// it's still connected to the linkset.
|
||||||
|
// Normal OpenSimulator operation will never do this because other SceneObjectPart information
|
||||||
|
// has to be updated also (like pointer to prim's parent).
|
||||||
|
private void RemoveChildFromOtherLinkset(BSPrim pchild)
|
||||||
|
{
|
||||||
|
pchild.Linkset = new BSLinkset(m_physicsScene, pchild);
|
||||||
|
RemoveChildFromLinkset(pchild);
|
||||||
|
}
|
||||||
|
|
||||||
// I am the root of a linkset and one of my children is being removed.
|
// I am the root of a linkset and one of my children is being removed.
|
||||||
// Safe to call even if the child is not really in my linkset.
|
// Safe to call even if the child is not really in my linkset.
|
||||||
public void RemoveChildFromLinkset(BSPrim pchild)
|
private void RemoveChildFromLinkset(BSPrim child)
|
||||||
{
|
{
|
||||||
BSPrim child = pchild;
|
|
||||||
|
|
||||||
if (m_children.Remove(child))
|
if (m_children.Remove(child))
|
||||||
{
|
{
|
||||||
m_scene.TaintedObject(delegate()
|
BSPrim rootx = LinksetRoot; // capture the root as of now
|
||||||
|
BSPrim childx = child;
|
||||||
|
m_physicsScene.TaintedObject("RemoveChildFromLinkset", delegate()
|
||||||
{
|
{
|
||||||
DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID);
|
// DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID);
|
||||||
DetailLog("{0},RemoveChildFromLinkset,child={1}", m_linksetRoot.LocalID, pchild.LocalID);
|
// DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
|
||||||
|
|
||||||
if (m_children.Count == 0)
|
PhysicallyUnlinkAChildFromRoot(rootx, childx);
|
||||||
{
|
|
||||||
// if the linkset is empty, make sure all linkages have been removed
|
|
||||||
PhysicallyUnlinkAllChildrenFromRoot();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PhysicallyUnlinkAChildFromRoot(pchild);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
RecomputeLinksetConstraintVariables();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// This will happen if we remove the root of the linkset first. Non-fatal occurance.
|
// This will happen if we remove the root of the linkset first. Non-fatal occurance.
|
||||||
// m_scene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader);
|
// PhysicsScene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a constraint between me (root of linkset) and the passed prim (the child).
|
// Create a constraint between me (root of linkset) and the passed prim (the child).
|
||||||
// Called at taint time!
|
// Called at taint time!
|
||||||
private void PhysicallyLinkAChildToRoot(BSPrim childPrim)
|
private void PhysicallyLinkAChildToRoot(BSPrim rootPrim, BSPrim childPrim)
|
||||||
{
|
{
|
||||||
// Zero motion for children so they don't interpolate
|
// Zero motion for children so they don't interpolate
|
||||||
childPrim.ZeroMotion();
|
childPrim.ZeroMotion();
|
||||||
|
|
||||||
// relative position normalized to the root prim
|
// Relative position normalized to the root prim
|
||||||
OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(m_linksetRoot.Orientation);
|
// Essentually a vector pointing from center of rootPrim to center of childPrim
|
||||||
OMV.Vector3 childRelativePosition = (childPrim.Position - m_linksetRoot.Position) * invThisOrientation;
|
OMV.Vector3 childRelativePosition = childPrim.Position - rootPrim.Position;
|
||||||
|
|
||||||
// relative rotation of the child to the parent
|
// real world coordinate of midpoint between the two objects
|
||||||
OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation;
|
OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2);
|
||||||
|
|
||||||
// create a constraint that allows no freedom of movement between the two objects
|
// create a constraint that allows no freedom of movement between the two objects
|
||||||
// http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
|
// http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
|
||||||
// DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
|
// DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
|
||||||
DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID);
|
DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2},rLoc={3},cLoc={4},midLoc={5}",
|
||||||
BSConstraint constrain = m_scene.Constraints.CreateConstraint(
|
rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID, rootPrim.Position, childPrim.Position, midPoint);
|
||||||
m_scene.World, m_linksetRoot.Body, childPrim.Body,
|
BS6DofConstraint constrain = new BS6DofConstraint(
|
||||||
// childRelativePosition,
|
m_physicsScene.World, rootPrim.Body, childPrim.Body,
|
||||||
// childRelativeRotation,
|
midPoint,
|
||||||
OMV.Vector3.Zero,
|
true,
|
||||||
OMV.Quaternion.Identity,
|
true
|
||||||
OMV.Vector3.Zero,
|
|
||||||
OMV.Quaternion.Identity
|
|
||||||
);
|
);
|
||||||
|
/* NOTE: attempt to build constraint with full frame computation, etc.
|
||||||
|
* Using the midpoint is easier since it lets the Bullet code use the transforms
|
||||||
|
* of the objects.
|
||||||
|
* Code left here as an example.
|
||||||
|
// ==================================================================================
|
||||||
|
// relative position normalized to the root prim
|
||||||
|
OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation);
|
||||||
|
OMV.Vector3 childRelativePosition = (childPrim.Position - rootPrim.Position) * invThisOrientation;
|
||||||
|
|
||||||
|
// relative rotation of the child to the parent
|
||||||
|
OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation;
|
||||||
|
OMV.Quaternion inverseChildRelativeRotation = OMV.Quaternion.Inverse(childRelativeRotation);
|
||||||
|
|
||||||
|
// create a constraint that allows no freedom of movement between the two objects
|
||||||
|
// http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
|
||||||
|
// DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
|
||||||
|
DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
|
||||||
|
BS6DofConstraint constrain = new BS6DofConstraint(
|
||||||
|
PhysicsScene.World, rootPrim.Body, childPrim.Body,
|
||||||
|
OMV.Vector3.Zero,
|
||||||
|
OMV.Quaternion.Inverse(rootPrim.Orientation),
|
||||||
|
OMV.Vector3.Zero,
|
||||||
|
OMV.Quaternion.Inverse(childPrim.Orientation),
|
||||||
|
// A point half way between the parent and child
|
||||||
|
// childRelativePosition/2,
|
||||||
|
// childRelativeRotation,
|
||||||
|
// childRelativePosition/2,
|
||||||
|
// inverseChildRelativeRotation,
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
// ==================================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
m_physicsScene.Constraints.AddConstraint(constrain);
|
||||||
|
|
||||||
|
// zero linear and angular limits makes the objects unable to move in relation to each other
|
||||||
constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
|
constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
|
||||||
constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
|
constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
|
||||||
|
|
||||||
// tweek the constraint to increase stability
|
// tweek the constraint to increase stability
|
||||||
constrain.UseFrameOffset(m_scene.BoolNumeric(m_scene.Params.linkConstraintUseFrameOffset));
|
constrain.UseFrameOffset(PhysicsScene.BoolNumeric(PhysicsScene.Params.linkConstraintUseFrameOffset));
|
||||||
constrain.TranslationalLimitMotor(m_scene.BoolNumeric(m_scene.Params.linkConstraintEnableTransMotor),
|
constrain.TranslationalLimitMotor(PhysicsScene.BoolNumeric(PhysicsScene.Params.linkConstraintEnableTransMotor),
|
||||||
m_scene.Params.linkConstraintTransMotorMaxVel,
|
PhysicsScene.Params.linkConstraintTransMotorMaxVel,
|
||||||
m_scene.Params.linkConstraintTransMotorMaxForce);
|
PhysicsScene.Params.linkConstraintTransMotorMaxForce);
|
||||||
constrain.SetCFMAndERP(m_scene.Params.linkConstraintCFM, m_scene.Params.linkConstraintERP);
|
constrain.SetCFMAndERP(PhysicsScene.Params.linkConstraintCFM, PhysicsScene.Params.linkConstraintERP);
|
||||||
|
|
||||||
|
RecomputeLinksetConstraintVariables();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove linkage between myself and a particular child
|
// Remove linkage between myself and a particular child
|
||||||
// Called at taint time!
|
// Called at taint time!
|
||||||
private void PhysicallyUnlinkAChildFromRoot(BSPrim childPrim)
|
private void PhysicallyUnlinkAChildFromRoot(BSPrim rootPrim, BSPrim childPrim)
|
||||||
{
|
{
|
||||||
DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}",
|
// DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}",
|
||||||
LogHeader, m_linksetRoot.LocalID, childPrim.LocalID);
|
// LogHeader, rootPrim.LocalID, childPrim.LocalID);
|
||||||
DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID);
|
DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
|
||||||
// BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, childPrim.LocalID);
|
|
||||||
m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body, childPrim.Body);
|
// Find the constraint for this link and get rid of it from the overall collection and from my list
|
||||||
|
m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body, childPrim.Body);
|
||||||
|
|
||||||
|
// Make the child refresh its location
|
||||||
|
BulletSimAPI.PushUpdate2(childPrim.Body.Ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove linkage between myself and any possible children I might have
|
// Remove linkage between myself and any possible children I might have
|
||||||
// Called at taint time!
|
// Called at taint time!
|
||||||
private void PhysicallyUnlinkAllChildrenFromRoot()
|
private void PhysicallyUnlinkAllChildrenFromRoot(BSPrim rootPrim)
|
||||||
{
|
{
|
||||||
// DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader);
|
// DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader);
|
||||||
DetailLog("{0},PhysicallyUnlinkAllChildren,taint", m_linksetRoot.LocalID);
|
DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
|
||||||
m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body);
|
|
||||||
// BulletSimAPI.RemoveConstraintByID(_scene.WorldID, LocalID);
|
m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoke the detailed logger and output something if it's enabled.
|
// Invoke the detailed logger and output something if it's enabled.
|
||||||
private void DebugLog(string msg, params Object[] args)
|
private void DebugLog(string msg, params Object[] args)
|
||||||
{
|
{
|
||||||
m_scene.Logger.DebugFormat(msg, args);
|
if (m_physicsScene.ShouldDebugLog)
|
||||||
|
m_physicsScene.Logger.DebugFormat(msg, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoke the detailed logger and output something if it's enabled.
|
// Invoke the detailed logger and output something if it's enabled.
|
||||||
private void DetailLog(string msg, params Object[] args)
|
private void DetailLog(string msg, params Object[] args)
|
||||||
{
|
{
|
||||||
m_scene.PhysicsLogging.Write(msg, args);
|
m_physicsScene.PhysicsLogging.Write(msg, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ public sealed class BSPrim : PhysicsActor
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
private static readonly string LogHeader = "[BULLETS PRIM]";
|
private static readonly string LogHeader = "[BULLETS PRIM]";
|
||||||
|
|
||||||
private void DebugLog(string mm, params Object[] xx) { if (_scene.shouldDebugLog) m_log.DebugFormat(mm, xx); }
|
private void DebugLog(string mm, params Object[] xx) { if (_scene.ShouldDebugLog) m_log.DebugFormat(mm, xx); }
|
||||||
|
|
||||||
private IMesh _mesh;
|
private IMesh _mesh;
|
||||||
private PrimitiveBaseShape _pbs;
|
private PrimitiveBaseShape _pbs;
|
||||||
|
@ -138,14 +138,15 @@ public sealed class BSPrim : PhysicsActor
|
||||||
_isPhysical = pisPhysical;
|
_isPhysical = pisPhysical;
|
||||||
_isVolumeDetect = false;
|
_isVolumeDetect = false;
|
||||||
_subscribedEventsMs = 0;
|
_subscribedEventsMs = 0;
|
||||||
_friction = _scene.Params.defaultFriction; // TODO: compute based on object material
|
_friction = _scene.Params.defaultFriction; // TODO: compute based on object material
|
||||||
_density = _scene.Params.defaultDensity; // TODO: compute based on object material
|
_density = _scene.Params.defaultDensity; // TODO: compute based on object material
|
||||||
_restitution = _scene.Params.defaultRestitution;
|
_restitution = _scene.Params.defaultRestitution;
|
||||||
_linkset = new BSLinkset(_scene, this); // a linkset of one
|
_linkset = new BSLinkset(_scene, this); // a linkset of one
|
||||||
_vehicle = new BSDynamics(this); // add vehicleness
|
_vehicle = new BSDynamics(this); // add vehicleness
|
||||||
_mass = CalculateMass();
|
_mass = CalculateMass();
|
||||||
// do the actual object creation at taint time
|
// do the actual object creation at taint time
|
||||||
_scene.TaintedObject(delegate()
|
DetailLog("{0},BSPrim.constructor,call", LocalID);
|
||||||
|
_scene.TaintedObject("BSPrim.create", delegate()
|
||||||
{
|
{
|
||||||
RecreateGeomAndObject();
|
RecreateGeomAndObject();
|
||||||
|
|
||||||
|
@ -160,17 +161,22 @@ public sealed class BSPrim : PhysicsActor
|
||||||
public void Destroy()
|
public void Destroy()
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID);
|
// m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID);
|
||||||
// DetailLog("{0},Destroy", LocalID);
|
|
||||||
|
// Undo any links between me and any other object
|
||||||
|
BSPrim parentBefore = _linkset.LinksetRoot;
|
||||||
|
int childrenBefore = _linkset.NumberOfChildren;
|
||||||
|
|
||||||
|
_linkset = _linkset.RemoveMeFromLinkset(this);
|
||||||
|
|
||||||
|
DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}",
|
||||||
|
LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren);
|
||||||
|
|
||||||
// Undo any vehicle properties
|
// Undo any vehicle properties
|
||||||
_vehicle.ProcessTypeChange(Vehicle.TYPE_NONE);
|
this.VehicleType = (int)Vehicle.TYPE_NONE;
|
||||||
_scene.RemoveVehiclePrim(this); // just to make sure
|
|
||||||
|
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSPrim.destroy", delegate()
|
||||||
{
|
{
|
||||||
// Undo any links between me and any other object
|
DetailLog("{0},BSPrim.Destroy,taint,", LocalID);
|
||||||
_linkset = _linkset.RemoveMeFromLinkset(this);
|
|
||||||
|
|
||||||
// everything in the C# world will get garbage collected. Tell the C++ world to free stuff.
|
// everything in the C# world will get garbage collected. Tell the C++ world to free stuff.
|
||||||
BulletSimAPI.DestroyObject(_scene.WorldID, LocalID);
|
BulletSimAPI.DestroyObject(_scene.WorldID, LocalID);
|
||||||
});
|
});
|
||||||
|
@ -183,11 +189,11 @@ public sealed class BSPrim : PhysicsActor
|
||||||
get { return _size; }
|
get { return _size; }
|
||||||
set {
|
set {
|
||||||
_size = value;
|
_size = value;
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSPrim.setSize", delegate()
|
||||||
{
|
{
|
||||||
_mass = CalculateMass(); // changing size changes the mass
|
_mass = CalculateMass(); // changing size changes the mass
|
||||||
BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical);
|
BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical);
|
||||||
DetailLog("{0}: setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical);
|
// DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical);
|
||||||
RecreateGeomAndObject();
|
RecreateGeomAndObject();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -195,7 +201,7 @@ public sealed class BSPrim : PhysicsActor
|
||||||
public override PrimitiveBaseShape Shape {
|
public override PrimitiveBaseShape Shape {
|
||||||
set {
|
set {
|
||||||
_pbs = value;
|
_pbs = value;
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSPrim.setShape", delegate()
|
||||||
{
|
{
|
||||||
_mass = CalculateMass(); // changing the shape changes the mass
|
_mass = CalculateMass(); // changing the shape changes the mass
|
||||||
RecreateGeomAndObject();
|
RecreateGeomAndObject();
|
||||||
|
@ -213,7 +219,7 @@ public sealed class BSPrim : PhysicsActor
|
||||||
public override bool Selected {
|
public override bool Selected {
|
||||||
set {
|
set {
|
||||||
_isSelected = value;
|
_isSelected = value;
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSPrim.setSelected", delegate()
|
||||||
{
|
{
|
||||||
SetObjectDynamic();
|
SetObjectDynamic();
|
||||||
});
|
});
|
||||||
|
@ -224,10 +230,17 @@ public sealed class BSPrim : PhysicsActor
|
||||||
// link me to the specified parent
|
// link me to the specified parent
|
||||||
public override void link(PhysicsActor obj) {
|
public override void link(PhysicsActor obj) {
|
||||||
BSPrim parent = obj as BSPrim;
|
BSPrim parent = obj as BSPrim;
|
||||||
DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID);
|
if (parent != null)
|
||||||
DetailLog("{0},link,parent={1}", LocalID, obj.LocalID);
|
{
|
||||||
|
DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, parent.LocalID);
|
||||||
|
BSPrim parentBefore = _linkset.LinksetRoot;
|
||||||
|
int childrenBefore = _linkset.NumberOfChildren;
|
||||||
|
|
||||||
_linkset = _linkset.AddMeToLinkset(this, parent);
|
_linkset = parent.Linkset.AddMeToLinkset(this);
|
||||||
|
|
||||||
|
DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}",
|
||||||
|
LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,10 +249,15 @@ public sealed class BSPrim : PhysicsActor
|
||||||
// TODO: decide if this parent checking needs to happen at taint time
|
// TODO: decide if this parent checking needs to happen at taint time
|
||||||
// Race condition here: if link() and delink() in same simulation tick, the delink will not happen
|
// Race condition here: if link() and delink() in same simulation tick, the delink will not happen
|
||||||
DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID,
|
DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID,
|
||||||
_linkset.Root._avName+"/"+_linkset.Root.LocalID.ToString());
|
_linkset.LinksetRoot._avName+"/"+_linkset.LinksetRoot.LocalID.ToString());
|
||||||
DetailLog("{0},delink,parent={1}", LocalID, _linkset.Root.LocalID.ToString());
|
|
||||||
|
|
||||||
_linkset.RemoveMeFromLinkset(this);
|
BSPrim parentBefore = _linkset.LinksetRoot;
|
||||||
|
int childrenBefore = _linkset.NumberOfChildren;
|
||||||
|
|
||||||
|
_linkset = _linkset.RemoveMeFromLinkset(this);
|
||||||
|
|
||||||
|
DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",
|
||||||
|
LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +280,7 @@ public sealed class BSPrim : PhysicsActor
|
||||||
|
|
||||||
public override void LockAngularMotion(OMV.Vector3 axis)
|
public override void LockAngularMotion(OMV.Vector3 axis)
|
||||||
{
|
{
|
||||||
DetailLog("{0},LockAngularMotion,call,axis={1}", LocalID, axis);
|
// DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,9 +297,9 @@ public sealed class BSPrim : PhysicsActor
|
||||||
set {
|
set {
|
||||||
_position = value;
|
_position = value;
|
||||||
// TODO: what does it mean to set the position of a child prim?? Rebuild the constraint?
|
// TODO: what does it mean to set the position of a child prim?? Rebuild the constraint?
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSPrim.setPosition", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
// DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||||
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
|
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -316,9 +334,9 @@ public sealed class BSPrim : PhysicsActor
|
||||||
get { return _force; }
|
get { return _force; }
|
||||||
set {
|
set {
|
||||||
_force = value;
|
_force = value;
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSPrim.setForce", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},SetForce,taint,force={1}", LocalID, _force);
|
// DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force);
|
||||||
// BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
|
// BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
|
||||||
BulletSimAPI.SetObjectForce2(Body.Ptr, _force);
|
BulletSimAPI.SetObjectForce2(Body.Ptr, _force);
|
||||||
});
|
});
|
||||||
|
@ -331,53 +349,41 @@ public sealed class BSPrim : PhysicsActor
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
Vehicle type = (Vehicle)value;
|
Vehicle type = (Vehicle)value;
|
||||||
_scene.TaintedObject(delegate()
|
BSPrim vehiclePrim = this;
|
||||||
|
_scene.TaintedObject("setVehicleType", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},SetVehicleType,taint,type={1}", LocalID, type);
|
// Done at taint time so we're sure the physics engine is not using the variables
|
||||||
|
// Vehicle code changes the parameters for this vehicle type.
|
||||||
_vehicle.ProcessTypeChange(type);
|
_vehicle.ProcessTypeChange(type);
|
||||||
if (type == Vehicle.TYPE_NONE)
|
// Tell the scene about the vehicle so it will get processing each frame.
|
||||||
{
|
_scene.VehicleInSceneTypeChanged(this, type);
|
||||||
_scene.RemoveVehiclePrim(this);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_scene.TaintedObject(delegate()
|
|
||||||
{
|
|
||||||
// Tell the physics engine to clear state
|
|
||||||
BulletSimAPI.ClearForces2(this.Body.Ptr);
|
|
||||||
});
|
|
||||||
|
|
||||||
// make it so the scene will call us each tick to do vehicle things
|
|
||||||
_scene.AddVehiclePrim(this);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public override void VehicleFloatParam(int param, float value)
|
public override void VehicleFloatParam(int param, float value)
|
||||||
{
|
{
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
|
||||||
{
|
{
|
||||||
_vehicle.ProcessFloatVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep);
|
_vehicle.ProcessFloatVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public override void VehicleVectorParam(int param, OMV.Vector3 value)
|
public override void VehicleVectorParam(int param, OMV.Vector3 value)
|
||||||
{
|
{
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
|
||||||
{
|
{
|
||||||
_vehicle.ProcessVectorVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep);
|
_vehicle.ProcessVectorVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public override void VehicleRotationParam(int param, OMV.Quaternion rotation)
|
public override void VehicleRotationParam(int param, OMV.Quaternion rotation)
|
||||||
{
|
{
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSPrim.VehicleRotationParam", delegate()
|
||||||
{
|
{
|
||||||
_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
|
_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public override void VehicleFlags(int param, bool remove)
|
public override void VehicleFlags(int param, bool remove)
|
||||||
{
|
{
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSPrim.VehicleFlags", delegate()
|
||||||
{
|
{
|
||||||
_vehicle.ProcessVehicleFlags(param, remove);
|
_vehicle.ProcessVehicleFlags(param, remove);
|
||||||
});
|
});
|
||||||
|
@ -395,7 +401,7 @@ public sealed class BSPrim : PhysicsActor
|
||||||
public override void SetVolumeDetect(int param) {
|
public override void SetVolumeDetect(int param) {
|
||||||
bool newValue = (param != 0);
|
bool newValue = (param != 0);
|
||||||
_isVolumeDetect = newValue;
|
_isVolumeDetect = newValue;
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSPrim.SetVolumeDetect", delegate()
|
||||||
{
|
{
|
||||||
SetObjectDynamic();
|
SetObjectDynamic();
|
||||||
});
|
});
|
||||||
|
@ -406,9 +412,9 @@ public sealed class BSPrim : PhysicsActor
|
||||||
get { return _velocity; }
|
get { return _velocity; }
|
||||||
set {
|
set {
|
||||||
_velocity = value;
|
_velocity = value;
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSPrim.setVelocity", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},SetVelocity,taint,vel={1}", LocalID, _velocity);
|
// DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity);
|
||||||
BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity);
|
BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -416,7 +422,7 @@ public sealed class BSPrim : PhysicsActor
|
||||||
public override OMV.Vector3 Torque {
|
public override OMV.Vector3 Torque {
|
||||||
get { return _torque; }
|
get { return _torque; }
|
||||||
set { _torque = value;
|
set { _torque = value;
|
||||||
DetailLog("{0},SetTorque,call,torque={1}", LocalID, _torque);
|
// DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public override float CollisionScore {
|
public override float CollisionScore {
|
||||||
|
@ -440,10 +446,10 @@ public sealed class BSPrim : PhysicsActor
|
||||||
set {
|
set {
|
||||||
_orientation = value;
|
_orientation = value;
|
||||||
// TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint?
|
// TODO: what does it mean if a child in a linkset changes its orientation? Rebuild the constraint?
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSPrim.setOrientation", delegate()
|
||||||
{
|
{
|
||||||
// _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
|
// _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
|
||||||
DetailLog("{0},SetOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
// DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||||
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
|
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -457,7 +463,7 @@ public sealed class BSPrim : PhysicsActor
|
||||||
get { return _isPhysical; }
|
get { return _isPhysical; }
|
||||||
set {
|
set {
|
||||||
_isPhysical = value;
|
_isPhysical = value;
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSPrim.setIsPhysical", delegate()
|
||||||
{
|
{
|
||||||
SetObjectDynamic();
|
SetObjectDynamic();
|
||||||
});
|
});
|
||||||
|
@ -478,7 +484,6 @@ public sealed class BSPrim : PhysicsActor
|
||||||
|
|
||||||
// Make gravity work if the object is physical and not selected
|
// Make gravity work if the object is physical and not selected
|
||||||
// No locking here because only called when it is safe
|
// No locking here because only called when it is safe
|
||||||
// Only called at taint time so it is save to call into Bullet.
|
|
||||||
private void SetObjectDynamic()
|
private void SetObjectDynamic()
|
||||||
{
|
{
|
||||||
// RA: remove this for the moment.
|
// RA: remove this for the moment.
|
||||||
|
@ -487,13 +492,16 @@ public sealed class BSPrim : PhysicsActor
|
||||||
// Maybe a VerifyCorrectPhysicalShape() routine?
|
// Maybe a VerifyCorrectPhysicalShape() routine?
|
||||||
// RecreateGeomAndObject();
|
// RecreateGeomAndObject();
|
||||||
|
|
||||||
float mass = _mass;
|
// Bullet wants static objects to have a mass of zero
|
||||||
// Bullet wants static objects have a mass of zero
|
float mass = IsStatic ? 0f : _mass;
|
||||||
if (IsStatic)
|
|
||||||
mass = 0f;
|
|
||||||
|
|
||||||
DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, mass);
|
|
||||||
BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass);
|
BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass);
|
||||||
|
|
||||||
|
// recompute any linkset parameters
|
||||||
|
_linkset.Refresh(this);
|
||||||
|
|
||||||
|
CollisionFlags cf = BulletSimAPI.GetCollisionFlags2(Body.Ptr);
|
||||||
|
// DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, cf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// prims don't fly
|
// prims don't fly
|
||||||
|
@ -548,9 +556,9 @@ public sealed class BSPrim : PhysicsActor
|
||||||
set {
|
set {
|
||||||
_rotationalVelocity = value;
|
_rotationalVelocity = value;
|
||||||
// m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
|
// m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
|
// DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
|
||||||
BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity);
|
BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -565,9 +573,9 @@ public sealed class BSPrim : PhysicsActor
|
||||||
get { return _buoyancy; }
|
get { return _buoyancy; }
|
||||||
set {
|
set {
|
||||||
_buoyancy = value;
|
_buoyancy = value;
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSPrim.setBuoyancy", delegate()
|
||||||
{
|
{
|
||||||
DetailLog("{0},SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
|
// DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
|
||||||
BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy);
|
BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -607,6 +615,7 @@ public sealed class BSPrim : PhysicsActor
|
||||||
|
|
||||||
private List<OMV.Vector3> m_accumulatedForces = new List<OMV.Vector3>();
|
private List<OMV.Vector3> m_accumulatedForces = new List<OMV.Vector3>();
|
||||||
public override void AddForce(OMV.Vector3 force, bool pushforce) {
|
public override void AddForce(OMV.Vector3 force, bool pushforce) {
|
||||||
|
// for an object, doesn't matter if force is a pushforce or not
|
||||||
if (force.IsFinite())
|
if (force.IsFinite())
|
||||||
{
|
{
|
||||||
// _force += force;
|
// _force += force;
|
||||||
|
@ -618,40 +627,48 @@ public sealed class BSPrim : PhysicsActor
|
||||||
m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader);
|
m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject("BSPrim.AddForce", delegate()
|
||||||
{
|
{
|
||||||
|
OMV.Vector3 fSum = OMV.Vector3.Zero;
|
||||||
lock (m_accumulatedForces)
|
lock (m_accumulatedForces)
|
||||||
{
|
{
|
||||||
if (m_accumulatedForces.Count > 0)
|
foreach (OMV.Vector3 v in m_accumulatedForces)
|
||||||
{
|
{
|
||||||
OMV.Vector3 fSum = OMV.Vector3.Zero;
|
fSum += v;
|
||||||
foreach (OMV.Vector3 v in m_accumulatedForces)
|
|
||||||
{
|
|
||||||
fSum += v;
|
|
||||||
}
|
|
||||||
m_accumulatedForces.Clear();
|
|
||||||
|
|
||||||
DetailLog("{0},SetObjectForce,taint,force={1}", LocalID, fSum);
|
|
||||||
BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, fSum);
|
|
||||||
}
|
}
|
||||||
|
m_accumulatedForces.Clear();
|
||||||
}
|
}
|
||||||
|
// DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force);
|
||||||
|
BulletSimAPI.AddObjectForce2(Body.Ptr, fSum);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
|
public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
|
||||||
DetailLog("{0},AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce);
|
// DetailLog("{0},BSPrim.AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce);
|
||||||
// m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce);
|
// m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce);
|
||||||
}
|
}
|
||||||
public override void SetMomentum(OMV.Vector3 momentum) {
|
public override void SetMomentum(OMV.Vector3 momentum) {
|
||||||
DetailLog("{0},SetMomentum,call,mom={1}", LocalID, momentum);
|
// DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum);
|
||||||
}
|
}
|
||||||
public override void SubscribeEvents(int ms) {
|
public override void SubscribeEvents(int ms) {
|
||||||
_subscribedEventsMs = ms;
|
_subscribedEventsMs = ms;
|
||||||
// make sure first collision happens
|
if (ms > 0)
|
||||||
_nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs;
|
{
|
||||||
|
// make sure first collision happens
|
||||||
|
_nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs;
|
||||||
|
|
||||||
|
Scene.TaintedObject("BSPrim.SubscribeEvents", delegate()
|
||||||
|
{
|
||||||
|
BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public override void UnSubscribeEvents() {
|
public override void UnSubscribeEvents() {
|
||||||
_subscribedEventsMs = 0;
|
_subscribedEventsMs = 0;
|
||||||
|
Scene.TaintedObject("BSPrim.UnSubscribeEvents", delegate()
|
||||||
|
{
|
||||||
|
BulletSimAPI.RemoveFromCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
public override bool SubscribedEvents() {
|
public override bool SubscribedEvents() {
|
||||||
return (_subscribedEventsMs > 0);
|
return (_subscribedEventsMs > 0);
|
||||||
|
@ -970,26 +987,26 @@ public sealed class BSPrim : PhysicsActor
|
||||||
{
|
{
|
||||||
if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
|
if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
|
||||||
{
|
{
|
||||||
if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
|
// if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
|
||||||
{
|
// {
|
||||||
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size);
|
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size);
|
||||||
if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE))
|
if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE))
|
||||||
{
|
{
|
||||||
DetailLog("{0},CreateGeom,sphere", LocalID);
|
// DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild);
|
||||||
_shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE;
|
_shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE;
|
||||||
// Bullet native objects are scaled by the Bullet engine so pass the size in
|
// Bullet native objects are scaled by the Bullet engine so pass the size in
|
||||||
_scale = _size;
|
_scale = _size;
|
||||||
// TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
|
// TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size);
|
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size);
|
||||||
if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX))
|
if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX))
|
||||||
{
|
{
|
||||||
DetailLog("{0},CreateGeom,box", LocalID);
|
// DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild);
|
||||||
_shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
|
_shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
|
||||||
_scale = _size;
|
_scale = _size;
|
||||||
// TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
|
// TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
|
||||||
|
@ -1032,12 +1049,12 @@ public sealed class BSPrim : PhysicsActor
|
||||||
// if this new shape is the same as last time, don't recreate the mesh
|
// if this new shape is the same as last time, don't recreate the mesh
|
||||||
if (_meshKey == newMeshKey) return;
|
if (_meshKey == newMeshKey) return;
|
||||||
|
|
||||||
DetailLog("{0},CreateGeomMesh,create,key={1}", LocalID, _meshKey);
|
// DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey);
|
||||||
// Since we're recreating new, get rid of any previously generated shape
|
// Since we're recreating new, get rid of any previously generated shape
|
||||||
if (_meshKey != 0)
|
if (_meshKey != 0)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey);
|
// m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey);
|
||||||
DetailLog("{0},CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey);
|
// DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey);
|
||||||
BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey);
|
BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey);
|
||||||
_mesh = null;
|
_mesh = null;
|
||||||
_meshKey = 0;
|
_meshKey = 0;
|
||||||
|
@ -1067,7 +1084,7 @@ public sealed class BSPrim : PhysicsActor
|
||||||
_shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH;
|
_shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH;
|
||||||
// meshes are already scaled by the meshmerizer
|
// meshes are already scaled by the meshmerizer
|
||||||
_scale = new OMV.Vector3(1f, 1f, 1f);
|
_scale = new OMV.Vector3(1f, 1f, 1f);
|
||||||
DetailLog("{0},CreateGeomMesh,done", LocalID);
|
// DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1081,28 +1098,21 @@ public sealed class BSPrim : PhysicsActor
|
||||||
// if the hull hasn't changed, don't rebuild it
|
// if the hull hasn't changed, don't rebuild it
|
||||||
if (newHullKey == _hullKey) return;
|
if (newHullKey == _hullKey) return;
|
||||||
|
|
||||||
DetailLog("{0},CreateGeomHull,create,key={1}", LocalID, _meshKey);
|
// DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey);
|
||||||
|
|
||||||
// Since we're recreating new, get rid of any previously generated shape
|
// Since we're recreating new, get rid of any previously generated shape
|
||||||
if (_hullKey != 0)
|
if (_hullKey != 0)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey);
|
// m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey);
|
||||||
DetailLog("{0},CreateGeomHull,deleteOldHull,key={1}", LocalID, _meshKey);
|
// DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey);
|
||||||
BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey);
|
BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey);
|
||||||
_hullKey = 0;
|
_hullKey = 0;
|
||||||
_hulls.Clear();
|
|
||||||
DetailLog("{0},CreateGeomHull,deleteOldMesh,key={1}", LocalID, _meshKey);
|
|
||||||
BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey);
|
|
||||||
_mesh = null; // the mesh cannot match either
|
|
||||||
_meshKey = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_hullKey = newHullKey;
|
_hullKey = newHullKey;
|
||||||
if (_meshKey != _hullKey)
|
|
||||||
{
|
// Make sure the underlying mesh exists and is correct
|
||||||
// if the underlying mesh has changed, rebuild it
|
CreateGeomMesh();
|
||||||
CreateGeomMesh();
|
|
||||||
}
|
|
||||||
|
|
||||||
int[] indices = _mesh.getIndexListAsInt();
|
int[] indices = _mesh.getIndexListAsInt();
|
||||||
List<OMV.Vector3> vertices = _mesh.getVertexList();
|
List<OMV.Vector3> vertices = _mesh.getVertexList();
|
||||||
|
@ -1128,7 +1138,7 @@ public sealed class BSPrim : PhysicsActor
|
||||||
// create the hull into the _hulls variable
|
// create the hull into the _hulls variable
|
||||||
convexBuilder.process(dcomp);
|
convexBuilder.process(dcomp);
|
||||||
|
|
||||||
// Convert the vertices and indices for passing to unmanaged
|
// Convert the vertices and indices for passing to unmanaged.
|
||||||
// The hull information is passed as a large floating point array.
|
// The hull information is passed as a large floating point array.
|
||||||
// The format is:
|
// The format is:
|
||||||
// convHulls[0] = number of hulls
|
// convHulls[0] = number of hulls
|
||||||
|
@ -1188,7 +1198,7 @@ public sealed class BSPrim : PhysicsActor
|
||||||
_shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL;
|
_shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL;
|
||||||
// meshes are already scaled by the meshmerizer
|
// meshes are already scaled by the meshmerizer
|
||||||
_scale = new OMV.Vector3(1f, 1f, 1f);
|
_scale = new OMV.Vector3(1f, 1f, 1f);
|
||||||
DetailLog("{0},CreateGeomHull,done", LocalID);
|
// DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1214,7 +1224,7 @@ public sealed class BSPrim : PhysicsActor
|
||||||
bool ret = BulletSimAPI.CreateObject(_scene.WorldID, shape);
|
bool ret = BulletSimAPI.CreateObject(_scene.WorldID, shape);
|
||||||
|
|
||||||
// the CreateObject() may have recreated the rigid body. Make sure we have the latest.
|
// the CreateObject() may have recreated the rigid body. Make sure we have the latest.
|
||||||
m_body.Ptr = BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID);
|
Body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1326,8 +1336,8 @@ public sealed class BSPrim : PhysicsActor
|
||||||
|
|
||||||
// m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}, vel={5}, acc={6}, rvel={7}",
|
// m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}, vel={5}, acc={6}, rvel={7}",
|
||||||
// LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
|
// LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
|
||||||
DetailLog("{0},UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
|
// DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
|
||||||
LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
|
// LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
|
||||||
|
|
||||||
base.RequestPhysicsterseUpdate();
|
base.RequestPhysicsterseUpdate();
|
||||||
}
|
}
|
||||||
|
@ -1335,7 +1345,7 @@ public sealed class BSPrim : PhysicsActor
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// For debugging, we also report the movement of children
|
// For debugging, we also report the movement of children
|
||||||
DetailLog("{0},UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
|
DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
|
||||||
LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,
|
LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,
|
||||||
entprop.Acceleration, entprop.RotationalVelocity);
|
entprop.Acceleration, entprop.RotationalVelocity);
|
||||||
}
|
}
|
||||||
|
@ -1343,7 +1353,7 @@ public sealed class BSPrim : PhysicsActor
|
||||||
}
|
}
|
||||||
|
|
||||||
// I've collided with something
|
// I've collided with something
|
||||||
CollisionEventUpdate collisionCollection = null;
|
CollisionEventUpdate collisionCollection;
|
||||||
public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
|
public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
|
// m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
|
||||||
|
@ -1355,6 +1365,8 @@ public sealed class BSPrim : PhysicsActor
|
||||||
_collidingGroundStep = _scene.SimulationStep;
|
_collidingGroundStep = _scene.SimulationStep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith);
|
||||||
|
|
||||||
// if someone is subscribed to collision events....
|
// if someone is subscribed to collision events....
|
||||||
if (_subscribedEventsMs != 0) {
|
if (_subscribedEventsMs != 0) {
|
||||||
// throttle the collisions to the number of milliseconds specified in the subscription
|
// throttle the collisions to the number of milliseconds specified in the subscription
|
||||||
|
@ -1375,7 +1387,9 @@ public sealed class BSPrim : PhysicsActor
|
||||||
if (collisionCollection != null && collisionCollection.Count > 0)
|
if (collisionCollection != null && collisionCollection.Count > 0)
|
||||||
{
|
{
|
||||||
base.SendCollisionUpdate(collisionCollection);
|
base.SendCollisionUpdate(collisionCollection);
|
||||||
collisionCollection.Clear();
|
// The collisionCollection structure is passed around in the simulator.
|
||||||
|
// Make sure we don't have a handle to that one and that a new one is used next time.
|
||||||
|
collisionCollection = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
private static readonly string LogHeader = "[BULLETS SCENE]";
|
private static readonly string LogHeader = "[BULLETS SCENE]";
|
||||||
|
|
||||||
public void DebugLog(string mm, params Object[] xx) { if (shouldDebugLog) m_log.DebugFormat(mm, xx); }
|
public void DebugLog(string mm, params Object[] xx) { if (ShouldDebugLog) m_log.DebugFormat(mm, xx); }
|
||||||
|
|
||||||
public string BulletSimVersion = "?";
|
public string BulletSimVersion = "?";
|
||||||
|
|
||||||
|
@ -162,14 +162,24 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
}
|
}
|
||||||
|
|
||||||
public delegate void TaintCallback();
|
public delegate void TaintCallback();
|
||||||
private List<TaintCallback> _taintedObjects;
|
private struct TaintCallbackEntry
|
||||||
|
{
|
||||||
|
public String ident;
|
||||||
|
public TaintCallback callback;
|
||||||
|
public TaintCallbackEntry(string i, TaintCallback c)
|
||||||
|
{
|
||||||
|
ident = i;
|
||||||
|
callback = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private List<TaintCallbackEntry> _taintedObjects;
|
||||||
private Object _taintLock = new Object();
|
private Object _taintLock = new Object();
|
||||||
|
|
||||||
// A pointer to an instance if this structure is passed to the C++ code
|
// A pointer to an instance if this structure is passed to the C++ code
|
||||||
ConfigurationParameters[] m_params;
|
ConfigurationParameters[] m_params;
|
||||||
GCHandle m_paramsHandle;
|
GCHandle m_paramsHandle;
|
||||||
|
|
||||||
public bool shouldDebugLog { get; private set; }
|
public bool ShouldDebugLog { get; private set; }
|
||||||
|
|
||||||
private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle;
|
private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle;
|
||||||
|
|
||||||
|
@ -232,7 +242,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle);
|
BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
_taintedObjects = new List<TaintCallback>();
|
_taintedObjects = new List<TaintCallbackEntry>();
|
||||||
|
|
||||||
mesher = meshmerizer;
|
mesher = meshmerizer;
|
||||||
// The bounding box for the simulated world
|
// The bounding box for the simulated world
|
||||||
|
@ -245,7 +255,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
|
|
||||||
// Initialization to support the transition to a new API which puts most of the logic
|
// Initialization to support the transition to a new API which puts most of the logic
|
||||||
// into the C# code so it is easier to modify and add to.
|
// into the C# code so it is easier to modify and add to.
|
||||||
m_worldSim = new BulletSim(m_worldID, BulletSimAPI.GetSimHandle2(m_worldID));
|
m_worldSim = new BulletSim(m_worldID, this, BulletSimAPI.GetSimHandle2(m_worldID));
|
||||||
m_constraintCollection = new BSConstraintCollection(World);
|
m_constraintCollection = new BSConstraintCollection(World);
|
||||||
|
|
||||||
m_initialized = true;
|
m_initialized = true;
|
||||||
|
@ -352,7 +362,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
BSPrim bsprim = prim as BSPrim;
|
BSPrim bsprim = prim as BSPrim;
|
||||||
if (bsprim != null)
|
if (bsprim != null)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID);
|
// DetailLog("{0},RemovePrim,call", bsprim.LocalID);
|
||||||
|
// m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
lock (m_prims) m_prims.Remove(bsprim.LocalID);
|
lock (m_prims) m_prims.Remove(bsprim.LocalID);
|
||||||
|
@ -377,6 +388,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
|
|
||||||
if (!m_initialized) return null;
|
if (!m_initialized) return null;
|
||||||
|
|
||||||
|
// DetailLog("{0},AddPrimShape,call", localID);
|
||||||
|
|
||||||
BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical);
|
BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical);
|
||||||
lock (m_prims) m_prims.Add(localID, prim);
|
lock (m_prims) m_prims.Add(localID, prim);
|
||||||
return prim;
|
return prim;
|
||||||
|
@ -400,7 +413,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
// prevent simulation until we've been initialized
|
// prevent simulation until we've been initialized
|
||||||
if (!m_initialized) return 10.0f;
|
if (!m_initialized) return 10.0f;
|
||||||
|
|
||||||
long simulateStartTime = Util.EnvironmentTickCount();
|
int simulateStartTime = Util.EnvironmentTickCount();
|
||||||
|
|
||||||
// update the prim states while we know the physics engine is not busy
|
// update the prim states while we know the physics engine is not busy
|
||||||
ProcessTaints();
|
ProcessTaints();
|
||||||
|
@ -416,12 +429,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
{
|
{
|
||||||
numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep,
|
numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep,
|
||||||
out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
|
out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
|
||||||
DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", "0000000000", numSubSteps, updatedEntityCount, collidersCount);
|
// DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("{0},PhysicsStep Exception: substeps={1}, updates={2}, colliders={3}, e={4}", LogHeader, numSubSteps, updatedEntityCount, collidersCount, e);
|
m_log.WarnFormat("{0},PhysicsStep Exception: substeps={1}, updates={2}, colliders={3}, e={4}", LogHeader, numSubSteps, updatedEntityCount, collidersCount, e);
|
||||||
DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", "0000000000", numSubSteps, updatedEntityCount, collidersCount);
|
// DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount);
|
||||||
// updatedEntityCount = 0;
|
// updatedEntityCount = 0;
|
||||||
collidersCount = 0;
|
collidersCount = 0;
|
||||||
}
|
}
|
||||||
|
@ -498,8 +511,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
// long simulateTotalTime = Util.EnvironmentTickCountSubtract(simulateStartTime);
|
// long simulateTotalTime = Util.EnvironmentTickCountSubtract(simulateStartTime);
|
||||||
// return (timeStep * (float)simulateTotalTime);
|
// return (timeStep * (float)simulateTotalTime);
|
||||||
|
|
||||||
// TODO: FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation.
|
// TODO: FIX THIS: fps calculation possibly wrong.
|
||||||
return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f;
|
// This calculation says 1/timeStep is the ideal frame rate. Any time added to
|
||||||
|
// that by the physics simulation gives a slower frame rate.
|
||||||
|
long totalSimulationTime = Util.EnvironmentTickCountSubtract(simulateStartTime);
|
||||||
|
if (totalSimulationTime >= timeStep)
|
||||||
|
return 0;
|
||||||
|
return 1f / (timeStep + totalSimulationTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Something has collided
|
// Something has collided
|
||||||
|
@ -535,7 +553,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
|
|
||||||
public override void SetTerrain(float[] heightMap) {
|
public override void SetTerrain(float[] heightMap) {
|
||||||
m_heightMap = heightMap;
|
m_heightMap = heightMap;
|
||||||
this.TaintedObject(delegate()
|
this.TaintedObject("BSScene.SetTerrain", delegate()
|
||||||
{
|
{
|
||||||
BulletSimAPI.SetHeightmap(m_worldID, m_heightMap);
|
BulletSimAPI.SetHeightmap(m_worldID, m_heightMap);
|
||||||
});
|
});
|
||||||
|
@ -577,12 +595,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
// make sure no stepping happens while we're deleting stuff
|
// make sure no stepping happens while we're deleting stuff
|
||||||
m_initialized = false;
|
m_initialized = false;
|
||||||
|
|
||||||
if (m_constraintCollection != null)
|
|
||||||
{
|
|
||||||
m_constraintCollection.Dispose();
|
|
||||||
m_constraintCollection = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars)
|
foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars)
|
||||||
{
|
{
|
||||||
kvp.Value.Destroy();
|
kvp.Value.Destroy();
|
||||||
|
@ -595,6 +607,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
}
|
}
|
||||||
m_prims.Clear();
|
m_prims.Clear();
|
||||||
|
|
||||||
|
// Now that the prims are all cleaned up, there should be no constraints left
|
||||||
|
if (m_constraintCollection != null)
|
||||||
|
{
|
||||||
|
m_constraintCollection.Dispose();
|
||||||
|
m_constraintCollection = null;
|
||||||
|
}
|
||||||
|
|
||||||
// Anything left in the unmanaged code should be cleaned out
|
// Anything left in the unmanaged code should be cleaned out
|
||||||
BulletSimAPI.Shutdown(WorldID);
|
BulletSimAPI.Shutdown(WorldID);
|
||||||
|
|
||||||
|
@ -727,12 +746,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
// Calls to the PhysicsActors can't directly call into the physics engine
|
// Calls to the PhysicsActors can't directly call into the physics engine
|
||||||
// because it might be busy. We delay changes to a known time.
|
// because it might be busy. We delay changes to a known time.
|
||||||
// We rely on C#'s closure to save and restore the context for the delegate.
|
// We rely on C#'s closure to save and restore the context for the delegate.
|
||||||
public void TaintedObject(TaintCallback callback)
|
public void TaintedObject(String ident, TaintCallback callback)
|
||||||
{
|
{
|
||||||
if (!m_initialized) return;
|
if (!m_initialized) return;
|
||||||
|
|
||||||
lock (_taintLock)
|
lock (_taintLock)
|
||||||
_taintedObjects.Add(callback);
|
_taintedObjects.Add(new TaintCallbackEntry(ident, callback));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -744,22 +763,22 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
if (_taintedObjects.Count > 0) // save allocating new list if there is nothing to process
|
if (_taintedObjects.Count > 0) // save allocating new list if there is nothing to process
|
||||||
{
|
{
|
||||||
// swizzle a new list into the list location so we can process what's there
|
// swizzle a new list into the list location so we can process what's there
|
||||||
List<TaintCallback> oldList;
|
List<TaintCallbackEntry> oldList;
|
||||||
lock (_taintLock)
|
lock (_taintLock)
|
||||||
{
|
{
|
||||||
oldList = _taintedObjects;
|
oldList = _taintedObjects;
|
||||||
_taintedObjects = new List<TaintCallback>();
|
_taintedObjects = new List<TaintCallbackEntry>();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (TaintCallback callback in oldList)
|
foreach (TaintCallbackEntry tcbe in oldList)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
callback();
|
tcbe.callback();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat("{0}: ProcessTaints: Exception: {1}", LogHeader, e);
|
m_log.ErrorFormat("{0}: ProcessTaints: {1}: Exception: {2}", LogHeader, tcbe.ident, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
oldList.Clear();
|
oldList.Clear();
|
||||||
|
@ -767,6 +786,20 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Vehicles
|
#region Vehicles
|
||||||
|
|
||||||
|
public void VehicleInSceneTypeChanged(BSPrim vehic, Vehicle newType)
|
||||||
|
{
|
||||||
|
if (newType == Vehicle.TYPE_NONE)
|
||||||
|
{
|
||||||
|
RemoveVehiclePrim(vehic);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// make it so the scene will call us each tick to do vehicle things
|
||||||
|
AddVehiclePrim(vehic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Make so the scene will call this prim for vehicle actions each tick.
|
// Make so the scene will call this prim for vehicle actions each tick.
|
||||||
// Safe to call if prim is already in the vehicle list.
|
// Safe to call if prim is already in the vehicle list.
|
||||||
public void AddVehiclePrim(BSPrim vehicle)
|
public void AddVehiclePrim(BSPrim vehicle)
|
||||||
|
@ -812,12 +845,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
|
|
||||||
private struct ParameterDefn
|
private struct ParameterDefn
|
||||||
{
|
{
|
||||||
public string name;
|
public string name; // string name of the parameter
|
||||||
public string desc;
|
public string desc; // a short description of what the parameter means
|
||||||
public float defaultValue;
|
public float defaultValue; // default value if not specified anywhere else
|
||||||
public ParamUser userParam;
|
public ParamUser userParam; // get the value from the configuration file
|
||||||
public ParamGet getter;
|
public ParamGet getter; // return the current value stored for this parameter
|
||||||
public ParamSet setter;
|
public ParamSet setter; // set the current value for this parameter
|
||||||
public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s)
|
public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s)
|
||||||
{
|
{
|
||||||
name = n;
|
name = n;
|
||||||
|
@ -834,7 +867,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
// To add a new externally referencable/settable parameter, add the paramter storage
|
// To add a new externally referencable/settable parameter, add the paramter storage
|
||||||
// location somewhere in the program and make an entry in this table with the
|
// location somewhere in the program and make an entry in this table with the
|
||||||
// getters and setters.
|
// getters and setters.
|
||||||
// To add a new variable, it is easiest to find an existing definition and copy it.
|
// It is easiest to find an existing definition and copy it.
|
||||||
// Parameter values are floats. Booleans are converted to a floating value.
|
// Parameter values are floats. Booleans are converted to a floating value.
|
||||||
//
|
//
|
||||||
// A ParameterDefn() takes the following parameters:
|
// A ParameterDefn() takes the following parameters:
|
||||||
|
@ -870,7 +903,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
(s) => { return (float)s.m_meshLOD; },
|
(s) => { return (float)s.m_meshLOD; },
|
||||||
(s,p,l,v) => { s.m_meshLOD = (int)v; } ),
|
(s,p,l,v) => { s.m_meshLOD = (int)v; } ),
|
||||||
new ParameterDefn("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)",
|
new ParameterDefn("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)",
|
||||||
32,
|
32f,
|
||||||
(s,cf,p,v) => { s.m_sculptLOD = cf.GetInt(p, (int)v); },
|
(s,cf,p,v) => { s.m_sculptLOD = cf.GetInt(p, (int)v); },
|
||||||
(s) => { return (float)s.m_sculptLOD; },
|
(s) => { return (float)s.m_sculptLOD; },
|
||||||
(s,p,l,v) => { s.m_sculptLOD = (int)v; } ),
|
(s,p,l,v) => { s.m_sculptLOD = (int)v; } ),
|
||||||
|
@ -1027,14 +1060,19 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
(s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ),
|
(s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ),
|
||||||
|
|
||||||
|
|
||||||
new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default)",
|
new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
|
||||||
0f, // zero to disable
|
0f, // zero to disable
|
||||||
(s,cf,p,v) => { s.m_params[0].maxPersistantManifoldPoolSize = cf.GetFloat(p, v); },
|
(s,cf,p,v) => { s.m_params[0].maxPersistantManifoldPoolSize = cf.GetFloat(p, v); },
|
||||||
(s) => { return s.m_params[0].maxPersistantManifoldPoolSize; },
|
(s) => { return s.m_params[0].maxPersistantManifoldPoolSize; },
|
||||||
(s,p,l,v) => { s.m_params[0].maxPersistantManifoldPoolSize = v; } ),
|
(s,p,l,v) => { s.m_params[0].maxPersistantManifoldPoolSize = v; } ),
|
||||||
|
new ParameterDefn("MaxCollisionAlgorithmPoolSize", "Number of collisions pooled (0 means default of 4096)",
|
||||||
|
0f, // zero to disable
|
||||||
|
(s,cf,p,v) => { s.m_params[0].maxCollisionAlgorithmPoolSize = cf.GetFloat(p, v); },
|
||||||
|
(s) => { return s.m_params[0].maxCollisionAlgorithmPoolSize; },
|
||||||
|
(s,p,l,v) => { s.m_params[0].maxCollisionAlgorithmPoolSize = v; } ),
|
||||||
new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count",
|
new ParameterDefn("ShouldDisableContactPoolDynamicAllocation", "Enable to allow large changes in object count",
|
||||||
ConfigurationParameters.numericTrue,
|
ConfigurationParameters.numericFalse,
|
||||||
(s,cf,p,v) => { s.m_params[0].maxPersistantManifoldPoolSize = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
|
(s,cf,p,v) => { s.m_params[0].shouldDisableContactPoolDynamicAllocation = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
|
||||||
(s) => { return s.m_params[0].shouldDisableContactPoolDynamicAllocation; },
|
(s) => { return s.m_params[0].shouldDisableContactPoolDynamicAllocation; },
|
||||||
(s,p,l,v) => { s.m_params[0].shouldDisableContactPoolDynamicAllocation = v; } ),
|
(s,p,l,v) => { s.m_params[0].shouldDisableContactPoolDynamicAllocation = v; } ),
|
||||||
new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step",
|
new ParameterDefn("ShouldForceUpdateAllAabbs", "Enable to recomputer AABBs every simulator step",
|
||||||
|
@ -1101,9 +1139,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
(s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ),
|
(s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ),
|
||||||
new ParameterDefn("ShouldDebugLog", "Enables detailed DEBUG log statements",
|
new ParameterDefn("ShouldDebugLog", "Enables detailed DEBUG log statements",
|
||||||
ConfigurationParameters.numericFalse,
|
ConfigurationParameters.numericFalse,
|
||||||
(s,cf,p,v) => { s.shouldDebugLog = cf.GetBoolean(p, s.BoolNumeric(v)); },
|
(s,cf,p,v) => { s.ShouldDebugLog = cf.GetBoolean(p, s.BoolNumeric(v)); },
|
||||||
(s) => { return s.NumericBool(s.shouldDebugLog); },
|
(s) => { return s.NumericBool(s.ShouldDebugLog); },
|
||||||
(s,p,l,v) => { s.shouldDebugLog = s.BoolNumeric(v); } ),
|
(s,p,l,v) => { s.ShouldDebugLog = s.BoolNumeric(v); } ),
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1243,7 +1281,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
List<uint> objectIDs = lIDs;
|
List<uint> objectIDs = lIDs;
|
||||||
string xparm = parm.ToLower();
|
string xparm = parm.ToLower();
|
||||||
float xval = val;
|
float xval = val;
|
||||||
TaintedObject(delegate() {
|
TaintedObject("BSScene.UpdateParameterSet", delegate() {
|
||||||
foreach (uint lID in objectIDs)
|
foreach (uint lID in objectIDs)
|
||||||
{
|
{
|
||||||
BulletSimAPI.UpdateParameter(m_worldID, lID, xparm, xval);
|
BulletSimAPI.UpdateParameter(m_worldID, lID, xparm, xval);
|
||||||
|
@ -1263,7 +1301,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
uint xlocalID = localID;
|
uint xlocalID = localID;
|
||||||
string xparm = parm.ToLower();
|
string xparm = parm.ToLower();
|
||||||
float xval = val;
|
float xval = val;
|
||||||
TaintedObject(delegate() {
|
TaintedObject("BSScene.TaintedUpdateParameter", delegate() {
|
||||||
BulletSimAPI.UpdateParameter(m_worldID, xlocalID, xparm, xval);
|
BulletSimAPI.UpdateParameter(m_worldID, xlocalID, xparm, xval);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1289,10 +1327,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
#endregion Runtime settable parameters
|
#endregion Runtime settable parameters
|
||||||
|
|
||||||
// Invoke the detailed logger and output something if it's enabled.
|
// Invoke the detailed logger and output something if it's enabled.
|
||||||
private void DetailLog(string msg, params Object[] args)
|
public void DetailLog(string msg, params Object[] args)
|
||||||
{
|
{
|
||||||
PhysicsLogging.Write(msg, args);
|
PhysicsLogging.Write(msg, args);
|
||||||
}
|
}
|
||||||
|
// used to fill in the LocalID when there isn't one
|
||||||
|
public const string DetailLogZero = "0000000000";
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,9 +35,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin {
|
||||||
// Classes to allow some type checking for the API
|
// Classes to allow some type checking for the API
|
||||||
public struct BulletSim
|
public struct BulletSim
|
||||||
{
|
{
|
||||||
public BulletSim(uint id, IntPtr xx) { ID = id; Ptr = xx; }
|
public BulletSim(uint id, BSScene bss, IntPtr xx) { ID = id; scene = bss; Ptr = xx; }
|
||||||
public IntPtr Ptr;
|
|
||||||
public uint ID;
|
public uint ID;
|
||||||
|
// The scene is only in here so very low level routines have a handle to print debug/error messages
|
||||||
|
public BSScene scene;
|
||||||
|
public IntPtr Ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct BulletBody
|
public struct BulletBody
|
||||||
|
@ -158,6 +160,7 @@ public struct ConfigurationParameters
|
||||||
public float avatarContactProcessingThreshold;
|
public float avatarContactProcessingThreshold;
|
||||||
|
|
||||||
public float maxPersistantManifoldPoolSize;
|
public float maxPersistantManifoldPoolSize;
|
||||||
|
public float maxCollisionAlgorithmPoolSize;
|
||||||
public float shouldDisableContactPoolDynamicAllocation;
|
public float shouldDisableContactPoolDynamicAllocation;
|
||||||
public float shouldForceUpdateAllAabbs;
|
public float shouldForceUpdateAllAabbs;
|
||||||
public float shouldRandomizeSolverOrder;
|
public float shouldRandomizeSolverOrder;
|
||||||
|
@ -179,17 +182,18 @@ public struct ConfigurationParameters
|
||||||
// Values used by Bullet and BulletSim to control collisions
|
// Values used by Bullet and BulletSim to control collisions
|
||||||
public enum CollisionFlags : uint
|
public enum CollisionFlags : uint
|
||||||
{
|
{
|
||||||
STATIC_OBJECT = 1 << 0,
|
CF_STATIC_OBJECT = 1 << 0,
|
||||||
KINEMATIC_OBJECT = 1 << 1,
|
CF_KINEMATIC_OBJECT = 1 << 1,
|
||||||
NO_CONTACT_RESPONSE = 1 << 2,
|
CF_NO_CONTACT_RESPONSE = 1 << 2,
|
||||||
CUSTOM_MATERIAL_CALLBACK = 1 << 3,
|
CF_CUSTOM_MATERIAL_CALLBACK = 1 << 3,
|
||||||
CHARACTER_OBJECT = 1 << 4,
|
CF_CHARACTER_OBJECT = 1 << 4,
|
||||||
DISABLE_VISUALIZE_OBJECT = 1 << 5,
|
CF_DISABLE_VISUALIZE_OBJECT = 1 << 5,
|
||||||
DISABLE_SPU_COLLISION_PROCESS = 1 << 6,
|
CF_DISABLE_SPU_COLLISION_PROCESS = 1 << 6,
|
||||||
// Following used by BulletSim to control collisions
|
// Following used by BulletSim to control collisions
|
||||||
VOLUME_DETECT_OBJECT = 1 << 10,
|
BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10,
|
||||||
PHANTOM_OBJECT = 1 << 11,
|
BS_VOLUME_DETECT_OBJECT = 1 << 11,
|
||||||
PHYSICAL_OBJECT = 1 << 12,
|
BS_PHANTOM_OBJECT = 1 << 12,
|
||||||
|
BS_PHYSICAL_OBJECT = 1 << 13,
|
||||||
};
|
};
|
||||||
|
|
||||||
// CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0
|
// CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0
|
||||||
|
@ -361,7 +365,7 @@ public static extern IntPtr GetSimHandle2(uint worldID);
|
||||||
public static extern IntPtr GetBodyHandleWorldID2(uint worldID, uint id);
|
public static extern IntPtr GetBodyHandleWorldID2(uint worldID, uint id);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern IntPtr GetBodyHandle2(IntPtr sim, uint id);
|
public static extern IntPtr GetBodyHandle2(IntPtr world, uint id);
|
||||||
|
|
||||||
// ===============================================================================
|
// ===============================================================================
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
|
@ -370,44 +374,68 @@ public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms,
|
||||||
int maxUpdates, IntPtr updateArray);
|
int maxUpdates, IntPtr updateArray);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern bool UpdateParameter2(IntPtr sim, uint localID, String parm, float value);
|
public static extern bool UpdateParameter2(IntPtr world, uint localID, String parm, float value);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern void SetHeightmap2(IntPtr sim, float[] heightmap);
|
public static extern void SetHeightmap2(IntPtr world, float[] heightmap);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern void Shutdown2(IntPtr sim);
|
public static extern void Shutdown2(IntPtr sim);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern int PhysicsStep2(IntPtr sim, float timeStep, int maxSubSteps, float fixedTimeStep,
|
public static extern int PhysicsStep2(IntPtr world, float timeStep, int maxSubSteps, float fixedTimeStep,
|
||||||
out int updatedEntityCount,
|
out int updatedEntityCount,
|
||||||
out IntPtr updatedEntitiesPtr,
|
out IntPtr updatedEntitiesPtr,
|
||||||
out int collidersCount,
|
out int collidersCount,
|
||||||
out IntPtr collidersPtr);
|
out IntPtr collidersPtr);
|
||||||
|
|
||||||
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
|
public static extern bool PushUpdate2(IntPtr obj);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern IntPtr CreateMesh2(IntPtr sim, int indicesCount, int* indices, int verticesCount, float* vertices );
|
public static extern IntPtr CreateMesh2(IntPtr world, int indicesCount, int* indices, int verticesCount, float* vertices );
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern bool BuildHull2(IntPtr sim, IntPtr mesh);
|
public static extern bool BuildHull2(IntPtr world, IntPtr mesh);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern bool ReleaseHull2(IntPtr sim, IntPtr mesh);
|
public static extern bool ReleaseHull2(IntPtr world, IntPtr mesh);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern bool DestroyMesh2(IntPtr sim, IntPtr mesh);
|
public static extern bool DestroyMesh2(IntPtr world, IntPtr mesh);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern IntPtr CreateObject2(IntPtr sim, ShapeData shapeData);
|
public static extern IntPtr CreateObject2(IntPtr world, ShapeData shapeData);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern IntPtr CreateConstraint2(IntPtr sim, IntPtr obj1, IntPtr obj2,
|
public static extern IntPtr Create6DofConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2,
|
||||||
Vector3 frame1loc, Quaternion frame1rot,
|
Vector3 frame1loc, Quaternion frame1rot,
|
||||||
Vector3 frame2loc, Quaternion frame2rot,
|
Vector3 frame2loc, Quaternion frame2rot,
|
||||||
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies);
|
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies);
|
||||||
|
|
||||||
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
|
public static extern IntPtr Create6DofConstraintToPoint2(IntPtr world, IntPtr obj1, IntPtr obj2,
|
||||||
|
Vector3 joinPoint,
|
||||||
|
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies);
|
||||||
|
|
||||||
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
|
public static extern IntPtr CreateHingeConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2,
|
||||||
|
Vector3 pivotinA, Vector3 pivotinB,
|
||||||
|
Vector3 axisInA, Vector3 axisInB,
|
||||||
|
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies);
|
||||||
|
|
||||||
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
|
public static extern void SetConstraintEnable2(IntPtr constrain, float numericTrueFalse);
|
||||||
|
|
||||||
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
|
public static extern void SetConstraintNumSolverIterations2(IntPtr constrain, float iterations);
|
||||||
|
|
||||||
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
|
public static extern bool SetFrames2(IntPtr constrain,
|
||||||
|
Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern bool SetLinearLimits2(IntPtr constrain, Vector3 low, Vector3 hi);
|
public static extern bool SetLinearLimits2(IntPtr constrain, Vector3 low, Vector3 hi);
|
||||||
|
|
||||||
|
@ -420,6 +448,9 @@ public static extern bool UseFrameOffset2(IntPtr constrain, float enable);
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern bool TranslationalLimitMotor2(IntPtr constrain, float enable, float targetVel, float maxMotorForce);
|
public static extern bool TranslationalLimitMotor2(IntPtr constrain, float enable, float targetVel, float maxMotorForce);
|
||||||
|
|
||||||
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
|
public static extern bool SetBreakingImpulseThreshold2(IntPtr constrain, float threshold);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern bool CalculateTransforms2(IntPtr constrain);
|
public static extern bool CalculateTransforms2(IntPtr constrain);
|
||||||
|
|
||||||
|
@ -427,7 +458,13 @@ public static extern bool CalculateTransforms2(IntPtr constrain);
|
||||||
public static extern bool SetConstraintParam2(IntPtr constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis);
|
public static extern bool SetConstraintParam2(IntPtr constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern bool DestroyConstraint2(IntPtr sim, IntPtr constrain);
|
public static extern bool DestroyConstraint2(IntPtr world, IntPtr constrain);
|
||||||
|
|
||||||
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
|
public static extern Vector3 AddObjectToWorld2(IntPtr world, IntPtr obj);
|
||||||
|
|
||||||
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
|
public static extern Vector3 RemoveObjectFromWorld2(IntPtr world, IntPtr obj);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern Vector3 GetPosition2(IntPtr obj);
|
public static extern Vector3 GetPosition2(IntPtr obj);
|
||||||
|
@ -447,6 +484,9 @@ public static extern bool SetAngularVelocity2(IntPtr obj, Vector3 angularVelocit
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern bool SetObjectForce2(IntPtr obj, Vector3 force);
|
public static extern bool SetObjectForce2(IntPtr obj, Vector3 force);
|
||||||
|
|
||||||
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
|
public static extern bool AddObjectForce2(IntPtr obj, Vector3 force);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern bool SetCcdMotionThreshold2(IntPtr obj, float val);
|
public static extern bool SetCcdMotionThreshold2(IntPtr obj, float val);
|
||||||
|
|
||||||
|
@ -478,13 +518,16 @@ public static extern bool SetLinearVelocity2(IntPtr obj, Vector3 val);
|
||||||
public static extern bool SetInterpolation2(IntPtr obj, Vector3 lin, Vector3 ang);
|
public static extern bool SetInterpolation2(IntPtr obj, Vector3 lin, Vector3 ang);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern IntPtr SetCollisionFlags2(IntPtr obj, uint flags);
|
public static extern CollisionFlags GetCollisionFlags2(IntPtr obj);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern IntPtr AddToCollisionFlags2(IntPtr obj, uint flags);
|
public static extern IntPtr SetCollisionFlags2(IntPtr obj, CollisionFlags flags);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern IntPtr RemoveFromCollisionFlags2(IntPtr obj, uint flags);
|
public static extern IntPtr AddToCollisionFlags2(IntPtr obj, CollisionFlags flags);
|
||||||
|
|
||||||
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
|
public static extern IntPtr RemoveFromCollisionFlags2(IntPtr obj, CollisionFlags flags);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern bool SetMassProps2(IntPtr obj, float mass, Vector3 inertia);
|
public static extern bool SetMassProps2(IntPtr obj, float mass, Vector3 inertia);
|
||||||
|
@ -498,18 +541,15 @@ public static extern bool SetGravity2(IntPtr obj, Vector3 val);
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern IntPtr ClearForces2(IntPtr obj);
|
public static extern IntPtr ClearForces2(IntPtr obj);
|
||||||
|
|
||||||
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
|
public static extern IntPtr ClearAllForces2(IntPtr obj);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern bool SetMargin2(IntPtr obj, float val);
|
public static extern bool SetMargin2(IntPtr obj, float val);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern bool UpdateSingleAabb2(IntPtr world, IntPtr obj);
|
public static extern bool UpdateSingleAabb2(IntPtr world, IntPtr obj);
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
|
||||||
public static extern bool AddObjectToWorld2(IntPtr world, IntPtr obj);
|
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
|
||||||
public static extern bool RemoveObjectFromWorld2(IntPtr world, IntPtr obj);
|
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern bool DestroyObject2(IntPtr world, uint id);
|
public static extern bool DestroyObject2(IntPtr world, uint id);
|
||||||
|
|
||||||
|
|
|
@ -226,6 +226,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
public void llResetScript()
|
public void llResetScript()
|
||||||
{
|
{
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
|
|
||||||
|
// We need to tell the URL module, if we hav one, to release
|
||||||
|
// the allocated URLs
|
||||||
|
if (m_UrlModule != null)
|
||||||
|
m_UrlModule.ScriptRemoved(m_item.ItemID);
|
||||||
|
|
||||||
m_ScriptEngine.ApiResetScript(m_item.ItemID);
|
m_ScriptEngine.ApiResetScript(m_item.ItemID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,35 +337,40 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SceneObjectPart> GetLinkParts(int linkType)
|
public List<SceneObjectPart> GetLinkParts(int linkType)
|
||||||
|
{
|
||||||
|
return GetLinkParts(m_host, linkType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
|
||||||
{
|
{
|
||||||
List<SceneObjectPart> ret = new List<SceneObjectPart>();
|
List<SceneObjectPart> ret = new List<SceneObjectPart>();
|
||||||
if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
|
if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
|
||||||
return ret;
|
return ret;
|
||||||
ret.Add(m_host);
|
ret.Add(part);
|
||||||
|
|
||||||
switch (linkType)
|
switch (linkType)
|
||||||
{
|
{
|
||||||
case ScriptBaseClass.LINK_SET:
|
case ScriptBaseClass.LINK_SET:
|
||||||
return new List<SceneObjectPart>(m_host.ParentGroup.Parts);
|
return new List<SceneObjectPart>(part.ParentGroup.Parts);
|
||||||
|
|
||||||
case ScriptBaseClass.LINK_ROOT:
|
case ScriptBaseClass.LINK_ROOT:
|
||||||
ret = new List<SceneObjectPart>();
|
ret = new List<SceneObjectPart>();
|
||||||
ret.Add(m_host.ParentGroup.RootPart);
|
ret.Add(part.ParentGroup.RootPart);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
case ScriptBaseClass.LINK_ALL_OTHERS:
|
case ScriptBaseClass.LINK_ALL_OTHERS:
|
||||||
ret = new List<SceneObjectPart>(m_host.ParentGroup.Parts);
|
ret = new List<SceneObjectPart>(part.ParentGroup.Parts);
|
||||||
|
|
||||||
if (ret.Contains(m_host))
|
if (ret.Contains(part))
|
||||||
ret.Remove(m_host);
|
ret.Remove(part);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
case ScriptBaseClass.LINK_ALL_CHILDREN:
|
case ScriptBaseClass.LINK_ALL_CHILDREN:
|
||||||
ret = new List<SceneObjectPart>(m_host.ParentGroup.Parts);
|
ret = new List<SceneObjectPart>(part.ParentGroup.Parts);
|
||||||
|
|
||||||
if (ret.Contains(m_host.ParentGroup.RootPart))
|
if (ret.Contains(part.ParentGroup.RootPart))
|
||||||
ret.Remove(m_host.ParentGroup.RootPart);
|
ret.Remove(part.ParentGroup.RootPart);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
case ScriptBaseClass.LINK_THIS:
|
case ScriptBaseClass.LINK_THIS:
|
||||||
|
@ -369,7 +380,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
if (linkType < 0)
|
if (linkType < 0)
|
||||||
return new List<SceneObjectPart>();
|
return new List<SceneObjectPart>();
|
||||||
|
|
||||||
SceneObjectPart target = m_host.ParentGroup.GetLinkNumPart(linkType);
|
SceneObjectPart target = part.ParentGroup.GetLinkNumPart(linkType);
|
||||||
if (target == null)
|
if (target == null)
|
||||||
return new List<SceneObjectPart>();
|
return new List<SceneObjectPart>();
|
||||||
ret = new List<SceneObjectPart>();
|
ret = new List<SceneObjectPart>();
|
||||||
|
@ -1764,13 +1775,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
parts[0].ParentGroup.areUpdatesSuspended = true;
|
|
||||||
foreach (SceneObjectPart part in parts)
|
foreach (SceneObjectPart part in parts)
|
||||||
SetAlpha(part, alpha, face);
|
SetAlpha(part, alpha, face);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
parts[0].ParentGroup.areUpdatesSuspended = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1951,13 +1960,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
parts[0].ParentGroup.areUpdatesSuspended = true;
|
|
||||||
foreach (SceneObjectPart part in parts)
|
foreach (SceneObjectPart part in parts)
|
||||||
SetTexture(part, texture, face);
|
SetTexture(part, texture, face);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
parts[0].ParentGroup.areUpdatesSuspended = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ScriptSleep(200);
|
ScriptSleep(200);
|
||||||
|
@ -3340,7 +3347,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
|
IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
|
||||||
|
|
||||||
if (attachmentsModule != null)
|
if (attachmentsModule != null)
|
||||||
return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true);
|
return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3747,29 +3754,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
|
|
||||||
|
int implicitPerms = 0;
|
||||||
|
|
||||||
if (m_host.ParentGroup.IsAttachment && (UUID)agent == m_host.ParentGroup.AttachedAvatar)
|
if (m_host.ParentGroup.IsAttachment && (UUID)agent == m_host.ParentGroup.AttachedAvatar)
|
||||||
{
|
{
|
||||||
// When attached, certain permissions are implicit if requested from owner
|
// When attached, certain permissions are implicit if requested from owner
|
||||||
int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
|
implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
|
||||||
ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
|
ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
|
||||||
ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
|
ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
|
||||||
ScriptBaseClass.PERMISSION_TRACK_CAMERA |
|
ScriptBaseClass.PERMISSION_TRACK_CAMERA |
|
||||||
ScriptBaseClass.PERMISSION_ATTACH;
|
ScriptBaseClass.PERMISSION_ATTACH;
|
||||||
|
|
||||||
if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
|
|
||||||
{
|
|
||||||
m_host.TaskInventory.LockItemsForWrite(true);
|
|
||||||
m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
|
|
||||||
m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
|
|
||||||
m_host.TaskInventory.LockItemsForWrite(false);
|
|
||||||
|
|
||||||
m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
|
|
||||||
"run_time_permissions", new Object[] {
|
|
||||||
new LSL_Integer(perm) },
|
|
||||||
new DetectParams[0]));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3790,26 +3785,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
if (sitting)
|
if (sitting)
|
||||||
{
|
{
|
||||||
// When agent is sitting, certain permissions are implicit if requested from sitting agent
|
// When agent is sitting, certain permissions are implicit if requested from sitting agent
|
||||||
int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
|
implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
|
||||||
ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
|
ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
|
||||||
ScriptBaseClass.PERMISSION_TRACK_CAMERA |
|
ScriptBaseClass.PERMISSION_TRACK_CAMERA |
|
||||||
ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
|
ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
|
||||||
|
|
||||||
if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
|
|
||||||
{
|
|
||||||
m_host.TaskInventory.LockItemsForWrite(true);
|
|
||||||
m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
|
|
||||||
m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
|
|
||||||
m_host.TaskInventory.LockItemsForWrite(false);
|
|
||||||
|
|
||||||
m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
|
|
||||||
"run_time_permissions", new Object[] {
|
|
||||||
new LSL_Integer(perm) },
|
|
||||||
new DetectParams[0]));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
|
||||||
|
implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
|
||||||
|
{
|
||||||
|
m_host.TaskInventory.LockItemsForWrite(true);
|
||||||
|
m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
|
||||||
|
m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
|
||||||
|
m_host.TaskInventory.LockItemsForWrite(false);
|
||||||
|
|
||||||
|
m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
|
||||||
|
"run_time_permissions", new Object[] {
|
||||||
|
new LSL_Integer(perm) },
|
||||||
|
new DetectParams[0]));
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScenePresence presence = World.GetScenePresence(agentID);
|
ScenePresence presence = World.GetScenePresence(agentID);
|
||||||
|
@ -3927,13 +3927,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
parts[0].ParentGroup.areUpdatesSuspended = true;
|
|
||||||
foreach (SceneObjectPart part in parts)
|
foreach (SceneObjectPart part in parts)
|
||||||
part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
|
part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
parts[0].ParentGroup.areUpdatesSuspended = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4051,7 +4049,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
parts[0].ParentGroup.areUpdatesSuspended = true;
|
|
||||||
foreach (SceneObjectPart part in parts)
|
foreach (SceneObjectPart part in parts)
|
||||||
{
|
{
|
||||||
parentPrim.DelinkFromGroup(part.LocalId, true);
|
parentPrim.DelinkFromGroup(part.LocalId, true);
|
||||||
|
@ -4059,7 +4056,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
parts[0].ParentGroup.areUpdatesSuspended = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4074,7 +4070,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
parts[0].ParentGroup.areUpdatesSuspended = true;
|
|
||||||
foreach (SceneObjectPart part in parts)
|
foreach (SceneObjectPart part in parts)
|
||||||
{
|
{
|
||||||
part.ClearUpdateSchedule();
|
part.ClearUpdateSchedule();
|
||||||
|
@ -4083,7 +4078,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
parts[0].ParentGroup.areUpdatesSuspended = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -5369,12 +5363,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Vectors & Rotations always return zero in SL, but
|
||||||
|
// keys don't always return zero, it seems to be a bit complex.
|
||||||
|
else if (src.Data[index] is LSL_Vector ||
|
||||||
|
src.Data[index] is LSL_Rotation)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
if (src.Data[index] is LSL_Integer)
|
if (src.Data[index] is LSL_Integer)
|
||||||
return (LSL_Integer) src.Data[index];
|
return (LSL_Integer)src.Data[index];
|
||||||
else if (src.Data[index] is LSL_Float)
|
else if (src.Data[index] is LSL_Float)
|
||||||
return Convert.ToInt32(((LSL_Float) src.Data[index]).value);
|
return Convert.ToInt32(((LSL_Float)src.Data[index]).value);
|
||||||
return new LSL_Integer(src.Data[index].ToString());
|
return new LSL_Integer(src.Data[index].ToString());
|
||||||
}
|
}
|
||||||
catch (FormatException)
|
catch (FormatException)
|
||||||
|
@ -5394,12 +5397,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Vectors & Rotations always return zero in SL
|
||||||
|
else if (src.Data[index] is LSL_Vector ||
|
||||||
|
src.Data[index] is LSL_Rotation)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// valid keys seem to get parsed as integers then converted to floats
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UUID uuidt;
|
||||||
|
if (src.Data[index] is LSL_Key && UUID.TryParse(src.Data[index].ToString(), out uuidt))
|
||||||
|
{
|
||||||
|
return Convert.ToDouble(new LSL_Integer(src.Data[index].ToString()).value);
|
||||||
|
}
|
||||||
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (src.Data[index] is LSL_Integer)
|
if (src.Data[index] is LSL_Integer)
|
||||||
return Convert.ToDouble(((LSL_Integer) src.Data[index]).value);
|
return Convert.ToDouble(((LSL_Integer)src.Data[index]).value);
|
||||||
else if (src.Data[index] is LSL_Float)
|
else if (src.Data[index] is LSL_Float)
|
||||||
return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
|
return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
|
||||||
else if (src.Data[index] is LSL_String)
|
else if (src.Data[index] is LSL_String)
|
||||||
{
|
{
|
||||||
string str = ((LSL_String) src.Data[index]).m_string;
|
string str = ((LSL_String) src.Data[index]).m_string;
|
||||||
|
@ -5437,17 +5456,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
return src.Data[index].ToString();
|
return src.Data[index].ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public LSL_String llList2Key(LSL_List src, int index)
|
public LSL_Key llList2Key(LSL_List src, int index)
|
||||||
{
|
{
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
{
|
{
|
||||||
index = src.Length + index;
|
index = src.Length + index;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index >= src.Length || index < 0)
|
if (index >= src.Length || index < 0)
|
||||||
{
|
{
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SL spits out an empty string for types other than key & string
|
||||||
|
// At the time of patching, LSL_Key is currently LSL_String,
|
||||||
|
// so the OR check may be a little redundant, but it's being done
|
||||||
|
// for completion and should LSL_Key ever be implemented
|
||||||
|
// as it's own struct
|
||||||
|
else if (!(src.Data[index] is LSL_String ||
|
||||||
|
src.Data[index] is LSL_Key))
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
return src.Data[index].ToString();
|
return src.Data[index].ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5466,6 +5498,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
return (LSL_Vector)src.Data[index];
|
return (LSL_Vector)src.Data[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SL spits always out ZERO_VECTOR for anything other than
|
||||||
|
// strings or vectors. Although keys always return ZERO_VECTOR,
|
||||||
|
// it is currently difficult to make the distinction between
|
||||||
|
// a string, a key as string and a string that by coincidence
|
||||||
|
// is a string, so we're going to leave that up to the
|
||||||
|
// LSL_Vector constructor.
|
||||||
|
else if (!(src.Data[index] is LSL_String ||
|
||||||
|
src.Data[index] is LSL_Vector))
|
||||||
|
{
|
||||||
|
return new LSL_Vector(0, 0, 0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new LSL_Vector(src.Data[index].ToString());
|
return new LSL_Vector(src.Data[index].ToString());
|
||||||
|
@ -5483,7 +5527,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
return new LSL_Rotation(0, 0, 0, 1);
|
return new LSL_Rotation(0, 0, 0, 1);
|
||||||
}
|
}
|
||||||
if (src.Data[index].GetType() == typeof(LSL_Rotation))
|
|
||||||
|
// SL spits always out ZERO_ROTATION for anything other than
|
||||||
|
// strings or vectors. Although keys always return ZERO_ROTATION,
|
||||||
|
// it is currently difficult to make the distinction between
|
||||||
|
// a string, a key as string and a string that by coincidence
|
||||||
|
// is a string, so we're going to leave that up to the
|
||||||
|
// LSL_Rotation constructor.
|
||||||
|
else if (!(src.Data[index] is LSL_String ||
|
||||||
|
src.Data[index] is LSL_Rotation))
|
||||||
|
{
|
||||||
|
return new LSL_Rotation(0, 0, 0, 1);
|
||||||
|
}
|
||||||
|
else if (src.Data[index].GetType() == typeof(LSL_Rotation))
|
||||||
{
|
{
|
||||||
return (LSL_Rotation)src.Data[index];
|
return (LSL_Rotation)src.Data[index];
|
||||||
}
|
}
|
||||||
|
@ -6236,7 +6292,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
parts[0].ParentGroup.areUpdatesSuspended = true;
|
|
||||||
foreach (var part in parts)
|
foreach (var part in parts)
|
||||||
{
|
{
|
||||||
SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
|
SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
|
||||||
|
@ -6244,7 +6299,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
parts[0].ParentGroup.areUpdatesSuspended = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7689,7 +7743,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
public void llSetPrimitiveParams(LSL_List rules)
|
public void llSetPrimitiveParams(LSL_List rules)
|
||||||
{
|
{
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
SetPrimParams(m_host, rules);
|
|
||||||
|
setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules);
|
||||||
|
|
||||||
ScriptSleep(200);
|
ScriptSleep(200);
|
||||||
}
|
}
|
||||||
|
@ -7703,26 +7758,47 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
private void setLinkPrimParams(int linknumber, LSL_List rules)
|
private void setLinkPrimParams(int linknumber, LSL_List rules)
|
||||||
{
|
{
|
||||||
List<SceneObjectPart> parts = GetLinkParts(linknumber);
|
List<object> parts = new List<object>();
|
||||||
|
List<SceneObjectPart> prims = GetLinkParts(linknumber);
|
||||||
List<ScenePresence> avatars = GetLinkAvatars(linknumber);
|
List<ScenePresence> avatars = GetLinkAvatars(linknumber);
|
||||||
if (parts.Count>0)
|
foreach (SceneObjectPart p in prims)
|
||||||
|
parts.Add(p);
|
||||||
|
foreach (ScenePresence p in avatars)
|
||||||
|
parts.Add(p);
|
||||||
|
|
||||||
|
LSL_List remaining = null;
|
||||||
|
|
||||||
|
if (parts.Count > 0)
|
||||||
{
|
{
|
||||||
try
|
foreach (object part in parts)
|
||||||
{
|
{
|
||||||
parts[0].ParentGroup.areUpdatesSuspended = true;
|
if (part is SceneObjectPart)
|
||||||
foreach (SceneObjectPart part in parts)
|
remaining = SetPrimParams((SceneObjectPart)part, rules);
|
||||||
SetPrimParams(part, rules);
|
else
|
||||||
|
remaining = SetPrimParams((ScenePresence)part, rules);
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
|
while((object)remaining != null && remaining.Length > 2)
|
||||||
{
|
{
|
||||||
parts[0].ParentGroup.areUpdatesSuspended = false;
|
linknumber = remaining.GetLSLIntegerItem(0);
|
||||||
|
rules = remaining.GetSublist(1,-1);
|
||||||
|
parts.Clear();
|
||||||
|
prims = GetLinkParts(linknumber);
|
||||||
|
avatars = GetLinkAvatars(linknumber);
|
||||||
|
foreach (SceneObjectPart p in prims)
|
||||||
|
parts.Add(p);
|
||||||
|
foreach (ScenePresence p in avatars)
|
||||||
|
parts.Add(p);
|
||||||
|
|
||||||
|
foreach (object part in parts)
|
||||||
|
{
|
||||||
|
if (part is SceneObjectPart)
|
||||||
|
remaining = SetPrimParams((SceneObjectPart)part, rules);
|
||||||
|
else
|
||||||
|
remaining = SetPrimParams((ScenePresence)part, rules);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (avatars.Count > 0)
|
|
||||||
{
|
|
||||||
foreach (ScenePresence avatar in avatars)
|
|
||||||
SetPrimParams(avatar, rules);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
|
private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
|
||||||
|
@ -7784,7 +7860,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
return new Vector3((float)x, (float)y, (float)z);
|
return new Vector3((float)x, (float)y, (float)z);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void SetPrimParams(ScenePresence av, LSL_List rules)
|
protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules)
|
||||||
{
|
{
|
||||||
//This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
|
//This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
|
||||||
|
|
||||||
|
@ -7807,7 +7883,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
case (int)ScriptBaseClass.PRIM_POS_LOCAL:
|
case (int)ScriptBaseClass.PRIM_POS_LOCAL:
|
||||||
{
|
{
|
||||||
if (remain < 1)
|
if (remain < 1)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
LSL_Vector v;
|
LSL_Vector v;
|
||||||
v = rules.GetVector3Item(idx++);
|
v = rules.GetVector3Item(idx++);
|
||||||
|
@ -7841,7 +7917,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
case (int)ScriptBaseClass.PRIM_ROTATION:
|
case (int)ScriptBaseClass.PRIM_ROTATION:
|
||||||
{
|
{
|
||||||
if (remain < 1)
|
if (remain < 1)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
LSL_Rotation r;
|
LSL_Rotation r;
|
||||||
r = rules.GetQuaternionItem(idx++);
|
r = rules.GetQuaternionItem(idx++);
|
||||||
|
@ -7872,7 +7948,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
case (int)ScriptBaseClass.PRIM_NAME:
|
case (int)ScriptBaseClass.PRIM_NAME:
|
||||||
case (int)ScriptBaseClass.PRIM_DESC:
|
case (int)ScriptBaseClass.PRIM_DESC:
|
||||||
if (remain < 1)
|
if (remain < 1)
|
||||||
return;
|
return null;
|
||||||
idx++;
|
idx++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -7880,13 +7956,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
|
case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
|
||||||
case (int)ScriptBaseClass.PRIM_TEXGEN:
|
case (int)ScriptBaseClass.PRIM_TEXGEN:
|
||||||
if (remain < 2)
|
if (remain < 2)
|
||||||
return;
|
return null;
|
||||||
idx += 2;
|
idx += 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_TYPE:
|
case (int)ScriptBaseClass.PRIM_TYPE:
|
||||||
if (remain < 3)
|
if (remain < 3)
|
||||||
return;
|
return null;
|
||||||
code = (int)rules.GetLSLIntegerItem(idx++);
|
code = (int)rules.GetLSLIntegerItem(idx++);
|
||||||
remain = rules.Length - idx;
|
remain = rules.Length - idx;
|
||||||
switch (code)
|
switch (code)
|
||||||
|
@ -7895,13 +7971,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
|
case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
|
||||||
case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
|
case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
|
||||||
if (remain < 6)
|
if (remain < 6)
|
||||||
return;
|
return null;
|
||||||
idx += 6;
|
idx += 6;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
|
case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
|
||||||
if (remain < 5)
|
if (remain < 5)
|
||||||
return;
|
return null;
|
||||||
idx += 5;
|
idx += 5;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -7909,13 +7985,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
|
case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
|
||||||
case (int)ScriptBaseClass.PRIM_TYPE_RING:
|
case (int)ScriptBaseClass.PRIM_TYPE_RING:
|
||||||
if (remain < 11)
|
if (remain < 11)
|
||||||
return;
|
return null;
|
||||||
idx += 11;
|
idx += 11;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
|
case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
|
||||||
if (remain < 2)
|
if (remain < 2)
|
||||||
return;
|
return null;
|
||||||
idx += 2;
|
idx += 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -7926,7 +8002,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
|
case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
|
||||||
case (int)ScriptBaseClass.PRIM_OMEGA:
|
case (int)ScriptBaseClass.PRIM_OMEGA:
|
||||||
if (remain < 3)
|
if (remain < 3)
|
||||||
return;
|
return null;
|
||||||
idx += 3;
|
idx += 3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -7934,33 +8010,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
|
case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
|
||||||
case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
|
case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
|
||||||
if (remain < 5)
|
if (remain < 5)
|
||||||
return;
|
return null;
|
||||||
idx += 5;
|
idx += 5;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_FLEXIBLE:
|
case (int)ScriptBaseClass.PRIM_FLEXIBLE:
|
||||||
if (remain < 7)
|
if (remain < 7)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
idx += 7;
|
idx += 7;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_LINK_TARGET:
|
case (int)ScriptBaseClass.PRIM_LINK_TARGET:
|
||||||
if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
|
if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
if (positionChanged)
|
return rules.GetSublist(idx, -1);
|
||||||
{
|
|
||||||
positionChanged = false;
|
|
||||||
av.OffsetPosition = finalPos;
|
|
||||||
// av.SendAvatarDataToAllAgents();
|
|
||||||
av.SendTerseUpdateToAllClients();
|
|
||||||
}
|
|
||||||
|
|
||||||
LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
|
|
||||||
LSL_List new_rules = rules.GetSublist(idx, -1);
|
|
||||||
setLinkPrimParams((int)new_linknumber, new_rules);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7975,12 +8040,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
positionChanged = false;
|
positionChanged = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
|
protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules)
|
||||||
{
|
{
|
||||||
if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
|
if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
|
||||||
|
@ -8005,7 +8071,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
case (int)ScriptBaseClass.PRIM_POSITION:
|
case (int)ScriptBaseClass.PRIM_POSITION:
|
||||||
case (int)ScriptBaseClass.PRIM_POS_LOCAL:
|
case (int)ScriptBaseClass.PRIM_POS_LOCAL:
|
||||||
if (remain < 1)
|
if (remain < 1)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
v=rules.GetVector3Item(idx++);
|
v=rules.GetVector3Item(idx++);
|
||||||
currentPosition = GetSetPosTarget(part, v, currentPosition);
|
currentPosition = GetSetPosTarget(part, v, currentPosition);
|
||||||
|
@ -8014,7 +8080,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
break;
|
break;
|
||||||
case (int)ScriptBaseClass.PRIM_SIZE:
|
case (int)ScriptBaseClass.PRIM_SIZE:
|
||||||
if (remain < 1)
|
if (remain < 1)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
v=rules.GetVector3Item(idx++);
|
v=rules.GetVector3Item(idx++);
|
||||||
SetScale(part, v);
|
SetScale(part, v);
|
||||||
|
@ -8022,7 +8088,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
break;
|
break;
|
||||||
case (int)ScriptBaseClass.PRIM_ROTATION:
|
case (int)ScriptBaseClass.PRIM_ROTATION:
|
||||||
if (remain < 1)
|
if (remain < 1)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
LSL_Rotation q = rules.GetQuaternionItem(idx++);
|
LSL_Rotation q = rules.GetQuaternionItem(idx++);
|
||||||
SceneObjectPart rootPart = parentgrp.RootPart;
|
SceneObjectPart rootPart = parentgrp.RootPart;
|
||||||
|
@ -8043,7 +8109,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_TYPE:
|
case (int)ScriptBaseClass.PRIM_TYPE:
|
||||||
if (remain < 3)
|
if (remain < 3)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
code = (int)rules.GetLSLIntegerItem(idx++);
|
code = (int)rules.GetLSLIntegerItem(idx++);
|
||||||
|
|
||||||
|
@ -8062,7 +8128,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
case (int)ScriptBaseClass.PRIM_TYPE_BOX:
|
case (int)ScriptBaseClass.PRIM_TYPE_BOX:
|
||||||
if (remain < 6)
|
if (remain < 6)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
face = (int)rules.GetLSLIntegerItem(idx++);
|
face = (int)rules.GetLSLIntegerItem(idx++);
|
||||||
v = rules.GetVector3Item(idx++); // cut
|
v = rules.GetVector3Item(idx++); // cut
|
||||||
|
@ -8077,7 +8143,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
|
case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
|
||||||
if (remain < 6)
|
if (remain < 6)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
|
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
|
||||||
v = rules.GetVector3Item(idx++); // cut
|
v = rules.GetVector3Item(idx++); // cut
|
||||||
|
@ -8091,7 +8157,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
|
case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
|
||||||
if (remain < 6)
|
if (remain < 6)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
|
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
|
||||||
v = rules.GetVector3Item(idx++); //cut
|
v = rules.GetVector3Item(idx++); //cut
|
||||||
|
@ -8105,7 +8171,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
|
case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
|
||||||
if (remain < 5)
|
if (remain < 5)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
|
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
|
||||||
v = rules.GetVector3Item(idx++); // cut
|
v = rules.GetVector3Item(idx++); // cut
|
||||||
|
@ -8118,7 +8184,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
|
case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
|
||||||
if (remain < 11)
|
if (remain < 11)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
|
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
|
||||||
v = rules.GetVector3Item(idx++); //cut
|
v = rules.GetVector3Item(idx++); //cut
|
||||||
|
@ -8137,7 +8203,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
|
case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
|
||||||
if (remain < 11)
|
if (remain < 11)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
|
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
|
||||||
v = rules.GetVector3Item(idx++); //cut
|
v = rules.GetVector3Item(idx++); //cut
|
||||||
|
@ -8156,7 +8222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_TYPE_RING:
|
case (int)ScriptBaseClass.PRIM_TYPE_RING:
|
||||||
if (remain < 11)
|
if (remain < 11)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
|
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
|
||||||
v = rules.GetVector3Item(idx++); //cut
|
v = rules.GetVector3Item(idx++); //cut
|
||||||
|
@ -8175,7 +8241,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
|
case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
|
||||||
if (remain < 2)
|
if (remain < 2)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
string map = rules.Data[idx++].ToString();
|
string map = rules.Data[idx++].ToString();
|
||||||
face = (int)rules.GetLSLIntegerItem(idx++); // type
|
face = (int)rules.GetLSLIntegerItem(idx++); // type
|
||||||
|
@ -8187,7 +8253,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_TEXTURE:
|
case (int)ScriptBaseClass.PRIM_TEXTURE:
|
||||||
if (remain < 5)
|
if (remain < 5)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
face=(int)rules.GetLSLIntegerItem(idx++);
|
face=(int)rules.GetLSLIntegerItem(idx++);
|
||||||
string tex=rules.Data[idx++].ToString();
|
string tex=rules.Data[idx++].ToString();
|
||||||
|
@ -8204,7 +8270,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_COLOR:
|
case (int)ScriptBaseClass.PRIM_COLOR:
|
||||||
if (remain < 3)
|
if (remain < 3)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
face=(int)rules.GetLSLIntegerItem(idx++);
|
face=(int)rules.GetLSLIntegerItem(idx++);
|
||||||
LSL_Vector color=rules.GetVector3Item(idx++);
|
LSL_Vector color=rules.GetVector3Item(idx++);
|
||||||
|
@ -8217,7 +8283,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_FLEXIBLE:
|
case (int)ScriptBaseClass.PRIM_FLEXIBLE:
|
||||||
if (remain < 7)
|
if (remain < 7)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
bool flexi = rules.GetLSLIntegerItem(idx++);
|
bool flexi = rules.GetLSLIntegerItem(idx++);
|
||||||
int softness = rules.GetLSLIntegerItem(idx++);
|
int softness = rules.GetLSLIntegerItem(idx++);
|
||||||
|
@ -8233,7 +8299,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
|
case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
|
||||||
if (remain < 5)
|
if (remain < 5)
|
||||||
return;
|
return null;
|
||||||
bool light = rules.GetLSLIntegerItem(idx++);
|
bool light = rules.GetLSLIntegerItem(idx++);
|
||||||
LSL_Vector lightcolor = rules.GetVector3Item(idx++);
|
LSL_Vector lightcolor = rules.GetVector3Item(idx++);
|
||||||
float intensity = (float)rules.GetLSLFloatItem(idx++);
|
float intensity = (float)rules.GetLSLFloatItem(idx++);
|
||||||
|
@ -8246,7 +8312,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_GLOW:
|
case (int)ScriptBaseClass.PRIM_GLOW:
|
||||||
if (remain < 2)
|
if (remain < 2)
|
||||||
return;
|
return null;
|
||||||
face = rules.GetLSLIntegerItem(idx++);
|
face = rules.GetLSLIntegerItem(idx++);
|
||||||
float glow = (float)rules.GetLSLFloatItem(idx++);
|
float glow = (float)rules.GetLSLFloatItem(idx++);
|
||||||
|
|
||||||
|
@ -8256,7 +8322,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
|
case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
|
||||||
if (remain < 3)
|
if (remain < 3)
|
||||||
return;
|
return null;
|
||||||
face = (int)rules.GetLSLIntegerItem(idx++);
|
face = (int)rules.GetLSLIntegerItem(idx++);
|
||||||
int shiny = (int)rules.GetLSLIntegerItem(idx++);
|
int shiny = (int)rules.GetLSLIntegerItem(idx++);
|
||||||
Bumpiness bump = (Bumpiness)(int)rules.GetLSLIntegerItem(idx++);
|
Bumpiness bump = (Bumpiness)(int)rules.GetLSLIntegerItem(idx++);
|
||||||
|
@ -8267,7 +8333,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
|
case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
|
||||||
if (remain < 2)
|
if (remain < 2)
|
||||||
return;
|
return null;
|
||||||
face = rules.GetLSLIntegerItem(idx++);
|
face = rules.GetLSLIntegerItem(idx++);
|
||||||
bool st = rules.GetLSLIntegerItem(idx++);
|
bool st = rules.GetLSLIntegerItem(idx++);
|
||||||
SetFullBright(part, face , st);
|
SetFullBright(part, face , st);
|
||||||
|
@ -8275,17 +8341,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_MATERIAL:
|
case (int)ScriptBaseClass.PRIM_MATERIAL:
|
||||||
if (remain < 1)
|
if (remain < 1)
|
||||||
return;
|
return null;
|
||||||
int mat = rules.GetLSLIntegerItem(idx++);
|
int mat = rules.GetLSLIntegerItem(idx++);
|
||||||
if (mat < 0 || mat > 7)
|
if (mat < 0 || mat > 7)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
part.Material = Convert.ToByte(mat);
|
part.Material = Convert.ToByte(mat);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_PHANTOM:
|
case (int)ScriptBaseClass.PRIM_PHANTOM:
|
||||||
if (remain < 1)
|
if (remain < 1)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
string ph = rules.Data[idx++].ToString();
|
string ph = rules.Data[idx++].ToString();
|
||||||
parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
|
parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
|
||||||
|
@ -8294,7 +8360,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_PHYSICS:
|
case (int)ScriptBaseClass.PRIM_PHYSICS:
|
||||||
if (remain < 1)
|
if (remain < 1)
|
||||||
return;
|
return null;
|
||||||
string phy = rules.Data[idx++].ToString();
|
string phy = rules.Data[idx++].ToString();
|
||||||
bool physics;
|
bool physics;
|
||||||
|
|
||||||
|
@ -8308,7 +8374,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
|
case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
|
||||||
if (remain < 1)
|
if (remain < 1)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
int shape_type = rules.GetLSLIntegerItem(idx++);
|
int shape_type = rules.GetLSLIntegerItem(idx++);
|
||||||
|
|
||||||
|
@ -8324,7 +8390,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
|
case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
|
||||||
if (remain < 5)
|
if (remain < 5)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
int material_bits = rules.GetLSLIntegerItem(idx++);
|
int material_bits = rules.GetLSLIntegerItem(idx++);
|
||||||
float material_density = (float)rules.GetLSLFloatItem(idx++);
|
float material_density = (float)rules.GetLSLFloatItem(idx++);
|
||||||
|
@ -8338,7 +8404,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
|
case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
|
||||||
if (remain < 1)
|
if (remain < 1)
|
||||||
return;
|
return null;
|
||||||
string temp = rules.Data[idx++].ToString();
|
string temp = rules.Data[idx++].ToString();
|
||||||
|
|
||||||
parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
|
parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
|
||||||
|
@ -8347,7 +8413,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_TEXGEN:
|
case (int)ScriptBaseClass.PRIM_TEXGEN:
|
||||||
if (remain < 2)
|
if (remain < 2)
|
||||||
return;
|
return null;
|
||||||
//face,type
|
//face,type
|
||||||
face = rules.GetLSLIntegerItem(idx++);
|
face = rules.GetLSLIntegerItem(idx++);
|
||||||
int style = rules.GetLSLIntegerItem(idx++);
|
int style = rules.GetLSLIntegerItem(idx++);
|
||||||
|
@ -8355,7 +8421,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
break;
|
break;
|
||||||
case (int)ScriptBaseClass.PRIM_TEXT:
|
case (int)ScriptBaseClass.PRIM_TEXT:
|
||||||
if (remain < 3)
|
if (remain < 3)
|
||||||
return;
|
return null;
|
||||||
string primText = rules.GetLSLStringItem(idx++);
|
string primText = rules.GetLSLStringItem(idx++);
|
||||||
LSL_Vector primTextColor = rules.GetVector3Item(idx++);
|
LSL_Vector primTextColor = rules.GetVector3Item(idx++);
|
||||||
LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++);
|
LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++);
|
||||||
|
@ -8367,26 +8433,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
break;
|
break;
|
||||||
case (int)ScriptBaseClass.PRIM_NAME:
|
case (int)ScriptBaseClass.PRIM_NAME:
|
||||||
if (remain < 1)
|
if (remain < 1)
|
||||||
return;
|
return null;
|
||||||
string primName = rules.GetLSLStringItem(idx++);
|
string primName = rules.GetLSLStringItem(idx++);
|
||||||
part.Name = primName;
|
part.Name = primName;
|
||||||
break;
|
break;
|
||||||
case (int)ScriptBaseClass.PRIM_DESC:
|
case (int)ScriptBaseClass.PRIM_DESC:
|
||||||
if (remain < 1)
|
if (remain < 1)
|
||||||
return;
|
return null;
|
||||||
string primDesc = rules.GetLSLStringItem(idx++);
|
string primDesc = rules.GetLSLStringItem(idx++);
|
||||||
part.Description = primDesc;
|
part.Description = primDesc;
|
||||||
break;
|
break;
|
||||||
case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
|
case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
|
||||||
if (remain < 1)
|
if (remain < 1)
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
LSL_Rotation lr = rules.GetQuaternionItem(idx++);
|
LSL_Rotation lr = rules.GetQuaternionItem(idx++);
|
||||||
SetRot(part, Rot2Quaternion(lr));
|
SetRot(part, Rot2Quaternion(lr));
|
||||||
break;
|
break;
|
||||||
case (int)ScriptBaseClass.PRIM_OMEGA:
|
case (int)ScriptBaseClass.PRIM_OMEGA:
|
||||||
if (remain < 3)
|
if (remain < 3)
|
||||||
return;
|
return null;
|
||||||
LSL_Vector axis = rules.GetVector3Item(idx++);
|
LSL_Vector axis = rules.GetVector3Item(idx++);
|
||||||
LSL_Float spinrate = rules.GetLSLFloatItem(idx++);
|
LSL_Float spinrate = rules.GetLSLFloatItem(idx++);
|
||||||
LSL_Float gain = rules.GetLSLFloatItem(idx++);
|
LSL_Float gain = rules.GetLSLFloatItem(idx++);
|
||||||
|
@ -8395,35 +8460,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_LINK_TARGET:
|
case (int)ScriptBaseClass.PRIM_LINK_TARGET:
|
||||||
if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
|
if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
|
||||||
return;
|
return null;
|
||||||
|
|
||||||
// do a pending position change before jumping to other part/avatar
|
return rules.GetSublist(idx, -1);
|
||||||
if (positionChanged)
|
|
||||||
{
|
|
||||||
positionChanged = false;
|
|
||||||
if (parentgrp == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (parentgrp.RootPart == part)
|
|
||||||
{
|
|
||||||
|
|
||||||
Util.FireAndForget(delegate(object x)
|
|
||||||
{
|
|
||||||
parentgrp.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
|
|
||||||
parentgrp.HasGroupChanged = true;
|
|
||||||
parentgrp.ScheduleGroupForTerseUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
|
|
||||||
LSL_List new_rules = rules.GetSublist(idx, -1);
|
|
||||||
setLinkPrimParams((int)new_linknumber, new_rules);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8447,6 +8486,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LSL_String llStringToBase64(string str)
|
public LSL_String llStringToBase64(string str)
|
||||||
|
@ -12082,7 +12122,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
if (obj.OwnerID != m_host.OwnerID)
|
if (obj.OwnerID != m_host.OwnerID)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SetPrimParams(obj, rules);
|
LSL_List remaining = SetPrimParams(obj, rules);
|
||||||
|
|
||||||
|
while ((object)remaining != null && remaining.Length > 2)
|
||||||
|
{
|
||||||
|
LSL_Integer newLink = remaining.GetLSLIntegerItem(0);
|
||||||
|
LSL_List newrules = remaining.GetSublist(1, -1);
|
||||||
|
foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){
|
||||||
|
remaining = SetPrimParams(part, newrules);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules)
|
public LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules)
|
||||||
|
|
|
@ -2466,8 +2466,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
if (!npcModule.CheckPermissions(npcId, m_host.OwnerID))
|
if (!npcModule.CheckPermissions(npcId, m_host.OwnerID))
|
||||||
return new LSL_Vector(0, 0, 0);
|
return new LSL_Vector(0, 0, 0);
|
||||||
|
|
||||||
Vector3 pos = World.GetScenePresence(npcId).AbsolutePosition;
|
ScenePresence sp = World.GetScenePresence(npcId);
|
||||||
return new LSL_Vector(pos.X, pos.Y, pos.Z);
|
|
||||||
|
if (sp != null)
|
||||||
|
{
|
||||||
|
Vector3 pos = sp.AbsolutePosition;
|
||||||
|
return new LSL_Vector(pos.X, pos.Y, pos.Z);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new LSL_Vector(0, 0, 0);
|
return new LSL_Vector(0, 0, 0);
|
||||||
|
@ -2535,9 +2540,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W);
|
return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W);
|
||||||
|
|
||||||
ScenePresence sp = World.GetScenePresence(npcId);
|
ScenePresence sp = World.GetScenePresence(npcId);
|
||||||
Quaternion rot = sp.Rotation;
|
|
||||||
|
|
||||||
return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
|
if (sp != null)
|
||||||
|
{
|
||||||
|
Quaternion rot = sp.Rotation;
|
||||||
|
return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W);
|
return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W);
|
||||||
|
@ -2559,7 +2567,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ScenePresence sp = World.GetScenePresence(npcId);
|
ScenePresence sp = World.GetScenePresence(npcId);
|
||||||
sp.Rotation = LSL_Api.Rot2Quaternion(rotation);
|
|
||||||
|
if (sp != null)
|
||||||
|
sp.Rotation = LSL_Api.Rot2Quaternion(rotation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2737,6 +2747,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
CheckThreatLevel(ThreatLevel.High, "osNpcTouch");
|
CheckThreatLevel(ThreatLevel.High, "osNpcTouch");
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
|
|
||||||
INPCModule module = World.RequestModuleInterface<INPCModule>();
|
INPCModule module = World.RequestModuleInterface<INPCModule>();
|
||||||
int linkNum = link_num.value;
|
int linkNum = link_num.value;
|
||||||
if (module != null || (linkNum < 0 && linkNum != ScriptBaseClass.LINK_THIS))
|
if (module != null || (linkNum < 0 && linkNum != ScriptBaseClass.LINK_THIS))
|
||||||
|
@ -2744,12 +2755,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
UUID npcId;
|
UUID npcId;
|
||||||
if (!UUID.TryParse(npcLSL_Key, out npcId) || !module.CheckPermissions(npcId, m_host.OwnerID))
|
if (!UUID.TryParse(npcLSL_Key, out npcId) || !module.CheckPermissions(npcId, m_host.OwnerID))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SceneObjectPart part = null;
|
SceneObjectPart part = null;
|
||||||
UUID objectId;
|
UUID objectId;
|
||||||
if (UUID.TryParse(LSL_String.ToString(object_key), out objectId))
|
if (UUID.TryParse(LSL_String.ToString(object_key), out objectId))
|
||||||
part = World.GetSceneObjectPart(objectId);
|
part = World.GetSceneObjectPart(objectId);
|
||||||
|
|
||||||
if (part == null)
|
if (part == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (linkNum != ScriptBaseClass.LINK_THIS)
|
if (linkNum != ScriptBaseClass.LINK_THIS)
|
||||||
{
|
{
|
||||||
if (linkNum == 0 || linkNum == ScriptBaseClass.LINK_ROOT)
|
if (linkNum == 0 || linkNum == ScriptBaseClass.LINK_ROOT)
|
||||||
|
@ -2764,6 +2778,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.Touch(npcId, part.UUID);
|
module.Touch(npcId, part.UUID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,6 +226,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||||
public const int ATTACH_BELLY = 28;
|
public const int ATTACH_BELLY = 28;
|
||||||
public const int ATTACH_RPEC = 29;
|
public const int ATTACH_RPEC = 29;
|
||||||
public const int ATTACH_LPEC = 30;
|
public const int ATTACH_LPEC = 30;
|
||||||
|
public const int ATTACH_LEFT_PEC = 29; // Same value as ATTACH_RPEC, see https://jira.secondlife.com/browse/SVC-580
|
||||||
|
public const int ATTACH_RIGHT_PEC = 30; // Same value as ATTACH_LPEC, see https://jira.secondlife.com/browse/SVC-580
|
||||||
public const int ATTACH_HUD_CENTER_2 = 31;
|
public const int ATTACH_HUD_CENTER_2 = 31;
|
||||||
public const int ATTACH_HUD_TOP_RIGHT = 32;
|
public const int ATTACH_HUD_TOP_RIGHT = 32;
|
||||||
public const int ATTACH_HUD_TOP_CENTER = 33;
|
public const int ATTACH_HUD_TOP_CENTER = 33;
|
||||||
|
|
|
@ -64,6 +64,15 @@ namespace OpenSim.Services.AuthenticationService
|
||||||
|
|
||||||
public string Authenticate(UUID principalID, string password, int lifetime)
|
public string Authenticate(UUID principalID, string password, int lifetime)
|
||||||
{
|
{
|
||||||
|
UUID realID;
|
||||||
|
|
||||||
|
return Authenticate(principalID, password, lifetime, out realID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Authenticate(UUID principalID, string password, int lifetime, out UUID realID)
|
||||||
|
{
|
||||||
|
realID = UUID.Zero;
|
||||||
|
|
||||||
m_log.DebugFormat("[AUTH SERVICE]: Authenticating for {0}, user account service present: {1}", principalID, m_UserAccountService != null);
|
m_log.DebugFormat("[AUTH SERVICE]: Authenticating for {0}, user account service present: {1}", principalID, m_UserAccountService != null);
|
||||||
AuthenticationData data = m_Database.Get(principalID);
|
AuthenticationData data = m_Database.Get(principalID);
|
||||||
UserAccount user = null;
|
UserAccount user = null;
|
||||||
|
@ -127,6 +136,7 @@ namespace OpenSim.Services.AuthenticationService
|
||||||
if (data.Data["passwordHash"].ToString() == hashed)
|
if (data.Data["passwordHash"].ToString() == hashed)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[PASS AUTH]: {0} {1} impersonating {2}, proceeding with login", a.FirstName, a.LastName, principalID);
|
m_log.DebugFormat("[PASS AUTH]: {0} {1} impersonating {2}, proceeding with login", a.FirstName, a.LastName, principalID);
|
||||||
|
realID = a.PrincipalID;
|
||||||
return GetToken(principalID, lifetime);
|
return GetToken(principalID, lifetime);
|
||||||
}
|
}
|
||||||
// else
|
// else
|
||||||
|
|
|
@ -60,6 +60,13 @@ namespace OpenSim.Services.AuthenticationService
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string Authenticate(UUID principalID, string password, int lifetime, out UUID realID)
|
||||||
|
{
|
||||||
|
realID = UUID.Zero;
|
||||||
|
|
||||||
|
return Authenticate(principalID, password, lifetime);
|
||||||
|
}
|
||||||
|
|
||||||
public string Authenticate(UUID principalID, string password, int lifetime)
|
public string Authenticate(UUID principalID, string password, int lifetime)
|
||||||
{
|
{
|
||||||
if (new UUID(password) == UUID.Zero)
|
if (new UUID(password) == UUID.Zero)
|
||||||
|
|
|
@ -54,6 +54,13 @@ namespace OpenSim.Services.AuthenticationService
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Authenticate(UUID principalID, string password, int lifetime)
|
public string Authenticate(UUID principalID, string password, int lifetime)
|
||||||
|
{
|
||||||
|
UUID realID;
|
||||||
|
|
||||||
|
return Authenticate(principalID, password, lifetime, out realID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Authenticate(UUID principalID, string password, int lifetime, out UUID realID)
|
||||||
{
|
{
|
||||||
AuthenticationData data = m_Database.Get(principalID);
|
AuthenticationData data = m_Database.Get(principalID);
|
||||||
string result = String.Empty;
|
string result = String.Empty;
|
||||||
|
@ -62,7 +69,7 @@ namespace OpenSim.Services.AuthenticationService
|
||||||
if (data.Data.ContainsKey("webLoginKey"))
|
if (data.Data.ContainsKey("webLoginKey"))
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[AUTH SERVICE]: Attempting web key authentication for PrincipalID {0}", principalID);
|
m_log.DebugFormat("[AUTH SERVICE]: Attempting web key authentication for PrincipalID {0}", principalID);
|
||||||
result = m_svcChecks["web_login_key"].Authenticate(principalID, password, lifetime);
|
result = m_svcChecks["web_login_key"].Authenticate(principalID, password, lifetime, out realID);
|
||||||
if (result == String.Empty)
|
if (result == String.Empty)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[AUTH SERVICE]: Web Login failed for PrincipalID {0}", principalID);
|
m_log.DebugFormat("[AUTH SERVICE]: Web Login failed for PrincipalID {0}", principalID);
|
||||||
|
@ -71,12 +78,15 @@ namespace OpenSim.Services.AuthenticationService
|
||||||
if (result == string.Empty && data.Data.ContainsKey("passwordHash") && data.Data.ContainsKey("passwordSalt"))
|
if (result == string.Empty && data.Data.ContainsKey("passwordHash") && data.Data.ContainsKey("passwordSalt"))
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[AUTH SERVICE]: Attempting password authentication for PrincipalID {0}", principalID);
|
m_log.DebugFormat("[AUTH SERVICE]: Attempting password authentication for PrincipalID {0}", principalID);
|
||||||
result = m_svcChecks["password"].Authenticate(principalID, password, lifetime);
|
result = m_svcChecks["password"].Authenticate(principalID, password, lifetime, out realID);
|
||||||
if (result == String.Empty)
|
if (result == String.Empty)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[AUTH SERVICE]: Password login failed for PrincipalID {0}", principalID);
|
m_log.DebugFormat("[AUTH SERVICE]: Password login failed for PrincipalID {0}", principalID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
realID = UUID.Zero;
|
||||||
|
|
||||||
if (result == string.Empty)
|
if (result == string.Empty)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[AUTH SERVICE]: Both password and webLoginKey-based authentication failed for PrincipalID {0}", principalID);
|
m_log.DebugFormat("[AUTH SERVICE]: Both password and webLoginKey-based authentication failed for PrincipalID {0}", principalID);
|
||||||
|
@ -89,4 +99,4 @@ namespace OpenSim.Services.AuthenticationService
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,13 @@ namespace OpenSim.Services.Connectors
|
||||||
m_ServerURI = serviceURI;
|
m_ServerURI = serviceURI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string Authenticate(UUID principalID, string password, int lifetime, out UUID realID)
|
||||||
|
{
|
||||||
|
realID = UUID.Zero;
|
||||||
|
|
||||||
|
return Authenticate(principalID, password, lifetime);
|
||||||
|
}
|
||||||
|
|
||||||
public string Authenticate(UUID principalID, string password, int lifetime)
|
public string Authenticate(UUID principalID, string password, int lifetime)
|
||||||
{
|
{
|
||||||
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||||
|
|
|
@ -102,6 +102,11 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
||||||
m_log.Info("[SIMIAN AUTH CONNECTOR]: No AuthenticationServerURI specified, disabling connector");
|
m_log.Info("[SIMIAN AUTH CONNECTOR]: No AuthenticationServerURI specified, disabling connector");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string Authenticate(UUID principalID, string password, int lifetime, out UUID realID)
|
||||||
|
{
|
||||||
|
return Authenticate(principalID, password, lifetime);
|
||||||
|
}
|
||||||
|
|
||||||
public string Authenticate(UUID principalID, string password, int lifetime)
|
public string Authenticate(UUID principalID, string password, int lifetime)
|
||||||
{
|
{
|
||||||
NameValueCollection requestArgs = new NameValueCollection
|
NameValueCollection requestArgs = new NameValueCollection
|
||||||
|
|
|
@ -168,5 +168,20 @@ namespace OpenSim.Services.Connectors
|
||||||
{
|
{
|
||||||
return m_database.GetObjectIDs(regionID);
|
return m_database.GetObjectIDs(regionID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SaveExtra(UUID regionID, string name, string val)
|
||||||
|
{
|
||||||
|
m_database.SaveExtra(regionID, name, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveExtra(UUID regionID, string name)
|
||||||
|
{
|
||||||
|
m_database.RemoveExtra(regionID, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, string> GetExtra(UUID regionID)
|
||||||
|
{
|
||||||
|
return m_database.GetExtra(regionID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,7 @@ namespace OpenSim.Services.Interfaces
|
||||||
// various services.
|
// various services.
|
||||||
//
|
//
|
||||||
string Authenticate(UUID principalID, string password, int lifetime);
|
string Authenticate(UUID principalID, string password, int lifetime);
|
||||||
|
string Authenticate(UUID principalID, string password, int lifetime, out UUID realID);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
// Verification
|
// Verification
|
||||||
|
|
|
@ -182,7 +182,8 @@ namespace OpenSim.Services.Interfaces
|
||||||
List<AvatarAttachment> attachments = appearance.GetAttachments();
|
List<AvatarAttachment> attachments = appearance.GetAttachments();
|
||||||
foreach (AvatarAttachment attach in attachments)
|
foreach (AvatarAttachment attach in attachments)
|
||||||
{
|
{
|
||||||
Data["_ap_" + attach.AttachPoint] = attach.ItemID.ToString();
|
if (attach.ItemID != UUID.Zero)
|
||||||
|
Data["_ap_" + attach.AttachPoint] = attach.ItemID.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,6 +150,7 @@ namespace OpenSim.Services.LLLoginService
|
||||||
private UUID agentID;
|
private UUID agentID;
|
||||||
private UUID sessionID;
|
private UUID sessionID;
|
||||||
private UUID secureSessionID;
|
private UUID secureSessionID;
|
||||||
|
private UUID realID;
|
||||||
|
|
||||||
// Login Flags
|
// Login Flags
|
||||||
private string dst;
|
private string dst;
|
||||||
|
@ -232,7 +233,7 @@ namespace OpenSim.Services.LLLoginService
|
||||||
GridRegion destination, List<InventoryFolderBase> invSkel, FriendInfo[] friendsList, ILibraryService libService,
|
GridRegion destination, List<InventoryFolderBase> invSkel, FriendInfo[] friendsList, ILibraryService libService,
|
||||||
string where, string startlocation, Vector3 position, Vector3 lookAt, List<InventoryItemBase> gestures, string message,
|
string where, string startlocation, Vector3 position, Vector3 lookAt, List<InventoryItemBase> gestures, string message,
|
||||||
GridRegion home, IPEndPoint clientIP, string mapTileURL, string profileURL, string openIDURL, string searchURL, string currency,
|
GridRegion home, IPEndPoint clientIP, string mapTileURL, string profileURL, string openIDURL, string searchURL, string currency,
|
||||||
string DSTZone)
|
string DSTZone, UUID realID)
|
||||||
: this()
|
: this()
|
||||||
{
|
{
|
||||||
FillOutInventoryData(invSkel, libService);
|
FillOutInventoryData(invSkel, libService);
|
||||||
|
@ -245,6 +246,7 @@ namespace OpenSim.Services.LLLoginService
|
||||||
AgentID = account.PrincipalID;
|
AgentID = account.PrincipalID;
|
||||||
SessionID = aCircuit.SessionID;
|
SessionID = aCircuit.SessionID;
|
||||||
SecureSessionID = aCircuit.SecureSessionID;
|
SecureSessionID = aCircuit.SecureSessionID;
|
||||||
|
RealID = realID;
|
||||||
Message = message;
|
Message = message;
|
||||||
BuddList = ConvertFriendListItem(friendsList);
|
BuddList = ConvertFriendListItem(friendsList);
|
||||||
StartLocation = where;
|
StartLocation = where;
|
||||||
|
@ -456,6 +458,7 @@ namespace OpenSim.Services.LLLoginService
|
||||||
SessionID = UUID.Random();
|
SessionID = UUID.Random();
|
||||||
SecureSessionID = UUID.Random();
|
SecureSessionID = UUID.Random();
|
||||||
AgentID = UUID.Random();
|
AgentID = UUID.Random();
|
||||||
|
RealID = UUID.Zero;
|
||||||
|
|
||||||
Hashtable InitialOutfitHash = new Hashtable();
|
Hashtable InitialOutfitHash = new Hashtable();
|
||||||
InitialOutfitHash["folder_name"] = "Nightclub Female";
|
InitialOutfitHash["folder_name"] = "Nightclub Female";
|
||||||
|
@ -499,6 +502,7 @@ namespace OpenSim.Services.LLLoginService
|
||||||
responseData["http_port"] = (Int32)SimHttpPort;
|
responseData["http_port"] = (Int32)SimHttpPort;
|
||||||
|
|
||||||
responseData["agent_id"] = AgentID.ToString();
|
responseData["agent_id"] = AgentID.ToString();
|
||||||
|
responseData["real_id"] = RealID.ToString();
|
||||||
responseData["session_id"] = SessionID.ToString();
|
responseData["session_id"] = SessionID.ToString();
|
||||||
responseData["secure_session_id"] = SecureSessionID.ToString();
|
responseData["secure_session_id"] = SecureSessionID.ToString();
|
||||||
responseData["circuit_code"] = CircuitCode;
|
responseData["circuit_code"] = CircuitCode;
|
||||||
|
@ -581,6 +585,7 @@ namespace OpenSim.Services.LLLoginService
|
||||||
map["sim_ip"] = OSD.FromString(SimAddress);
|
map["sim_ip"] = OSD.FromString(SimAddress);
|
||||||
|
|
||||||
map["agent_id"] = OSD.FromUUID(AgentID);
|
map["agent_id"] = OSD.FromUUID(AgentID);
|
||||||
|
map["real_id"] = OSD.FromUUID(RealID);
|
||||||
map["session_id"] = OSD.FromUUID(SessionID);
|
map["session_id"] = OSD.FromUUID(SessionID);
|
||||||
map["secure_session_id"] = OSD.FromUUID(SecureSessionID);
|
map["secure_session_id"] = OSD.FromUUID(SecureSessionID);
|
||||||
map["circuit_code"] = OSD.FromInteger(CircuitCode);
|
map["circuit_code"] = OSD.FromInteger(CircuitCode);
|
||||||
|
@ -888,6 +893,12 @@ namespace OpenSim.Services.LLLoginService
|
||||||
set { secureSessionID = value; }
|
set { secureSessionID = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UUID RealID
|
||||||
|
{
|
||||||
|
get { return realID; }
|
||||||
|
set { realID = value; }
|
||||||
|
}
|
||||||
|
|
||||||
public Int32 CircuitCode
|
public Int32 CircuitCode
|
||||||
{
|
{
|
||||||
get { return circuitCode; }
|
get { return circuitCode; }
|
||||||
|
|
|
@ -327,7 +327,8 @@ namespace OpenSim.Services.LLLoginService
|
||||||
if (!passwd.StartsWith("$1$"))
|
if (!passwd.StartsWith("$1$"))
|
||||||
passwd = "$1$" + Util.Md5Hash(passwd);
|
passwd = "$1$" + Util.Md5Hash(passwd);
|
||||||
passwd = passwd.Remove(0, 3); //remove $1$
|
passwd = passwd.Remove(0, 3); //remove $1$
|
||||||
string token = m_AuthenticationService.Authenticate(account.PrincipalID, passwd, 30);
|
UUID realID;
|
||||||
|
string token = m_AuthenticationService.Authenticate(account.PrincipalID, passwd, 30, out realID);
|
||||||
UUID secureSession = UUID.Zero;
|
UUID secureSession = UUID.Zero;
|
||||||
if ((token == string.Empty) || (token != string.Empty && !UUID.TryParse(token, out secureSession)))
|
if ((token == string.Empty) || (token != string.Empty && !UUID.TryParse(token, out secureSession)))
|
||||||
{
|
{
|
||||||
|
@ -459,7 +460,7 @@ namespace OpenSim.Services.LLLoginService
|
||||||
= new LLLoginResponse(
|
= new LLLoginResponse(
|
||||||
account, aCircuit, guinfo, destination, inventorySkel, friendsList, m_LibraryService,
|
account, aCircuit, guinfo, destination, inventorySkel, friendsList, m_LibraryService,
|
||||||
where, startLocation, position, lookAt, gestures, m_WelcomeMessage, home, clientIP,
|
where, startLocation, position, lookAt, gestures, m_WelcomeMessage, home, clientIP,
|
||||||
m_MapTileURL, m_ProfileURL, m_OpenIDURL, m_SearchURL, m_Currency, m_DSTZone);
|
m_MapTileURL, m_ProfileURL, m_OpenIDURL, m_SearchURL, m_Currency, m_DSTZone, realID);
|
||||||
|
|
||||||
m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to {0} {1}", firstName, lastName);
|
m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to {0} {1}", firstName, lastName);
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,19 @@ namespace OpenSim.Data.Null
|
||||||
{
|
{
|
||||||
return new UUID[0];
|
return new UUID[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SaveExtra(UUID regionID, string name, string value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveExtra(UUID regionID, string name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, string> GetExtra(UUID regionID)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -328,5 +341,18 @@ namespace OpenSim.Data.Null
|
||||||
{
|
{
|
||||||
return new UUID[0];
|
return new UUID[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SaveExtra(UUID regionID, string name, string value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveExtra(UUID regionID, string name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, string> GetExtra(UUID regionID)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,11 +181,6 @@
|
||||||
; Objects will always be considered for persistance in the next sweep if the first change occurred this number of seconds ago
|
; Objects will always be considered for persistance in the next sweep if the first change occurred this number of seconds ago
|
||||||
MaximumTimeBeforePersistenceConsidered = 600
|
MaximumTimeBeforePersistenceConsidered = 600
|
||||||
|
|
||||||
; Experimental setting to resend appearance updates every 60 seconds.
|
|
||||||
; These packets are small and this can help with grey avatar syndrome.
|
|
||||||
; Default is false
|
|
||||||
SendPeriodicAppearanceUpdates = false
|
|
||||||
|
|
||||||
; ##
|
; ##
|
||||||
; ## PHYSICS
|
; ## PHYSICS
|
||||||
; ##
|
; ##
|
||||||
|
@ -341,27 +336,12 @@
|
||||||
; OpenJPEG if false
|
; OpenJPEG if false
|
||||||
; UseCSJ2K = true
|
; UseCSJ2K = true
|
||||||
|
|
||||||
|
|
||||||
; Use "Trash" folder for items deleted from the scene
|
; Use "Trash" folder for items deleted from the scene
|
||||||
; When set to True (the default) items deleted from the scene will be
|
; When set to True (the default) items deleted from the scene will be
|
||||||
; stored in the user's trash or lost and found folder. When set to
|
; stored in the user's trash or lost and found folder. When set to
|
||||||
; False items will be removed from the scene permanently
|
; False items will be removed from the scene permanently
|
||||||
UseTrashOnDelete = True
|
UseTrashOnDelete = True
|
||||||
|
|
||||||
; Persist avatar baked textures
|
|
||||||
; Persisting baked textures can speed up login and region border
|
|
||||||
; crossings especially with large numbers of users, though it
|
|
||||||
; will store potentially large numbers of textures in your asset
|
|
||||||
; database
|
|
||||||
PersistBakedTextures = false
|
|
||||||
|
|
||||||
; Control the delay before appearance is sent to other avatars and
|
|
||||||
; saved in the avatar service. Attempts to limit the impact caused
|
|
||||||
; by the very chatty dialog that sets appearance when an avatar
|
|
||||||
; logs in or teleports into a region; values are in seconds
|
|
||||||
DelayBeforeAppearanceSave = 5
|
|
||||||
DelayBeforeAppearanceSend = 2
|
|
||||||
|
|
||||||
|
|
||||||
[RegionReady]
|
[RegionReady]
|
||||||
; Enable this module to get notified once all items and scripts in the region have been completely loaded and compiled
|
; Enable this module to get notified once all items and scripts in the region have been completely loaded and compiled
|
||||||
|
@ -671,6 +651,28 @@
|
||||||
CoalesceMultipleObjectsToInventory = true
|
CoalesceMultipleObjectsToInventory = true
|
||||||
|
|
||||||
|
|
||||||
|
[Appearance]
|
||||||
|
; Persist avatar baked textures
|
||||||
|
; Persisting baked textures can speed up login and region border
|
||||||
|
; crossings especially with large numbers of users, though it
|
||||||
|
; will store potentially large numbers of textures in your asset
|
||||||
|
; database
|
||||||
|
PersistBakedTextures = false
|
||||||
|
|
||||||
|
; Control the delay before appearance is sent to other avatars and
|
||||||
|
; saved in the avatar service. Attempts to limit the impact caused
|
||||||
|
; by the very chatty dialog that sets appearance when an avatar
|
||||||
|
; logs in or teleports into a region; values are in seconds
|
||||||
|
DelayBeforeAppearanceSave = 5
|
||||||
|
DelayBeforeAppearanceSend = 2
|
||||||
|
|
||||||
|
; If true, avatar appearance information is resent to other avatars in the simulator every 60 seconds.
|
||||||
|
; This may help with some situations where avatars are persistently grey, though it will not help
|
||||||
|
; in other situations (e.g. appearance baking failures where the avatar only appears as a cloud to others).
|
||||||
|
; This setting is experimental.
|
||||||
|
ResendAppearanceUpdates = false
|
||||||
|
|
||||||
|
|
||||||
[Attachments]
|
[Attachments]
|
||||||
; Controls whether avatar attachments are enabled.
|
; Controls whether avatar attachments are enabled.
|
||||||
; Defaults to true - only set to false for debugging purposes
|
; Defaults to true - only set to false for debugging purposes
|
||||||
|
@ -892,7 +894,7 @@
|
||||||
AvatarDensity = 60.0
|
AvatarDensity = 60.0
|
||||||
AvatarCapsuleRadius = 0.37
|
AvatarCapsuleRadius = 0.37
|
||||||
AvatarCapsuleHeight = 1.5
|
AvatarCapsuleHeight = 1.5
|
||||||
AvatarContactProcessingThreshold = 0.1;
|
AvatarContactProcessingThreshold = 0.1
|
||||||
|
|
||||||
MaxObjectMass = 10000.01
|
MaxObjectMass = 10000.01
|
||||||
|
|
||||||
|
@ -906,19 +908,19 @@
|
||||||
CcdSweptSphereRadius = 0.0
|
CcdSweptSphereRadius = 0.0
|
||||||
ContactProcessingThreshold = 0.1
|
ContactProcessingThreshold = 0.1
|
||||||
; If setting a pool size, also disable dynamic allocation (default pool size is 4096 with dynamic alloc)
|
; If setting a pool size, also disable dynamic allocation (default pool size is 4096 with dynamic alloc)
|
||||||
MaxPersistantManifoldPoolSize = 0;
|
MaxPersistantManifoldPoolSize = 0
|
||||||
ShouldDisableContactPoolDynamicAllocation = False;
|
ShouldDisableContactPoolDynamicAllocation = False
|
||||||
ShouldForceUpdateAllAabbs = False;
|
ShouldForceUpdateAllAabbs = False
|
||||||
ShouldRandomizeSolverOrder = False;
|
ShouldRandomizeSolverOrder = False
|
||||||
ShouldSplitSimulationIslands = False;
|
ShouldSplitSimulationIslands = False
|
||||||
ShouldEnableFrictionCaching = False;
|
ShouldEnableFrictionCaching = False
|
||||||
NumberOfSolverIterations = 0;
|
NumberOfSolverIterations = 0;
|
||||||
|
|
||||||
; Linkset constraint parameters
|
; Linkset constraint parameters
|
||||||
LinkConstraintUseFrameOffset = False;
|
LinkConstraintUseFrameOffset = False
|
||||||
LinkConstraintEnableTransMotor = True;
|
LinkConstraintEnableTransMotor = True
|
||||||
LinkConstraintTransMotorMaxVel = 5.0;
|
LinkConstraintTransMotorMaxVel = 5.0
|
||||||
LinkConstraintTransMotorMaxForce = 0.1;
|
LinkConstraintTransMotorMaxForce = 0.1
|
||||||
|
|
||||||
|
|
||||||
; Whether to mesh sculpties
|
; Whether to mesh sculpties
|
||||||
|
@ -933,11 +935,16 @@
|
||||||
SculptLevelOfDetail = 32
|
SculptLevelOfDetail = 32
|
||||||
|
|
||||||
; Bullet step parameters
|
; Bullet step parameters
|
||||||
MaxSubSteps = 10;
|
MaxSubSteps = 10
|
||||||
FixedTimeStep = .01667
|
FixedTimeStep = .01667
|
||||||
|
|
||||||
MaxCollisionsPerFrame = 2048
|
MaxCollisionsPerFrame = 2048
|
||||||
MaxUpdatesPerFrame = 2048
|
MaxUpdatesPerFrame = 8192
|
||||||
|
|
||||||
|
; Detailed physics debug logging
|
||||||
|
PhysicsLoggingEnabled = False
|
||||||
|
PhysicsLoggingDir = "."
|
||||||
|
VehicleLoggingEnabled = False
|
||||||
|
|
||||||
[RemoteAdmin]
|
[RemoteAdmin]
|
||||||
enabled = false
|
enabled = false
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue