Merge branch 'master' of ssh://3dhosting.de/var/git/careminster
commit
fc1ac25935
|
@ -82,9 +82,11 @@ namespace OpenSim.ConsoleClient
|
|||
|
||||
private static void SendCommand(string module, string[] cmd)
|
||||
{
|
||||
string sendCmd = cmd[0];
|
||||
string sendCmd = "";
|
||||
if (cmd.Length > 1)
|
||||
{
|
||||
sendCmd = cmd[0];
|
||||
|
||||
Array.Copy(cmd, 1, cmd, 0, cmd.Length-1);
|
||||
Array.Resize(ref cmd, cmd.Length-1);
|
||||
sendCmd += "\"" + String.Join("\" \"", cmd) + "\"";
|
||||
|
|
|
@ -762,7 +762,7 @@ namespace Flotsam.RegionModules.AssetCache
|
|||
case "expire":
|
||||
|
||||
|
||||
if (cmdparams.Length >= 3)
|
||||
if (cmdparams.Length < 3)
|
||||
{
|
||||
m_log.InfoFormat("[FLOTSAM ASSET CACHE] Invalid parameters for Expire, please specify a valid date & time", cmd);
|
||||
break;
|
||||
|
|
|
@ -42,6 +42,7 @@ using OpenSim.Region.CoreModules.World.Terrain;
|
|||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
using OpenSim.Tests.Common.Setup;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
||||
|
@ -52,6 +53,20 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
|||
private Guid m_lastRequestId;
|
||||
private string m_lastErrorMessage;
|
||||
|
||||
protected TestScene m_scene;
|
||||
protected ArchiverModule m_archiverModule;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
m_archiverModule = new ArchiverModule();
|
||||
SerialiserModule serialiserModule = new SerialiserModule();
|
||||
TerrainModule terrainModule = new TerrainModule();
|
||||
|
||||
m_scene = SceneSetupHelpers.SetupScene("scene1");
|
||||
SceneSetupHelpers.SetupSceneModules(m_scene, m_archiverModule, serialiserModule, terrainModule);
|
||||
}
|
||||
|
||||
private void LoadCompleted(Guid requestId, string errorMessage)
|
||||
{
|
||||
lock (this)
|
||||
|
@ -75,6 +90,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
|||
}
|
||||
}
|
||||
|
||||
protected SceneObjectPart CreateSceneObjectPart1()
|
||||
{
|
||||
string partName = "My Little Pony";
|
||||
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000015");
|
||||
PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere();
|
||||
Vector3 groupPosition = new Vector3(10, 20, 30);
|
||||
Quaternion rotationOffset = new Quaternion(20, 30, 40, 50);
|
||||
Vector3 offsetPosition = new Vector3(5, 10, 15);
|
||||
|
||||
return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition) { Name = partName };
|
||||
}
|
||||
|
||||
protected SceneObjectPart CreateSceneObjectPart2()
|
||||
{
|
||||
string partName = "Action Man";
|
||||
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000016");
|
||||
PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder();
|
||||
Vector3 groupPosition = new Vector3(90, 80, 70);
|
||||
Quaternion rotationOffset = new Quaternion(60, 70, 80, 90);
|
||||
Vector3 offsetPosition = new Vector3(20, 25, 30);
|
||||
|
||||
return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition) { Name = partName };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test saving a V0.2 OpenSim Region Archive.
|
||||
/// </summary>
|
||||
|
@ -84,59 +123,20 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
|||
TestHelper.InMethod();
|
||||
//log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
ArchiverModule archiverModule = new ArchiverModule();
|
||||
SerialiserModule serialiserModule = new SerialiserModule();
|
||||
TerrainModule terrainModule = new TerrainModule();
|
||||
SceneObjectPart part1 = CreateSceneObjectPart1();
|
||||
m_scene.AddNewSceneObject(new SceneObjectGroup(part1), false);
|
||||
|
||||
Scene scene = SceneSetupHelpers.SetupScene("asset");
|
||||
SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
|
||||
|
||||
SceneObjectPart part1;
|
||||
|
||||
// Create and add prim 1
|
||||
{
|
||||
string partName = "My Little Pony";
|
||||
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000015");
|
||||
PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere();
|
||||
Vector3 groupPosition = new Vector3(10, 20, 30);
|
||||
Quaternion rotationOffset = new Quaternion(20, 30, 40, 50);
|
||||
Vector3 offsetPosition = new Vector3(5, 10, 15);
|
||||
|
||||
part1
|
||||
= new SceneObjectPart(
|
||||
ownerId, shape, groupPosition, rotationOffset, offsetPosition);
|
||||
part1.Name = partName;
|
||||
|
||||
scene.AddNewSceneObject(new SceneObjectGroup(part1), false);
|
||||
}
|
||||
|
||||
SceneObjectPart part2;
|
||||
|
||||
// Create and add prim 2
|
||||
{
|
||||
string partName = "Action Man";
|
||||
UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000016");
|
||||
PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder();
|
||||
Vector3 groupPosition = new Vector3(90, 80, 70);
|
||||
Quaternion rotationOffset = new Quaternion(60, 70, 80, 90);
|
||||
Vector3 offsetPosition = new Vector3(20, 25, 30);
|
||||
|
||||
part2
|
||||
= new SceneObjectPart(
|
||||
ownerId, shape, groupPosition, rotationOffset, offsetPosition);
|
||||
part2.Name = partName;
|
||||
|
||||
scene.AddNewSceneObject(new SceneObjectGroup(part2), false);
|
||||
}
|
||||
SceneObjectPart part2 = CreateSceneObjectPart2();
|
||||
m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false);
|
||||
|
||||
MemoryStream archiveWriteStream = new MemoryStream();
|
||||
scene.EventManager.OnOarFileSaved += SaveCompleted;
|
||||
m_scene.EventManager.OnOarFileSaved += SaveCompleted;
|
||||
|
||||
Guid requestId = new Guid("00000000-0000-0000-0000-808080808080");
|
||||
|
||||
lock (this)
|
||||
{
|
||||
archiverModule.ArchiveRegion(archiveWriteStream, requestId);
|
||||
m_archiverModule.ArchiveRegion(archiveWriteStream, requestId);
|
||||
//AssetServerBase assetServer = (AssetServerBase)scene.CommsManager.AssetCache.AssetServer;
|
||||
//while (assetServer.HasWaitingRequests())
|
||||
// assetServer.ProcessNextRequest();
|
||||
|
@ -218,25 +218,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
|||
|
||||
tar.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, ArchiveWriteRequestExecution.Create0p2ControlFile());
|
||||
|
||||
string part1Name = "object1";
|
||||
PrimitiveBaseShape shape = PrimitiveBaseShape.CreateCylinder();
|
||||
Vector3 groupPosition = new Vector3(90, 80, 70);
|
||||
Quaternion rotationOffset = new Quaternion(60, 70, 80, 90);
|
||||
Vector3 offsetPosition = new Vector3(20, 25, 30);
|
||||
|
||||
SerialiserModule serialiserModule = new SerialiserModule();
|
||||
ArchiverModule archiverModule = new ArchiverModule();
|
||||
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
|
||||
|
||||
SceneObjectPart part1
|
||||
= new SceneObjectPart(
|
||||
UUID.Zero, shape, groupPosition, rotationOffset, offsetPosition);
|
||||
part1.Name = part1Name;
|
||||
SceneObjectPart part1 = CreateSceneObjectPart1();
|
||||
SceneObjectGroup object1 = new SceneObjectGroup(part1);
|
||||
|
||||
// Let's put some inventory items into our object
|
||||
string soundItemName = "sound-item1";
|
||||
UUID soundItemUuid = UUID.Parse("00000000-0000-0000-0000-000000000002");
|
||||
Type type = GetType();
|
||||
Assembly assembly = type.Assembly;
|
||||
|
@ -269,17 +255,18 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
|||
asset1FileName = ArchiveConstants.ASSETS_PATH + soundUuid + ".wav";
|
||||
*/
|
||||
|
||||
TaskInventoryItem item1 = new TaskInventoryItem { AssetID = soundUuid, ItemID = soundItemUuid };
|
||||
TaskInventoryItem item1
|
||||
= new TaskInventoryItem { AssetID = soundUuid, ItemID = soundItemUuid, Name = soundItemName };
|
||||
part1.Inventory.AddInventoryItem(item1, true);
|
||||
}
|
||||
}
|
||||
|
||||
scene.AddNewSceneObject(object1, false);
|
||||
m_scene.AddNewSceneObject(object1, false);
|
||||
|
||||
string object1FileName = string.Format(
|
||||
"{0}_{1:000}-{2:000}-{3:000}__{4}.xml",
|
||||
part1Name,
|
||||
Math.Round(groupPosition.X), Math.Round(groupPosition.Y), Math.Round(groupPosition.Z),
|
||||
part1.Name,
|
||||
Math.Round(part1.GroupPosition.X), Math.Round(part1.GroupPosition.Y), Math.Round(part1.GroupPosition.Z),
|
||||
part1.UUID);
|
||||
tar.WriteFile(ArchiveConstants.OBJECTS_PATH + object1FileName, SceneObjectSerializer.ToXml2Format(object1));
|
||||
|
||||
|
@ -289,30 +276,27 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
|||
|
||||
lock (this)
|
||||
{
|
||||
scene.EventManager.OnOarFileLoaded += LoadCompleted;
|
||||
archiverModule.DearchiveRegion(archiveReadStream);
|
||||
m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
|
||||
m_archiverModule.DearchiveRegion(archiveReadStream);
|
||||
}
|
||||
|
||||
Assert.That(m_lastErrorMessage, Is.Null);
|
||||
|
||||
SceneObjectPart object1PartLoaded = scene.GetSceneObjectPart(part1Name);
|
||||
SceneObjectPart object1PartLoaded = m_scene.GetSceneObjectPart(part1.Name);
|
||||
|
||||
Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded");
|
||||
Assert.That(object1PartLoaded.Name, Is.EqualTo(part1Name), "object1 names not identical");
|
||||
Assert.That(object1PartLoaded.GroupPosition, Is.EqualTo(groupPosition), "object1 group position not equal");
|
||||
Assert.That(object1PartLoaded.Name, Is.EqualTo(part1.Name), "object1 names not identical");
|
||||
Assert.That(object1PartLoaded.GroupPosition, Is.EqualTo(part1.GroupPosition), "object1 group position not equal");
|
||||
Assert.That(
|
||||
object1PartLoaded.RotationOffset, Is.EqualTo(rotationOffset), "object1 rotation offset not equal");
|
||||
object1PartLoaded.RotationOffset, Is.EqualTo(part1.RotationOffset), "object1 rotation offset not equal");
|
||||
Assert.That(
|
||||
object1PartLoaded.OffsetPosition, Is.EqualTo(offsetPosition), "object1 offset position not equal");
|
||||
object1PartLoaded.OffsetPosition, Is.EqualTo(part1.OffsetPosition), "object1 offset position not equal");
|
||||
|
||||
// Need to implement a method to get the task inventory item by name (since the uuid will have changed on load)
|
||||
/*
|
||||
TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItem(soundItemUuid);
|
||||
TaskInventoryItem loadedSoundItem = object1PartLoaded.Inventory.GetInventoryItems(soundItemName)[0];
|
||||
Assert.That(loadedSoundItem, Is.Not.Null, "loaded sound item was null");
|
||||
AssetBase loadedSoundAsset = scene.AssetService.Get(loadedSoundItem.AssetID.ToString());
|
||||
AssetBase loadedSoundAsset = m_scene.AssetService.Get(loadedSoundItem.AssetID.ToString());
|
||||
Assert.That(loadedSoundAsset, Is.Not.Null, "loaded sound asset was null");
|
||||
Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match");
|
||||
*/
|
||||
|
||||
// Temporary
|
||||
Console.WriteLine("Successfully completed {0}", MethodBase.GetCurrentMethod());
|
||||
|
@ -327,11 +311,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
|||
TestHelper.InMethod();
|
||||
//log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
SerialiserModule serialiserModule = new SerialiserModule();
|
||||
ArchiverModule archiverModule = new ArchiverModule();
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule);
|
||||
|
||||
MemoryStream archiveWriteStream = new MemoryStream();
|
||||
TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
|
||||
|
||||
|
@ -377,12 +356,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
|||
|
||||
lock (this)
|
||||
{
|
||||
scene.EventManager.OnOarFileLoaded += LoadCompleted;
|
||||
archiverModule.DearchiveRegion(archiveReadStream);
|
||||
m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
|
||||
m_archiverModule.DearchiveRegion(archiveReadStream);
|
||||
}
|
||||
|
||||
Assert.That(m_lastErrorMessage, Is.Null);
|
||||
RegionSettings loadedRs = scene.RegionInfo.RegionSettings;
|
||||
RegionSettings loadedRs = m_scene.RegionInfo.RegionSettings;
|
||||
|
||||
Assert.That(loadedRs.AgentLimit, Is.EqualTo(17));
|
||||
Assert.That(loadedRs.AllowDamage, Is.True);
|
||||
|
@ -426,11 +405,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
|||
|
||||
MemoryStream archiveWriteStream = new MemoryStream();
|
||||
|
||||
string part2Name = "objectMerge";
|
||||
PrimitiveBaseShape part2Shape = PrimitiveBaseShape.CreateCylinder();
|
||||
Vector3 part2GroupPosition = new Vector3(90, 80, 70);
|
||||
Quaternion part2RotationOffset = new Quaternion(60, 70, 80, 90);
|
||||
Vector3 part2OffsetPosition = new Vector3(20, 25, 30);
|
||||
// string part2Name = "objectMerge";
|
||||
// PrimitiveBaseShape part2Shape = PrimitiveBaseShape.CreateCylinder();
|
||||
// Vector3 part2GroupPosition = new Vector3(90, 80, 70);
|
||||
// Quaternion part2RotationOffset = new Quaternion(60, 70, 80, 90);
|
||||
// Vector3 part2OffsetPosition = new Vector3(20, 25, 30);
|
||||
|
||||
SceneObjectPart part2 = CreateSceneObjectPart2();
|
||||
|
||||
// Create an oar file that we can use for the merge
|
||||
{
|
||||
|
@ -441,61 +422,37 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
|||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
|
||||
|
||||
SceneObjectPart part2
|
||||
= new SceneObjectPart(
|
||||
UUID.Zero, part2Shape, part2GroupPosition, part2RotationOffset, part2OffsetPosition);
|
||||
part2.Name = part2Name;
|
||||
SceneObjectGroup object2 = new SceneObjectGroup(part2);
|
||||
|
||||
scene.AddNewSceneObject(object2, false);
|
||||
m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false);
|
||||
|
||||
// Write out this scene
|
||||
scene.EventManager.OnOarFileSaved += SaveCompleted;
|
||||
|
||||
lock (this)
|
||||
{
|
||||
archiverModule.ArchiveRegion(archiveWriteStream);
|
||||
m_archiverModule.ArchiveRegion(archiveWriteStream);
|
||||
Monitor.Wait(this, 60000);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
ArchiverModule archiverModule = new ArchiverModule();
|
||||
SerialiserModule serialiserModule = new SerialiserModule();
|
||||
TerrainModule terrainModule = new TerrainModule();
|
||||
|
||||
Scene scene = SceneSetupHelpers.SetupScene();
|
||||
SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
|
||||
|
||||
string part1Name = "objectExisting";
|
||||
PrimitiveBaseShape part1Shape = PrimitiveBaseShape.CreateCylinder();
|
||||
Vector3 part1GroupPosition = new Vector3(80, 70, 60);
|
||||
Quaternion part1RotationOffset = new Quaternion(50, 60, 70, 80);
|
||||
Vector3 part1OffsetPosition = new Vector3(15, 20, 25);
|
||||
|
||||
SceneObjectPart part1
|
||||
= new SceneObjectPart(
|
||||
UUID.Zero, part1Shape, part1GroupPosition, part1RotationOffset, part1OffsetPosition);
|
||||
part1.Name = part1Name;
|
||||
SceneObjectGroup object1 = new SceneObjectGroup(part1);
|
||||
|
||||
scene.AddNewSceneObject(object1, false);
|
||||
SceneObjectPart part1 = CreateSceneObjectPart1();
|
||||
m_scene.AddNewSceneObject(new SceneObjectGroup(part1), false);
|
||||
|
||||
// Merge in the archive we created earlier
|
||||
byte[] archive = archiveWriteStream.ToArray();
|
||||
MemoryStream archiveReadStream = new MemoryStream(archive);
|
||||
|
||||
archiverModule.DearchiveRegion(archiveReadStream, true, Guid.Empty);
|
||||
m_archiverModule.DearchiveRegion(archiveReadStream, true, Guid.Empty);
|
||||
|
||||
SceneObjectPart object1Existing = scene.GetSceneObjectPart(part1Name);
|
||||
SceneObjectPart object1Existing = m_scene.GetSceneObjectPart(part1.Name);
|
||||
Assert.That(object1Existing, Is.Not.Null, "object1 was not present after merge");
|
||||
Assert.That(object1Existing.Name, Is.EqualTo(part1Name), "object1 names not identical after merge");
|
||||
Assert.That(object1Existing.GroupPosition, Is.EqualTo(part1GroupPosition), "object1 group position not equal after merge");
|
||||
Assert.That(object1Existing.Name, Is.EqualTo(part1.Name), "object1 names not identical after merge");
|
||||
Assert.That(object1Existing.GroupPosition, Is.EqualTo(part1.GroupPosition), "object1 group position not equal after merge");
|
||||
|
||||
SceneObjectPart object2PartMerged = scene.GetSceneObjectPart(part2Name);
|
||||
SceneObjectPart object2PartMerged = m_scene.GetSceneObjectPart(part2.Name);
|
||||
Assert.That(object2PartMerged, Is.Not.Null, "object2 was not present after merge");
|
||||
Assert.That(object2PartMerged.Name, Is.EqualTo(part2Name), "object2 names not identical after merge");
|
||||
Assert.That(object2PartMerged.GroupPosition, Is.EqualTo(part2GroupPosition), "object2 group position not equal after merge");
|
||||
Assert.That(object2PartMerged.Name, Is.EqualTo(part2.Name), "object2 names not identical after merge");
|
||||
Assert.That(object2PartMerged.GroupPosition, Is.EqualTo(part2.GroupPosition), "object2 group position not equal after merge");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,8 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
/// <summary>
|
||||
/// Start all the scripts contained in this entity's inventory
|
||||
/// </summary>
|
||||
void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource);
|
||||
void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource);
|
||||
|
||||
ArrayList GetScriptErrors(UUID itemID);
|
||||
|
||||
/// <summary>
|
||||
|
@ -142,6 +143,16 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
/// <returns>null if the item does not exist</returns>
|
||||
TaskInventoryItem GetInventoryItem(UUID itemId);
|
||||
|
||||
/// <summary>
|
||||
/// Get inventory items by name.
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns>
|
||||
/// A list of inventory items with that name.
|
||||
/// If no inventory item has that name then an empty list is returned.
|
||||
/// </returns>
|
||||
IList<TaskInventoryItem> GetInventoryItems(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Update an existing inventory item.
|
||||
/// </summary>
|
||||
|
|
|
@ -49,10 +49,49 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
|
||||
public interface IWorldComm
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a listen event callback with the specified filters.
|
||||
/// The parameters localID,itemID are needed to uniquely identify
|
||||
/// the script during 'peek' time. Parameter hostID is needed to
|
||||
/// determine the position of the script.
|
||||
/// </summary>
|
||||
/// <param name="localID">localID of the script engine</param>
|
||||
/// <param name="itemID">UUID of the script engine</param>
|
||||
/// <param name="hostID">UUID of the SceneObjectPart</param>
|
||||
/// <param name="channel">channel to listen on</param>
|
||||
/// <param name="name">name to filter on</param>
|
||||
/// <param name="id">key to filter on (user given, could be totally faked)</param>
|
||||
/// <param name="msg">msg to filter on</param>
|
||||
/// <returns>number of the scripts handle</returns>
|
||||
int Listen(uint LocalID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg);
|
||||
|
||||
/// <summary>
|
||||
/// This method scans over the objects which registered an interest in listen callbacks.
|
||||
/// For everyone it finds, it checks if it fits the given filter. If it does, then
|
||||
/// enqueue the message for delivery to the objects listen event handler.
|
||||
/// The enqueued ListenerInfo no longer has filter values, but the actually trigged values.
|
||||
/// Objects that do an llSay have their messages delivered here and for nearby avatars,
|
||||
/// the OnChatFromClient event is used.
|
||||
/// </summary>
|
||||
/// <param name="type">type of delvery (whisper,say,shout or regionwide)</param>
|
||||
/// <param name="channel">channel to sent on</param>
|
||||
/// <param name="name">name of sender (object or avatar)</param>
|
||||
/// <param name="id">key of sender (object or avatar)</param>
|
||||
/// <param name="msg">msg to sent</param>
|
||||
void DeliverMessage(ChatTypeEnum type, int channel, string name, UUID id, string msg);
|
||||
|
||||
/// <summary>
|
||||
/// Are there any listen events ready to be dispatched?
|
||||
/// </summary>
|
||||
/// <returns>boolean indication</returns>
|
||||
bool HasMessages();
|
||||
|
||||
/// <summary>
|
||||
/// Pop the first availlable listen event from the queue
|
||||
/// </summary>
|
||||
/// <returns>ListenerInfo with filter filled in</returns>
|
||||
IWorldCommListenerInfo GetNextMessage();
|
||||
|
||||
void ListenControl(UUID itemID, int handle, int active);
|
||||
void ListenRemove(UUID itemID, int handle);
|
||||
void DeleteListener(UUID itemID);
|
||||
|
|
|
@ -93,7 +93,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
public event OnShutdownDelegate OnShutdown;
|
||||
|
||||
public delegate void ObjectGrabDelegate(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs);
|
||||
public delegate void ObjectDeGrabDelegate(uint localID, uint originalID, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs);
|
||||
public delegate void ScriptResetDelegate(uint localID, UUID itemID);
|
||||
|
||||
|
@ -103,62 +102,57 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
public event OnSetRootAgentSceneDelegate OnSetRootAgentScene;
|
||||
|
||||
/// <summary>
|
||||
/// Called when an object is touched/grabbed.
|
||||
/// </summary>
|
||||
/// The originalID is the local ID of the part that was actually touched. The localID itself is always that of
|
||||
/// the root part.
|
||||
public delegate void ObjectGrabDelegate(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs);
|
||||
public event ObjectGrabDelegate OnObjectGrab;
|
||||
|
||||
public event ObjectGrabDelegate OnObjectGrabbing;
|
||||
public event ObjectDeGrabDelegate OnObjectDeGrab;
|
||||
public event ScriptResetDelegate OnScriptReset;
|
||||
|
||||
public event OnPermissionErrorDelegate OnPermissionError;
|
||||
|
||||
public delegate void NewRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource);
|
||||
|
||||
public event NewRezScript OnRezScript;
|
||||
|
||||
public delegate void RemoveScript(uint localID, UUID itemID);
|
||||
|
||||
public event RemoveScript OnRemoveScript;
|
||||
|
||||
public delegate void StartScript(uint localID, UUID itemID);
|
||||
|
||||
public event StartScript OnStartScript;
|
||||
|
||||
public delegate void StopScript(uint localID, UUID itemID);
|
||||
|
||||
public event StopScript OnStopScript;
|
||||
|
||||
public delegate bool SceneGroupMoved(UUID groupID, Vector3 delta);
|
||||
|
||||
public event SceneGroupMoved OnSceneGroupMove;
|
||||
|
||||
public delegate void SceneGroupGrabed(UUID groupID, Vector3 offset, UUID userID);
|
||||
|
||||
public event SceneGroupGrabed OnSceneGroupGrab;
|
||||
|
||||
public delegate bool SceneGroupSpinStarted(UUID groupID);
|
||||
|
||||
public event SceneGroupSpinStarted OnSceneGroupSpinStart;
|
||||
|
||||
public delegate bool SceneGroupSpun(UUID groupID, Quaternion rotation);
|
||||
|
||||
public event SceneGroupSpun OnSceneGroupSpin;
|
||||
|
||||
public delegate void LandObjectAdded(ILandObject newParcel);
|
||||
|
||||
public event LandObjectAdded OnLandObjectAdded;
|
||||
|
||||
public delegate void LandObjectRemoved(UUID globalID);
|
||||
|
||||
public event LandObjectRemoved OnLandObjectRemoved;
|
||||
|
||||
public delegate void AvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID);
|
||||
|
||||
public event AvatarEnteringNewParcel OnAvatarEnteringNewParcel;
|
||||
|
||||
public delegate void SignificantClientMovement(IClientAPI remote_client);
|
||||
|
||||
public event SignificantClientMovement OnSignificantClientMovement;
|
||||
|
||||
public delegate void IncomingInstantMessage(GridInstantMessage message);
|
||||
|
||||
public event IncomingInstantMessage OnIncomingInstantMessage;
|
||||
|
||||
public event IncomingInstantMessage OnUnhandledInstantMessage;
|
||||
|
@ -316,9 +310,10 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
public event EmptyScriptCompileQueue OnEmptyScriptCompileQueue;
|
||||
|
||||
/// <summary>
|
||||
/// Called whenever an object is attached, or detached
|
||||
/// from an in-world presence.
|
||||
/// Called whenever an object is attached, or detached from an in-world presence.
|
||||
/// </summary>
|
||||
/// If the object is being attached, then the avatarID will be present. If the object is being detached then
|
||||
/// the avatarID is UUID.Zero (I know, this doesn't make much sense but now it's historical).
|
||||
public delegate void Attach(uint localID, UUID itemID, UUID avatarID);
|
||||
public event Attach OnAttach;
|
||||
|
||||
|
@ -412,6 +407,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
private OnParcelPrimCountAddDelegate handlerParcelPrimCountAdd = null; //OnParcelPrimCountAdd;
|
||||
private OnShutdownDelegate handlerShutdown = null; //OnShutdown;
|
||||
private ObjectGrabDelegate handlerObjectGrab = null; //OnObjectGrab;
|
||||
private ObjectGrabDelegate handlerObjectGrabbing = null; //OnObjectGrabbing;
|
||||
private ObjectDeGrabDelegate handlerObjectDeGrab = null; //OnObjectDeGrab;
|
||||
private ScriptResetDelegate handlerScriptReset = null; // OnScriptReset
|
||||
private NewRezScript handlerRezScript = null; //OnRezScript;
|
||||
|
@ -626,6 +622,15 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
public void TriggerObjectGrabbing(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
|
||||
{
|
||||
handlerObjectGrabbing = OnObjectGrabbing;
|
||||
if (handlerObjectGrabbing != null)
|
||||
{
|
||||
handlerObjectGrabbing(localID, originalID, offsetPos, remoteClient, surfaceArgs);
|
||||
}
|
||||
}
|
||||
|
||||
public void TriggerObjectDeGrab(uint localID, uint originalID, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
|
||||
{
|
||||
handlerObjectDeGrab = OnObjectDeGrab;
|
||||
|
|
|
@ -2385,9 +2385,19 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
public void AttachObject(IClientAPI controllingClient, uint localID, uint attachPoint, Quaternion rot, Vector3 pos, bool silent)
|
||||
/// <summary>
|
||||
/// Attach an object.
|
||||
/// </summary>
|
||||
/// <param name="controllingClient"></param>
|
||||
/// <param name="localID"></param>
|
||||
/// <param name="attachPoint"></param>
|
||||
/// <param name="rot"></param>
|
||||
/// <param name="pos"></param>
|
||||
/// <param name="silent"></param>
|
||||
/// <returns>true if the object was successfully attached, false otherwise</returns>
|
||||
public bool AttachObject(IClientAPI controllingClient, uint localID, uint attachPoint, Quaternion rot, Vector3 pos, bool silent)
|
||||
{
|
||||
m_sceneGraph.AttachObject(controllingClient, localID, attachPoint, rot, pos, silent);
|
||||
return m_sceneGraph.AttachObject(controllingClient, localID, attachPoint, rot, pos, silent);
|
||||
}
|
||||
|
||||
public void AttachObject(IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
|
||||
|
|
|
@ -292,6 +292,46 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
public virtual void ProcessObjectGrabUpdate(UUID objectID, Vector3 offset, Vector3 pos, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs)
|
||||
{
|
||||
List<EntityBase> EntityList = GetEntities();
|
||||
|
||||
SurfaceTouchEventArgs surfaceArg = null;
|
||||
if (surfaceArgs != null && surfaceArgs.Count > 0)
|
||||
surfaceArg = surfaceArgs[0];
|
||||
|
||||
foreach (EntityBase ent in EntityList)
|
||||
{
|
||||
if (ent is SceneObjectGroup)
|
||||
{
|
||||
SceneObjectGroup obj = ent as SceneObjectGroup;
|
||||
if (obj != null)
|
||||
{
|
||||
// Is this prim part of the group
|
||||
if (obj.HasChildPrim(objectID))
|
||||
{
|
||||
SceneObjectPart part = obj.GetChildPart(objectID);
|
||||
|
||||
// If the touched prim handles touches, deliver it
|
||||
// If not, deliver to root prim
|
||||
if ((part.ScriptEvents & scriptEvents.touch) != 0)
|
||||
EventManager.TriggerObjectGrabbing(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg);
|
||||
// Deliver to the root prim if the touched prim doesn't handle touches
|
||||
// or if we're meant to pass on touches anyway. Don't send to root prim
|
||||
// if prim touched is the root prim as we just did it
|
||||
if (((part.ScriptEvents & scriptEvents.touch) == 0) ||
|
||||
(part.PassTouches && (part.LocalId != obj.RootPart.LocalId)))
|
||||
{
|
||||
EventManager.TriggerObjectGrabbing(obj.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ProcessObjectDeGrab(uint localID, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs)
|
||||
{
|
||||
List<EntityBase> EntityList = GetEntities();
|
||||
|
|
|
@ -2702,6 +2702,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
client.OnRequestObjectPropertiesFamily += m_sceneGraph.RequestObjectPropertiesFamily;
|
||||
client.OnObjectPermissions += HandleObjectPermissionsUpdate;
|
||||
client.OnGrabObject += ProcessObjectGrab;
|
||||
client.OnGrabUpdate += ProcessObjectGrabUpdate;
|
||||
client.OnDeGrabObject += ProcessObjectDeGrab;
|
||||
client.OnUndo += m_sceneGraph.HandleUndo;
|
||||
client.OnObjectDescription += m_sceneGraph.PrimDescription;
|
||||
|
|
|
@ -502,46 +502,62 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
if (part == null)
|
||||
return;
|
||||
|
||||
if (!m_parentScene.Permissions.CanTakeObject(
|
||||
part.UUID, remoteClient.AgentId))
|
||||
if (!m_parentScene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId))
|
||||
return;
|
||||
|
||||
// Calls attach with a Zero position
|
||||
AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false);
|
||||
m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
|
||||
|
||||
// Save avatar attachment information
|
||||
ScenePresence presence;
|
||||
if (m_parentScene.AvatarFactory != null && m_parentScene.TryGetAvatar(remoteClient.AgentId, out presence))
|
||||
if (AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false))
|
||||
{
|
||||
m_log.Info("[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + ", AttachmentPoint: " + AttachmentPt);
|
||||
m_parentScene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
|
||||
m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
|
||||
|
||||
// Save avatar attachment information
|
||||
ScenePresence presence;
|
||||
if (m_parentScene.AvatarFactory != null && m_parentScene.TryGetAvatar(remoteClient.AgentId, out presence))
|
||||
{
|
||||
m_log.Info(
|
||||
"[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
|
||||
+ ", AttachmentPoint: " + AttachmentPt);
|
||||
|
||||
m_parentScene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SceneObjectGroup RezSingleAttachment(
|
||||
IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
|
||||
/// <summary>
|
||||
/// Rez an attachment
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="itemID"></param>
|
||||
/// <param name="AttachmentPt"></param>
|
||||
/// <returns>The scene object that was attached. Null if the scene object could not be found</returns>
|
||||
public SceneObjectGroup RezSingleAttachment(IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
|
||||
{
|
||||
SceneObjectGroup objatt = m_parentScene.RezObject(remoteClient,
|
||||
itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
|
||||
false, false, remoteClient.AgentId, true);
|
||||
|
||||
|
||||
if (objatt != null)
|
||||
{
|
||||
bool tainted = false;
|
||||
if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint())
|
||||
tainted = true;
|
||||
|
||||
AttachObject(remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false);
|
||||
objatt.ScheduleGroupForFullUpdate();
|
||||
if (tainted)
|
||||
objatt.HasGroupChanged = true;
|
||||
if (AttachObject(
|
||||
remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false))
|
||||
{
|
||||
objatt.ScheduleGroupForFullUpdate();
|
||||
if (tainted)
|
||||
objatt.HasGroupChanged = true;
|
||||
|
||||
// Fire after attach, so we don't get messy perms dialogs
|
||||
// 3 == AttachedRez
|
||||
objatt.CreateScriptInstances(0, true, m_parentScene.DefaultScriptEngine, 3);
|
||||
// Fire after attach, so we don't get messy perms dialogs
|
||||
// 3 == AttachedRez
|
||||
objatt.CreateScriptInstances(0, true, m_parentScene.DefaultScriptEngine, 3);
|
||||
|
||||
// Do this last so that event listeners have access to all the effects of the attachment
|
||||
m_parentScene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId);
|
||||
}
|
||||
}
|
||||
|
||||
return objatt;
|
||||
}
|
||||
|
||||
|
@ -590,7 +606,17 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
protected internal void AttachObject(
|
||||
/// <summary>
|
||||
/// Attach a scene object to an avatar.
|
||||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="objectLocalID"></param>
|
||||
/// <param name="AttachmentPt"></param>
|
||||
/// <param name="rot"></param>
|
||||
/// <param name="attachPos"></param>
|
||||
/// <param name="silent"></param>
|
||||
/// <returns>true if the attachment was successful, false otherwise</returns>
|
||||
protected internal bool AttachObject(
|
||||
IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent)
|
||||
{
|
||||
SceneObjectGroup group = GetGroupByPrim(objectLocalID);
|
||||
|
@ -619,10 +645,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
// Stick it on left hand with Zero Offset from the attachment point.
|
||||
AttachmentPt = (uint)AttachmentPoint.LeftHand;
|
||||
attachPos = Vector3.Zero;
|
||||
|
||||
}
|
||||
|
||||
|
||||
group.SetAttachmentPoint((byte)AttachmentPt);
|
||||
group.AbsolutePosition = attachPos;
|
||||
|
||||
|
@ -650,10 +674,16 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
else
|
||||
{
|
||||
remoteClient.SendAgentAlertMessage("You don't have sufficient permissions to attach this object", false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[SCENE GRAPH]: AttachObject found no such scene object {0}", objectLocalID);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance)
|
||||
|
|
|
@ -301,6 +301,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
set { m_rootPart.GroupID = value; }
|
||||
}
|
||||
|
||||
/// <value>
|
||||
/// The parts of this scene object group. You must lock this property before using it.
|
||||
/// </value>
|
||||
public Dictionary<UUID, SceneObjectPart> Children
|
||||
{
|
||||
get { return m_parts; }
|
||||
|
@ -2239,7 +2242,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a child part with a given UUID
|
||||
/// Get a part with a given UUID
|
||||
/// </summary>
|
||||
/// <param name="primID"></param>
|
||||
/// <returns>null if a child part with the primID was not found</returns>
|
||||
|
@ -2254,7 +2257,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a child part with a given local ID
|
||||
/// Get a part with a given local ID
|
||||
/// </summary>
|
||||
/// <param name="localID"></param>
|
||||
/// <returns>null if a child part with the local ID was not found</returns>
|
||||
|
|
|
@ -90,10 +90,27 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
SCALE = 0x40
|
||||
}
|
||||
|
||||
public enum PrimType : int
|
||||
{
|
||||
BOX = 0,
|
||||
CYLINDER = 1,
|
||||
PRISM = 2,
|
||||
SPHERE = 3,
|
||||
TORUS = 4,
|
||||
TUBE = 5,
|
||||
RING = 6,
|
||||
SCULPT = 7
|
||||
}
|
||||
|
||||
#endregion Enumerations
|
||||
|
||||
public class SceneObjectPart : IScriptHost
|
||||
{
|
||||
/// <value>
|
||||
/// Denote all sides of the prim
|
||||
/// </value>
|
||||
public const int ALL_SIDES = -1;
|
||||
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
// use only one serializer to give the runtime a chance to optimize it (it won't do that if you
|
||||
|
@ -741,6 +758,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
/// <value>
|
||||
/// Text color.
|
||||
/// </value>
|
||||
public Color Color
|
||||
{
|
||||
get { return m_color; }
|
||||
|
@ -1910,7 +1930,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
foreach (uint localId in startedColliders)
|
||||
{
|
||||
if (localId == 0)
|
||||
return;
|
||||
continue;
|
||||
// always running this check because if the user deletes the object it would return a null reference.
|
||||
if (m_parentGroup == null)
|
||||
return;
|
||||
|
@ -2046,7 +2066,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
{
|
||||
// always running this check because if the user deletes the object it would return a null reference.
|
||||
if (localId == 0)
|
||||
return;
|
||||
continue;
|
||||
|
||||
if (m_parentGroup == null)
|
||||
return;
|
||||
|
@ -2178,7 +2198,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
foreach (uint localId in endedColliders)
|
||||
{
|
||||
if (localId == 0)
|
||||
return;
|
||||
continue;
|
||||
|
||||
// always running this check because if the user deletes the object it would return a null reference.
|
||||
if (m_parentGroup == null)
|
||||
|
@ -2982,6 +3002,178 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the color of prim faces
|
||||
/// </summary>
|
||||
/// <param name="color"></param>
|
||||
/// <param name="face"></param>
|
||||
public void SetFaceColor(Vector3 color, int face)
|
||||
{
|
||||
Primitive.TextureEntry tex = Shape.Textures;
|
||||
Color4 texcolor;
|
||||
if (face >= 0 && face < GetNumberOfSides())
|
||||
{
|
||||
texcolor = tex.CreateFace((uint)face).RGBA;
|
||||
texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f);
|
||||
texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f);
|
||||
texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f);
|
||||
tex.FaceTextures[face].RGBA = texcolor;
|
||||
UpdateTexture(tex);
|
||||
return;
|
||||
}
|
||||
else if (face == ALL_SIDES)
|
||||
{
|
||||
for (uint i = 0; i < GetNumberOfSides(); i++)
|
||||
{
|
||||
if (tex.FaceTextures[i] != null)
|
||||
{
|
||||
texcolor = tex.FaceTextures[i].RGBA;
|
||||
texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f);
|
||||
texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f);
|
||||
texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f);
|
||||
tex.FaceTextures[i].RGBA = texcolor;
|
||||
}
|
||||
texcolor = tex.DefaultTexture.RGBA;
|
||||
texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f);
|
||||
texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f);
|
||||
texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f);
|
||||
tex.DefaultTexture.RGBA = texcolor;
|
||||
}
|
||||
UpdateTexture(tex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the number of sides that this part has.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public int GetNumberOfSides()
|
||||
{
|
||||
int ret = 0;
|
||||
bool hasCut;
|
||||
bool hasHollow;
|
||||
bool hasDimple;
|
||||
bool hasProfileCut;
|
||||
|
||||
PrimType primType = GetPrimType();
|
||||
HasCutHollowDimpleProfileCut(primType, Shape, out hasCut, out hasHollow, out hasDimple, out hasProfileCut);
|
||||
|
||||
switch (primType)
|
||||
{
|
||||
case PrimType.BOX:
|
||||
ret = 6;
|
||||
if (hasCut) ret += 2;
|
||||
if (hasHollow) ret += 1;
|
||||
break;
|
||||
case PrimType.CYLINDER:
|
||||
ret = 3;
|
||||
if (hasCut) ret += 2;
|
||||
if (hasHollow) ret += 1;
|
||||
break;
|
||||
case PrimType.PRISM:
|
||||
ret = 5;
|
||||
if (hasCut) ret += 2;
|
||||
if (hasHollow) ret += 1;
|
||||
break;
|
||||
case PrimType.SPHERE:
|
||||
ret = 1;
|
||||
if (hasCut) ret += 2;
|
||||
if (hasDimple) ret += 2;
|
||||
if (hasHollow) ret += 1;
|
||||
break;
|
||||
case PrimType.TORUS:
|
||||
ret = 1;
|
||||
if (hasCut) ret += 2;
|
||||
if (hasProfileCut) ret += 2;
|
||||
if (hasHollow) ret += 1;
|
||||
break;
|
||||
case PrimType.TUBE:
|
||||
ret = 4;
|
||||
if (hasCut) ret += 2;
|
||||
if (hasProfileCut) ret += 2;
|
||||
if (hasHollow) ret += 1;
|
||||
break;
|
||||
case PrimType.RING:
|
||||
ret = 3;
|
||||
if (hasCut) ret += 2;
|
||||
if (hasProfileCut) ret += 2;
|
||||
if (hasHollow) ret += 1;
|
||||
break;
|
||||
case PrimType.SCULPT:
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tell us what type this prim is
|
||||
/// </summary>
|
||||
/// <param name="primShape"></param>
|
||||
/// <returns></returns>
|
||||
public PrimType GetPrimType()
|
||||
{
|
||||
if (Shape.SculptEntry)
|
||||
return PrimType.SCULPT;
|
||||
if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
|
||||
{
|
||||
if (Shape.PathCurve == (byte)Extrusion.Straight)
|
||||
return PrimType.BOX;
|
||||
else if (Shape.PathCurve == (byte)Extrusion.Curve1)
|
||||
return PrimType.TUBE;
|
||||
}
|
||||
else if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
|
||||
{
|
||||
if (Shape.PathCurve == (byte)Extrusion.Straight)
|
||||
return PrimType.CYLINDER;
|
||||
// ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
|
||||
else if (Shape.PathCurve == (byte)Extrusion.Curve1)
|
||||
return PrimType.TORUS;
|
||||
}
|
||||
else if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
|
||||
{
|
||||
if (Shape.PathCurve == (byte)Extrusion.Curve1 || Shape.PathCurve == (byte)Extrusion.Curve2)
|
||||
return PrimType.SPHERE;
|
||||
}
|
||||
else if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
|
||||
{
|
||||
if (Shape.PathCurve == (byte)Extrusion.Straight)
|
||||
return PrimType.PRISM;
|
||||
else if (Shape.PathCurve == (byte)Extrusion.Curve1)
|
||||
return PrimType.RING;
|
||||
}
|
||||
|
||||
return PrimType.BOX;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tell us if this object has cut, hollow, dimple, and other factors affecting the number of faces
|
||||
/// </summary>
|
||||
/// <param name="primType"></param>
|
||||
/// <param name="shape"></param>
|
||||
/// <param name="hasCut"></param>
|
||||
/// <param name="hasHollow"></param>
|
||||
/// <param name="hasDimple"></param>
|
||||
/// <param name="hasProfileCut"></param>
|
||||
protected static void HasCutHollowDimpleProfileCut(PrimType primType, PrimitiveBaseShape shape, out bool hasCut, out bool hasHollow,
|
||||
out bool hasDimple, out bool hasProfileCut)
|
||||
{
|
||||
if (primType == PrimType.BOX
|
||||
||
|
||||
primType == PrimType.CYLINDER
|
||||
||
|
||||
primType == PrimType.PRISM)
|
||||
|
||||
hasCut = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0);
|
||||
else
|
||||
hasCut = (shape.PathBegin > 0) || (shape.PathEnd > 0);
|
||||
|
||||
hasHollow = shape.ProfileHollow > 0;
|
||||
hasDimple = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0); // taken from llSetPrimitiveParms
|
||||
hasProfileCut = hasDimple; // is it the same thing?
|
||||
}
|
||||
|
||||
public void SetGroup(UUID groupID, IClientAPI client)
|
||||
{
|
||||
_groupID = groupID;
|
||||
|
@ -3013,6 +3205,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the events that this part will pass on to listeners.
|
||||
/// </summary>
|
||||
/// <param name="scriptid"></param>
|
||||
/// <param name="events"></param>
|
||||
public void SetScriptEvents(UUID scriptid, int events)
|
||||
{
|
||||
// scriptEvents oldparts;
|
||||
|
|
|
@ -587,6 +587,30 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
return item;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get inventory items by name.
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns>
|
||||
/// A list of inventory items with that name.
|
||||
/// If no inventory item has that name then an empty list is returned.
|
||||
/// </returns>
|
||||
public IList<TaskInventoryItem> GetInventoryItems(string name)
|
||||
{
|
||||
IList<TaskInventoryItem> items = new List<TaskInventoryItem>();
|
||||
|
||||
lock (m_items)
|
||||
{
|
||||
foreach (TaskInventoryItem item in m_items.Values)
|
||||
{
|
||||
if (item.Name == name)
|
||||
items.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update an existing inventory item.
|
||||
/// </summary>
|
||||
|
|
|
@ -116,7 +116,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
|
|||
|
||||
static string ConvertMRMKeywords(string script)
|
||||
{
|
||||
script = script.Replace("microthreaded void ", "IEnumerable");
|
||||
script = script.Replace("microthreaded void", "IEnumerable");
|
||||
script = script.Replace("relax;", "yield return null;");
|
||||
|
||||
return script;
|
||||
|
|
|
@ -54,8 +54,8 @@ using OpenSim.Region.ScriptEngine.Interfaces;
|
|||
using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
using PrimType = OpenSim.Region.Framework.Scenes.PrimType;
|
||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||
|
||||
using AssetLandmark = OpenSim.Framework.AssetLandmark;
|
||||
|
||||
using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
|
||||
|
@ -1442,6 +1442,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
part.UpdateTexture(tex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (face == ScriptBaseClass.ALL_SIDES)
|
||||
face = SceneObjectPart.ALL_SIDES;
|
||||
|
||||
m_host.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
|
||||
}
|
||||
|
||||
public void SetTexGen(SceneObjectPart part, int face,int style)
|
||||
|
@ -1599,7 +1604,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
{
|
||||
int i;
|
||||
double sum = 0.0;
|
||||
for (i = 0 ; i < GetNumberOfSides(part) ; i++)
|
||||
for (i = 0 ; i < GetNumberOfSides(part); i++)
|
||||
sum += (double)tex.GetFace((uint)i).RGBA.A;
|
||||
return sum;
|
||||
}
|
||||
|
@ -1749,7 +1754,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < GetNumberOfSides(part) ; i++)
|
||||
for (i = 0 ; i < GetNumberOfSides(part); i++)
|
||||
{
|
||||
texcolor = tex.GetFace((uint)i).RGBA;
|
||||
rgb.x += texcolor.R;
|
||||
|
@ -3568,7 +3573,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
List<SceneObjectPart> parts = GetLinkParts(linknumber);
|
||||
|
||||
foreach (SceneObjectPart part in parts)
|
||||
SetColor(part, color, face);
|
||||
part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
|
||||
}
|
||||
|
||||
public void llCreateLink(string target, int parent)
|
||||
|
@ -4423,63 +4428,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
return result;
|
||||
}
|
||||
|
||||
// this function to understand which shape it is (taken from meshmerizer)
|
||||
// quite useful can be used by meshmerizer to have a centralized point of understanding the shape
|
||||
// except that it refers to scripting constants
|
||||
public int getScriptPrimType(PrimitiveBaseShape primShape)
|
||||
{
|
||||
if (primShape.SculptEntry)
|
||||
return ScriptBaseClass.PRIM_TYPE_SCULPT;
|
||||
if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
|
||||
{
|
||||
if (primShape.PathCurve == (byte)Extrusion.Straight)
|
||||
return ScriptBaseClass.PRIM_TYPE_BOX;
|
||||
else if (primShape.PathCurve == (byte)Extrusion.Curve1)
|
||||
return ScriptBaseClass.PRIM_TYPE_TUBE;
|
||||
}
|
||||
else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
|
||||
{
|
||||
if (primShape.PathCurve == (byte)Extrusion.Straight)
|
||||
return ScriptBaseClass.PRIM_TYPE_CYLINDER;
|
||||
// ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
|
||||
else if (primShape.PathCurve == (byte)Extrusion.Curve1)
|
||||
return ScriptBaseClass.PRIM_TYPE_TORUS;
|
||||
}
|
||||
else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
|
||||
{
|
||||
if (primShape.PathCurve == (byte)Extrusion.Curve1 || primShape.PathCurve == (byte)Extrusion.Curve2)
|
||||
return ScriptBaseClass.PRIM_TYPE_SPHERE;
|
||||
}
|
||||
else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
|
||||
{
|
||||
if (primShape.PathCurve == (byte)Extrusion.Straight)
|
||||
return ScriptBaseClass.PRIM_TYPE_PRISM;
|
||||
else if (primShape.PathCurve == (byte)Extrusion.Curve1)
|
||||
return ScriptBaseClass.PRIM_TYPE_RING;
|
||||
}
|
||||
return ScriptBaseClass.PRIM_TYPE_BOX;
|
||||
}
|
||||
|
||||
// Helper functions to understand if object has cut, hollow, dimple, and other affecting number of faces
|
||||
protected void hasCutHollowDimpleProfileCut(int primType, PrimitiveBaseShape shape, out bool hasCut, out bool hasHollow,
|
||||
out bool hasDimple, out bool hasProfileCut)
|
||||
{
|
||||
if (primType == ScriptBaseClass.PRIM_TYPE_BOX
|
||||
||
|
||||
primType == ScriptBaseClass.PRIM_TYPE_CYLINDER
|
||||
||
|
||||
primType == ScriptBaseClass.PRIM_TYPE_PRISM)
|
||||
|
||||
hasCut = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0);
|
||||
else
|
||||
hasCut = (shape.PathBegin > 0) || (shape.PathEnd > 0);
|
||||
|
||||
hasHollow = shape.ProfileHollow > 0;
|
||||
hasDimple = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0); // taken from llSetPrimitiveParms
|
||||
hasProfileCut = hasDimple; // is it the same thing?
|
||||
|
||||
}
|
||||
|
||||
public LSL_Integer llGetNumberOfSides()
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
|
@ -4489,61 +4437,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
|
||||
protected int GetNumberOfSides(SceneObjectPart part)
|
||||
{
|
||||
int ret = 0;
|
||||
bool hasCut;
|
||||
bool hasHollow;
|
||||
bool hasDimple;
|
||||
bool hasProfileCut;
|
||||
int sides = part.GetNumberOfSides();
|
||||
|
||||
int primType = getScriptPrimType(part.Shape);
|
||||
hasCutHollowDimpleProfileCut(primType, part.Shape, out hasCut, out hasHollow, out hasDimple, out hasProfileCut);
|
||||
|
||||
switch (primType)
|
||||
if (part.GetPrimType() == PrimType.SPHERE && part.Shape.ProfileHollow > 0)
|
||||
{
|
||||
case ScriptBaseClass.PRIM_TYPE_BOX:
|
||||
ret = 6;
|
||||
if (hasCut) ret += 2;
|
||||
if (hasHollow) ret += 1;
|
||||
break;
|
||||
case ScriptBaseClass.PRIM_TYPE_CYLINDER:
|
||||
ret = 3;
|
||||
if (hasCut) ret += 2;
|
||||
if (hasHollow) ret += 1;
|
||||
break;
|
||||
case ScriptBaseClass.PRIM_TYPE_PRISM:
|
||||
ret = 5;
|
||||
if (hasCut) ret += 2;
|
||||
if (hasHollow) ret += 1;
|
||||
break;
|
||||
case ScriptBaseClass.PRIM_TYPE_SPHERE:
|
||||
ret = 1;
|
||||
if (hasCut) ret += 2;
|
||||
if (hasDimple) ret += 2;
|
||||
if (hasHollow) ret += 3; // Emulate lsl on secondlife (according to documentation it should have added only +1)
|
||||
break;
|
||||
case ScriptBaseClass.PRIM_TYPE_TORUS:
|
||||
ret = 1;
|
||||
if (hasCut) ret += 2;
|
||||
if (hasProfileCut) ret += 2;
|
||||
if (hasHollow) ret += 1;
|
||||
break;
|
||||
case ScriptBaseClass.PRIM_TYPE_TUBE:
|
||||
ret = 4;
|
||||
if (hasCut) ret += 2;
|
||||
if (hasProfileCut) ret += 2;
|
||||
if (hasHollow) ret += 1;
|
||||
break;
|
||||
case ScriptBaseClass.PRIM_TYPE_RING:
|
||||
ret = 3;
|
||||
if (hasCut) ret += 2;
|
||||
if (hasProfileCut) ret += 2;
|
||||
if (hasHollow) ret += 1;
|
||||
break;
|
||||
case ScriptBaseClass.PRIM_TYPE_SCULPT:
|
||||
ret = 1;
|
||||
break;
|
||||
// Make up for a bug where LSL shows 4 sides rather than 2
|
||||
sides += 2;
|
||||
}
|
||||
return ret;
|
||||
|
||||
return sides;
|
||||
}
|
||||
|
||||
|
||||
|
@ -4570,8 +4472,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// Xantor 29/apr/2008
|
||||
// Returns rotation described by rotating angle radians about axis.
|
||||
// q = cos(a/2) + i (x * sin(a/2)) + j (y * sin(a/2)) + k (z * sin(a/2))
|
||||
|
@ -7203,10 +7103,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
LSL_Vector color=rules.GetVector3Item(idx++);
|
||||
double alpha=(double)rules.GetLSLFloatItem(idx++);
|
||||
|
||||
SetColor(part, color, face);
|
||||
part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
|
||||
SetAlpha(part, alpha, face);
|
||||
|
||||
break;
|
||||
|
||||
case (int)ScriptBaseClass.PRIM_FLEXIBLE:
|
||||
if (remain < 7)
|
||||
return;
|
||||
|
@ -7222,6 +7123,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
SetFlexi(part, flexi, softness, gravity, friction, wind, tension, force);
|
||||
|
||||
break;
|
||||
|
||||
case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
|
||||
if (remain < 5)
|
||||
return;
|
||||
|
@ -7234,6 +7136,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
SetPointLight(part, light, lightcolor, intensity, radius, falloff);
|
||||
|
||||
break;
|
||||
|
||||
case (int)ScriptBaseClass.PRIM_GLOW:
|
||||
if (remain < 2)
|
||||
return;
|
||||
|
@ -7243,6 +7146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
SetGlow(part, face, glow);
|
||||
|
||||
break;
|
||||
|
||||
case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
|
||||
if (remain < 3)
|
||||
return;
|
||||
|
@ -7253,6 +7157,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
SetShiny(part, face, shiny, bump);
|
||||
|
||||
break;
|
||||
|
||||
case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
|
||||
if (remain < 2)
|
||||
return;
|
||||
|
@ -7260,6 +7165,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
bool st = rules.GetLSLIntegerItem(idx++);
|
||||
SetFullBright(part, face , st);
|
||||
break;
|
||||
|
||||
case (int)ScriptBaseClass.PRIM_MATERIAL:
|
||||
if (remain < 1)
|
||||
return;
|
||||
|
@ -7269,6 +7175,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
|
||||
part.Material = Convert.ToByte(mat);
|
||||
break;
|
||||
|
||||
case (int)ScriptBaseClass.PRIM_PHANTOM:
|
||||
if (remain < 1)
|
||||
return;
|
||||
|
@ -7283,6 +7190,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
|
||||
part.ScriptSetPhantomStatus(phantom);
|
||||
break;
|
||||
|
||||
case (int)ScriptBaseClass.PRIM_PHYSICS:
|
||||
if (remain < 1)
|
||||
return;
|
||||
|
@ -7296,6 +7204,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
|
||||
part.ScriptSetPhysicsStatus(physics);
|
||||
break;
|
||||
|
||||
case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
|
||||
if (remain < 1)
|
||||
return;
|
||||
|
@ -7563,7 +7472,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
|
||||
public LSL_List GetLinkPrimitiveParams(SceneObjectPart part, LSL_List rules)
|
||||
{
|
||||
|
||||
LSL_List res = new LSL_List();
|
||||
int idx=0;
|
||||
while (idx < rules.Length)
|
||||
|
@ -7625,7 +7533,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
case (int)ScriptBaseClass.PRIM_TYPE:
|
||||
// implementing box
|
||||
PrimitiveBaseShape Shape = part.Shape;
|
||||
int primType = getScriptPrimType(part.Shape);
|
||||
int primType = (int)part.GetPrimType();
|
||||
res.Add(new LSL_Integer(primType));
|
||||
double topshearx = (double)(sbyte)Shape.PathShearX / 100.0; // Fix negative values for PathShearX
|
||||
double topsheary = (double)(sbyte)Shape.PathShearY / 100.0; // and PathShearY.
|
||||
|
@ -7705,7 +7613,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
Primitive.TextureEntry tex = part.Shape.Textures;
|
||||
if (face == ScriptBaseClass.ALL_SIDES)
|
||||
{
|
||||
for (face = 0 ; face < GetNumberOfSides(part) ; face++)
|
||||
for (face = 0 ; face < GetNumberOfSides(part); face++)
|
||||
{
|
||||
Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
|
||||
|
||||
|
@ -7747,7 +7655,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
Color4 texcolor;
|
||||
if (face == ScriptBaseClass.ALL_SIDES)
|
||||
{
|
||||
for (face = 0 ; face < GetNumberOfSides(part) ; face++)
|
||||
for (face = 0 ; face < GetNumberOfSides(part); face++)
|
||||
{
|
||||
texcolor = tex.GetFace((uint)face).RGBA;
|
||||
res.Add(new LSL_Vector(texcolor.R,
|
||||
|
|
|
@ -55,6 +55,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
m_log.Info("[XEngine] Hooking up to server events");
|
||||
myScriptEngine.World.EventManager.OnAttach += attach;
|
||||
myScriptEngine.World.EventManager.OnObjectGrab += touch_start;
|
||||
myScriptEngine.World.EventManager.OnObjectGrabbing += touch;
|
||||
myScriptEngine.World.EventManager.OnObjectDeGrab += touch_end;
|
||||
myScriptEngine.World.EventManager.OnScriptChangedEvent += changed;
|
||||
myScriptEngine.World.EventManager.OnScriptAtTargetEvent += at_target;
|
||||
|
@ -148,7 +149,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
}
|
||||
|
||||
public void touch(uint localID, uint originalID, Vector3 offsetPos,
|
||||
IClientAPI remoteClient)
|
||||
IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
|
||||
{
|
||||
// Add to queue for all scripts in ObjectID object
|
||||
DetectParams[] det = new DetectParams[1];
|
||||
|
@ -172,6 +173,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
SceneObjectPart originalPart = myScriptEngine.World.GetSceneObjectPart(originalID);
|
||||
det[0].LinkNum = originalPart.LinkNum;
|
||||
}
|
||||
if (surfaceArgs != null)
|
||||
{
|
||||
det[0].SurfaceTouchArgs = surfaceArgs;
|
||||
}
|
||||
|
||||
myScriptEngine.PostObjectEvent(localID, new EventParams(
|
||||
"touch", new Object[] { new LSL_Types.LSLInteger(1) },
|
||||
|
|
Loading…
Reference in New Issue