Merge branch 'ubitwork' of ssh://3dhosting.de/var/git/careminster into ubitwork

avinationmerge
ubit 2012-08-16 16:13:38 +02:00
commit d09fa0d76e
66 changed files with 2147 additions and 838 deletions

View File

@ -91,6 +91,7 @@ what it is today.
* Fly-Man
* Flyte Xevious
* Garmin Kawaguichi
* Gryc Ueusp
* Imaze Rhiano
* Intimidated
* Jeremy Bongio (IBM)

View File

@ -2207,5 +2207,18 @@ VALUES
{
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;
}
}
}

View File

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

View File

@ -895,3 +895,10 @@ CREATE TABLE `regionenvironment` (
COMMIT;
:VERSION 45
BEGIN;
CREATE TABLE `regionextra` (`RegionID` char(36) not null, `Name` varchar(32) not null, `value` text, primary key(`RegionID`, `Name`));
COMMIT;

View File

@ -156,5 +156,18 @@ namespace OpenSim.Data.Null
{
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;
}
}
}

View File

@ -2894,5 +2894,18 @@ namespace OpenSim.Data.SQLite
{
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;
}
}
}

View File

@ -678,6 +678,8 @@ namespace OpenSim.Framework.Console
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public event OnOutputDelegate OnOutput;
public ICommands Commands { get; private set; }
public CommandConsole(string defaultPrompt) : base(defaultPrompt)
@ -697,6 +699,13 @@ namespace OpenSim.Framework.Console
Output(s);
}
protected void FireOnOutput(string text)
{
OnOutputDelegate onOutput = OnOutput;
if (onOutput != null)
onOutput(text);
}
/// <summary>
/// Display a command prompt on the console and wait for user input
/// </summary>

View File

@ -319,6 +319,8 @@ namespace OpenSim.Framework.Console
public override void Output(string text, string level)
{
FireOnOutput(text);
lock (m_commandLine)
{
if (m_cursorYPosition == -1)
@ -509,4 +511,4 @@ namespace OpenSim.Framework.Console
}
}
}
}
}

View File

@ -40,6 +40,8 @@ namespace OpenSim.Framework.Console
/// </summary>
public class MockConsole : ICommandConsole
{
public event OnOutputDelegate OnOutput;
private MockCommands m_commands = new MockCommands();
public ICommands Commands { get { return m_commands; } }
@ -76,4 +78,4 @@ namespace OpenSim.Framework.Console
public string[] Resolve(string[] cmd) { return null; }
public XmlElement GetXml(XmlDocument doc) { return null; }
}
}
}

View File

@ -100,6 +100,7 @@ namespace OpenSim.Framework.Console
m_LineNumber++;
m_Scrollback.Add(String.Format("{0}", m_LineNumber)+":"+level+":"+text);
}
FireOnOutput(text.Trim());
System.Console.WriteLine(text.Trim());
}

View File

@ -126,7 +126,7 @@ namespace OpenSim.Framework
public delegate void ObjectDrop(uint localID, IClientAPI remoteClient);
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);

View File

@ -74,8 +74,12 @@ namespace OpenSim.Framework
XmlElement GetXml(XmlDocument doc);
}
public delegate void OnOutputDelegate(string message);
public interface ICommandConsole : IConsole
{
event OnOutputDelegate OnOutput;
ICommands Commands { get; }
/// <summary>
@ -87,4 +91,4 @@ namespace OpenSim.Framework
string ReadLine(string p, bool isCommand, bool e);
}
}
}

View File

@ -97,6 +97,32 @@ namespace OpenSim.Framework.Monitoring
/// /summary>
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 Dictionary<int, ThreadWatchdogInfo> m_threads;
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.AutoReset = false;
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>

View File

@ -93,6 +93,8 @@ namespace OpenSim.Framework.Serialization.External
"MediaURL", (ld, xtr) => ld.MediaURL = xtr.ReadElementString("MediaURL"));
m_ldProcessors.Add(
"MusicURL", (ld, xtr) => ld.MusicURL = xtr.ReadElementString("MusicURL"));
m_ldProcessors.Add(
"OwnerID", (ld, xtr) => ld.OwnerID = UUID.Parse(xtr.ReadElementString("OwnerID")));
m_ldProcessors.Add(
"ParcelAccessList", ProcessParcelAccessList);
@ -186,7 +188,16 @@ namespace OpenSim.Framework.Serialization.External
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();
XmlTextWriter xtw = new XmlTextWriter(sw);
@ -215,7 +226,14 @@ namespace OpenSim.Framework.Serialization.External
xtw.WriteElementString("MediaID", landData.MediaID.ToString());
xtw.WriteElementString("MediaURL", landData.MediaURL);
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");
foreach (LandAccessEntry pal in landData.ParcelAccessList)

View File

@ -42,22 +42,23 @@ namespace OpenSim.Framework.Serialization.Tests
private LandData land;
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>&lt;0, 0, 0&gt;</UserLocation>\n <UserLookAt>&lt;0, 0, 0&gt;</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>&lt;0, 0, 0&gt;</UserLocation>\n <UserLookAt>&lt;0, 0, 0&gt;</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>&lt;0, 0, 0&gt;</UserLocation>\n <UserLookAt>&lt;0, 0, 0&gt;</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>&lt;0, 0, 0&gt;</UserLocation>\n <UserLookAt>&lt;0, 0, 0&gt;</UserLookAt>\n <Dwell>0</Dwell>\n <OtherCleanTime>0</OtherCleanTime>\n</LandData>";
[SetUp]
public void setup()
{
// setup LandData object
this.land = new LandData();
this.land.AABBMax = new Vector3(0, 0, 0);
this.land.AABBMin = new Vector3(128, 128, 128);
this.land.AABBMax = new Vector3(1, 2, 3);
this.land.AABBMin = new Vector3(129, 130, 131);
this.land.Area = 128;
this.land.AuctionID = 0;
this.land.AuthBuyerID = new UUID();
this.land.AuctionID = 4;
this.land.AuthBuyerID = new UUID("7176df0c-6c50-45db-8a37-5e78be56a0cd");
this.land.Category = ParcelCategory.Residential;
this.land.ClaimDate = 0;
this.land.ClaimPrice = 0;
this.land.ClaimDate = 1;
this.land.ClaimPrice = 2;
this.land.GlobalID = new UUID("54ff9641-dd40-4a2c-b1f1-47dd3af24e50");
this.land.GroupID = new UUID("d740204e-bbbf-44aa-949d-02c7d739f6a5");
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.Name = "LandDataSerializerTest Land";
this.land.Status = ParcelStatus.Leased;
this.land.LocalID = 0;
this.land.LocalID = 1;
this.land.MediaAutoScale = (byte)0x01;
this.land.MediaID = new UUID("d4452578-2f25-4b97-a81b-819af559cfd7");
this.land.MediaURL = "http://videos.opensimulator.org/bumblebee.mp4";
@ -90,26 +91,26 @@ namespace OpenSim.Framework.Serialization.Tests
/// <summary>
/// Test the LandDataSerializer.Serialize() method
/// </summary>
[Test]
public void LandDataSerializerSerializeTest()
{
TestHelpers.InMethod();
string serialized = LandDataSerializer.Serialize(this.land).Replace("\r\n", "\n");
Assert.That(serialized.Length > 0, "Serialize(LandData) returned empty string");
// adding a simple boolean variable because resharper nUnit integration doesn't like this
// XML data in the Assert.That statement. Not sure why.
bool result = (serialized == preSerialized);
Assert.That(result, "result of Serialize LandData does not match expected result");
string serializedWithParcelAccessList = LandDataSerializer.Serialize(this.landWithParcelAccessList).Replace("\r\n", "\n");
Assert.That(serializedWithParcelAccessList.Length > 0,
"Serialize(LandData) returned empty string for LandData object with ParcelAccessList");
result = (serializedWithParcelAccessList == preSerializedWithParcelAccessList);
Assert.That(result,
"result of Serialize(LandData) does not match expected result (pre-serialized with parcel access list");
}
// [Test]
// public void LandDataSerializerSerializeTest()
// {
// TestHelpers.InMethod();
//
// string serialized = LandDataSerializer.Serialize(this.land).Replace("\r\n", "\n");
// Assert.That(serialized.Length > 0, "Serialize(LandData) returned empty string");
//
// // adding a simple boolean variable because resharper nUnit integration doesn't like this
// // XML data in the Assert.That statement. Not sure why.
// bool result = (serialized == preSerialized);
// Assert.That(result, "result of Serialize LandData does not match expected result");
//
// string serializedWithParcelAccessList = LandDataSerializer.Serialize(this.landWithParcelAccessList).Replace("\r\n", "\n");
// Assert.That(serializedWithParcelAccessList.Length > 0,
// "Serialize(LandData) returned empty string for LandData object with ParcelAccessList");
// result = (serializedWithParcelAccessList == preSerializedWithParcelAccessList);
// Assert.That(result,
// "result of Serialize(LandData) does not match expected result (pre-serialized with parcel access list");
// }
/// <summary>
/// Test the LandDataSerializer.Deserialize() method
@ -120,10 +121,28 @@ namespace OpenSim.Framework.Serialization.Tests
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
LandData ld = LandDataSerializer.Deserialize(LandDataSerializerTest.preSerialized);
Assert.That(ld != null, "Deserialize(string) returned null");
Assert.That(ld.GlobalID == this.land.GlobalID, "Reified LandData.GlobalID != original LandData.GlobalID");
Assert.That(ld.Name == this.land.Name, "Reified LandData.Name != original LandData.Name");
LandData ld = LandDataSerializer.Deserialize(LandDataSerializer.Serialize(this.land, null));
Assert.That(ld, Is.Not.Null, "Deserialize(string) returned null");
// Assert.That(ld.AABBMax, Is.EqualTo(land.AABBMax));
// 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]

View File

@ -294,14 +294,13 @@ namespace OpenSim
"save oar [-h|--home=<url>] [--noassets] [--publish] [--perm=<permissions>] [<OAR path>]",
"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
"-h|--home=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
+ "--noassets stops assets being saved to the OAR." + Environment.NewLine
+ "--publish saves an OAR stripped of owner and last owner information." + Environment.NewLine
+ " on reload, the estate owner will be the owner of all objects" + Environment.NewLine
+ " 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 option is EXPERIMENTAL" + Environment.NewLine
+ "--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" + 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.\n"
+ "--publish saves an OAR stripped of owner and last owner information.\n"
+ " 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\n"
+ "--perm=<permissions> stops objects with insufficient permissions from being saved to the OAR.\n"
+ " <permissions> can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer\n"
+ "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.",
SaveOar);

View File

@ -320,8 +320,13 @@ namespace OpenSim
m_httpServerPort = m_networkServersInfo.HttpListenerPort;
SceneManager.OnRestartSim += handleRestartRegion;
// Only start the memory watchdog once all regions are ready
SceneManager.OnRegionsReadyStatusChange += sm => MemoryWatchdog.Enabled = sm.AllRegionsReady;
// Only enable the watchdogs when all regions are ready. Otherwise we get false positives when cpu is
// 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>

View File

@ -126,9 +126,14 @@ namespace OpenSim.Region.ClientStack.Linden
IConfig sconfig = config.Configs["Startup"];
if (sconfig != null)
{
m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
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;

View File

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

View File

@ -66,9 +66,9 @@ namespace OpenSim.Region.ClientStack.Linden
public void Initialise(IConfigSource source)
{
IConfig sconfig = source.Configs["Startup"];
if (sconfig != null)
m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
IConfig appearanceConfig = source.Configs["Appearance"];
if (appearanceConfig != null)
m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
}
public void AddRegion(Scene s)

View File

@ -284,7 +284,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
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)
{
@ -361,7 +361,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
group.AbsolutePosition = attachPos;
if (sp.PresenceType != PresenceType.Npc)
UpdateUserInventoryWithAttachment(sp, group, attachmentPt);
UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp);
AttachToAgent(sp, group, attachmentPt, attachPos, silent);
}
@ -369,7 +369,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
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
List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
@ -379,18 +379,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
{
if (attachments[0].FromItemID != UUID.Zero)
DetachSingleAttachmentToInvInternal(sp, attachments[0]);
else
m_log.WarnFormat(
"[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);
// Error logging commented because UUID.Zero now means temp attachment
// else
// m_log.WarnFormat(
// "[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.
UUID newAttachmentItemID = group.FromItemID;
if (newAttachmentItemID == UUID.Zero)
newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
if (!temp)
{
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)
@ -474,6 +478,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
UUID inventoryID = so.FromItemID;
// As per Linden spec, drop is disabled for temp attachs
if (inventoryID == UUID.Zero)
return;
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}",
// so.Name, so.LocalId, inventoryID);
@ -484,7 +492,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
so.PrimCount, sp.UUID, sp.AbsolutePosition))
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)
m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
@ -516,6 +526,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so)
{
// As per Linden spec, detach (take) is disabled for temp attachs
if (so.FromItemID == UUID.Zero)
return;
lock (sp.AttachmentsSyncLock)
{
// Save avatar attachment information
@ -589,6 +603,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
/// <param name="saveAllScripted"></param>
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!
INPCModule module = m_scene.RequestModuleInterface<INPCModule>();
if (module != null)
@ -845,7 +866,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
// This will throw if the attachment fails
try
{
AttachObject(sp, objatt, attachmentPt, false, false);
AttachObject(sp, objatt, attachmentPt, false, false, false);
}
catch (Exception e)
{
@ -1005,7 +1026,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
AttachmentPt &= 0x7f;
// 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(
// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId

View File

@ -189,7 +189,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
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
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.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(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));

View File

@ -66,11 +66,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
scene.RegisterModuleInterface<IAvatarFactoryModule>(this);
scene.EventManager.OnNewClient += SubscribeToClientEvents;
IConfig sconfig = config.Configs["Startup"];
if (sconfig != null)
IConfig appearanceConfig = config.Configs["Appearance"];
if (appearanceConfig != null)
{
m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime)));
m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime)));
m_savetime = Convert.ToInt32(appearanceConfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime)));
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);
}

View File

@ -596,9 +596,14 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
}
break;
case "R":
Font anewFont = new Font(myFont, FontStyle.Regular);
myFont.Dispose();
myFont = anewFont;
// We need to place this newFont inside its own context so that the .NET compiler
// doesn't complain about a redefinition of an existing newFont, even though there is none
// The mono compiler doesn't produce this error.
{
Font newFont = new Font(myFont, FontStyle.Regular);
myFont.Dispose();
myFont = newFont;
}
break;
}
}
@ -768,4 +773,4 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
return null;
}
}
}
}

View File

@ -137,6 +137,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authentication
#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)
{
// Not implemented at the regions

View File

@ -124,7 +124,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
LandData landData = lo.LandData;
string landDataPath = String.Format("{0}{1}.xml", ArchiveConstants.LANDDATA_PATH,
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.");

View File

@ -84,7 +84,7 @@ namespace OpenSim.Region.Framework.Interfaces
/// <param name="AttachmentPt"></param>
/// <param name="silent"></param>
/// <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>
/// Rez an attachment from user inventory and change inventory status to match.

View File

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

View File

@ -117,5 +117,11 @@ namespace OpenSim.Region.Framework.Interfaces
void RemoveRegionEnvironmentSettings(UUID regionUUID);
UUID[] GetObjectIDs(UUID regionID);
void SaveExtra(UUID regionID, string name, string value);
void RemoveExtra(UUID regionID, string name);
Dictionary<string, string> GetExtra(UUID regionID);
}
}

View File

@ -128,6 +128,12 @@ namespace OpenSim.Region.Framework.Interfaces
/// <param name="regionUUID">the region UUID</param>
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();
}
}

View File

@ -217,6 +217,9 @@ namespace OpenSim.Region.Framework.Scenes
/// </remarks>
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)
{
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);
}
}
}
}
}
}

View File

@ -177,6 +177,8 @@ namespace OpenSim.Region.Framework.Scenes
protected ICapabilitiesModule m_capsModule;
protected IGroupsModule m_groupsModule;
private Dictionary<string, string> m_extraSettings;
/// <summary>
/// Current scene frame number
/// </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
// region is set up and avoid these gyrations.
RegionSettings rs = simDataService.LoadRegionSettings(RegionInfo.RegionID);
m_extraSettings = simDataService.GetExtra(RegionInfo.RegionID);
bool updatedTerrainTextures = false;
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_terrain = startupConfig.GetInt( "UpdateTerrainEveryNFrames", m_update_terrain);
m_update_temp_cleaning = startupConfig.GetInt( "UpdateTempCleaningEveryNFrames", m_update_temp_cleaning);
SendPeriodicAppearanceUpdates = startupConfig.GetBoolean("SendPeriodicAppearanceUpdates", SendPeriodicAppearanceUpdates);
}
}
catch (Exception e)
@ -850,6 +853,14 @@ namespace OpenSim.Region.Framework.Scenes
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
#region Interest Management
@ -2748,7 +2759,7 @@ namespace OpenSim.Region.Framework.Scenes
RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
if (AttachmentsModule != null)
AttachmentsModule.AttachObject(sp, grp, 0, false, false);
AttachmentsModule.AttachObject(sp, grp, 0, false, false, false);
}
else
{
@ -5843,5 +5854,44 @@ Environment.Exit(1);
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);
}
}
}

View File

@ -1793,7 +1793,6 @@ namespace OpenSim.Region.Framework.Scenes
try
{
parentGroup.areUpdatesSuspended = true;
List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
@ -1850,7 +1849,6 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectGroupsByLocalPartID[part.LocalId] = parentGroup;
}
parentGroup.areUpdatesSuspended = false;
parentGroup.HasGroupChanged = true;
parentGroup.ProcessBackup(m_parentScene.SimulationDataService, true);
parentGroup.ScheduleGroupForFullUpdate();
@ -1896,7 +1894,6 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectGroup group = part.ParentGroup;
if (!affectedGroups.Contains(group))
{
group.areUpdatesSuspended = true;
affectedGroups.Add(group);
}
}
@ -1922,7 +1919,6 @@ namespace OpenSim.Region.Framework.Scenes
// However, editing linked parts and unlinking may be different
//
SceneObjectGroup group = root.ParentGroup;
group.areUpdatesSuspended = true;
List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts);
int numChildren = newSet.Count;
@ -1945,7 +1941,6 @@ namespace OpenSim.Region.Framework.Scenes
group.DelinkFromGroup(p, sendEventsToRemainder);
if (numChildren > 2)
{
p.ParentGroup.areUpdatesSuspended = true;
}
else
{
@ -1980,7 +1975,6 @@ namespace OpenSim.Region.Framework.Scenes
foreach (SceneObjectPart newChild in newSet)
newChild.ClearUpdateSchedule();
newRoot.ParentGroup.areUpdatesSuspended = true;
LinkObjects(newRoot, newSet);
if (!affectedGroups.Contains(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);
g.TriggerScriptChangedEvent(Changed.LINK);
g.HasGroupChanged = true; // Persist
g.areUpdatesSuspended = false;
g.ScheduleGroupForFullUpdate();
}
}

View File

@ -113,25 +113,8 @@ namespace OpenSim.Region.Framework.Scenes
private long m_maxPersistTime = 0;
private long m_minPersistTime = 0;
private Random m_rand;
private bool m_suspendUpdates;
private List<ScenePresence> m_linkedAvatars = new List<ScenePresence>();
public bool areUpdatesSuspended
{
get
{
return m_suspendUpdates;
}
set
{
m_suspendUpdates = value;
if (!value)
{
QueueForUpdateCheck();
}
}
}
/// <summary>
/// This indicates whether the object has changed such that it needs to be repersisted to permenant storage
/// (the database).
@ -951,7 +934,7 @@ namespace OpenSim.Region.Framework.Scenes
/// its existing localID and UUID.
/// </summary>
/// <param name='part'>Root part for this scene object.</param>
public SceneObjectGroup(SceneObjectPart part)
public SceneObjectGroup(SceneObjectPart part) : this()
{
SetRootPart(part);
}

View File

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

View File

@ -469,8 +469,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
avatarName = avatar.Name;
m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: scene = {0}, agentID = {1}", scene, agentID);
m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}",
request, path, param);
// m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}",
// request, path, param);
XmlElement resp;
bool retry = false;
@ -577,7 +577,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
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;
}
@ -625,8 +625,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
// voice channel
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}",
scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param);
// 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);
// m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: avatar \"{0}\": location: {1} {2} {3}",
// 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);
string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo);
m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": {4}",
scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, r);
// m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": {4}",
// scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, r);
return r;
}
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,
UUID agentID, Caps caps)
{
ScenePresence avatar = scene.GetScenePresence(agentID);
string avatarName = avatar.Name;
// ScenePresence avatar = scene.GetScenePresence(agentID);
// string avatarName = avatar.Name;
m_log.DebugFormat("[VivoxVoice][CHATSESSION]: avatar \"{0}\": request: {1}, path: {2}, param: {3}",
avatarName, request, path, param);
// m_log.DebugFormat("[VivoxVoice][CHATSESSION]: avatar \"{0}\": request: {1}, path: {2}, param: {3}",
// avatarName, request, path, param);
return "<llsd>true</llsd>";
}
@ -1119,7 +1119,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
try
{
// 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);
HttpWebResponse rsp = null;

View File

@ -124,9 +124,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC
NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, owner, senseAsAgent, scene);
npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0, int.MaxValue);
m_log.DebugFormat(
"[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);
// m_log.DebugFormat(
// "[NPC MODULE]: Creating NPC {0} {1} {2}, owner={3}, senseAsAgent={4} at {5} in {6}",
// firstname, lastname, npcAvatar.AgentId, owner, senseAsAgent, position, scene.RegionInfo.RegionName);
AgentCircuitData acd = new AgentCircuitData();
acd.AgentID = npcAvatar.AgentId;
@ -157,7 +157,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{
sp.CompleteMovement(npcAvatar, false);
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();
@ -177,16 +177,17 @@ namespace OpenSim.Region.OptionalModules.World.NPC
if (m_avatars.ContainsKey(agentID))
{
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(
"[NPC MODULE]: Moving {0} to {1} in {2}, noFly {3}, landAtTarget {4}",
sp.Name, pos, scene.RegionInfo.RegionName, noFly, landAtTarget);
sp.MoveToTarget(pos, noFly, landAtTarget);
sp.SetAlwaysRun = running;
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))
{
ScenePresence sp;
scene.TryGetScenePresence(agentID, out sp);
if (scene.TryGetScenePresence(agentID, out sp))
{
sp.Velocity = Vector3.Zero;
sp.ResetMoveToTarget();
sp.Velocity = Vector3.Zero;
sp.ResetMoveToTarget();
return true;
return true;
}
}
}
@ -223,9 +225,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{
if (m_avatars.ContainsKey(agentID))
{
ScenePresence sp;
scene.TryGetScenePresence(agentID, out sp);
m_avatars[agentID].Say(channel, text);
return true;
@ -241,9 +240,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{
if (m_avatars.ContainsKey(agentID))
{
ScenePresence sp;
scene.TryGetScenePresence(agentID, out sp);
m_avatars[agentID].Shout(channel, text);
return true;
@ -260,11 +256,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC
if (m_avatars.ContainsKey(agentID))
{
ScenePresence sp;
scene.TryGetScenePresence(agentID, out sp);
sp.HandleAgentRequestSit(m_avatars[agentID], agentID, partID, Vector3.Zero);
// sp.HandleAgentSit(m_avatars[agentID], agentID);
return true;
if (scene.TryGetScenePresence(agentID, out sp))
{
sp.HandleAgentRequestSit(m_avatars[agentID], agentID, partID, Vector3.Zero);
// sp.HandleAgentSit(m_avatars[agentID], agentID);
return true;
}
}
}
@ -277,9 +275,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{
if (m_avatars.ContainsKey(agentID))
{
ScenePresence sp;
scene.TryGetScenePresence(agentID, out sp);
m_avatars[agentID].Whisper(channel, text);
return true;
@ -296,10 +291,12 @@ namespace OpenSim.Region.OptionalModules.World.NPC
if (m_avatars.ContainsKey(agentID))
{
ScenePresence sp;
scene.TryGetScenePresence(agentID, out sp);
sp.StandUp();
if (scene.TryGetScenePresence(agentID, out sp))
{
sp.StandUp();
return true;
return true;
}
}
}
@ -312,6 +309,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{
if (m_avatars.ContainsKey(agentID))
return m_avatars[agentID].Touch(objectID);
return false;
}
}
@ -322,9 +320,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{
NPCAvatar av;
if (m_avatars.TryGetValue(agentID, out av))
{
return av.OwnerID;
}
}
return UUID.Zero;
@ -352,7 +348,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
scene.RemoveClient(agentID, false);
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;
}
}

View File

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

View File

@ -40,6 +40,7 @@ public class BSCharacter : PhysicsActor
private static readonly string LogHeader = "[BULLETS CHAR]";
private BSScene _scene;
public BSScene Scene { get { return _scene; } }
private String _avName;
// private bool _stopped;
private Vector3 _size;
@ -73,6 +74,12 @@ public class BSCharacter : PhysicsActor
private bool _kinematic;
private float _buoyancy;
private BulletBody m_body;
public BulletBody Body {
get { return m_body; }
set { m_body = value; }
}
private int _subscribedEventsMs = 0;
private int _nextCollisionOkTime = 0;
@ -95,7 +102,9 @@ public class BSCharacter : PhysicsActor
_orientation = Quaternion.Identity;
_velocity = Vector3.Zero;
_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;
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;
// do actual create at taint time
_scene.TaintedObject(delegate()
_scene.TaintedObject("BSCharacter.create", delegate()
{
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;
@ -124,7 +137,8 @@ public class BSCharacter : PhysicsActor
// called when this character is being destroyed and the resources should be released
public void Destroy()
{
_scene.TaintedObject(delegate()
// DetailLog("{0},BSCharacter.Destroy", LocalID);
_scene.TaintedObject("BSCharacter.destroy", delegate()
{
BulletSimAPI.DestroyObject(_scene.WorldID, _localID);
});
@ -138,9 +152,28 @@ public class BSCharacter : PhysicsActor
public override bool Stopped {
get { return false; }
}
public override Vector3 Size {
get { return _size; }
set { _size = value;
public override Vector3 Size {
get
{
// 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 {
@ -172,12 +205,37 @@ public class BSCharacter : PhysicsActor
}
set {
_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);
});
}
}
// 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 {
get {
return _mass;
@ -188,9 +246,10 @@ public class BSCharacter : PhysicsActor
set {
_force = value;
// 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 {
_velocity = value;
// 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);
});
}
@ -239,7 +299,7 @@ public class BSCharacter : PhysicsActor
set {
_orientation = value;
// m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation);
_scene.TaintedObject(delegate()
_scene.TaintedObject("BSCharacter.setOrientation", delegate()
{
// _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
@ -259,9 +319,12 @@ public class BSCharacter : PhysicsActor
public override bool Flying {
get { return _flying; }
set {
_flying = value;
// simulate flying by changing the effect of gravity
this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
if (_flying != value)
{
_flying = value;
// simulate flying by changing the effect of gravity
this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
}
}
}
private float ComputeBuoyancyFromFlying(bool ifFlying) {
@ -303,8 +366,9 @@ public class BSCharacter : PhysicsActor
public override float Buoyancy {
get { return _buoyancy; }
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);
});
}
@ -349,9 +413,10 @@ public class BSCharacter : PhysicsActor
_force.Y += force.Y;
_force.Z += force.Z;
// 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
@ -369,11 +434,25 @@ public class BSCharacter : PhysicsActor
// Turn on collision events at a rate no faster than one every the given milliseconds
public override void SubscribeEvents(int 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
public override void UnSubscribeEvents() {
_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
public override bool SubscribedEvents() {
@ -385,9 +464,15 @@ public class BSCharacter : PhysicsActor
{
_avatarVolume = (float)(
Math.PI
* _scene.Params.avatarCapsuleRadius * _scale.X
* _scene.Params.avatarCapsuleRadius * _scale.Y
* _scene.Params.avatarCapsuleHeight * _scale.Z);
* _scale.X
* _scale.Y // the area of capsule cylinder
* _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;
}
@ -395,43 +480,19 @@ public class BSCharacter : PhysicsActor
// the world that things have changed.
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;
_orientation = entprop.Rotation;
_velocity = entprop.Velocity;
_acceleration = entprop.Acceleration;
_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();
/*
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
@ -448,6 +509,7 @@ public class BSCharacter : PhysicsActor
{
_collidingGroundStep = _scene.SimulationStep;
}
// DetailLog("{0},BSCharacter.Collison,call,with={1}", LocalID, collidingWith);
// throttle collisions to the rate specified in the subscription
if (_subscribedEventsMs != 0) {
@ -476,9 +538,17 @@ public class BSCharacter : PhysicsActor
if (collisionCollection == null)
collisionCollection = new CollisionEventUpdate();
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
}
// Invoke the detailed logger and output something if it's enabled.
private void DetailLog(string msg, params Object[] args)
{
Scene.PhysicsLogging.Write(msg, args);
}
}
}

View File

@ -32,35 +32,26 @@ using OpenMetaverse;
namespace OpenSim.Region.Physics.BulletSPlugin
{
public class BSConstraint : IDisposable
public abstract class BSConstraint : IDisposable
{
private BulletSim m_world;
private BulletBody m_body1;
private BulletBody m_body2;
private BulletConstraint m_constraint;
private bool m_enabled = false;
protected BulletSim m_world;
protected BulletBody m_body1;
protected BulletBody m_body2;
protected BulletConstraint m_constraint;
protected bool m_enabled = false;
public BSConstraint(BulletSim world, BulletBody obj1, BulletBody obj2,
Vector3 frame1, Quaternion frame1rot,
Vector3 frame2, Quaternion frame2rot
)
public BSConstraint()
{
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)
{
// 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;
}
}
@ -68,7 +59,7 @@ public class BSConstraint : IDisposable
public BulletBody Body1 { get { return m_body1; } }
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;
if (m_enabled)
@ -76,7 +67,7 @@ public class BSConstraint : IDisposable
return ret;
}
public bool SetAngularLimits(Vector3 low, Vector3 high)
public virtual bool SetAngularLimits(Vector3 low, Vector3 high)
{
bool ret = false;
if (m_enabled)
@ -84,42 +75,38 @@ public class BSConstraint : IDisposable
return ret;
}
public bool SetCFMAndERP(float cfm, float erp)
{
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()
public virtual bool CalculateTransforms()
{
bool ret = false;
if (m_enabled)
{
// Recompute the internal transforms
BulletSimAPI.CalculateTransforms2(m_constraint.Ptr);
ret = true;
}
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;
}
}
}

View File

@ -56,29 +56,25 @@ public class BSConstraintCollection : IDisposable
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)
{
// There is only one constraint between any bodies. Remove any old just to make sure.
RemoveAndDestroyConstraint(cons.Body1, cons.Body2);
lock (m_constraints)
{
// 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;
}
@ -92,16 +88,19 @@ public class BSConstraintCollection : IDisposable
uint lookingID1 = body1.ID;
uint lookingID2 = body2.ID;
ForEachConstraint(delegate(BSConstraint constrain)
lock (m_constraints)
{
if ((constrain.Body1.ID == lookingID1 && constrain.Body2.ID == lookingID2)
|| (constrain.Body1.ID == lookingID2 && constrain.Body2.ID == lookingID1))
foreach (BSConstraint constrain in m_constraints)
{
foundConstraint = constrain;
found = true;
if ((constrain.Body1.ID == lookingID1 && constrain.Body2.ID == lookingID2)
|| (constrain.Body1.ID == lookingID2 && constrain.Body2.ID == lookingID1))
{
foundConstraint = constrain;
found = true;
break;
}
}
return found;
});
}
returnConstraint = foundConstraint;
return found;
}
@ -111,24 +110,35 @@ public class BSConstraintCollection : IDisposable
// Return 'true' if a constraint was found and destroyed.
public bool RemoveAndDestroyConstraint(BulletBody body1, BulletBody body2)
{
// return BulletSimAPI.RemoveConstraint(m_world.ID, obj1.ID, obj2.ID);
bool ret = false;
BSConstraint constrain;
if (this.TryGetConstraint(body1, body2, out 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
ret = true;
BSConstraint constrain;
if (this.TryGetConstraint(body1, body2, out constrain))
{
// remove the constraint from our collection
RemoveAndDestroyConstraint(constrain);
ret = true;
}
}
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.
// Return 'true' if any constraints were destroyed.
public bool RemoveAndDestroyConstraint(BulletBody body1)
@ -137,16 +147,15 @@ public class BSConstraintCollection : IDisposable
List<BSConstraint> toRemove = new List<BSConstraint>();
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)
{
foreach (BSConstraint constrain in m_constraints)
{
if (constrain.Body1.ID == lookingID || constrain.Body2.ID == lookingID)
{
toRemove.Add(constrain);
}
}
foreach (BSConstraint constrain in toRemove)
{
m_constraints.Remove(constrain);
@ -158,27 +167,16 @@ public class BSConstraintCollection : IDisposable
public bool RecalculateAllConstraints()
{
foreach (BSConstraint constrain in m_constraints)
{
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)
{
bool ret = false;
lock (m_constraints)
{
foreach (BSConstraint constrain in m_constraints)
{
if (action(constrain))
break;
constrain.CalculateTransforms();
ret = true;
}
}
return ret;
}
}
}

View File

@ -613,7 +613,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
MoveAngular(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);
}// end Step

View File

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

View File

@ -37,10 +37,12 @@ public class BSLinkset
private static string LogHeader = "[BULLETSIM LINKSET]";
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;
// We lock the diddling of linkset classes to prevent any badness.
@ -72,7 +74,7 @@ public class BSLinkset
public BSLinkset(BSScene scene, BSPrim parent)
{
// A simple linkset of one (no children)
m_scene = scene;
m_physicsScene = scene;
m_linksetRoot = parent;
m_children = new List<BSPrim>();
m_mass = parent.MassRaw;
@ -80,16 +82,19 @@ public class BSLinkset
// Link to a linkset where the child knows the parent.
// Parent changing should not happen so do some sanity checking.
// We return the parent's linkset so the child can track it's membership.
public BSLinkset AddMeToLinkset(BSPrim child, BSPrim parent)
// We return the parent's linkset so the child can track its membership.
public BSLinkset AddMeToLinkset(BSPrim child)
{
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)
{
lock (m_linksetActivityLock)
@ -101,7 +106,7 @@ public class BSLinkset
{
// Note that we don't do a foreach because the remove routine
// takes it out of the list.
RemoveChildFromLinkset(m_children[0]);
RemoveChildFromOtherLinkset(m_children[0]);
}
m_children.Clear(); // just to make sure
}
@ -113,63 +118,17 @@ public class BSLinkset
}
// 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
public bool IsRoot(BSPrim requestor)
{
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)
public bool HasAnyChildren { get { return (m_children.Count > 0); } }
@ -177,12 +136,15 @@ public class BSLinkset
public bool HasChild(BSPrim child)
{
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;
break;
if (child.LocalID == bp.LocalID)
{
ret = true;
break;
}
}
}
return ret;
@ -203,12 +165,16 @@ public class BSLinkset
OMV.Vector3 com = m_linksetRoot.Position * m_linksetRoot.MassRaw;
float totalMass = m_linksetRoot.MassRaw;
foreach (BSPrim bp in m_children)
lock (m_linksetActivityLock)
{
com += bp.Position * bp.MassRaw;
totalMass += bp.MassRaw;
foreach (BSPrim bp in m_children)
{
com += bp.Position * bp.MassRaw;
totalMass += bp.MassRaw;
}
if (totalMass != 0f)
com /= totalMass;
}
com /= totalMass;
return com;
}
@ -217,135 +183,237 @@ public class BSLinkset
{
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;
}
// I am the root of a linkset and a new child is being added
public void AddChildToLinkset(BSPrim pchild)
// When physical properties are changed the linkset needs to recalculate
// 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))
{
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);
DetailLog("{0},AddChildToLinkset,child={1}", m_linksetRoot.LocalID, pchild.LocalID);
PhysicallyLinkAChildToRoot(pchild); // build the physical binding between me and the child
// DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID);
// DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
PhysicallyLinkAChildToRoot(rootx, childx); // build the physical binding between me and the child
});
}
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.
// 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))
{
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);
DetailLog("{0},RemoveChildFromLinkset,child={1}", m_linksetRoot.LocalID, pchild.LocalID);
// DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID);
// DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
if (m_children.Count == 0)
{
// if the linkset is empty, make sure all linkages have been removed
PhysicallyUnlinkAllChildrenFromRoot();
}
else
{
PhysicallyUnlinkAChildFromRoot(pchild);
}
PhysicallyUnlinkAChildFromRoot(rootx, childx);
});
RecomputeLinksetConstraintVariables();
}
else
{
// 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;
}
// Create a constraint between me (root of linkset) and the passed prim (the child).
// 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
childPrim.ZeroMotion();
// relative position normalized to the root prim
OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(m_linksetRoot.Orientation);
OMV.Vector3 childRelativePosition = (childPrim.Position - m_linksetRoot.Position) * invThisOrientation;
// Relative position normalized to the root prim
// Essentually a vector pointing from center of rootPrim to center of childPrim
OMV.Vector3 childRelativePosition = childPrim.Position - rootPrim.Position;
// relative rotation of the child to the parent
OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation;
// real world coordinate of midpoint between the two objects
OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2);
// 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},LinkAChildToMe,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID);
BSConstraint constrain = m_scene.Constraints.CreateConstraint(
m_scene.World, m_linksetRoot.Body, childPrim.Body,
// childRelativePosition,
// childRelativeRotation,
OMV.Vector3.Zero,
OMV.Quaternion.Identity,
OMV.Vector3.Zero,
OMV.Quaternion.Identity
DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2},rLoc={3},cLoc={4},midLoc={5}",
rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID, rootPrim.Position, childPrim.Position, midPoint);
BS6DofConstraint constrain = new BS6DofConstraint(
m_physicsScene.World, rootPrim.Body, childPrim.Body,
midPoint,
true,
true
);
/* 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.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
// tweek the constraint to increase stability
constrain.UseFrameOffset(m_scene.BoolNumeric(m_scene.Params.linkConstraintUseFrameOffset));
constrain.TranslationalLimitMotor(m_scene.BoolNumeric(m_scene.Params.linkConstraintEnableTransMotor),
m_scene.Params.linkConstraintTransMotorMaxVel,
m_scene.Params.linkConstraintTransMotorMaxForce);
constrain.SetCFMAndERP(m_scene.Params.linkConstraintCFM, m_scene.Params.linkConstraintERP);
constrain.UseFrameOffset(PhysicsScene.BoolNumeric(PhysicsScene.Params.linkConstraintUseFrameOffset));
constrain.TranslationalLimitMotor(PhysicsScene.BoolNumeric(PhysicsScene.Params.linkConstraintEnableTransMotor),
PhysicsScene.Params.linkConstraintTransMotorMaxVel,
PhysicsScene.Params.linkConstraintTransMotorMaxForce);
constrain.SetCFMAndERP(PhysicsScene.Params.linkConstraintCFM, PhysicsScene.Params.linkConstraintERP);
RecomputeLinksetConstraintVariables();
}
// Remove linkage between myself and a particular child
// 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}",
LogHeader, m_linksetRoot.LocalID, childPrim.LocalID);
DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID);
// BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, childPrim.LocalID);
m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body, childPrim.Body);
// DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}",
// LogHeader, rootPrim.LocalID, childPrim.LocalID);
DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
// Find the constraint for this link and get rid of it from the overall collection and from my list
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
// Called at taint time!
private void PhysicallyUnlinkAllChildrenFromRoot()
private void PhysicallyUnlinkAllChildrenFromRoot(BSPrim rootPrim)
{
// DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader);
DetailLog("{0},PhysicallyUnlinkAllChildren,taint", m_linksetRoot.LocalID);
m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body);
// BulletSimAPI.RemoveConstraintByID(_scene.WorldID, LocalID);
DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body);
}
// Invoke the detailed logger and output something if it's enabled.
private void DebugLog(string msg, params Object[] args)
{
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.
private void DetailLog(string msg, params Object[] args)
{
m_scene.PhysicsLogging.Write(msg, args);
m_physicsScene.PhysicsLogging.Write(msg, args);
}
}

View File

@ -42,7 +42,7 @@ public sealed class BSPrim : PhysicsActor
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string LogHeader = "[BULLETS PRIM]";
private void DebugLog(string mm, params Object[] xx) { if (_scene.shouldDebugLog) m_log.DebugFormat(mm, xx); }
private void DebugLog(string mm, params Object[] xx) { if (_scene.ShouldDebugLog) m_log.DebugFormat(mm, xx); }
private IMesh _mesh;
private PrimitiveBaseShape _pbs;
@ -138,14 +138,15 @@ public sealed class BSPrim : PhysicsActor
_isPhysical = pisPhysical;
_isVolumeDetect = false;
_subscribedEventsMs = 0;
_friction = _scene.Params.defaultFriction; // TODO: compute based on object material
_density = _scene.Params.defaultDensity; // 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
_restitution = _scene.Params.defaultRestitution;
_linkset = new BSLinkset(_scene, this); // a linkset of one
_vehicle = new BSDynamics(this); // add vehicleness
_vehicle = new BSDynamics(this); // add vehicleness
_mass = CalculateMass();
// do the actual object creation at taint time
_scene.TaintedObject(delegate()
DetailLog("{0},BSPrim.constructor,call", LocalID);
_scene.TaintedObject("BSPrim.create", delegate()
{
RecreateGeomAndObject();
@ -160,17 +161,22 @@ public sealed class BSPrim : PhysicsActor
public void Destroy()
{
// 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
_vehicle.ProcessTypeChange(Vehicle.TYPE_NONE);
_scene.RemoveVehiclePrim(this); // just to make sure
this.VehicleType = (int)Vehicle.TYPE_NONE;
_scene.TaintedObject(delegate()
_scene.TaintedObject("BSPrim.destroy", delegate()
{
// Undo any links between me and any other object
_linkset = _linkset.RemoveMeFromLinkset(this);
DetailLog("{0},BSPrim.Destroy,taint,", LocalID);
// everything in the C# world will get garbage collected. Tell the C++ world to free stuff.
BulletSimAPI.DestroyObject(_scene.WorldID, LocalID);
});
@ -183,11 +189,11 @@ public sealed class BSPrim : PhysicsActor
get { return _size; }
set {
_size = value;
_scene.TaintedObject(delegate()
_scene.TaintedObject("BSPrim.setSize", delegate()
{
_mass = CalculateMass(); // changing size changes the mass
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();
});
}
@ -195,7 +201,7 @@ public sealed class BSPrim : PhysicsActor
public override PrimitiveBaseShape Shape {
set {
_pbs = value;
_scene.TaintedObject(delegate()
_scene.TaintedObject("BSPrim.setShape", delegate()
{
_mass = CalculateMass(); // changing the shape changes the mass
RecreateGeomAndObject();
@ -213,7 +219,7 @@ public sealed class BSPrim : PhysicsActor
public override bool Selected {
set {
_isSelected = value;
_scene.TaintedObject(delegate()
_scene.TaintedObject("BSPrim.setSelected", delegate()
{
SetObjectDynamic();
});
@ -224,10 +230,17 @@ public sealed class BSPrim : PhysicsActor
// link me to the specified parent
public override void link(PhysicsActor obj) {
BSPrim parent = obj as BSPrim;
DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID);
DetailLog("{0},link,parent={1}", LocalID, obj.LocalID);
if (parent != null)
{
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;
}
@ -236,10 +249,15 @@ public sealed class BSPrim : PhysicsActor
// TODO: decide if this parent checking needs to happen at taint time
// Race condition here: if link() and delink() in same simulation tick, the delink will not happen
DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID,
_linkset.Root._avName+"/"+_linkset.Root.LocalID.ToString());
DetailLog("{0},delink,parent={1}", LocalID, _linkset.Root.LocalID.ToString());
_linkset.LinksetRoot._avName+"/"+_linkset.LinksetRoot.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;
}
@ -262,7 +280,7 @@ public sealed class BSPrim : PhysicsActor
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;
}
@ -279,9 +297,9 @@ public sealed class BSPrim : PhysicsActor
set {
_position = value;
// 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);
});
}
@ -316,9 +334,9 @@ public sealed class BSPrim : PhysicsActor
get { return _force; }
set {
_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.SetObjectForce2(Body.Ptr, _force);
});
@ -331,53 +349,41 @@ public sealed class BSPrim : PhysicsActor
}
set {
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);
if (type == Vehicle.TYPE_NONE)
{
_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;
// Tell the scene about the vehicle so it will get processing each frame.
_scene.VehicleInSceneTypeChanged(this, type);
});
}
}
public override void VehicleFloatParam(int param, float value)
{
_scene.TaintedObject(delegate()
_scene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
{
_vehicle.ProcessFloatVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep);
});
}
public override void VehicleVectorParam(int param, OMV.Vector3 value)
{
_scene.TaintedObject(delegate()
_scene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
{
_vehicle.ProcessVectorVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep);
});
}
public override void VehicleRotationParam(int param, OMV.Quaternion rotation)
{
_scene.TaintedObject(delegate()
_scene.TaintedObject("BSPrim.VehicleRotationParam", delegate()
{
_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
});
}
public override void VehicleFlags(int param, bool remove)
{
_scene.TaintedObject(delegate()
_scene.TaintedObject("BSPrim.VehicleFlags", delegate()
{
_vehicle.ProcessVehicleFlags(param, remove);
});
@ -395,7 +401,7 @@ public sealed class BSPrim : PhysicsActor
public override void SetVolumeDetect(int param) {
bool newValue = (param != 0);
_isVolumeDetect = newValue;
_scene.TaintedObject(delegate()
_scene.TaintedObject("BSPrim.SetVolumeDetect", delegate()
{
SetObjectDynamic();
});
@ -406,9 +412,9 @@ public sealed class BSPrim : PhysicsActor
get { return _velocity; }
set {
_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);
});
}
@ -416,7 +422,7 @@ public sealed class BSPrim : PhysicsActor
public override OMV.Vector3 Torque {
get { return _torque; }
set { _torque = value;
DetailLog("{0},SetTorque,call,torque={1}", LocalID, _torque);
// DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque);
}
}
public override float CollisionScore {
@ -440,10 +446,10 @@ public sealed class BSPrim : PhysicsActor
set {
_orientation = value;
// 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);
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);
});
}
@ -457,7 +463,7 @@ public sealed class BSPrim : PhysicsActor
get { return _isPhysical; }
set {
_isPhysical = value;
_scene.TaintedObject(delegate()
_scene.TaintedObject("BSPrim.setIsPhysical", delegate()
{
SetObjectDynamic();
});
@ -478,7 +484,6 @@ public sealed class BSPrim : PhysicsActor
// Make gravity work if the object is physical and not selected
// 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()
{
// RA: remove this for the moment.
@ -487,13 +492,16 @@ public sealed class BSPrim : PhysicsActor
// Maybe a VerifyCorrectPhysicalShape() routine?
// RecreateGeomAndObject();
float mass = _mass;
// Bullet wants static objects have a mass of zero
if (IsStatic)
mass = 0f;
// Bullet wants static objects to have a mass of zero
float mass = IsStatic ? 0f : _mass;
DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, 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
@ -548,9 +556,9 @@ public sealed class BSPrim : PhysicsActor
set {
_rotationalVelocity = value;
// 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);
});
}
@ -565,9 +573,9 @@ public sealed class BSPrim : PhysicsActor
get { return _buoyancy; }
set {
_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);
});
}
@ -607,6 +615,7 @@ public sealed class BSPrim : PhysicsActor
private List<OMV.Vector3> m_accumulatedForces = new List<OMV.Vector3>();
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())
{
// _force += force;
@ -618,40 +627,48 @@ public sealed class BSPrim : PhysicsActor
m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader);
return;
}
_scene.TaintedObject(delegate()
_scene.TaintedObject("BSPrim.AddForce", delegate()
{
OMV.Vector3 fSum = OMV.Vector3.Zero;
lock (m_accumulatedForces)
{
if (m_accumulatedForces.Count > 0)
foreach (OMV.Vector3 v in m_accumulatedForces)
{
OMV.Vector3 fSum = OMV.Vector3.Zero;
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);
fSum += v;
}
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) {
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);
}
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) {
_subscribedEventsMs = ms;
// make sure first collision happens
_nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs;
if (ms > 0)
{
// 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() {
_subscribedEventsMs = 0;
Scene.TaintedObject("BSPrim.UnSubscribeEvents", delegate()
{
BulletSimAPI.RemoveFromCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
});
}
public override bool SubscribedEvents() {
return (_subscribedEventsMs > 0);
@ -970,26 +987,26 @@ public sealed class BSPrim : PhysicsActor
{
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);
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;
// Bullet native objects are scaled by the Bullet engine so pass the size in
_scale = _size;
// TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
ret = true;
}
}
// }
}
else
{
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size);
if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX))
{
DetailLog("{0},CreateGeom,box", LocalID);
// DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild);
_shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
_scale = _size;
// TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
@ -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 (_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
if (_meshKey != 0)
{
// 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);
_mesh = null;
_meshKey = 0;
@ -1067,7 +1084,7 @@ public sealed class BSPrim : PhysicsActor
_shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH;
// meshes are already scaled by the meshmerizer
_scale = new OMV.Vector3(1f, 1f, 1f);
DetailLog("{0},CreateGeomMesh,done", LocalID);
// DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID);
return;
}
@ -1081,28 +1098,21 @@ public sealed class BSPrim : PhysicsActor
// if the hull hasn't changed, don't rebuild it
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
if (_hullKey != 0)
{
// 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);
_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;
if (_meshKey != _hullKey)
{
// if the underlying mesh has changed, rebuild it
CreateGeomMesh();
}
// Make sure the underlying mesh exists and is correct
CreateGeomMesh();
int[] indices = _mesh.getIndexListAsInt();
List<OMV.Vector3> vertices = _mesh.getVertexList();
@ -1128,7 +1138,7 @@ public sealed class BSPrim : PhysicsActor
// create the hull into the _hulls variable
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 format is:
// convHulls[0] = number of hulls
@ -1188,7 +1198,7 @@ public sealed class BSPrim : PhysicsActor
_shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL;
// meshes are already scaled by the meshmerizer
_scale = new OMV.Vector3(1f, 1f, 1f);
DetailLog("{0},CreateGeomHull,done", LocalID);
// DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID);
return;
}
@ -1214,7 +1224,7 @@ public sealed class BSPrim : PhysicsActor
bool ret = BulletSimAPI.CreateObject(_scene.WorldID, shape);
// 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;
}
@ -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}",
// LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
DetailLog("{0},UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
// DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
// LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
base.RequestPhysicsterseUpdate();
}
@ -1335,7 +1345,7 @@ public sealed class BSPrim : PhysicsActor
else
{
// 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,
entprop.Acceleration, entprop.RotationalVelocity);
}
@ -1343,7 +1353,7 @@ public sealed class BSPrim : PhysicsActor
}
// 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)
{
// 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;
}
// DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith);
// if someone is subscribed to collision events....
if (_subscribedEventsMs != 0) {
// 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)
{
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;
}
}

View File

@ -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 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 = "?";
@ -162,14 +162,24 @@ public class BSScene : PhysicsScene, IPhysicsParameters
}
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();
// A pointer to an instance if this structure is passed to the C++ code
ConfigurationParameters[] m_params;
GCHandle m_paramsHandle;
public bool shouldDebugLog { get; private set; }
public bool ShouldDebugLog { get; private set; }
private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle;
@ -232,7 +242,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle);
}
_taintedObjects = new List<TaintCallback>();
_taintedObjects = new List<TaintCallbackEntry>();
mesher = meshmerizer;
// 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
// 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_initialized = true;
@ -352,7 +362,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
BSPrim bsprim = prim as BSPrim;
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
{
lock (m_prims) m_prims.Remove(bsprim.LocalID);
@ -377,6 +388,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
if (!m_initialized) return null;
// DetailLog("{0},AddPrimShape,call", localID);
BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical);
lock (m_prims) m_prims.Add(localID, prim);
return prim;
@ -400,7 +413,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
// prevent simulation until we've been initialized
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
ProcessTaints();
@ -416,12 +429,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
{
numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep,
out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", "0000000000", numSubSteps, updatedEntityCount, collidersCount);
// DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount);
}
catch (Exception e)
{
m_log.WarnFormat("{0},PhysicsStep Exception: substeps={1}, updates={2}, colliders={3}, e={4}", LogHeader, numSubSteps, updatedEntityCount, collidersCount, e);
DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", "0000000000", numSubSteps, updatedEntityCount, collidersCount);
// DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount);
// updatedEntityCount = 0;
collidersCount = 0;
}
@ -498,8 +511,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
// long simulateTotalTime = Util.EnvironmentTickCountSubtract(simulateStartTime);
// return (timeStep * (float)simulateTotalTime);
// TODO: FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation.
return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f;
// TODO: FIX THIS: fps calculation possibly wrong.
// 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
@ -535,7 +553,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
public override void SetTerrain(float[] heightMap) {
m_heightMap = heightMap;
this.TaintedObject(delegate()
this.TaintedObject("BSScene.SetTerrain", delegate()
{
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
m_initialized = false;
if (m_constraintCollection != null)
{
m_constraintCollection.Dispose();
m_constraintCollection = null;
}
foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars)
{
kvp.Value.Destroy();
@ -595,6 +607,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
}
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
BulletSimAPI.Shutdown(WorldID);
@ -727,12 +746,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
// Calls to the PhysicsActors can't directly call into the physics engine
// 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.
public void TaintedObject(TaintCallback callback)
public void TaintedObject(String ident, TaintCallback callback)
{
if (!m_initialized) return;
lock (_taintLock)
_taintedObjects.Add(callback);
_taintedObjects.Add(new TaintCallbackEntry(ident, callback));
return;
}
@ -744,22 +763,22 @@ public class BSScene : PhysicsScene, IPhysicsParameters
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
List<TaintCallback> oldList;
List<TaintCallbackEntry> oldList;
lock (_taintLock)
{
oldList = _taintedObjects;
_taintedObjects = new List<TaintCallback>();
_taintedObjects = new List<TaintCallbackEntry>();
}
foreach (TaintCallback callback in oldList)
foreach (TaintCallbackEntry tcbe in oldList)
{
try
{
callback();
tcbe.callback();
}
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();
@ -767,6 +786,20 @@ public class BSScene : PhysicsScene, IPhysicsParameters
}
#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.
// Safe to call if prim is already in the vehicle list.
public void AddVehiclePrim(BSPrim vehicle)
@ -812,12 +845,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
private struct ParameterDefn
{
public string name;
public string desc;
public float defaultValue;
public ParamUser userParam;
public ParamGet getter;
public ParamSet setter;
public string name; // string name of the parameter
public string desc; // a short description of what the parameter means
public float defaultValue; // default value if not specified anywhere else
public ParamUser userParam; // get the value from the configuration file
public ParamGet getter; // return the current value stored for this parameter
public ParamSet setter; // set the current value for this parameter
public ParameterDefn(string n, string d, float v, ParamUser u, ParamGet g, ParamSet s)
{
name = n;
@ -834,7 +867,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
// 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
// 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.
//
// A ParameterDefn() takes the following parameters:
@ -870,7 +903,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
(s) => { return (float)s.m_meshLOD; },
(s,p,l,v) => { s.m_meshLOD = (int)v; } ),
new ParameterDefn("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)",
32,
32f,
(s,cf,p,v) => { s.m_sculptLOD = cf.GetInt(p, (int)v); },
(s) => { return (float)s.m_sculptLOD; },
(s,p,l,v) => { s.m_sculptLOD = (int)v; } ),
@ -1027,14 +1060,19 @@ public class BSScene : PhysicsScene, IPhysicsParameters
(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
(s,cf,p,v) => { s.m_params[0].maxPersistantManifoldPoolSize = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].maxPersistantManifoldPoolSize; },
(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",
ConfigurationParameters.numericTrue,
(s,cf,p,v) => { s.m_params[0].maxPersistantManifoldPoolSize = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
ConfigurationParameters.numericFalse,
(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,p,l,v) => { s.m_params[0].shouldDisableContactPoolDynamicAllocation = v; } ),
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; } ),
new ParameterDefn("ShouldDebugLog", "Enables detailed DEBUG log statements",
ConfigurationParameters.numericFalse,
(s,cf,p,v) => { s.shouldDebugLog = cf.GetBoolean(p, s.BoolNumeric(v)); },
(s) => { return s.NumericBool(s.shouldDebugLog); },
(s,p,l,v) => { s.shouldDebugLog = s.BoolNumeric(v); } ),
(s,cf,p,v) => { s.ShouldDebugLog = cf.GetBoolean(p, s.BoolNumeric(v)); },
(s) => { return s.NumericBool(s.ShouldDebugLog); },
(s,p,l,v) => { s.ShouldDebugLog = s.BoolNumeric(v); } ),
};
@ -1243,7 +1281,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
List<uint> objectIDs = lIDs;
string xparm = parm.ToLower();
float xval = val;
TaintedObject(delegate() {
TaintedObject("BSScene.UpdateParameterSet", delegate() {
foreach (uint lID in objectIDs)
{
BulletSimAPI.UpdateParameter(m_worldID, lID, xparm, xval);
@ -1263,7 +1301,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
uint xlocalID = localID;
string xparm = parm.ToLower();
float xval = val;
TaintedObject(delegate() {
TaintedObject("BSScene.TaintedUpdateParameter", delegate() {
BulletSimAPI.UpdateParameter(m_worldID, xlocalID, xparm, xval);
});
}
@ -1289,10 +1327,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
#endregion Runtime settable parameters
// 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);
}
// used to fill in the LocalID when there isn't one
public const string DetailLogZero = "0000000000";
}
}

View File

@ -35,9 +35,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin {
// Classes to allow some type checking for the API
public struct BulletSim
{
public BulletSim(uint id, IntPtr xx) { ID = id; Ptr = xx; }
public IntPtr Ptr;
public BulletSim(uint id, BSScene bss, IntPtr xx) { ID = id; scene = bss; Ptr = xx; }
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
@ -158,6 +160,7 @@ public struct ConfigurationParameters
public float avatarContactProcessingThreshold;
public float maxPersistantManifoldPoolSize;
public float maxCollisionAlgorithmPoolSize;
public float shouldDisableContactPoolDynamicAllocation;
public float shouldForceUpdateAllAabbs;
public float shouldRandomizeSolverOrder;
@ -179,17 +182,18 @@ public struct ConfigurationParameters
// Values used by Bullet and BulletSim to control collisions
public enum CollisionFlags : uint
{
STATIC_OBJECT = 1 << 0,
KINEMATIC_OBJECT = 1 << 1,
NO_CONTACT_RESPONSE = 1 << 2,
CUSTOM_MATERIAL_CALLBACK = 1 << 3,
CHARACTER_OBJECT = 1 << 4,
DISABLE_VISUALIZE_OBJECT = 1 << 5,
DISABLE_SPU_COLLISION_PROCESS = 1 << 6,
CF_STATIC_OBJECT = 1 << 0,
CF_KINEMATIC_OBJECT = 1 << 1,
CF_NO_CONTACT_RESPONSE = 1 << 2,
CF_CUSTOM_MATERIAL_CALLBACK = 1 << 3,
CF_CHARACTER_OBJECT = 1 << 4,
CF_DISABLE_VISUALIZE_OBJECT = 1 << 5,
CF_DISABLE_SPU_COLLISION_PROCESS = 1 << 6,
// Following used by BulletSim to control collisions
VOLUME_DETECT_OBJECT = 1 << 10,
PHANTOM_OBJECT = 1 << 11,
PHYSICAL_OBJECT = 1 << 12,
BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10,
BS_VOLUME_DETECT_OBJECT = 1 << 11,
BS_PHANTOM_OBJECT = 1 << 12,
BS_PHYSICAL_OBJECT = 1 << 13,
};
// 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);
[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]
@ -370,44 +374,68 @@ public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms,
int maxUpdates, IntPtr updateArray);
[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]
public static extern void SetHeightmap2(IntPtr sim, float[] heightmap);
public static extern void SetHeightmap2(IntPtr world, float[] heightmap);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern void Shutdown2(IntPtr sim);
[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 IntPtr updatedEntitiesPtr,
out int collidersCount,
out IntPtr collidersPtr);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool PushUpdate2(IntPtr obj);
/*
[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]
public static extern bool BuildHull2(IntPtr sim, IntPtr mesh);
public static extern bool BuildHull2(IntPtr world, IntPtr mesh);
[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]
public static extern bool DestroyMesh2(IntPtr sim, IntPtr mesh);
public static extern bool DestroyMesh2(IntPtr world, IntPtr mesh);
[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]
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 frame2loc, Quaternion frame2rot,
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]
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]
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]
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);
[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]
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]
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]
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);
[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]
public static extern IntPtr AddToCollisionFlags2(IntPtr obj, uint flags);
public static extern IntPtr SetCollisionFlags2(IntPtr obj, CollisionFlags flags);
[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]
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]
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]
public static extern bool SetMargin2(IntPtr obj, float val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
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]
public static extern bool DestroyObject2(IntPtr world, uint id);

View File

@ -226,6 +226,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public void llResetScript()
{
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);
}
@ -331,35 +337,40 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
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>();
if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
return ret;
ret.Add(m_host);
ret.Add(part);
switch (linkType)
{
case ScriptBaseClass.LINK_SET:
return new List<SceneObjectPart>(m_host.ParentGroup.Parts);
return new List<SceneObjectPart>(part.ParentGroup.Parts);
case ScriptBaseClass.LINK_ROOT:
ret = new List<SceneObjectPart>();
ret.Add(m_host.ParentGroup.RootPart);
ret.Add(part.ParentGroup.RootPart);
return ret;
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))
ret.Remove(m_host);
if (ret.Contains(part))
ret.Remove(part);
return ret;
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))
ret.Remove(m_host.ParentGroup.RootPart);
if (ret.Contains(part.ParentGroup.RootPart))
ret.Remove(part.ParentGroup.RootPart);
return ret;
case ScriptBaseClass.LINK_THIS:
@ -369,7 +380,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (linkType < 0)
return new List<SceneObjectPart>();
SceneObjectPart target = m_host.ParentGroup.GetLinkNumPart(linkType);
SceneObjectPart target = part.ParentGroup.GetLinkNumPart(linkType);
if (target == null)
return new List<SceneObjectPart>();
ret = new List<SceneObjectPart>();
@ -1764,13 +1775,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
try
{
parts[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart part in parts)
SetAlpha(part, alpha, face);
}
finally
{
parts[0].ParentGroup.areUpdatesSuspended = false;
}
}
}
@ -1951,13 +1960,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
try
{
parts[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart part in parts)
SetTexture(part, texture, face);
}
finally
{
parts[0].ParentGroup.areUpdatesSuspended = false;
}
}
ScriptSleep(200);
@ -3340,7 +3347,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
if (attachmentsModule != null)
return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true);
return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
else
return false;
}
@ -3747,29 +3754,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.AddScriptLPS(1);
int implicitPerms = 0;
if (m_host.ParentGroup.IsAttachment && (UUID)agent == m_host.ParentGroup.AttachedAvatar)
{
// 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_CONTROL_CAMERA |
ScriptBaseClass.PERMISSION_TRACK_CAMERA |
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
{
@ -3790,26 +3785,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (sitting)
{
// 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_TRACK_CAMERA |
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);
@ -3927,13 +3927,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
try
{
parts[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart part in parts)
part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
}
finally
{
parts[0].ParentGroup.areUpdatesSuspended = false;
}
}
}
@ -4051,7 +4049,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
try
{
parts[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart part in parts)
{
parentPrim.DelinkFromGroup(part.LocalId, true);
@ -4059,7 +4056,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
finally
{
parts[0].ParentGroup.areUpdatesSuspended = false;
}
}
@ -4074,7 +4070,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
try
{
parts[0].ParentGroup.areUpdatesSuspended = true;
foreach (SceneObjectPart part in parts)
{
part.ClearUpdateSchedule();
@ -4083,7 +4078,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
finally
{
parts[0].ParentGroup.areUpdatesSuspended = false;
}
@ -5369,12 +5363,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
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
{
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)
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());
}
catch (FormatException)
@ -5394,12 +5397,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
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
{
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)
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)
{
string str = ((LSL_String) src.Data[index]).m_string;
@ -5437,17 +5456,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
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);
if (index < 0)
{
index = src.Length + index;
}
if (index >= src.Length || index < 0)
{
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();
}
@ -5466,6 +5498,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
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
{
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);
}
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];
}
@ -6236,7 +6292,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
try
{
parts[0].ParentGroup.areUpdatesSuspended = true;
foreach (var part in parts)
{
SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
@ -6244,7 +6299,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
finally
{
parts[0].ParentGroup.areUpdatesSuspended = false;
}
}
}
@ -7689,7 +7743,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public void llSetPrimitiveParams(LSL_List rules)
{
m_host.AddScriptLPS(1);
SetPrimParams(m_host, rules);
setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules);
ScriptSleep(200);
}
@ -7703,26 +7758,47 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
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);
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;
foreach (SceneObjectPart part in parts)
SetPrimParams(part, rules);
if (part is SceneObjectPart)
remaining = SetPrimParams((SceneObjectPart)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,
@ -7784,7 +7860,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
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.
@ -7807,7 +7883,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_POS_LOCAL:
{
if (remain < 1)
return;
return null;
LSL_Vector v;
v = rules.GetVector3Item(idx++);
@ -7841,7 +7917,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_ROTATION:
{
if (remain < 1)
return;
return null;
LSL_Rotation r;
r = rules.GetQuaternionItem(idx++);
@ -7872,7 +7948,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_NAME:
case (int)ScriptBaseClass.PRIM_DESC:
if (remain < 1)
return;
return null;
idx++;
break;
@ -7880,13 +7956,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
case (int)ScriptBaseClass.PRIM_TEXGEN:
if (remain < 2)
return;
return null;
idx += 2;
break;
case (int)ScriptBaseClass.PRIM_TYPE:
if (remain < 3)
return;
return null;
code = (int)rules.GetLSLIntegerItem(idx++);
remain = rules.Length - idx;
switch (code)
@ -7895,13 +7971,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
if (remain < 6)
return;
return null;
idx += 6;
break;
case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
if (remain < 5)
return;
return null;
idx += 5;
break;
@ -7909,13 +7985,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
case (int)ScriptBaseClass.PRIM_TYPE_RING:
if (remain < 11)
return;
return null;
idx += 11;
break;
case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
if (remain < 2)
return;
return null;
idx += 2;
break;
}
@ -7926,7 +8002,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
case (int)ScriptBaseClass.PRIM_OMEGA:
if (remain < 3)
return;
return null;
idx += 3;
break;
@ -7934,33 +8010,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
if (remain < 5)
return;
return null;
idx += 5;
break;
case (int)ScriptBaseClass.PRIM_FLEXIBLE:
if (remain < 7)
return;
return null;
idx += 7;
break;
case (int)ScriptBaseClass.PRIM_LINK_TARGET:
if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
return;
return null;
if (positionChanged)
{
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;
return rules.GetSublist(idx, -1);
}
}
}
@ -7975,12 +8040,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
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)
return;
return null;
int idx = 0;
@ -8005,7 +8071,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_POSITION:
case (int)ScriptBaseClass.PRIM_POS_LOCAL:
if (remain < 1)
return;
return null;
v=rules.GetVector3Item(idx++);
currentPosition = GetSetPosTarget(part, v, currentPosition);
@ -8014,7 +8080,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
break;
case (int)ScriptBaseClass.PRIM_SIZE:
if (remain < 1)
return;
return null;
v=rules.GetVector3Item(idx++);
SetScale(part, v);
@ -8022,7 +8088,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
break;
case (int)ScriptBaseClass.PRIM_ROTATION:
if (remain < 1)
return;
return null;
LSL_Rotation q = rules.GetQuaternionItem(idx++);
SceneObjectPart rootPart = parentgrp.RootPart;
@ -8043,7 +8109,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TYPE:
if (remain < 3)
return;
return null;
code = (int)rules.GetLSLIntegerItem(idx++);
@ -8062,7 +8128,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
case (int)ScriptBaseClass.PRIM_TYPE_BOX:
if (remain < 6)
return;
return null;
face = (int)rules.GetLSLIntegerItem(idx++);
v = rules.GetVector3Item(idx++); // cut
@ -8077,7 +8143,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
if (remain < 6)
return;
return null;
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
v = rules.GetVector3Item(idx++); // cut
@ -8091,7 +8157,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
if (remain < 6)
return;
return null;
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
v = rules.GetVector3Item(idx++); //cut
@ -8105,7 +8171,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
if (remain < 5)
return;
return null;
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
v = rules.GetVector3Item(idx++); // cut
@ -8118,7 +8184,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
if (remain < 11)
return;
return null;
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
v = rules.GetVector3Item(idx++); //cut
@ -8137,7 +8203,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
if (remain < 11)
return;
return null;
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
v = rules.GetVector3Item(idx++); //cut
@ -8156,7 +8222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TYPE_RING:
if (remain < 11)
return;
return null;
face = (int)rules.GetLSLIntegerItem(idx++); // holeshape
v = rules.GetVector3Item(idx++); //cut
@ -8175,7 +8241,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
if (remain < 2)
return;
return null;
string map = rules.Data[idx++].ToString();
face = (int)rules.GetLSLIntegerItem(idx++); // type
@ -8187,7 +8253,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TEXTURE:
if (remain < 5)
return;
return null;
face=(int)rules.GetLSLIntegerItem(idx++);
string tex=rules.Data[idx++].ToString();
@ -8204,7 +8270,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_COLOR:
if (remain < 3)
return;
return null;
face=(int)rules.GetLSLIntegerItem(idx++);
LSL_Vector color=rules.GetVector3Item(idx++);
@ -8217,7 +8283,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_FLEXIBLE:
if (remain < 7)
return;
return null;
bool flexi = rules.GetLSLIntegerItem(idx++);
int softness = rules.GetLSLIntegerItem(idx++);
@ -8233,7 +8299,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
if (remain < 5)
return;
return null;
bool light = rules.GetLSLIntegerItem(idx++);
LSL_Vector lightcolor = rules.GetVector3Item(idx++);
float intensity = (float)rules.GetLSLFloatItem(idx++);
@ -8246,7 +8312,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_GLOW:
if (remain < 2)
return;
return null;
face = rules.GetLSLIntegerItem(idx++);
float glow = (float)rules.GetLSLFloatItem(idx++);
@ -8256,7 +8322,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
if (remain < 3)
return;
return null;
face = (int)rules.GetLSLIntegerItem(idx++);
int shiny = (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:
if (remain < 2)
return;
return null;
face = rules.GetLSLIntegerItem(idx++);
bool st = rules.GetLSLIntegerItem(idx++);
SetFullBright(part, face , st);
@ -8275,17 +8341,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_MATERIAL:
if (remain < 1)
return;
return null;
int mat = rules.GetLSLIntegerItem(idx++);
if (mat < 0 || mat > 7)
return;
return null;
part.Material = Convert.ToByte(mat);
break;
case (int)ScriptBaseClass.PRIM_PHANTOM:
if (remain < 1)
return;
return null;
string ph = rules.Data[idx++].ToString();
parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
@ -8294,7 +8360,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_PHYSICS:
if (remain < 1)
return;
return null;
string phy = rules.Data[idx++].ToString();
bool physics;
@ -8308,7 +8374,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
if (remain < 1)
return;
return null;
int shape_type = rules.GetLSLIntegerItem(idx++);
@ -8324,7 +8390,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
if (remain < 5)
return;
return null;
int material_bits = rules.GetLSLIntegerItem(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:
if (remain < 1)
return;
return null;
string temp = rules.Data[idx++].ToString();
parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
@ -8347,7 +8413,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_TEXGEN:
if (remain < 2)
return;
return null;
//face,type
face = rules.GetLSLIntegerItem(idx++);
int style = rules.GetLSLIntegerItem(idx++);
@ -8355,7 +8421,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
break;
case (int)ScriptBaseClass.PRIM_TEXT:
if (remain < 3)
return;
return null;
string primText = rules.GetLSLStringItem(idx++);
LSL_Vector primTextColor = rules.GetVector3Item(idx++);
LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++);
@ -8367,26 +8433,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
break;
case (int)ScriptBaseClass.PRIM_NAME:
if (remain < 1)
return;
return null;
string primName = rules.GetLSLStringItem(idx++);
part.Name = primName;
break;
case (int)ScriptBaseClass.PRIM_DESC:
if (remain < 1)
return;
return null;
string primDesc = rules.GetLSLStringItem(idx++);
part.Description = primDesc;
break;
case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
if (remain < 1)
return;
return null;
LSL_Rotation lr = rules.GetQuaternionItem(idx++);
SetRot(part, Rot2Quaternion(lr));
break;
case (int)ScriptBaseClass.PRIM_OMEGA:
if (remain < 3)
return;
return null;
LSL_Vector axis = rules.GetVector3Item(idx++);
LSL_Float spinrate = 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:
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
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;
return rules.GetSublist(idx, -1);
}
}
}
@ -8447,6 +8486,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
}
}
return null;
}
public LSL_String llStringToBase64(string str)
@ -12082,7 +12122,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (obj.OwnerID != m_host.OwnerID)
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)

View File

@ -2466,8 +2466,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (!npcModule.CheckPermissions(npcId, m_host.OwnerID))
return new LSL_Vector(0, 0, 0);
Vector3 pos = World.GetScenePresence(npcId).AbsolutePosition;
return new LSL_Vector(pos.X, pos.Y, pos.Z);
ScenePresence sp = World.GetScenePresence(npcId);
if (sp != null)
{
Vector3 pos = sp.AbsolutePosition;
return new LSL_Vector(pos.X, pos.Y, pos.Z);
}
}
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);
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);
@ -2559,7 +2567,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return;
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");
m_host.AddScriptLPS(1);
INPCModule module = World.RequestModuleInterface<INPCModule>();
int linkNum = link_num.value;
if (module != null || (linkNum < 0 && linkNum != ScriptBaseClass.LINK_THIS))
@ -2744,12 +2755,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
UUID npcId;
if (!UUID.TryParse(npcLSL_Key, out npcId) || !module.CheckPermissions(npcId, m_host.OwnerID))
return;
SceneObjectPart part = null;
UUID objectId;
if (UUID.TryParse(LSL_String.ToString(object_key), out objectId))
part = World.GetSceneObjectPart(objectId);
if (part == null)
return;
if (linkNum != ScriptBaseClass.LINK_THIS)
{
if (linkNum == 0 || linkNum == ScriptBaseClass.LINK_ROOT)
@ -2764,6 +2778,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
return;
}
}
module.Touch(npcId, part.UUID);
}
}

View File

@ -226,6 +226,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public const int ATTACH_BELLY = 28;
public const int ATTACH_RPEC = 29;
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_TOP_RIGHT = 32;
public const int ATTACH_HUD_TOP_CENTER = 33;

View File

@ -64,6 +64,15 @@ namespace OpenSim.Services.AuthenticationService
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);
AuthenticationData data = m_Database.Get(principalID);
UserAccount user = null;
@ -127,6 +136,7 @@ namespace OpenSim.Services.AuthenticationService
if (data.Data["passwordHash"].ToString() == hashed)
{
m_log.DebugFormat("[PASS AUTH]: {0} {1} impersonating {2}, proceeding with login", a.FirstName, a.LastName, principalID);
realID = a.PrincipalID;
return GetToken(principalID, lifetime);
}
// else

View File

@ -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)
{
if (new UUID(password) == UUID.Zero)

View File

@ -54,6 +54,13 @@ namespace OpenSim.Services.AuthenticationService
}
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);
string result = String.Empty;
@ -62,7 +69,7 @@ namespace OpenSim.Services.AuthenticationService
if (data.Data.ContainsKey("webLoginKey"))
{
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)
{
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"))
{
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)
{
m_log.DebugFormat("[AUTH SERVICE]: Password login failed for PrincipalID {0}", principalID);
}
}
realID = UUID.Zero;
if (result == string.Empty)
{
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;
}
}
}
}

View File

@ -81,6 +81,13 @@ namespace OpenSim.Services.Connectors
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)
{
Dictionary<string, object> sendData = new Dictionary<string, object>();

View File

@ -102,6 +102,11 @@ namespace OpenSim.Services.Connectors.SimianGrid
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)
{
NameValueCollection requestArgs = new NameValueCollection

View File

@ -168,5 +168,20 @@ namespace OpenSim.Services.Connectors
{
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);
}
}
}

View File

@ -67,6 +67,7 @@ namespace OpenSim.Services.Interfaces
// various services.
//
string Authenticate(UUID principalID, string password, int lifetime);
string Authenticate(UUID principalID, string password, int lifetime, out UUID realID);
//////////////////////////////////////////////////////
// Verification

View File

@ -182,7 +182,8 @@ namespace OpenSim.Services.Interfaces
List<AvatarAttachment> attachments = appearance.GetAttachments();
foreach (AvatarAttachment attach in attachments)
{
Data["_ap_" + attach.AttachPoint] = attach.ItemID.ToString();
if (attach.ItemID != UUID.Zero)
Data["_ap_" + attach.AttachPoint] = attach.ItemID.ToString();
}
}

View File

@ -150,6 +150,7 @@ namespace OpenSim.Services.LLLoginService
private UUID agentID;
private UUID sessionID;
private UUID secureSessionID;
private UUID realID;
// Login Flags
private string dst;
@ -232,7 +233,7 @@ namespace OpenSim.Services.LLLoginService
GridRegion destination, List<InventoryFolderBase> invSkel, FriendInfo[] friendsList, ILibraryService libService,
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,
string DSTZone)
string DSTZone, UUID realID)
: this()
{
FillOutInventoryData(invSkel, libService);
@ -245,6 +246,7 @@ namespace OpenSim.Services.LLLoginService
AgentID = account.PrincipalID;
SessionID = aCircuit.SessionID;
SecureSessionID = aCircuit.SecureSessionID;
RealID = realID;
Message = message;
BuddList = ConvertFriendListItem(friendsList);
StartLocation = where;
@ -456,6 +458,7 @@ namespace OpenSim.Services.LLLoginService
SessionID = UUID.Random();
SecureSessionID = UUID.Random();
AgentID = UUID.Random();
RealID = UUID.Zero;
Hashtable InitialOutfitHash = new Hashtable();
InitialOutfitHash["folder_name"] = "Nightclub Female";
@ -499,6 +502,7 @@ namespace OpenSim.Services.LLLoginService
responseData["http_port"] = (Int32)SimHttpPort;
responseData["agent_id"] = AgentID.ToString();
responseData["real_id"] = RealID.ToString();
responseData["session_id"] = SessionID.ToString();
responseData["secure_session_id"] = SecureSessionID.ToString();
responseData["circuit_code"] = CircuitCode;
@ -581,6 +585,7 @@ namespace OpenSim.Services.LLLoginService
map["sim_ip"] = OSD.FromString(SimAddress);
map["agent_id"] = OSD.FromUUID(AgentID);
map["real_id"] = OSD.FromUUID(RealID);
map["session_id"] = OSD.FromUUID(SessionID);
map["secure_session_id"] = OSD.FromUUID(SecureSessionID);
map["circuit_code"] = OSD.FromInteger(CircuitCode);
@ -888,6 +893,12 @@ namespace OpenSim.Services.LLLoginService
set { secureSessionID = value; }
}
public UUID RealID
{
get { return realID; }
set { realID = value; }
}
public Int32 CircuitCode
{
get { return circuitCode; }

View File

@ -327,7 +327,8 @@ namespace OpenSim.Services.LLLoginService
if (!passwd.StartsWith("$1$"))
passwd = "$1$" + Util.Md5Hash(passwd);
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;
if ((token == string.Empty) || (token != string.Empty && !UUID.TryParse(token, out secureSession)))
{
@ -459,7 +460,7 @@ namespace OpenSim.Services.LLLoginService
= new LLLoginResponse(
account, aCircuit, guinfo, destination, inventorySkel, friendsList, m_LibraryService,
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);

View File

@ -132,6 +132,19 @@ namespace OpenSim.Data.Null
{
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>
@ -328,5 +341,18 @@ namespace OpenSim.Data.Null
{
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;
}
}
}

View File

@ -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
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
; ##
@ -341,27 +336,12 @@
; OpenJPEG if false
; UseCSJ2K = true
; Use "Trash" folder for items deleted from the scene
; 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
; False items will be removed from the scene permanently
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]
; 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
[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]
; Controls whether avatar attachments are enabled.
; Defaults to true - only set to false for debugging purposes
@ -892,7 +894,7 @@
AvatarDensity = 60.0
AvatarCapsuleRadius = 0.37
AvatarCapsuleHeight = 1.5
AvatarContactProcessingThreshold = 0.1;
AvatarContactProcessingThreshold = 0.1
MaxObjectMass = 10000.01
@ -906,19 +908,19 @@
CcdSweptSphereRadius = 0.0
ContactProcessingThreshold = 0.1
; If setting a pool size, also disable dynamic allocation (default pool size is 4096 with dynamic alloc)
MaxPersistantManifoldPoolSize = 0;
ShouldDisableContactPoolDynamicAllocation = False;
ShouldForceUpdateAllAabbs = False;
ShouldRandomizeSolverOrder = False;
ShouldSplitSimulationIslands = False;
ShouldEnableFrictionCaching = False;
MaxPersistantManifoldPoolSize = 0
ShouldDisableContactPoolDynamicAllocation = False
ShouldForceUpdateAllAabbs = False
ShouldRandomizeSolverOrder = False
ShouldSplitSimulationIslands = False
ShouldEnableFrictionCaching = False
NumberOfSolverIterations = 0;
; Linkset constraint parameters
LinkConstraintUseFrameOffset = False;
LinkConstraintEnableTransMotor = True;
LinkConstraintTransMotorMaxVel = 5.0;
LinkConstraintTransMotorMaxForce = 0.1;
LinkConstraintUseFrameOffset = False
LinkConstraintEnableTransMotor = True
LinkConstraintTransMotorMaxVel = 5.0
LinkConstraintTransMotorMaxForce = 0.1
; Whether to mesh sculpties
@ -933,11 +935,16 @@
SculptLevelOfDetail = 32
; Bullet step parameters
MaxSubSteps = 10;
MaxSubSteps = 10
FixedTimeStep = .01667
MaxCollisionsPerFrame = 2048
MaxUpdatesPerFrame = 2048
MaxUpdatesPerFrame = 8192
; Detailed physics debug logging
PhysicsLoggingEnabled = False
PhysicsLoggingDir = "."
VehicleLoggingEnabled = False
[RemoteAdmin]
enabled = false

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.