Merge branch 'master' of git://opensimulator.org/git/opensim
						commit
						e09467b30d
					
				| 
						 | 
					@ -535,6 +535,8 @@ namespace OpenSim.Framework.Servers.HttpServer
 | 
				
			||||||
        /// <param name="message"></param>
 | 
					        /// <param name="message"></param>
 | 
				
			||||||
        public void Close(string message)
 | 
					        public void Close(string message)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            if (_networkContext == null)
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
            if (_networkContext.Stream != null)
 | 
					            if (_networkContext.Stream != null)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (_networkContext.Stream.CanWrite)
 | 
					                if (_networkContext.Stream.CanWrite)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,6 +59,8 @@ namespace OpenSim.Region.ClientStack.Linden
 | 
				
			||||||
//        private static readonly ILog m_log =
 | 
					//        private static readonly ILog m_log =
 | 
				
			||||||
//            LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
					//            LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public event SimulatorFeaturesRequestDelegate OnSimulatorFeaturesRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private Scene m_scene;
 | 
					        private Scene m_scene;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
| 
						 | 
					@ -94,6 +96,8 @@ namespace OpenSim.Region.ClientStack.Linden
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            m_scene = s;
 | 
					            m_scene = s;
 | 
				
			||||||
            m_scene.EventManager.OnRegisterCaps += RegisterCaps;
 | 
					            m_scene.EventManager.OnRegisterCaps += RegisterCaps;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            m_scene.RegisterModuleInterface<ISimulatorFeaturesModule>(this);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public void RemoveRegion(Scene s)
 | 
					        public void RemoveRegion(Scene s)
 | 
				
			||||||
| 
						 | 
					@ -156,7 +160,7 @@ namespace OpenSim.Region.ClientStack.Linden
 | 
				
			||||||
            IRequestHandler reqHandler
 | 
					            IRequestHandler reqHandler
 | 
				
			||||||
                = new RestHTTPHandler(
 | 
					                = new RestHTTPHandler(
 | 
				
			||||||
                    "GET", "/CAPS/" + UUID.Random(),
 | 
					                    "GET", "/CAPS/" + UUID.Random(),
 | 
				
			||||||
                    HandleSimulatorFeaturesRequest, "SimulatorFeatures", agentID.ToString());
 | 
					                    x => { return HandleSimulatorFeaturesRequest(x, agentID); }, "SimulatorFeatures", agentID.ToString());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            caps.RegisterHandler("SimulatorFeatures", reqHandler);
 | 
					            caps.RegisterHandler("SimulatorFeatures", reqHandler);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -185,18 +189,33 @@ namespace OpenSim.Region.ClientStack.Linden
 | 
				
			||||||
                return new OSDMap(m_features);
 | 
					                return new OSDMap(m_features);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private Hashtable HandleSimulatorFeaturesRequest(Hashtable mDhttpMethod)
 | 
					        private OSDMap DeepCopy()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // This isn't the cheapest way of doing this but the rate
 | 
				
			||||||
 | 
					            // of occurrence is low (on sim entry only) and it's a sure
 | 
				
			||||||
 | 
					            // way to get a true deep copy.
 | 
				
			||||||
 | 
					            OSD copy = OSDParser.DeserializeLLSDXml(OSDParser.SerializeLLSDXmlString(m_features));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return (OSDMap)copy;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private Hashtable HandleSimulatorFeaturesRequest(Hashtable mDhttpMethod, UUID agentID)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
//            m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request");
 | 
					//            m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            OSDMap copy = DeepCopy();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SimulatorFeaturesRequestDelegate handlerOnSimulatorFeaturesRequest = OnSimulatorFeaturesRequest;
 | 
				
			||||||
 | 
					            if (handlerOnSimulatorFeaturesRequest != null)
 | 
				
			||||||
 | 
					                handlerOnSimulatorFeaturesRequest(agentID, ref copy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //Send back data
 | 
					            //Send back data
 | 
				
			||||||
            Hashtable responsedata = new Hashtable();
 | 
					            Hashtable responsedata = new Hashtable();
 | 
				
			||||||
            responsedata["int_response_code"] = 200; 
 | 
					            responsedata["int_response_code"] = 200; 
 | 
				
			||||||
            responsedata["content_type"] = "text/plain";
 | 
					            responsedata["content_type"] = "text/plain";
 | 
				
			||||||
            responsedata["keepalive"] = false;
 | 
					            responsedata["keepalive"] = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            lock (m_features)
 | 
					            responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(copy);
 | 
				
			||||||
                responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(m_features);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return responsedata;
 | 
					            return responsedata;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,7 +42,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
 | 
				
			||||||
    public class AssetTransactionModule : INonSharedRegionModule,
 | 
					    public class AssetTransactionModule : INonSharedRegionModule,
 | 
				
			||||||
            IAgentAssetTransactions
 | 
					            IAgentAssetTransactions
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
					//        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        protected Scene m_Scene;
 | 
					        protected Scene m_Scene;
 | 
				
			||||||
        private bool m_dumpAssetsToFile = false;
 | 
					        private bool m_dumpAssetsToFile = false;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,7 +44,7 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DAExampleModule
 | 
				
			||||||
    [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DAExampleModule")]
 | 
					    [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DAExampleModule")]
 | 
				
			||||||
    public class DAExampleModule : INonSharedRegionModule
 | 
					    public class DAExampleModule : INonSharedRegionModule
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
					//        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static readonly bool ENABLED = false;   // enable for testing
 | 
					        private static readonly bool ENABLED = false;   // enable for testing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,7 +57,7 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
 | 
				
			||||||
            try
 | 
					            try
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                IConfig statConfig = source.Configs["Statistics.Binary"];
 | 
					                IConfig statConfig = source.Configs["Statistics.Binary"];
 | 
				
			||||||
                if (statConfig.Contains("enabled") && statConfig.GetBoolean("enabled"))
 | 
					                if (statConfig != null && statConfig.Contains("enabled") && statConfig.GetBoolean("enabled"))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (statConfig.Contains("collect_region_stats"))
 | 
					                    if (statConfig.Contains("collect_region_stats"))
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -111,7 +111,8 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
 | 
				
			||||||
            m_rpcPending = new Dictionary<UUID, RPCRequestInfo>();
 | 
					            m_rpcPending = new Dictionary<UUID, RPCRequestInfo>();
 | 
				
			||||||
            m_rpcPendingResponses = new Dictionary<UUID, RPCRequestInfo>();
 | 
					            m_rpcPendingResponses = new Dictionary<UUID, RPCRequestInfo>();
 | 
				
			||||||
            m_pendingSRDResponses = new Dictionary<UUID, SendRemoteDataRequest>();
 | 
					            m_pendingSRDResponses = new Dictionary<UUID, SendRemoteDataRequest>();
 | 
				
			||||||
 | 
					            if (config.Configs["XMLRPC"] != null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                try
 | 
					                try
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    m_remoteDataPort = config.Configs["XMLRPC"].GetInt("XmlRpcPort", m_remoteDataPort);
 | 
					                    m_remoteDataPort = config.Configs["XMLRPC"].GetInt("XmlRpcPort", m_remoteDataPort);
 | 
				
			||||||
| 
						 | 
					@ -120,6 +121,7 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public void PostInitialise()
 | 
					        public void PostInitialise()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,6 +31,16 @@ using OpenMetaverse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenSim.Region.Framework.Interfaces
 | 
					namespace OpenSim.Region.Framework.Interfaces
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    // these could be expanded at some point to provide more type information
 | 
				
			||||||
 | 
					    // for now value accounts for all base types
 | 
				
			||||||
 | 
					    public enum JsonStoreNodeType
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Undefined = 0,
 | 
				
			||||||
 | 
					        Object = 1,
 | 
				
			||||||
 | 
					        Array = 2,
 | 
				
			||||||
 | 
					        Value = 3
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    public delegate void TakeValueCallback(string s);
 | 
					    public delegate void TakeValueCallback(string s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public interface IJsonStoreModule
 | 
					    public interface IJsonStoreModule
 | 
				
			||||||
| 
						 | 
					@ -38,13 +48,18 @@ namespace OpenSim.Region.Framework.Interfaces
 | 
				
			||||||
        bool AttachObjectStore(UUID objectID);
 | 
					        bool AttachObjectStore(UUID objectID);
 | 
				
			||||||
        bool CreateStore(string value, ref UUID result);
 | 
					        bool CreateStore(string value, ref UUID result);
 | 
				
			||||||
        bool DestroyStore(UUID storeID);
 | 
					        bool DestroyStore(UUID storeID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        JsonStoreNodeType GetPathType(UUID storeID, string path);
 | 
				
			||||||
        bool TestStore(UUID storeID);
 | 
					        bool TestStore(UUID storeID);
 | 
				
			||||||
        bool TestPath(UUID storeID, string path, bool useJson);
 | 
					        bool TestPath(UUID storeID, string path, bool useJson);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bool SetValue(UUID storeID, string path, string value, bool useJson);
 | 
					        bool SetValue(UUID storeID, string path, string value, bool useJson);
 | 
				
			||||||
        bool RemoveValue(UUID storeID, string path);
 | 
					        bool RemoveValue(UUID storeID, string path);
 | 
				
			||||||
        bool GetValue(UUID storeID, string path, bool useJson, out string value);
 | 
					        bool GetValue(UUID storeID, string path, bool useJson, out string value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);
 | 
					        void TakeValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);
 | 
				
			||||||
        void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);
 | 
					        void ReadValue(UUID storeID, string path, bool useJson, TakeValueCallback cback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int GetArrayLength(UUID storeID, string path);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,15 +26,19 @@
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					using OpenMetaverse;
 | 
				
			||||||
using OpenMetaverse.StructuredData;
 | 
					using OpenMetaverse.StructuredData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenSim.Region.Framework.Interfaces
 | 
					namespace OpenSim.Region.Framework.Interfaces
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    public delegate void SimulatorFeaturesRequestDelegate(UUID agentID, ref OSDMap features);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// <summary>
 | 
					    /// <summary>
 | 
				
			||||||
    /// Add remove or retrieve Simulator Features that will be given to a viewer via the SimulatorFeatures capability.
 | 
					    /// Add remove or retrieve Simulator Features that will be given to a viewer via the SimulatorFeatures capability.
 | 
				
			||||||
    /// </summary>
 | 
					    /// </summary>
 | 
				
			||||||
    public interface ISimulatorFeaturesModule
 | 
					    public interface ISimulatorFeaturesModule
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        event SimulatorFeaturesRequestDelegate OnSimulatorFeaturesRequest;
 | 
				
			||||||
        void AddFeature(string name, OSD value);
 | 
					        void AddFeature(string name, OSD value);
 | 
				
			||||||
        bool RemoveFeature(string name);
 | 
					        bool RemoveFeature(string name);
 | 
				
			||||||
        bool TryGetFeature(string name, out OSD value);
 | 
					        bool TryGetFeature(string name, out OSD value);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -790,6 +790,19 @@ namespace OpenSim.Region.Framework.Scenes
 | 
				
			||||||
        /// <param name="obj">The object being removed from the scene</param>
 | 
					        /// <param name="obj">The object being removed from the scene</param>
 | 
				
			||||||
        public delegate void ObjectBeingRemovedFromScene(SceneObjectGroup obj);
 | 
					        public delegate void ObjectBeingRemovedFromScene(SceneObjectGroup obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Triggered when an object is placed into the physical scene (PhysicsActor created).
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        public event Action<SceneObjectPart> OnObjectAddedToPhysicalScene;
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Triggered when an object is removed from the physical scene (PhysicsActor destroyed).
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <remarks>
 | 
				
			||||||
 | 
					        /// Note: this is triggered just before the PhysicsActor is removed from the
 | 
				
			||||||
 | 
					        /// physics engine so the receiver can do any necessary cleanup before its destruction.
 | 
				
			||||||
 | 
					        /// </remarks>
 | 
				
			||||||
 | 
					        public event Action<SceneObjectPart> OnObjectRemovedFromPhysicalScene;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// Triggered when an object is removed from the scene.
 | 
					        /// Triggered when an object is removed from the scene.
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
| 
						 | 
					@ -1516,6 +1529,48 @@ namespace OpenSim.Region.Framework.Scenes
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void TriggerObjectAddedToPhysicalScene(SceneObjectPart obj)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Action<SceneObjectPart> handler = OnObjectAddedToPhysicalScene;
 | 
				
			||||||
 | 
					            if (handler != null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                foreach (Action<SceneObjectPart> d in handler.GetInvocationList())
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    try
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        d(obj);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    catch (Exception e)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        m_log.ErrorFormat(
 | 
				
			||||||
 | 
					                            "[EVENT MANAGER]: Delegate for TriggerObjectAddedToPhysicalScene failed - continuing.  {0} {1}", 
 | 
				
			||||||
 | 
					                            e.Message, e.StackTrace);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void TriggerObjectRemovedFromPhysicalScene(SceneObjectPart obj)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Action<SceneObjectPart> handler = OnObjectRemovedFromPhysicalScene;
 | 
				
			||||||
 | 
					            if (handler != null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                foreach (Action<SceneObjectPart> d in handler.GetInvocationList())
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    try
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        d(obj);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    catch (Exception e)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        m_log.ErrorFormat(
 | 
				
			||||||
 | 
					                            "[EVENT MANAGER]: Delegate for TriggerObjectRemovedFromPhysicalScene failed - continuing.  {0} {1}", 
 | 
				
			||||||
 | 
					                            e.Message, e.StackTrace);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public void TriggerShutdown()
 | 
					        public void TriggerShutdown()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Action handlerShutdown = OnShutdown;
 | 
					            Action handlerShutdown = OnShutdown;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4316,6 +4316,7 @@ namespace OpenSim.Region.Framework.Scenes
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            PhysActor = pa;
 | 
					            PhysActor = pa;
 | 
				
			||||||
 | 
					            ParentGroup.Scene.EventManager.TriggerObjectAddedToPhysicalScene(this);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
| 
						 | 
					@ -4328,6 +4329,7 @@ namespace OpenSim.Region.Framework.Scenes
 | 
				
			||||||
        /// </remarks>
 | 
					        /// </remarks>
 | 
				
			||||||
        public void RemoveFromPhysics()
 | 
					        public void RemoveFromPhysics()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            ParentGroup.Scene.EventManager.TriggerObjectRemovedFromPhysicalScene(this);
 | 
				
			||||||
            ParentGroup.Scene.PhysicsScene.RemovePrim(PhysActor);
 | 
					            ParentGroup.Scene.PhysicsScene.RemovePrim(PhysActor);
 | 
				
			||||||
            PhysActor = null;
 | 
					            PhysActor = null;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,14 +68,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
 | 
				
			||||||
        protected List<TakeValueCallbackClass> m_TakeStore;
 | 
					        protected List<TakeValueCallbackClass> m_TakeStore;
 | 
				
			||||||
        protected List<TakeValueCallbackClass> m_ReadStore;
 | 
					        protected List<TakeValueCallbackClass> m_ReadStore;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        // add separators for quoted paths
 | 
					        // add separators for quoted paths and array references
 | 
				
			||||||
        protected static Regex m_ParsePassOne = new Regex("{[^}]+}");
 | 
					        protected static Regex m_ParsePassOne = new Regex("({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])");
 | 
				
			||||||
 | 
					 | 
				
			||||||
        // add separators for array references
 | 
					 | 
				
			||||||
        protected static Regex m_ParsePassTwo = new Regex("(\\[[0-9]+\\]|\\[\\+\\])");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // add quotes to bare identifiers which are limited to alphabetic characters
 | 
					        // add quotes to bare identifiers which are limited to alphabetic characters
 | 
				
			||||||
        protected static Regex m_ParsePassThree = new Regex("\\.([a-zA-Z]+)");
 | 
					        protected static Regex m_ParsePassThree = new Regex("(?<!{[^}]*)\\.([a-zA-Z]+)(?=\\.)");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // remove extra separator characters
 | 
					        // remove extra separator characters
 | 
				
			||||||
        protected static Regex m_ParsePassFour = new Regex("\\.+");
 | 
					        protected static Regex m_ParsePassFour = new Regex("\\.+");
 | 
				
			||||||
| 
						 | 
					@ -84,7 +81,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
 | 
				
			||||||
        protected static Regex m_ValidatePath = new Regex("^\\.(({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])\\.)*$");
 | 
					        protected static Regex m_ValidatePath = new Regex("^\\.(({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])\\.)*$");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // expression used to match path components
 | 
					        // expression used to match path components
 | 
				
			||||||
        protected static Regex m_PathComponent = new Regex("\\.({[^}]+}|\\[[0-9]+\\]|\\[\\+\\]+)");
 | 
					        protected static Regex m_PathComponent = new Regex("\\.({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // extract the internals of an array reference
 | 
					        // extract the internals of an array reference
 | 
				
			||||||
        protected static Regex m_SimpleArrayPattern = new Regex("\\[([0-9]+)\\]");
 | 
					        protected static Regex m_SimpleArrayPattern = new Regex("\\[([0-9]+)\\]");
 | 
				
			||||||
| 
						 | 
					@ -134,12 +131,43 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public JsonStore(string value) : this()
 | 
					        public JsonStore(string value) : this()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            // This is going to throw an exception if the value is not
 | 
				
			||||||
 | 
					            // a valid JSON chunk. Calling routines should catch the 
 | 
				
			||||||
 | 
					            // exception and handle it appropriately
 | 
				
			||||||
            if (String.IsNullOrEmpty(value))
 | 
					            if (String.IsNullOrEmpty(value))
 | 
				
			||||||
                ValueStore = new OSDMap();
 | 
					                ValueStore = new OSDMap();
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                ValueStore = OSDParser.DeserializeJson(value);
 | 
					                ValueStore = OSDParser.DeserializeJson(value);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        // -----------------------------------------------------------------
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        // -----------------------------------------------------------------
 | 
				
			||||||
 | 
					        public JsonStoreNodeType PathType(string expr)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Stack<string> path;
 | 
				
			||||||
 | 
					            if (! ParsePathExpression(expr,out path))
 | 
				
			||||||
 | 
					                return JsonStoreNodeType.Undefined;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            OSD result = ProcessPathExpression(ValueStore,path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (result == null)
 | 
				
			||||||
 | 
					                return JsonStoreNodeType.Undefined;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if (result is OSDMap)
 | 
				
			||||||
 | 
					                return JsonStoreNodeType.Object;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if (result is OSDArray)
 | 
				
			||||||
 | 
					                return JsonStoreNodeType.Array;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if (OSDBaseType(result.Type))
 | 
				
			||||||
 | 
					                return JsonStoreNodeType.Value;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            return JsonStoreNodeType.Undefined;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        // -----------------------------------------------------------------
 | 
					        // -----------------------------------------------------------------
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 
 | 
					        /// 
 | 
				
			||||||
| 
						 | 
					@ -162,6 +190,27 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        // -----------------------------------------------------------------
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        // -----------------------------------------------------------------
 | 
				
			||||||
 | 
					        public int ArrayLength(string expr)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Stack<string> path;
 | 
				
			||||||
 | 
					            if (! ParsePathExpression(expr,out path))
 | 
				
			||||||
 | 
					                return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            OSD result = ProcessPathExpression(ValueStore,path);
 | 
				
			||||||
 | 
					            if (result != null && result.Type == OSDType.Array)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                OSDArray arr = result as OSDArray;
 | 
				
			||||||
 | 
					                return arr.Count;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // -----------------------------------------------------------------
 | 
					        // -----------------------------------------------------------------
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 
 | 
					        /// 
 | 
				
			||||||
| 
						 | 
					@ -462,11 +511,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
 | 
				
			||||||
            // add front and rear separators
 | 
					            // add front and rear separators
 | 
				
			||||||
            expr = "." + expr + ".";
 | 
					            expr = "." + expr + ".";
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // add separators for quoted exprs
 | 
					            // add separators for quoted exprs and array references
 | 
				
			||||||
            expr = m_ParsePassOne.Replace(expr,".$0.",-1,0);
 | 
					            expr = m_ParsePassOne.Replace(expr,".$1.",-1,0);
 | 
				
			||||||
                
 | 
					 | 
				
			||||||
            // add separators for array references
 | 
					 | 
				
			||||||
            expr = m_ParsePassTwo.Replace(expr,".$0.",-1,0);
 | 
					 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
            // add quotes to bare identifier
 | 
					            // add quotes to bare identifier
 | 
				
			||||||
            expr = m_ParsePassThree.Replace(expr,".{$1}",-1,0);
 | 
					            expr = m_ParsePassThree.Replace(expr,".{$1}",-1,0);
 | 
				
			||||||
| 
						 | 
					@ -574,14 +620,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
 | 
				
			||||||
                // The path pointed to an intermediate hash structure
 | 
					                // The path pointed to an intermediate hash structure
 | 
				
			||||||
                if (result.Type == OSDType.Map)
 | 
					                if (result.Type == OSDType.Map)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    value = OSDParser.SerializeJsonString(result as OSDMap);
 | 
					                    value = OSDParser.SerializeJsonString(result as OSDMap,true);
 | 
				
			||||||
                    return true;
 | 
					                    return true;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // The path pointed to an intermediate hash structure
 | 
					                // The path pointed to an intermediate hash structure
 | 
				
			||||||
                if (result.Type == OSDType.Array)
 | 
					                if (result.Type == OSDType.Array)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    value = OSDParser.SerializeJsonString(result as OSDArray);
 | 
					                    value = OSDParser.SerializeJsonString(result as OSDArray,true);
 | 
				
			||||||
                    return true;
 | 
					                    return true;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -227,7 +227,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            catch (Exception e)
 | 
					            catch (Exception e)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                m_log.Error(string.Format("[JsonStore]: Unable to initialize store from {0}", value), e);
 | 
					                m_log.ErrorFormat("[JsonStore]: Unable to initialize store from {0}", value);
 | 
				
			||||||
                return false;
 | 
					                return false;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -265,6 +265,38 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
 | 
				
			||||||
                return m_JsonValueStore.ContainsKey(storeID);
 | 
					                return m_JsonValueStore.ContainsKey(storeID);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // -----------------------------------------------------------------
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        // -----------------------------------------------------------------
 | 
				
			||||||
 | 
					        public JsonStoreNodeType GetPathType(UUID storeID, string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (! m_enabled) return JsonStoreNodeType.Undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            JsonStore map = null;
 | 
				
			||||||
 | 
					            lock (m_JsonValueStore)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (! m_JsonValueStore.TryGetValue(storeID,out map))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
 | 
				
			||||||
 | 
					                    return JsonStoreNodeType.Undefined;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                lock (map)
 | 
				
			||||||
 | 
					                    return map.PathType(path);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception e)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                m_log.Error(string.Format("[JsonStore]: Path test failed for {0} in {1}", path, storeID), e);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return JsonStoreNodeType.Undefined;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // -----------------------------------------------------------------
 | 
					        // -----------------------------------------------------------------
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 
 | 
					        /// 
 | 
				
			||||||
| 
						 | 
					@ -370,6 +402,37 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        // -----------------------------------------------------------------
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        // -----------------------------------------------------------------
 | 
				
			||||||
 | 
					        public int GetArrayLength(UUID storeID, string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (! m_enabled) return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            JsonStore map = null;
 | 
				
			||||||
 | 
					            lock (m_JsonValueStore)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (! m_JsonValueStore.TryGetValue(storeID,out map))
 | 
				
			||||||
 | 
					                    return -1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                lock (map)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    return map.ArrayLength(path);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception e)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                m_log.Error("[JsonStore]: unable to retrieve value", e);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // -----------------------------------------------------------------
 | 
					        // -----------------------------------------------------------------
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 
 | 
					        /// 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -167,6 +167,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
 | 
				
			||||||
                try
 | 
					                try
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    m_comms.RegisterScriptInvocations(this);
 | 
					                    m_comms.RegisterScriptInvocations(this);
 | 
				
			||||||
 | 
					                    m_comms.RegisterConstants(this);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
                    // m_comms.RegisterScriptInvocation(this, "JsonCreateStore");
 | 
					                    // m_comms.RegisterScriptInvocation(this, "JsonCreateStore");
 | 
				
			||||||
                    // m_comms.RegisterScriptInvocation(this, "JsonAttachObjectStore");
 | 
					                    // m_comms.RegisterScriptInvocation(this, "JsonAttachObjectStore");
 | 
				
			||||||
| 
						 | 
					@ -214,6 +215,22 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endregion
 | 
					#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#region ScriptConstantsInterface
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [ScriptConstant]
 | 
				
			||||||
 | 
					        public static readonly int JSON_TYPE_UNDEF = (int)JsonStoreNodeType.Undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [ScriptConstant]
 | 
				
			||||||
 | 
					        public static readonly int JSON_TYPE_OBJECT = (int)JsonStoreNodeType.Object;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [ScriptConstant]
 | 
				
			||||||
 | 
					        public static readonly int JSON_TYPE_ARRAY = (int)JsonStoreNodeType.Array;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [ScriptConstant]
 | 
				
			||||||
 | 
					        public static readonly int JSON_TYPE_VALUE = (int)JsonStoreNodeType.Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endregion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#region ScriptInvocationInteface
 | 
					#region ScriptInvocationInteface
 | 
				
			||||||
        // -----------------------------------------------------------------
 | 
					        // -----------------------------------------------------------------
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
| 
						 | 
					@ -318,6 +335,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
 | 
				
			||||||
        /// 
 | 
					        /// 
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
        // -----------------------------------------------------------------
 | 
					        // -----------------------------------------------------------------
 | 
				
			||||||
 | 
					        [ScriptInvocation]
 | 
				
			||||||
 | 
					        public int JsonGetPathType(UUID hostID, UUID scriptID, UUID storeID, string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return (int)m_store.GetPathType(storeID,path);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [ScriptInvocation]
 | 
					        [ScriptInvocation]
 | 
				
			||||||
        public int JsonTestPath(UUID hostID, UUID scriptID, UUID storeID, string path)
 | 
					        public int JsonTestPath(UUID hostID, UUID scriptID, UUID storeID, string path)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -342,7 +365,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [ScriptInvocation]
 | 
					        [ScriptInvocation]
 | 
				
			||||||
        public int JsonSetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value)
 | 
					        public int JsonSetJson(UUID hostID, UUID scriptID, UUID storeID, string path, string value)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return m_store.SetValue(storeID,path,value,true) ? 1 : 0;
 | 
					            return m_store.SetValue(storeID,path,value,true) ? 1 : 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -358,6 +381,17 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
 | 
				
			||||||
            return m_store.RemoveValue(storeID,path) ? 1 : 0;
 | 
					            return m_store.RemoveValue(storeID,path) ? 1 : 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        // -----------------------------------------------------------------
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// 
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        // -----------------------------------------------------------------
 | 
				
			||||||
 | 
					        [ScriptInvocation]
 | 
				
			||||||
 | 
					        public int JsonGetArrayLength(UUID hostID, UUID scriptID, UUID storeID, string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return m_store.GetArrayLength(storeID,path);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        // -----------------------------------------------------------------
 | 
					        // -----------------------------------------------------------------
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        /// 
 | 
					        /// 
 | 
				
			||||||
| 
						 | 
					@ -372,7 +406,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [ScriptInvocation]
 | 
					        [ScriptInvocation]
 | 
				
			||||||
        public string JsonGetValueJson(UUID hostID, UUID scriptID, UUID storeID, string path)
 | 
					        public string JsonGetJson(UUID hostID, UUID scriptID, UUID storeID, string path)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            string value = String.Empty;
 | 
					            string value = String.Empty;
 | 
				
			||||||
            m_store.GetValue(storeID,path,true, out value);
 | 
					            m_store.GetValue(storeID,path,true, out value);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,6 +53,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
 | 
				
			||||||
        private Scene m_scene;
 | 
					        private Scene m_scene;
 | 
				
			||||||
        private MockScriptEngine m_engine;
 | 
					        private MockScriptEngine m_engine;
 | 
				
			||||||
        private ScriptModuleCommsModule m_smcm;
 | 
					        private ScriptModuleCommsModule m_smcm;
 | 
				
			||||||
 | 
					        private JsonStoreScriptModule m_jssm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [TestFixtureSetUp]
 | 
					        [TestFixtureSetUp]
 | 
				
			||||||
        public void FixtureInit()
 | 
					        public void FixtureInit()
 | 
				
			||||||
| 
						 | 
					@ -82,10 +83,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
 | 
				
			||||||
            m_engine = new MockScriptEngine();
 | 
					            m_engine = new MockScriptEngine();
 | 
				
			||||||
            m_smcm = new ScriptModuleCommsModule();
 | 
					            m_smcm = new ScriptModuleCommsModule();
 | 
				
			||||||
            JsonStoreModule jsm = new JsonStoreModule();
 | 
					            JsonStoreModule jsm = new JsonStoreModule();
 | 
				
			||||||
            JsonStoreScriptModule jssm = new JsonStoreScriptModule();
 | 
					            m_jssm = new JsonStoreScriptModule();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            m_scene = new SceneHelpers().SetupScene();
 | 
					            m_scene = new SceneHelpers().SetupScene();
 | 
				
			||||||
            SceneHelpers.SetupSceneModules(m_scene, configSource, m_engine, m_smcm, jsm, jssm);
 | 
					            SceneHelpers.SetupSceneModules(m_scene, configSource, m_engine, m_smcm, jsm, m_jssm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            try
 | 
					            try
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
| 
						 | 
					@ -115,10 +116,37 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
 | 
				
			||||||
            TestHelpers.InMethod();
 | 
					            TestHelpers.InMethod();
 | 
				
			||||||
//            TestHelpers.EnableLogging();
 | 
					//            TestHelpers.EnableLogging();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Test blank store
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
 | 
				
			||||||
                Assert.That(storeId, Is.Not.EqualTo(UUID.Zero));
 | 
					                Assert.That(storeId, Is.Not.EqualTo(UUID.Zero));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Test single element store
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }");
 | 
				
			||||||
 | 
					                Assert.That(storeId, Is.Not.EqualTo(UUID.Zero));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Test with an integer value
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 42.15 }");
 | 
				
			||||||
 | 
					                Assert.That(storeId, Is.Not.EqualTo(UUID.Zero));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                string value = (string)InvokeOp("JsonGetValue", storeId, "Hello");
 | 
				
			||||||
 | 
					                Assert.That(value, Is.EqualTo("42.15"));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Test with an array as the root node
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "[ 'one', 'two', 'three' ]");
 | 
				
			||||||
 | 
					                Assert.That(storeId, Is.Not.EqualTo(UUID.Zero));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                string value = (string)InvokeOp("JsonGetValue", storeId, "[1]");
 | 
				
			||||||
 | 
					                Assert.That(value, Is.EqualTo("two"));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Test]
 | 
					        [Test]
 | 
				
			||||||
        public void TestJsonDestroyStore()
 | 
					        public void TestJsonDestroyStore()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -181,7 +209,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Test]
 | 
					        [Test]
 | 
				
			||||||
        public void TestJsonGetValueJson()
 | 
					        public void TestJsonGetJson()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            TestHelpers.InMethod();
 | 
					            TestHelpers.InMethod();
 | 
				
			||||||
//            TestHelpers.EnableLogging();
 | 
					//            TestHelpers.EnableLogging();
 | 
				
			||||||
| 
						 | 
					@ -189,26 +217,26 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
 | 
				
			||||||
            UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Two' } }"); 
 | 
					            UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Two' } }"); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                string value = (string)InvokeOp("JsonGetValueJson", storeId, "Hello.World");
 | 
					                string value = (string)InvokeOp("JsonGetJson", storeId, "Hello.World");
 | 
				
			||||||
                Assert.That(value, Is.EqualTo("'Two'"));
 | 
					                Assert.That(value, Is.EqualTo("'Two'"));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Test get of path section instead of leaf
 | 
					            // Test get of path section instead of leaf
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                string value = (string)InvokeOp("JsonGetValueJson", storeId, "Hello");
 | 
					                string value = (string)InvokeOp("JsonGetJson", storeId, "Hello");
 | 
				
			||||||
                Assert.That(value, Is.EqualTo("{\"World\":\"Two\"}"));
 | 
					                Assert.That(value, Is.EqualTo("{\"World\":\"Two\"}"));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Test get of non-existing value
 | 
					            // Test get of non-existing value
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                string fakeValueGet = (string)InvokeOp("JsonGetValueJson", storeId, "foo");
 | 
					                string fakeValueGet = (string)InvokeOp("JsonGetJson", storeId, "foo");
 | 
				
			||||||
                Assert.That(fakeValueGet, Is.EqualTo(""));
 | 
					                Assert.That(fakeValueGet, Is.EqualTo(""));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Test get from non-existing store
 | 
					            // Test get from non-existing store
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                UUID fakeStoreId = TestHelpers.ParseTail(0x500);
 | 
					                UUID fakeStoreId = TestHelpers.ParseTail(0x500);
 | 
				
			||||||
                string fakeStoreValueGet = (string)InvokeOp("JsonGetValueJson", fakeStoreId, "Hello");
 | 
					                string fakeStoreValueGet = (string)InvokeOp("JsonGetJson", fakeStoreId, "Hello");
 | 
				
			||||||
                Assert.That(fakeStoreValueGet, Is.EqualTo(""));
 | 
					                Assert.That(fakeStoreValueGet, Is.EqualTo(""));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -242,6 +270,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
 | 
				
			||||||
            TestHelpers.InMethod();
 | 
					            TestHelpers.InMethod();
 | 
				
			||||||
//            TestHelpers.EnableLogging();
 | 
					//            TestHelpers.EnableLogging();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Test remove of node in object pointing to a string
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); 
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello");
 | 
					                int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello");
 | 
				
			||||||
| 
						 | 
					@ -252,78 +282,224 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                string returnValue2 = (string)InvokeOp("JsonGetValue", storeId, "Hello");
 | 
					                string returnValue2 = (string)InvokeOp("JsonGetValue", storeId, "Hello");
 | 
				
			||||||
                Assert.That(returnValue2, Is.EqualTo(""));
 | 
					                Assert.That(returnValue2, Is.EqualTo(""));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Test remove of node in object pointing to another object
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'Wally' } }"); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello");
 | 
				
			||||||
 | 
					                Assert.That(returnValue, Is.EqualTo(1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                int result = (int)InvokeOp("JsonTestPath", storeId, "Hello");
 | 
				
			||||||
 | 
					                Assert.That(result, Is.EqualTo(0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                string returnValue2 = (string)InvokeOp("JsonGetJson", storeId, "Hello");
 | 
				
			||||||
 | 
					                Assert.That(returnValue2, Is.EqualTo(""));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Test remove of node in an array
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                UUID storeId 
 | 
				
			||||||
 | 
					                    = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : [ 'value1', 'value2' ] }");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                int returnValue = (int)InvokeOp( "JsonRemoveValue", storeId, "Hello[0]");
 | 
				
			||||||
 | 
					                Assert.That(returnValue, Is.EqualTo(1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                int result = (int)InvokeOp("JsonTestPath", storeId, "Hello[0]");
 | 
				
			||||||
 | 
					                Assert.That(result, Is.EqualTo(1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                result = (int)InvokeOp("JsonTestPath", storeId, "Hello[1]");
 | 
				
			||||||
 | 
					                Assert.That(result, Is.EqualTo(0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                string stringReturnValue = (string)InvokeOp("JsonGetValue", storeId, "Hello[0]");
 | 
				
			||||||
 | 
					                Assert.That(stringReturnValue, Is.EqualTo("value2"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                stringReturnValue = (string)InvokeOp("JsonGetJson", storeId, "Hello[1]");
 | 
				
			||||||
 | 
					                Assert.That(stringReturnValue, Is.EqualTo(""));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Test remove of non-existing value
 | 
					            // Test remove of non-existing value
 | 
				
			||||||
            int fakeValueRemove = (int)InvokeOp("JsonRemoveValue", storeId, "Hello");
 | 
					            {
 | 
				
			||||||
            Assert.That(fakeValueRemove, Is.EqualTo(0));
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }"); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                int fakeValueRemove = (int)InvokeOp("JsonRemoveValue", storeId, "Cheese");
 | 
				
			||||||
 | 
					                Assert.That(fakeValueRemove, Is.EqualTo(0));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                // Test get from non-existing store
 | 
					                // Test get from non-existing store
 | 
				
			||||||
                UUID fakeStoreId = TestHelpers.ParseTail(0x500);
 | 
					                UUID fakeStoreId = TestHelpers.ParseTail(0x500);
 | 
				
			||||||
                int fakeStoreValueRemove = (int)InvokeOp("JsonRemoveValue", fakeStoreId, "Hello");
 | 
					                int fakeStoreValueRemove = (int)InvokeOp("JsonRemoveValue", fakeStoreId, "Hello");
 | 
				
			||||||
                Assert.That(fakeStoreValueRemove, Is.EqualTo(0));
 | 
					                Assert.That(fakeStoreValueRemove, Is.EqualTo(0));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//        [Test]
 | 
				
			||||||
 | 
					//        public void TestJsonTestPath()
 | 
				
			||||||
 | 
					//        {
 | 
				
			||||||
 | 
					//            TestHelpers.InMethod();
 | 
				
			||||||
 | 
					////            TestHelpers.EnableLogging();
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//            UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }"); 
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//            {
 | 
				
			||||||
 | 
					//                int result = (int)InvokeOp("JsonTestPath", storeId, "Hello.World");
 | 
				
			||||||
 | 
					//                Assert.That(result, Is.EqualTo(1));
 | 
				
			||||||
 | 
					//            }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//            // Test for path which does not resolve to a value.
 | 
				
			||||||
 | 
					//            {
 | 
				
			||||||
 | 
					//                int result = (int)InvokeOp("JsonTestPath", storeId, "Hello");
 | 
				
			||||||
 | 
					//                Assert.That(result, Is.EqualTo(0));
 | 
				
			||||||
 | 
					//            }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//            {
 | 
				
			||||||
 | 
					//                int result2 = (int)InvokeOp("JsonTestPath", storeId, "foo");
 | 
				
			||||||
 | 
					//                Assert.That(result2, Is.EqualTo(0));
 | 
				
			||||||
 | 
					//            }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//            // Test with fake store
 | 
				
			||||||
 | 
					//            {
 | 
				
			||||||
 | 
					//                UUID fakeStoreId = TestHelpers.ParseTail(0x500);
 | 
				
			||||||
 | 
					//                int fakeStoreValueRemove = (int)InvokeOp("JsonTestPath", fakeStoreId, "Hello");
 | 
				
			||||||
 | 
					//                Assert.That(fakeStoreValueRemove, Is.EqualTo(0));
 | 
				
			||||||
 | 
					//            }
 | 
				
			||||||
 | 
					//        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//        [Test]
 | 
				
			||||||
 | 
					//        public void TestJsonTestPathJson()
 | 
				
			||||||
 | 
					//        {
 | 
				
			||||||
 | 
					//            TestHelpers.InMethod();
 | 
				
			||||||
 | 
					////            TestHelpers.EnableLogging();
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//            UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }"); 
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//            {
 | 
				
			||||||
 | 
					//                int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello.World");
 | 
				
			||||||
 | 
					//                Assert.That(result, Is.EqualTo(1));
 | 
				
			||||||
 | 
					//            }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//            // Test for path which does not resolve to a value.
 | 
				
			||||||
 | 
					//            {
 | 
				
			||||||
 | 
					//                int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello");
 | 
				
			||||||
 | 
					//                Assert.That(result, Is.EqualTo(1));
 | 
				
			||||||
 | 
					//            }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//            {
 | 
				
			||||||
 | 
					//                int result2 = (int)InvokeOp("JsonTestPathJson", storeId, "foo");
 | 
				
			||||||
 | 
					//                Assert.That(result2, Is.EqualTo(0));
 | 
				
			||||||
 | 
					//            }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//            // Test with fake store
 | 
				
			||||||
 | 
					//            {
 | 
				
			||||||
 | 
					//                UUID fakeStoreId = TestHelpers.ParseTail(0x500);
 | 
				
			||||||
 | 
					//                int fakeStoreValueRemove = (int)InvokeOp("JsonTestPathJson", fakeStoreId, "Hello");
 | 
				
			||||||
 | 
					//                Assert.That(fakeStoreValueRemove, Is.EqualTo(0));
 | 
				
			||||||
 | 
					//            }
 | 
				
			||||||
 | 
					//        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Test]
 | 
					        [Test]
 | 
				
			||||||
        public void TestJsonTestPath()
 | 
					        public void TestGetArrayLength()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            TestHelpers.InMethod();
 | 
					            TestHelpers.InMethod();
 | 
				
			||||||
//            TestHelpers.EnableLogging();
 | 
					//            TestHelpers.EnableLogging();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }"); 
 | 
					            UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : [ 'one', 2 ] } }");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                int result = (int)InvokeOp("JsonTestPath", storeId, "Hello.World");
 | 
					                int result = (int)InvokeOp("JsonGetArrayLength", storeId, "Hello.World");
 | 
				
			||||||
                Assert.That(result, Is.EqualTo(1));
 | 
					                Assert.That(result, Is.EqualTo(2));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Test for path which does not resolve to a value.
 | 
					            // Test path which is not an array
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                int result = (int)InvokeOp("JsonTestPath", storeId, "Hello");
 | 
					                int result = (int)InvokeOp("JsonGetArrayLength", storeId, "Hello");
 | 
				
			||||||
                Assert.That(result, Is.EqualTo(0));
 | 
					                Assert.That(result, Is.EqualTo(-1));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Test fake path
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                int result2 = (int)InvokeOp("JsonTestPath", storeId, "foo");
 | 
					                int result = (int)InvokeOp("JsonGetArrayLength", storeId, "foo");
 | 
				
			||||||
                Assert.That(result2, Is.EqualTo(0));
 | 
					                Assert.That(result, Is.EqualTo(-1));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Test with fake store
 | 
					            // Test fake store
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                UUID fakeStoreId = TestHelpers.ParseTail(0x500);
 | 
					                UUID fakeStoreId = TestHelpers.ParseTail(0x500);
 | 
				
			||||||
                int fakeStoreValueRemove = (int)InvokeOp("JsonTestPath", fakeStoreId, "Hello");
 | 
					                int result = (int)InvokeOp("JsonGetArrayLength", fakeStoreId, "Hello.World");
 | 
				
			||||||
                Assert.That(fakeStoreValueRemove, Is.EqualTo(0));
 | 
					                Assert.That(result, Is.EqualTo(-1));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Test]
 | 
					        [Test]
 | 
				
			||||||
        public void TestJsonTestPathJson()
 | 
					        public void TestJsonGetPathType()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            TestHelpers.InMethod();
 | 
					            TestHelpers.InMethod();
 | 
				
			||||||
//            TestHelpers.EnableLogging();
 | 
					//            TestHelpers.EnableLogging();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : 'One' } }"); 
 | 
					            UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : { 'World' : [ 'one', 2 ] } }"); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello.World");
 | 
					                int result = (int)InvokeOp("JsonGetPathType", storeId, ".");
 | 
				
			||||||
                Assert.That(result, Is.EqualTo(1));
 | 
					                Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_OBJECT));
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Test for path which does not resolve to a value.
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                int result = (int)InvokeOp("JsonTestPathJson", storeId, "Hello");
 | 
					 | 
				
			||||||
                Assert.That(result, Is.EqualTo(1));
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                int result2 = (int)InvokeOp("JsonTestPathJson", storeId, "foo");
 | 
					                int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello");
 | 
				
			||||||
                Assert.That(result2, Is.EqualTo(0));
 | 
					                Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_OBJECT));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Test with fake store
 | 
					            {
 | 
				
			||||||
 | 
					                int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello.World");
 | 
				
			||||||
 | 
					                Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_ARRAY));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello.World[0]");
 | 
				
			||||||
 | 
					                Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_VALUE));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                int result = (int)InvokeOp("JsonGetPathType", storeId, "Hello.World[1]");
 | 
				
			||||||
 | 
					                Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_VALUE));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Test for non-existant path
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                int result = (int)InvokeOp("JsonGetPathType", storeId, "foo");
 | 
				
			||||||
 | 
					                Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Test for non-existant store
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                UUID fakeStoreId = TestHelpers.ParseTail(0x500);
 | 
					                UUID fakeStoreId = TestHelpers.ParseTail(0x500);
 | 
				
			||||||
                int fakeStoreValueRemove = (int)InvokeOp("JsonTestPathJson", fakeStoreId, "Hello");
 | 
					                int result = (int)InvokeOp("JsonGetPathType", fakeStoreId, ".");
 | 
				
			||||||
                Assert.That(fakeStoreValueRemove, Is.EqualTo(0));
 | 
					                Assert.That(result, Is.EqualTo(JsonStoreScriptModule.JSON_TYPE_UNDEF));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Test]
 | 
				
			||||||
 | 
					        public void TestJsonList2Path()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            TestHelpers.InMethod();
 | 
				
			||||||
 | 
					//            TestHelpers.EnableLogging();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Invoking these methods directly since I just couldn't get comms module invocation to work for some reason
 | 
				
			||||||
 | 
					            // - some confusion with the methods that take a params object[] invocation.
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo" });
 | 
				
			||||||
 | 
					                Assert.That(result, Is.EqualTo("{foo}"));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo", "bar" });
 | 
				
			||||||
 | 
					                Assert.That(result, Is.EqualTo("{foo}.{bar}"));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                string result = m_jssm.JsonList2Path(UUID.Zero, UUID.Zero, new object[] { "foo", 1, "bar" });
 | 
				
			||||||
 | 
					                Assert.That(result, Is.EqualTo("{foo}.[1].{bar}"));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -334,7 +510,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
 | 
				
			||||||
//            TestHelpers.EnableLogging();
 | 
					//            TestHelpers.EnableLogging();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); 
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                int result = (int)InvokeOp("JsonSetValue", storeId, "Fun", "Times");
 | 
					                int result = (int)InvokeOp("JsonSetValue", storeId, "Fun", "Times");
 | 
				
			||||||
                Assert.That(result, Is.EqualTo(1));
 | 
					                Assert.That(result, Is.EqualTo(1));
 | 
				
			||||||
| 
						 | 
					@ -343,9 +519,155 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
 | 
				
			||||||
                Assert.That(value, Is.EqualTo("Times"));
 | 
					                Assert.That(value, Is.EqualTo("Times"));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Test setting a key containing periods with delineation
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun.Circus}", "Times");
 | 
				
			||||||
 | 
					                Assert.That(result, Is.EqualTo(1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun.Circus}");
 | 
				
			||||||
 | 
					                Assert.That(value, Is.EqualTo("Times"));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // *** Test [] ***
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Test setting a key containing unbalanced ] without delineation.  Expecting failure
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                int result = (int)InvokeOp("JsonSetValue", storeId, "Fun]Circus", "Times");
 | 
				
			||||||
 | 
					                Assert.That(result, Is.EqualTo(0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                string value = (string)InvokeOp("JsonGetValue", storeId, "Fun]Circus");
 | 
				
			||||||
 | 
					                Assert.That(value, Is.EqualTo(""));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Test setting a key containing unbalanced [ without delineation.  Expecting failure
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                int result = (int)InvokeOp("JsonSetValue", storeId, "Fun[Circus", "Times");
 | 
				
			||||||
 | 
					                Assert.That(result, Is.EqualTo(0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                string value = (string)InvokeOp("JsonGetValue", storeId, "Fun[Circus");
 | 
				
			||||||
 | 
					                Assert.That(value, Is.EqualTo(""));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Test setting a key containing unbalanced [] without delineation.  Expecting failure
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                int result = (int)InvokeOp("JsonSetValue", storeId, "Fun[]Circus", "Times");
 | 
				
			||||||
 | 
					                Assert.That(result, Is.EqualTo(0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                string value = (string)InvokeOp("JsonGetValue", storeId, "Fun[]Circus");
 | 
				
			||||||
 | 
					                Assert.That(value, Is.EqualTo(""));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Test setting a key containing unbalanced ] with delineation
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun]Circus}", "Times");
 | 
				
			||||||
 | 
					                Assert.That(result, Is.EqualTo(1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun]Circus}");
 | 
				
			||||||
 | 
					                Assert.That(value, Is.EqualTo("Times"));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Test setting a key containing unbalanced [ with delineation
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[Circus}", "Times");
 | 
				
			||||||
 | 
					                Assert.That(result, Is.EqualTo(1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[Circus}");
 | 
				
			||||||
 | 
					                Assert.That(value, Is.EqualTo("Times"));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Test setting a key containing empty balanced [] with delineation
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[]Circus}", "Times");
 | 
				
			||||||
 | 
					                Assert.That(result, Is.EqualTo(1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[]Circus}");
 | 
				
			||||||
 | 
					                Assert.That(value, Is.EqualTo("Times"));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//            // Commented out as this currently unexpectedly fails.
 | 
				
			||||||
 | 
					//            // Test setting a key containing brackets around an integer with delineation
 | 
				
			||||||
 | 
					//            {
 | 
				
			||||||
 | 
					//                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); 
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//                int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun[0]Circus}", "Times");
 | 
				
			||||||
 | 
					//                Assert.That(result, Is.EqualTo(1));
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//                string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun[0]Circus}");
 | 
				
			||||||
 | 
					//                Assert.That(value, Is.EqualTo("Times"));
 | 
				
			||||||
 | 
					//            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // *** Test {} ***
 | 
				
			||||||
 | 
					           
 | 
				
			||||||
 | 
					            // Test setting a key containing unbalanced } without delineation.  Expecting failure (?)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                int result = (int)InvokeOp("JsonSetValue", storeId, "Fun}Circus", "Times");
 | 
				
			||||||
 | 
					                Assert.That(result, Is.EqualTo(0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                string value = (string)InvokeOp("JsonGetValue", storeId, "Fun}Circus");
 | 
				
			||||||
 | 
					                Assert.That(value, Is.EqualTo(""));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Test setting a key containing unbalanced { without delineation.  Expecting failure (?)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                int result = (int)InvokeOp("JsonSetValue", storeId, "Fun{Circus", "Times");
 | 
				
			||||||
 | 
					                Assert.That(result, Is.EqualTo(0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                string value = (string)InvokeOp("JsonGetValue", storeId, "Fun}Circus");
 | 
				
			||||||
 | 
					                Assert.That(value, Is.EqualTo(""));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//            // Commented out as this currently unexpectedly fails.
 | 
				
			||||||
 | 
					//            // Test setting a key containing unbalanced }
 | 
				
			||||||
 | 
					//            {
 | 
				
			||||||
 | 
					//                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); 
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//                int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun}Circus}", "Times");
 | 
				
			||||||
 | 
					//                Assert.That(result, Is.EqualTo(0));
 | 
				
			||||||
 | 
					//            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Test setting a key containing unbalanced { with delineation
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun{Circus}", "Times");
 | 
				
			||||||
 | 
					                Assert.That(result, Is.EqualTo(1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun{Circus}");
 | 
				
			||||||
 | 
					                Assert.That(value, Is.EqualTo("Times"));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Test setting a key containing balanced {} with delineation.  This should fail.
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                int result = (int)InvokeOp("JsonSetValue", storeId, "{Fun{Filled}Circus}", "Times");
 | 
				
			||||||
 | 
					                Assert.That(result, Is.EqualTo(0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                string value = (string)InvokeOp("JsonGetValue", storeId, "{Fun{Filled}Circus}");
 | 
				
			||||||
 | 
					                Assert.That(value, Is.EqualTo(""));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Test setting to location that does not exist.  This should fail.
 | 
					            // Test setting to location that does not exist.  This should fail.
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); 
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}"); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                int result = (int)InvokeOp("JsonSetValue", storeId, "Fun.Circus", "Times");
 | 
					                int result = (int)InvokeOp("JsonSetValue", storeId, "Fun.Circus", "Times");
 | 
				
			||||||
                Assert.That(result, Is.EqualTo(0));
 | 
					                Assert.That(result, Is.EqualTo(0));
 | 
				
			||||||
| 
						 | 
					@ -363,27 +685,27 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Test]
 | 
					        [Test]
 | 
				
			||||||
        public void TestJsonSetValueJson()
 | 
					        public void TestJsonSetJson()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            TestHelpers.InMethod();
 | 
					            TestHelpers.InMethod();
 | 
				
			||||||
//            TestHelpers.EnableLogging();
 | 
					//            TestHelpers.EnableLogging();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Single quoted token case
 | 
					            // Single quoted token case
 | 
				
			||||||
//            {
 | 
					            {
 | 
				
			||||||
//                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); 
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); 
 | 
				
			||||||
//
 | 
					
 | 
				
			||||||
//                int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun", "'Times'");
 | 
					                int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "'Times'");
 | 
				
			||||||
//                Assert.That(result, Is.EqualTo(1));
 | 
					                Assert.That(result, Is.EqualTo(1));
 | 
				
			||||||
//
 | 
					
 | 
				
			||||||
//                string value = (string)InvokeOp("JsonGetValue", storeId, "Fun");
 | 
					                string value = (string)InvokeOp("JsonGetValue", storeId, "Fun");
 | 
				
			||||||
//                Assert.That(value, Is.EqualTo("Times"));
 | 
					                Assert.That(value, Is.EqualTo("Times"));
 | 
				
			||||||
//            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Sub-tree case
 | 
					            // Sub-tree case
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); 
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun", "{ 'Filled' : 'Times' }");
 | 
					                int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "{ 'Filled' : 'Times' }");
 | 
				
			||||||
                Assert.That(result, Is.EqualTo(1));
 | 
					                Assert.That(result, Is.EqualTo(1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Filled");
 | 
					                string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Filled");
 | 
				
			||||||
| 
						 | 
					@ -394,7 +716,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); 
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun", "Times");
 | 
					                int result = (int)InvokeOp("JsonSetJson", storeId, "Fun", "Times");
 | 
				
			||||||
                Assert.That(result, Is.EqualTo(0));
 | 
					                Assert.That(result, Is.EqualTo(0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                string value = (string)InvokeOp("JsonGetValue", storeId, "Fun");
 | 
					                string value = (string)InvokeOp("JsonGetValue", storeId, "Fun");
 | 
				
			||||||
| 
						 | 
					@ -405,7 +727,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); 
 | 
					                UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ }"); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                int result = (int)InvokeOp("JsonSetValueJson", storeId, "Fun.Circus", "'Times'");
 | 
					                int result = (int)InvokeOp("JsonSetJson", storeId, "Fun.Circus", "'Times'");
 | 
				
			||||||
                Assert.That(result, Is.EqualTo(0));
 | 
					                Assert.That(result, Is.EqualTo(0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Circus");
 | 
					                string value = (string)InvokeOp("JsonGetValue", storeId, "Fun.Circus");
 | 
				
			||||||
| 
						 | 
					@ -415,7 +737,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
 | 
				
			||||||
            // Test with fake store
 | 
					            // Test with fake store
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                UUID fakeStoreId = TestHelpers.ParseTail(0x500);
 | 
					                UUID fakeStoreId = TestHelpers.ParseTail(0x500);
 | 
				
			||||||
                int fakeStoreValueSet = (int)InvokeOp("JsonSetValueJson", fakeStoreId, "Hello", "'World'");
 | 
					                int fakeStoreValueSet = (int)InvokeOp("JsonSetJson", fakeStoreId, "Hello", "'World'");
 | 
				
			||||||
                Assert.That(fakeStoreValueSet, Is.EqualTo(0));
 | 
					                Assert.That(fakeStoreValueSet, Is.EqualTo(0));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -225,9 +225,10 @@ public enum CollisionFlags : uint
 | 
				
			||||||
    CF_DISABLE_VISUALIZE_OBJECT      = 1 << 5,
 | 
					    CF_DISABLE_VISUALIZE_OBJECT      = 1 << 5,
 | 
				
			||||||
    CF_DISABLE_SPU_COLLISION_PROCESS = 1 << 6,
 | 
					    CF_DISABLE_SPU_COLLISION_PROCESS = 1 << 6,
 | 
				
			||||||
    // Following used by BulletSim to control collisions and updates
 | 
					    // Following used by BulletSim to control collisions and updates
 | 
				
			||||||
    BS_SUBSCRIBE_COLLISION_EVENTS    = 1 << 10,
 | 
					    BS_SUBSCRIBE_COLLISION_EVENTS    = 1 << 10, // return collision events from unmanaged to managed
 | 
				
			||||||
    BS_FLOATS_ON_WATER               = 1 << 11,
 | 
					    BS_FLOATS_ON_WATER               = 1 << 11, // the object should float at water level
 | 
				
			||||||
    BS_VEHICLE_COLLISIONS            = 1 << 12,
 | 
					    BS_VEHICLE_COLLISIONS            = 1 << 12, // return collisions for vehicle ground checking
 | 
				
			||||||
 | 
					    BS_RETURN_ROOT_COMPOUND_SHAPE    = 1 << 13, // return the pos/rot of the root shape in a compound shape
 | 
				
			||||||
    BS_NONE                          = 0,
 | 
					    BS_NONE                          = 0,
 | 
				
			||||||
    BS_ALL                           = 0xFFFFFFFF
 | 
					    BS_ALL                           = 0xFFFFFFFF
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,7 +83,7 @@ public sealed class BSCharacter : BSPhysObject
 | 
				
			||||||
        _velocity = OMV.Vector3.Zero;
 | 
					        _velocity = OMV.Vector3.Zero;
 | 
				
			||||||
        _buoyancy = ComputeBuoyancyFromFlying(isFlying);
 | 
					        _buoyancy = ComputeBuoyancyFromFlying(isFlying);
 | 
				
			||||||
        Friction = BSParam.AvatarStandingFriction;
 | 
					        Friction = BSParam.AvatarStandingFriction;
 | 
				
			||||||
        Density = BSParam.AvatarDensity;
 | 
					        Density = BSParam.AvatarDensity / BSParam.DensityScaleFactor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Old versions of ScenePresence passed only the height. If width and/or depth are zero,
 | 
					        // Old versions of ScenePresence passed only the height. If width and/or depth are zero,
 | 
				
			||||||
        //     replace with the default values.
 | 
					        //     replace with the default values.
 | 
				
			||||||
| 
						 | 
					@ -231,6 +231,15 @@ public sealed class BSCharacter : BSPhysObject
 | 
				
			||||||
                        PhysicsScene.PE.SetFriction(PhysBody, Friction);
 | 
					                        PhysicsScene.PE.SetFriction(PhysBody, Friction);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (Flying)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        // Flying and not collising and velocity nearly zero.
 | 
				
			||||||
 | 
					                        ZeroMotion(true /* inTaintTime */);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1},colliding={2}", LocalID, _velocityMotor.TargetValue, IsColliding);
 | 
					                DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1},colliding={2}", LocalID, _velocityMotor.TargetValue, IsColliding);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
| 
						 | 
					@ -274,7 +283,7 @@ public sealed class BSCharacter : BSPhysObject
 | 
				
			||||||
        // This test is done if moving forward, not flying and is colliding with something.
 | 
					        // This test is done if moving forward, not flying and is colliding with something.
 | 
				
			||||||
        // DetailLog("{0},BSCharacter.WalkUpStairs,IsColliding={1},flying={2},targSpeed={3},collisions={4}",
 | 
					        // DetailLog("{0},BSCharacter.WalkUpStairs,IsColliding={1},flying={2},targSpeed={3},collisions={4}",
 | 
				
			||||||
        //                 LocalID, IsColliding, Flying, TargetSpeed, CollisionsLastTick.Count);
 | 
					        //                 LocalID, IsColliding, Flying, TargetSpeed, CollisionsLastTick.Count);
 | 
				
			||||||
        if (IsColliding && !Flying && TargetSpeed > 0.1f /* && ForwardSpeed < 0.1f */)
 | 
					        if (IsColliding && !Flying && TargetVelocitySpeed > 0.1f /* && ForwardSpeed < 0.1f */)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            // The range near the character's feet where we will consider stairs
 | 
					            // The range near the character's feet where we will consider stairs
 | 
				
			||||||
            float nearFeetHeightMin = RawPosition.Z - (Size.Z / 2f) + 0.05f;
 | 
					            float nearFeetHeightMin = RawPosition.Z - (Size.Z / 2f) + 0.05f;
 | 
				
			||||||
| 
						 | 
					@ -869,7 +878,7 @@ public sealed class BSCharacter : BSPhysObject
 | 
				
			||||||
                        * Math.Min(Size.X, Size.Y) / 2
 | 
					                        * Math.Min(Size.X, Size.Y) / 2
 | 
				
			||||||
                        * Size.Y / 2f    // plus the volume of the capsule end caps
 | 
					                        * Size.Y / 2f    // plus the volume of the capsule end caps
 | 
				
			||||||
                        );
 | 
					                        );
 | 
				
			||||||
        _mass = Density * _avatarVolume;
 | 
					        _mass = Density * BSParam.DensityScaleFactor * _avatarVolume;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // The physics engine says that properties have updated. Update same and inform
 | 
					    // The physics engine says that properties have updated. Update same and inform
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -127,6 +127,8 @@ public abstract class BSLinkset
 | 
				
			||||||
        m_children = new HashSet<BSPrimLinkable>();
 | 
					        m_children = new HashSet<BSPrimLinkable>();
 | 
				
			||||||
        LinksetMass = parent.RawMass;
 | 
					        LinksetMass = parent.RawMass;
 | 
				
			||||||
        Rebuilding = false;
 | 
					        Rebuilding = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        parent.ClearDisplacement();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Link to a linkset where the child knows the parent.
 | 
					    // Link to a linkset where the child knows the parent.
 | 
				
			||||||
| 
						 | 
					@ -280,6 +282,7 @@ public abstract class BSLinkset
 | 
				
			||||||
        return mass;
 | 
					        return mass;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Computes linkset's center of mass in world coordinates.
 | 
				
			||||||
    protected virtual OMV.Vector3 ComputeLinksetCenterOfMass()
 | 
					    protected virtual OMV.Vector3 ComputeLinksetCenterOfMass()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        OMV.Vector3 com;
 | 
					        OMV.Vector3 com;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -93,7 +93,8 @@ public sealed class BSLinksetCompound : BSLinkset
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]";
 | 
					    private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public BSLinksetCompound(BSScene scene, BSPrimLinkable parent) : base(scene, parent)
 | 
					    public BSLinksetCompound(BSScene scene, BSPrimLinkable parent)
 | 
				
			||||||
 | 
					        : base(scene, parent)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -217,14 +218,6 @@ public sealed class BSLinksetCompound : BSLinkset
 | 
				
			||||||
            //     and that is caused by us updating the object.
 | 
					            //     and that is caused by us updating the object.
 | 
				
			||||||
            if ((whichUpdated & ~(UpdatedProperties.Position | UpdatedProperties.Orientation)) == 0)
 | 
					            if ((whichUpdated & ~(UpdatedProperties.Position | UpdatedProperties.Orientation)) == 0)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // Gather the child info. It might not be there if the linkset is in transition.
 | 
					 | 
				
			||||||
                BSLinksetCompoundInfo lsi = updated.LinksetInfo as BSLinksetCompoundInfo;
 | 
					 | 
				
			||||||
                if (lsi != null)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    // Since the child moved or rotationed, it needs a new relative position within the linkset
 | 
					 | 
				
			||||||
                    BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, OMV.Vector3.Zero);
 | 
					 | 
				
			||||||
                    updated.LinksetInfo = newLsi;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    // Find the physical instance of the child 
 | 
					                    // Find the physical instance of the child 
 | 
				
			||||||
                if (LinksetRoot.PhysShape.HasPhysicalShape && PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape))
 | 
					                if (LinksetRoot.PhysShape.HasPhysicalShape && PhysicsScene.PE.IsCompound(LinksetRoot.PhysShape))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
| 
						 | 
					@ -234,19 +227,19 @@ public sealed class BSLinksetCompound : BSLinkset
 | 
				
			||||||
                    // The index must be checked because Bullet references the child array but does no validity
 | 
					                    // The index must be checked because Bullet references the child array but does no validity
 | 
				
			||||||
                    //    checking of the child index passed.
 | 
					                    //    checking of the child index passed.
 | 
				
			||||||
                    int numLinksetChildren = PhysicsScene.PE.GetNumberOfCompoundChildren(LinksetRoot.PhysShape);
 | 
					                    int numLinksetChildren = PhysicsScene.PE.GetNumberOfCompoundChildren(LinksetRoot.PhysShape);
 | 
				
			||||||
                        if (lsi.Index < numLinksetChildren)
 | 
					                    if (updated.LinksetChildIndex < numLinksetChildren)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                            BulletShape linksetChildShape = PhysicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape, lsi.Index);
 | 
					                        BulletShape linksetChildShape = PhysicsScene.PE.GetChildShapeFromCompoundShapeIndex(LinksetRoot.PhysShape, updated.LinksetChildIndex);
 | 
				
			||||||
                        if (linksetChildShape.HasPhysicalShape)
 | 
					                        if (linksetChildShape.HasPhysicalShape)
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            // Found the child shape within the compound shape
 | 
					                            // Found the child shape within the compound shape
 | 
				
			||||||
                                PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, lsi.Index,
 | 
					                            PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, updated.LinksetChildIndex,
 | 
				
			||||||
                                                                            newLsi.OffsetFromCenterOfMass,
 | 
					                                                                        updated.RawPosition - LinksetRoot.RawPosition,
 | 
				
			||||||
                                                                            newLsi.OffsetRot,
 | 
					                                                                        updated.RawOrientation * OMV.Quaternion.Inverse(LinksetRoot.RawOrientation),
 | 
				
			||||||
                                                                        true /* shouldRecalculateLocalAabb */);
 | 
					                                                                        true /* shouldRecalculateLocalAabb */);
 | 
				
			||||||
                            updatedChild = true;
 | 
					                            updatedChild = true;
 | 
				
			||||||
                                DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1},newLsi={2}",
 | 
					                            DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1},pos={2},rot={3}",
 | 
				
			||||||
                                                                            updated.LocalID, whichUpdated, newLsi);
 | 
					                                                        updated.LocalID, whichUpdated, updated.RawPosition, updated.RawOrientation);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        else    // DEBUG DEBUG
 | 
					                        else    // DEBUG DEBUG
 | 
				
			||||||
                        {       // DEBUG DEBUG
 | 
					                        {       // DEBUG DEBUG
 | 
				
			||||||
| 
						 | 
					@ -258,19 +251,13 @@ public sealed class BSLinksetCompound : BSLinkset
 | 
				
			||||||
                    {       // DEBUG DEBUG
 | 
					                    {       // DEBUG DEBUG
 | 
				
			||||||
                        // the child is not yet in the compound shape. This is non-fatal.
 | 
					                        // the child is not yet in the compound shape. This is non-fatal.
 | 
				
			||||||
                        DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,childNotInCompoundShape,numChildren={1},index={2}",
 | 
					                        DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,childNotInCompoundShape,numChildren={1},index={2}",
 | 
				
			||||||
                                                                        updated.LocalID, numLinksetChildren, lsi.Index);
 | 
					                                                                    updated.LocalID, numLinksetChildren, updated.LinksetChildIndex);
 | 
				
			||||||
                    }       // DEBUG DEBUG
 | 
					                    }       // DEBUG DEBUG
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else    // DEBUG DEBUG
 | 
					                else    // DEBUG DEBUG
 | 
				
			||||||
                {       // DEBUG DEBUG
 | 
					                {       // DEBUG DEBUG
 | 
				
			||||||
                    DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noBodyOrNotCompound", updated.LocalID);
 | 
					                    DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noBodyOrNotCompound", updated.LocalID);
 | 
				
			||||||
                }       // DEBUG DEBUG
 | 
					                }       // DEBUG DEBUG
 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else    // DEBUG DEBUG
 | 
					 | 
				
			||||||
                {       // DEBUG DEBUG
 | 
					 | 
				
			||||||
                    DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild,noLinkSetInfo,rootPhysShape={1}",
 | 
					 | 
				
			||||||
                                                    updated.LocalID, LinksetRoot.PhysShape);
 | 
					 | 
				
			||||||
                }       // DEBUG DEBUG
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (!updatedChild)
 | 
					                if (!updatedChild)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
| 
						 | 
					@ -379,6 +366,8 @@ public sealed class BSLinksetCompound : BSLinkset
 | 
				
			||||||
    // Safe to call even if the child is not really in the linkset.
 | 
					    // Safe to call even if the child is not really in the linkset.
 | 
				
			||||||
    protected override void RemoveChildFromLinkset(BSPrimLinkable child)
 | 
					    protected override void RemoveChildFromLinkset(BSPrimLinkable child)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        child.ClearDisplacement();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (m_children.Remove(child))
 | 
					        if (m_children.Remove(child))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            DetailLog("{0},BSLinksetCompound.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}",
 | 
					            DetailLog("{0},BSLinksetCompound.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}",
 | 
				
			||||||
| 
						 | 
					@ -424,30 +413,31 @@ public sealed class BSLinksetCompound : BSLinkset
 | 
				
			||||||
            // The center of mass for the linkset is the geometric center of the group.
 | 
					            // The center of mass for the linkset is the geometric center of the group.
 | 
				
			||||||
            // Compute a displacement for each component so it is relative to the center-of-mass.
 | 
					            // Compute a displacement for each component so it is relative to the center-of-mass.
 | 
				
			||||||
            // Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass
 | 
					            // Bullet presumes an object's origin (relative <0,0,0>) is its center-of-mass
 | 
				
			||||||
            OMV.Vector3 centerOfMass;
 | 
					            OMV.Vector3 centerOfMassW = LinksetRoot.RawPosition;
 | 
				
			||||||
            OMV.Vector3 centerDisplacement = OMV.Vector3.Zero;
 | 
					            if (!disableCOM)                             // DEBUG DEBUG
 | 
				
			||||||
            if (disableCOM)                             // DEBUG DEBUG
 | 
					 | 
				
			||||||
            {                                           // DEBUG DEBUG
 | 
					 | 
				
			||||||
                centerOfMass = LinksetRoot.RawPosition; // DEBUG DEBUG
 | 
					 | 
				
			||||||
                // LinksetRoot.PositionDisplacement = OMV.Vector3.Zero;
 | 
					 | 
				
			||||||
            }                                           // DEBUG DEBUG
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                centerOfMass = ComputeLinksetCenterOfMass();
 | 
					                // Compute a center-of-mass in world coordinates.
 | 
				
			||||||
                // 'centerDisplacement' is the value to *add* to all the shape offsets
 | 
					                centerOfMassW = ComputeLinksetCenterOfMass();
 | 
				
			||||||
                centerDisplacement = LinksetRoot.RawPosition - centerOfMass;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // Since we're displacing the center of the shape, we need to move the body in the world
 | 
					 | 
				
			||||||
                // LinksetRoot.PositionDisplacement = centerDisplacement;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // This causes the root prim position to be set properly based on the new PositionDisplacement
 | 
					 | 
				
			||||||
                LinksetRoot.ForcePosition = LinksetRoot.RawPosition;
 | 
					 | 
				
			||||||
                // Update the local transform for the root child shape so it is offset from the <0,0,0> which is COM
 | 
					 | 
				
			||||||
                PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0, -centerDisplacement, OMV.Quaternion.Identity, false);
 | 
					 | 
				
			||||||
                DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}",
 | 
					 | 
				
			||||||
                                        LinksetRoot.LocalID, centerOfMass, LinksetRoot.RawPosition, centerDisplacement);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // 'centerDisplacement' is the value to subtract from children to give physical offset position
 | 
				
			||||||
 | 
					            OMV.Vector3 centerDisplacement = (centerOfMassW - LinksetRoot.RawPosition) * invRootOrientation;
 | 
				
			||||||
 | 
					            LinksetRoot.SetEffectiveCenterOfMassW(centerDisplacement);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // This causes the physical position of the root prim to be offset to accomodate for the displacements
 | 
				
			||||||
 | 
					            LinksetRoot.ForcePosition = LinksetRoot.RawPosition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Update the local transform for the root child shape so it is offset from the <0,0,0> which is COM
 | 
				
			||||||
 | 
					            PhysicsScene.PE.UpdateChildTransform(LinksetRoot.PhysShape, 0 /* childIndex */,
 | 
				
			||||||
 | 
					                                                -centerDisplacement,
 | 
				
			||||||
 | 
					                                                OMV.Quaternion.Identity, // LinksetRoot.RawOrientation,
 | 
				
			||||||
 | 
					                                                false /* shouldRecalculateLocalAabb (is done later after linkset built) */);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,COM,com={1},rootPos={2},centerDisp={3}",
 | 
				
			||||||
 | 
					                                    LinksetRoot.LocalID, centerOfMassW, LinksetRoot.RawPosition, centerDisplacement);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}",
 | 
					            DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}",
 | 
				
			||||||
                            LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren);
 | 
					                            LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -455,38 +445,33 @@ public sealed class BSLinksetCompound : BSLinkset
 | 
				
			||||||
            int memberIndex = 1;
 | 
					            int memberIndex = 1;
 | 
				
			||||||
            ForEachMember(delegate(BSPrimLinkable cPrim)
 | 
					            ForEachMember(delegate(BSPrimLinkable cPrim)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (!IsRoot(cPrim))
 | 
					                if (IsRoot(cPrim))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    // Compute the displacement of the child from the root of the linkset.
 | 
					                    cPrim.LinksetChildIndex = 0;
 | 
				
			||||||
                    // This info is saved in the child prim so the relationship does not
 | 
					 | 
				
			||||||
                    //    change over time and the new child position can be computed
 | 
					 | 
				
			||||||
                    //    when the linkset is being disassembled (the linkset may have moved).
 | 
					 | 
				
			||||||
                    BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo;
 | 
					 | 
				
			||||||
                    if (lci == null)
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        lci = new BSLinksetCompoundInfo(memberIndex, LinksetRoot, cPrim, centerDisplacement);
 | 
					 | 
				
			||||||
                        cPrim.LinksetInfo = lci;
 | 
					 | 
				
			||||||
                        DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci);
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
                    DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},lci={3}",
 | 
					                {
 | 
				
			||||||
                                                LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci);
 | 
					                    cPrim.LinksetChildIndex = memberIndex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (cPrim.PhysShape.isNativeShape)
 | 
					                    if (cPrim.PhysShape.isNativeShape)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        // A native shape is turned into a hull collision shape because native
 | 
					                        // A native shape is turned into a hull collision shape because native
 | 
				
			||||||
                        //    shapes are not shared so we have to hullify it so it will be tracked
 | 
					                        //    shapes are not shared so we have to hullify it so it will be tracked
 | 
				
			||||||
                        //    and freed at the correct time. This also solves the scaling problem
 | 
					                        //    and freed at the correct time. This also solves the scaling problem
 | 
				
			||||||
                        //    (native shapes scaled but hull/meshes are assumed to not be).
 | 
					                        //    (native shapes scale but hull/meshes are assumed to not be).
 | 
				
			||||||
                        // TODO: decide of the native shape can just be used in the compound shape.
 | 
					                        // TODO: decide of the native shape can just be used in the compound shape.
 | 
				
			||||||
                        //    Use call to CreateGeomNonSpecial().
 | 
					                        //    Use call to CreateGeomNonSpecial().
 | 
				
			||||||
                        BulletShape saveShape = cPrim.PhysShape;
 | 
					                        BulletShape saveShape = cPrim.PhysShape;
 | 
				
			||||||
                        cPrim.PhysShape.Clear();        // Don't let the create free the child's shape
 | 
					                        cPrim.PhysShape.Clear();        // Don't let the create free the child's shape
 | 
				
			||||||
                        // PhysicsScene.Shapes.CreateGeomNonSpecial(true, cPrim, null);
 | 
					 | 
				
			||||||
                        PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null);
 | 
					                        PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null);
 | 
				
			||||||
                        BulletShape newShape = cPrim.PhysShape;
 | 
					                        BulletShape newShape = cPrim.PhysShape;
 | 
				
			||||||
                        cPrim.PhysShape = saveShape;
 | 
					                        cPrim.PhysShape = saveShape;
 | 
				
			||||||
                        PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, lci.OffsetFromCenterOfMass, lci.OffsetRot);
 | 
					
 | 
				
			||||||
 | 
					                        OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacement;
 | 
				
			||||||
 | 
					                        OMV.Quaternion offsetRot = cPrim.RawOrientation * invRootOrientation;
 | 
				
			||||||
 | 
					                        PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, newShape, offsetPos, offsetRot);
 | 
				
			||||||
 | 
					                        DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addNative,indx={1},rShape={2},cShape={3},offPos={4},offRot={5}",
 | 
				
			||||||
 | 
					                                    LinksetRoot.LocalID, memberIndex, LinksetRoot.PhysShape, newShape, offsetPos, offsetRot);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    else
 | 
					                    else
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
| 
						 | 
					@ -498,9 +483,13 @@ public sealed class BSLinksetCompound : BSLinkset
 | 
				
			||||||
                            PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}",
 | 
					                            PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}",
 | 
				
			||||||
                                                LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape);
 | 
					                                                LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, lci.OffsetFromCenterOfMass, lci.OffsetRot);
 | 
					                        OMV.Vector3 offsetPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation - centerDisplacement;
 | 
				
			||||||
 | 
					                        OMV.Quaternion offsetRot = cPrim.RawOrientation * invRootOrientation;
 | 
				
			||||||
 | 
					                        PhysicsScene.PE.AddChildShapeToCompoundShape(LinksetRoot.PhysShape, cPrim.PhysShape, offsetPos, offsetRot);
 | 
				
			||||||
 | 
					                        DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addNonNative,indx={1},rShape={2},cShape={3},offPos={4},offRot={5}",
 | 
				
			||||||
 | 
					                                    LinksetRoot.LocalID, memberIndex, LinksetRoot.PhysShape, cPrim.PhysShape, offsetPos, offsetRot);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    lci.Index = memberIndex;
 | 
					 | 
				
			||||||
                    memberIndex++;
 | 
					                    memberIndex++;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                return false;   // 'false' says to move onto the next child in the list
 | 
					                return false;   // 'false' says to move onto the next child in the list
 | 
				
			||||||
| 
						 | 
					@ -509,12 +498,16 @@ public sealed class BSLinksetCompound : BSLinkset
 | 
				
			||||||
            // With all of the linkset packed into the root prim, it has the mass of everyone.
 | 
					            // With all of the linkset packed into the root prim, it has the mass of everyone.
 | 
				
			||||||
            LinksetMass = ComputeLinksetMass();
 | 
					            LinksetMass = ComputeLinksetMass();
 | 
				
			||||||
            LinksetRoot.UpdatePhysicalMassProperties(LinksetMass, true);
 | 
					            LinksetRoot.UpdatePhysicalMassProperties(LinksetMass, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Enable the physical position updator to return the position and rotation of the root shape
 | 
				
			||||||
 | 
					            PhysicsScene.PE.AddToCollisionFlags(LinksetRoot.PhysBody, CollisionFlags.BS_RETURN_ROOT_COMPOUND_SHAPE);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        finally
 | 
					        finally
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Rebuilding = false;
 | 
					            Rebuilding = false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // See that the Aabb surrounds the new shape
 | 
				
			||||||
        PhysicsScene.PE.RecalculateCompoundShapeLocalAabb(LinksetRoot.PhysShape);
 | 
					        PhysicsScene.PE.RecalculateCompoundShapeLocalAabb(LinksetRoot.PhysShape);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,6 +49,7 @@ public static class BSParam
 | 
				
			||||||
    public static float MaxLinearVelocity { get; private set; }
 | 
					    public static float MaxLinearVelocity { get; private set; }
 | 
				
			||||||
    public static float MaxAngularVelocity { get; private set; }
 | 
					    public static float MaxAngularVelocity { get; private set; }
 | 
				
			||||||
    public static float MaxAddForceMagnitude { get; private set; }
 | 
					    public static float MaxAddForceMagnitude { get; private set; }
 | 
				
			||||||
 | 
					    public static float DensityScaleFactor { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static float LinearDamping { get; private set; }
 | 
					    public static float LinearDamping { get; private set; }
 | 
				
			||||||
    public static float AngularDamping { get; private set; }
 | 
					    public static float AngularDamping { get; private set; }
 | 
				
			||||||
| 
						 | 
					@ -281,29 +282,35 @@ public static class BSParam
 | 
				
			||||||
        new ParameterDefn("MinObjectMass", "Minimum object mass (0.0001)",
 | 
					        new ParameterDefn("MinObjectMass", "Minimum object mass (0.0001)",
 | 
				
			||||||
            0.0001f,
 | 
					            0.0001f,
 | 
				
			||||||
            (s,cf,p,v) => { MinimumObjectMass = cf.GetFloat(p, v); },
 | 
					            (s,cf,p,v) => { MinimumObjectMass = cf.GetFloat(p, v); },
 | 
				
			||||||
            (s) => { return (float)MinimumObjectMass; },
 | 
					            (s) => { return MinimumObjectMass; },
 | 
				
			||||||
            (s,p,l,v) => { MinimumObjectMass = v; } ),
 | 
					            (s,p,l,v) => { MinimumObjectMass = v; } ),
 | 
				
			||||||
        new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)",
 | 
					        new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)",
 | 
				
			||||||
            10000.01f,
 | 
					            10000.01f,
 | 
				
			||||||
            (s,cf,p,v) => { MaximumObjectMass = cf.GetFloat(p, v); },
 | 
					            (s,cf,p,v) => { MaximumObjectMass = cf.GetFloat(p, v); },
 | 
				
			||||||
            (s) => { return (float)MaximumObjectMass; },
 | 
					            (s) => { return MaximumObjectMass; },
 | 
				
			||||||
            (s,p,l,v) => { MaximumObjectMass = v; } ),
 | 
					            (s,p,l,v) => { MaximumObjectMass = v; } ),
 | 
				
			||||||
        new ParameterDefn("MaxLinearVelocity", "Maximum velocity magnitude that can be assigned to an object",
 | 
					        new ParameterDefn("MaxLinearVelocity", "Maximum velocity magnitude that can be assigned to an object",
 | 
				
			||||||
            1000.0f,
 | 
					            1000.0f,
 | 
				
			||||||
            (s,cf,p,v) => { MaxLinearVelocity = cf.GetFloat(p, v); },
 | 
					            (s,cf,p,v) => { MaxLinearVelocity = cf.GetFloat(p, v); },
 | 
				
			||||||
            (s) => { return (float)MaxLinearVelocity; },
 | 
					            (s) => { return MaxLinearVelocity; },
 | 
				
			||||||
            (s,p,l,v) => { MaxLinearVelocity = v; } ),
 | 
					            (s,p,l,v) => { MaxLinearVelocity = v; } ),
 | 
				
			||||||
        new ParameterDefn("MaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to an object",
 | 
					        new ParameterDefn("MaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to an object",
 | 
				
			||||||
            1000.0f,
 | 
					            1000.0f,
 | 
				
			||||||
            (s,cf,p,v) => { MaxAngularVelocity = cf.GetFloat(p, v); },
 | 
					            (s,cf,p,v) => { MaxAngularVelocity = cf.GetFloat(p, v); },
 | 
				
			||||||
            (s) => { return (float)MaxAngularVelocity; },
 | 
					            (s) => { return MaxAngularVelocity; },
 | 
				
			||||||
            (s,p,l,v) => { MaxAngularVelocity = v; } ),
 | 
					            (s,p,l,v) => { MaxAngularVelocity = v; } ),
 | 
				
			||||||
        // LL documentation says thie number should be 20f for llApplyImpulse and 200f for llRezObject
 | 
					        // LL documentation says thie number should be 20f for llApplyImpulse and 200f for llRezObject
 | 
				
			||||||
        new ParameterDefn("MaxAddForceMagnitude", "Maximum force that can be applied by llApplyImpulse (SL says 20f)",
 | 
					        new ParameterDefn("MaxAddForceMagnitude", "Maximum force that can be applied by llApplyImpulse (SL says 20f)",
 | 
				
			||||||
            20000.0f,
 | 
					            20000.0f,
 | 
				
			||||||
            (s,cf,p,v) => { MaxAddForceMagnitude = cf.GetFloat(p, v); },
 | 
					            (s,cf,p,v) => { MaxAddForceMagnitude = cf.GetFloat(p, v); },
 | 
				
			||||||
            (s) => { return (float)MaxAddForceMagnitude; },
 | 
					            (s) => { return MaxAddForceMagnitude; },
 | 
				
			||||||
            (s,p,l,v) => { MaxAddForceMagnitude = v; } ),
 | 
					            (s,p,l,v) => { MaxAddForceMagnitude = v; } ),
 | 
				
			||||||
 | 
					        // Density is passed around as 100kg/m3. This scales that to 1kg/m3.
 | 
				
			||||||
 | 
					        new ParameterDefn("DensityScaleFactor", "Conversion for simulator/viewer density (100kg/m3) to physical density (1kg/m3)",
 | 
				
			||||||
 | 
					            0.01f,
 | 
				
			||||||
 | 
					            (s,cf,p,v) => { DensityScaleFactor = cf.GetFloat(p, v); },
 | 
				
			||||||
 | 
					            (s) => { return DensityScaleFactor; },
 | 
				
			||||||
 | 
					            (s,p,l,v) => { DensityScaleFactor = v; } ),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        new ParameterDefn("PID_D", "Derivitive factor for motion smoothing",
 | 
					        new ParameterDefn("PID_D", "Derivitive factor for motion smoothing",
 | 
				
			||||||
            2200f,
 | 
					            2200f,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,6 +99,9 @@ public abstract class BSPhysObject : PhysicsActor
 | 
				
			||||||
        CollisionAccumulation = 0;
 | 
					        CollisionAccumulation = 0;
 | 
				
			||||||
        ColliderIsMoving = false;
 | 
					        ColliderIsMoving = false;
 | 
				
			||||||
        CollisionScore = 0;
 | 
					        CollisionScore = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // All axis free.
 | 
				
			||||||
 | 
					        LockedAxis = LockedAxisFree;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Tell the object to clean up.
 | 
					    // Tell the object to clean up.
 | 
				
			||||||
| 
						 | 
					@ -136,6 +139,7 @@ public abstract class BSPhysObject : PhysicsActor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // The objects base shape information. Null if not a prim type shape.
 | 
					    // The objects base shape information. Null if not a prim type shape.
 | 
				
			||||||
    public PrimitiveBaseShape BaseShape { get; protected set; }
 | 
					    public PrimitiveBaseShape BaseShape { get; protected set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Some types of objects have preferred physical representations.
 | 
					    // Some types of objects have preferred physical representations.
 | 
				
			||||||
    // Returns SHAPE_UNKNOWN if there is no preference.
 | 
					    // Returns SHAPE_UNKNOWN if there is no preference.
 | 
				
			||||||
    public virtual BSPhysicsShapeType PreferredPhysicalShape
 | 
					    public virtual BSPhysicsShapeType PreferredPhysicalShape
 | 
				
			||||||
| 
						 | 
					@ -150,15 +154,17 @@ public abstract class BSPhysObject : PhysicsActor
 | 
				
			||||||
    public EntityProperties LastEntityProperties { get; set; }
 | 
					    public EntityProperties LastEntityProperties { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public virtual OMV.Vector3 Scale { get; set; }
 | 
					    public virtual OMV.Vector3 Scale { get; set; }
 | 
				
			||||||
    public abstract bool IsSolid { get; }
 | 
					 | 
				
			||||||
    public abstract bool IsStatic { get; }
 | 
					 | 
				
			||||||
    public abstract bool IsSelected { get; }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // It can be confusing for an actor to know if it should move or update an object
 | 
					    // It can be confusing for an actor to know if it should move or update an object
 | 
				
			||||||
    //    depeneding on the setting of 'selected', 'physical, ...
 | 
					    //    depeneding on the setting of 'selected', 'physical, ...
 | 
				
			||||||
    // This flag is the true test -- if true, the object is being acted on in the physical world
 | 
					    // This flag is the true test -- if true, the object is being acted on in the physical world
 | 
				
			||||||
    public abstract bool IsPhysicallyActive { get; }
 | 
					    public abstract bool IsPhysicallyActive { get; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Detailed state of the object.
 | 
				
			||||||
 | 
					    public abstract bool IsSolid { get; }
 | 
				
			||||||
 | 
					    public abstract bool IsStatic { get; }
 | 
				
			||||||
 | 
					    public abstract bool IsSelected { get; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Materialness
 | 
					    // Materialness
 | 
				
			||||||
    public MaterialAttributes.Material Material { get; private set; }
 | 
					    public MaterialAttributes.Material Material { get; private set; }
 | 
				
			||||||
    public override void SetMaterial(int material)
 | 
					    public override void SetMaterial(int material)
 | 
				
			||||||
| 
						 | 
					@ -169,7 +175,8 @@ public abstract class BSPhysObject : PhysicsActor
 | 
				
			||||||
        MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false);
 | 
					        MaterialAttributes matAttrib = BSMaterials.GetAttributes(Material, false);
 | 
				
			||||||
        Friction = matAttrib.friction;
 | 
					        Friction = matAttrib.friction;
 | 
				
			||||||
        Restitution = matAttrib.restitution;
 | 
					        Restitution = matAttrib.restitution;
 | 
				
			||||||
        Density = matAttrib.density;
 | 
					        Density = matAttrib.density / BSParam.DensityScaleFactor;
 | 
				
			||||||
 | 
					        DetailLog("{0},{1}.SetMaterial,Mat={2},frict={3},rest={4},den={5}", LocalID, TypeName, Material, Friction, Restitution, Density);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Stop all physical motion.
 | 
					    // Stop all physical motion.
 | 
				
			||||||
| 
						 | 
					@ -185,14 +192,6 @@ public abstract class BSPhysObject : PhysicsActor
 | 
				
			||||||
    public abstract OMV.Quaternion RawOrientation { get; set; }
 | 
					    public abstract OMV.Quaternion RawOrientation { get; set; }
 | 
				
			||||||
    public abstract OMV.Quaternion ForceOrientation { get; set; }
 | 
					    public abstract OMV.Quaternion ForceOrientation { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public virtual float TargetSpeed
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        get
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            OMV.Vector3 characterOrientedVelocity = TargetVelocity * OMV.Quaternion.Inverse(OMV.Quaternion.Normalize(RawOrientation));
 | 
					 | 
				
			||||||
            return characterOrientedVelocity.X;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    public abstract OMV.Vector3 RawVelocity { get; set; }
 | 
					    public abstract OMV.Vector3 RawVelocity { get; set; }
 | 
				
			||||||
    public abstract OMV.Vector3 ForceVelocity { get; set; }
 | 
					    public abstract OMV.Vector3 ForceVelocity { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -202,6 +201,7 @@ public abstract class BSPhysObject : PhysicsActor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; }
 | 
					    public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // The current velocity forward
 | 
				
			||||||
    public virtual float ForwardSpeed
 | 
					    public virtual float ForwardSpeed
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        get
 | 
					        get
 | 
				
			||||||
| 
						 | 
					@ -210,6 +210,22 @@ public abstract class BSPhysObject : PhysicsActor
 | 
				
			||||||
            return characterOrientedVelocity.X;
 | 
					            return characterOrientedVelocity.X;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    // The forward speed we are trying to achieve (TargetVelocity)
 | 
				
			||||||
 | 
					    public virtual float TargetVelocitySpeed
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        get
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            OMV.Vector3 characterOrientedVelocity = TargetVelocity * OMV.Quaternion.Inverse(OMV.Quaternion.Normalize(RawOrientation));
 | 
				
			||||||
 | 
					            return characterOrientedVelocity.X;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // The user can optionally set the center of mass. The user's setting will override any
 | 
				
			||||||
 | 
					    //    computed center-of-mass (like in linksets).
 | 
				
			||||||
 | 
					    public OMV.Vector3? UserSetCenterOfMass { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public OMV.Vector3 LockedAxis { get; set; } // zero means locked. one means free.
 | 
				
			||||||
 | 
					    public readonly OMV.Vector3 LockedAxisFree = new OMV.Vector3(1f, 1f, 1f);  // All axis are free
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #region Collisions
 | 
					    #region Collisions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -407,9 +423,7 @@ public abstract class BSPhysObject : PhysicsActor
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            // Clean out any existing action
 | 
					            // Clean out any existing action
 | 
				
			||||||
            UnRegisterPreStepAction(op, id);
 | 
					            UnRegisterPreStepAction(op, id);
 | 
				
			||||||
 | 
					 | 
				
			||||||
            RegisteredPrestepActions[identifier] = actn;
 | 
					            RegisteredPrestepActions[identifier] = actn;
 | 
				
			||||||
 | 
					 | 
				
			||||||
            PhysicsScene.BeforeStep += actn;
 | 
					            PhysicsScene.BeforeStep += actn;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier);
 | 
					        DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier);
 | 
				
			||||||
| 
						 | 
					@ -455,9 +469,7 @@ public abstract class BSPhysObject : PhysicsActor
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            // Clean out any existing action
 | 
					            // Clean out any existing action
 | 
				
			||||||
            UnRegisterPostStepAction(op, id);
 | 
					            UnRegisterPostStepAction(op, id);
 | 
				
			||||||
 | 
					 | 
				
			||||||
            RegisteredPoststepActions[identifier] = actn;
 | 
					            RegisteredPoststepActions[identifier] = actn;
 | 
				
			||||||
 | 
					 | 
				
			||||||
            PhysicsScene.AfterStep += actn;
 | 
					            PhysicsScene.AfterStep += actn;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        DetailLog("{0},BSPhysObject.RegisterPostStepAction,id={1}", LocalID, identifier);
 | 
					        DetailLog("{0},BSPhysObject.RegisterPostStepAction,id={1}", LocalID, identifier);
 | 
				
			||||||
| 
						 | 
					@ -495,6 +507,57 @@ public abstract class BSPhysObject : PhysicsActor
 | 
				
			||||||
        DetailLog("{0},BSPhysObject.UnRegisterAllPostStepActions,", LocalID);
 | 
					        DetailLog("{0},BSPhysObject.UnRegisterAllPostStepActions,", LocalID);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // When an update to the physical properties happens, this event is fired to let
 | 
				
			||||||
 | 
					    //    different actors to modify the update before it is passed around
 | 
				
			||||||
 | 
					    public delegate void PreUpdatePropertyAction(ref EntityProperties entprop);
 | 
				
			||||||
 | 
					    public event PreUpdatePropertyAction OnPreUpdateProperty;
 | 
				
			||||||
 | 
					    protected void TriggerPreUpdatePropertyAction(ref EntityProperties entprop)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        PreUpdatePropertyAction actions = OnPreUpdateProperty;
 | 
				
			||||||
 | 
					        if (actions != null)
 | 
				
			||||||
 | 
					            actions(ref entprop);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private Dictionary<string, PreUpdatePropertyAction> RegisteredPreUpdatePropertyActions = new Dictionary<string, PreUpdatePropertyAction>();
 | 
				
			||||||
 | 
					    public void RegisterPreUpdatePropertyAction(string identifier, PreUpdatePropertyAction actn)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        lock (RegisteredPreUpdatePropertyActions)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Clean out any existing action
 | 
				
			||||||
 | 
					            UnRegisterPreUpdatePropertyAction(identifier);
 | 
				
			||||||
 | 
					            RegisteredPreUpdatePropertyActions[identifier] = actn;
 | 
				
			||||||
 | 
					            OnPreUpdateProperty += actn;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        DetailLog("{0},BSPhysObject.RegisterPreUpdatePropertyAction,id={1}", LocalID, identifier);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public bool UnRegisterPreUpdatePropertyAction(string identifier)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        bool removed = false;
 | 
				
			||||||
 | 
					        lock (RegisteredPreUpdatePropertyActions)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (RegisteredPreUpdatePropertyActions.ContainsKey(identifier))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                OnPreUpdateProperty -= RegisteredPreUpdatePropertyActions[identifier];
 | 
				
			||||||
 | 
					                RegisteredPreUpdatePropertyActions.Remove(identifier);
 | 
				
			||||||
 | 
					                removed = true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        DetailLog("{0},BSPhysObject.UnRegisterPreUpdatePropertyAction,id={1},removed={2}", LocalID, identifier, removed);
 | 
				
			||||||
 | 
					        return removed;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public void UnRegisterAllPreUpdatePropertyActions()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        lock (RegisteredPreUpdatePropertyActions)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            foreach (KeyValuePair<string, PreUpdatePropertyAction> kvp in RegisteredPreUpdatePropertyActions)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                OnPreUpdateProperty -= kvp.Value;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            RegisteredPreUpdatePropertyActions.Clear();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        DetailLog("{0},BSPhysObject.UnRegisterAllPreUpdatePropertyAction,", LocalID);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #endregion // Per Simulation Step actions
 | 
					    #endregion // Per Simulation Step actions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // High performance detailed logging routine used by the physical objects.
 | 
					    // High performance detailed logging routine used by the physical objects.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -242,6 +242,45 @@ public class BSPrim : BSPhysObject
 | 
				
			||||||
    public override void LockAngularMotion(OMV.Vector3 axis)
 | 
					    public override void LockAngularMotion(OMV.Vector3 axis)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
 | 
					        DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        OMV.Vector3 locking = new OMV.Vector3(1f, 1f, 1f);
 | 
				
			||||||
 | 
					        if (axis.X != 1) locking.X = 0f;
 | 
				
			||||||
 | 
					        if (axis.Y != 1) locking.Y = 0f;
 | 
				
			||||||
 | 
					        if (axis.Z != 1) locking.Z = 0f;
 | 
				
			||||||
 | 
					        LockedAxis = locking;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*  Not implemented yet
 | 
				
			||||||
 | 
					        if (LockedAxis != LockedAxisFree)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Something is locked so start the thingy that keeps that axis from changing
 | 
				
			||||||
 | 
					            RegisterPreUpdatePropertyAction("BSPrim.LockAngularMotion", delegate(ref EntityProperties entprop)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (LockedAxis != LockedAxisFree)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (IsPhysicallyActive)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        // Bullet can lock axis but it only works for global axis.
 | 
				
			||||||
 | 
					                        // Check if this prim is aligned on global axis and use Bullet's
 | 
				
			||||||
 | 
					                        //    system if so.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        ForceOrientation = entprop.Rotation;
 | 
				
			||||||
 | 
					                        ForceRotationalVelocity = entprop.RotationalVelocity;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    UnRegisterPreUpdatePropertyAction("BSPrim.LockAngularMotion");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Everything seems unlocked
 | 
				
			||||||
 | 
					            UnRegisterPreUpdatePropertyAction("BSPrim.LockAngularMotion");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -311,7 +350,8 @@ public class BSPrim : BSPhysObject
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition);
 | 
					        float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition);
 | 
				
			||||||
        OMV.Vector3 upForce = OMV.Vector3.Zero;
 | 
					        OMV.Vector3 upForce = OMV.Vector3.Zero;
 | 
				
			||||||
        if (RawPosition.Z < terrainHeight)
 | 
					        float approxSize = Math.Max(Size.X, Math.Max(Size.Y, Size.Z));
 | 
				
			||||||
 | 
					        if ((RawPosition.Z + approxSize / 2f) < terrainHeight)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, RawPosition, terrainHeight);
 | 
					            DetailLog("{0},BSPrim.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, RawPosition, terrainHeight);
 | 
				
			||||||
            float targetHeight = terrainHeight + (Size.Z / 2f);
 | 
					            float targetHeight = terrainHeight + (Size.Z / 2f);
 | 
				
			||||||
| 
						 | 
					@ -442,7 +482,7 @@ public class BSPrim : BSPhysObject
 | 
				
			||||||
                RegisterPreStepAction("BSPrim.setForce", LocalID,
 | 
					                RegisterPreStepAction("BSPrim.setForce", LocalID,
 | 
				
			||||||
                    delegate(float timeStep)
 | 
					                    delegate(float timeStep)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        if (!IsPhysicallyActive)
 | 
					                        if (!IsPhysicallyActive || _force == OMV.Vector3.Zero)
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            UnRegisterPreStepAction("BSPrim.setForce", LocalID);
 | 
					                            UnRegisterPreStepAction("BSPrim.setForce", LocalID);
 | 
				
			||||||
                            return;
 | 
					                            return;
 | 
				
			||||||
| 
						 | 
					@ -576,6 +616,8 @@ public class BSPrim : BSPhysObject
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    // The simulator/viewer keep density as 100kg/m3.
 | 
				
			||||||
 | 
					    // Remember to use BSParam.DensityScaleFactor to create the physical density.
 | 
				
			||||||
    public override float Density
 | 
					    public override float Density
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        get { return base.Density; }
 | 
					        get { return base.Density; }
 | 
				
			||||||
| 
						 | 
					@ -647,7 +689,7 @@ public class BSPrim : BSPhysObject
 | 
				
			||||||
                RegisterPreStepAction("BSPrim.setTorque", LocalID,
 | 
					                RegisterPreStepAction("BSPrim.setTorque", LocalID,
 | 
				
			||||||
                    delegate(float timeStep)
 | 
					                    delegate(float timeStep)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        if (!IsPhysicallyActive)
 | 
					                        if (!IsPhysicallyActive || _torque == OMV.Vector3.Zero)
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            UnRegisterPreStepAction("BSPrim.setTorque", LocalID);
 | 
					                            UnRegisterPreStepAction("BSPrim.setTorque", LocalID);
 | 
				
			||||||
                            return;
 | 
					                            return;
 | 
				
			||||||
| 
						 | 
					@ -1569,7 +1611,8 @@ public class BSPrim : BSPhysObject
 | 
				
			||||||
        profileEnd = 1.0f - (float)BaseShape.ProfileEnd * 2.0e-5f;
 | 
					        profileEnd = 1.0f - (float)BaseShape.ProfileEnd * 2.0e-5f;
 | 
				
			||||||
        volume *= (profileEnd - profileBegin);
 | 
					        volume *= (profileEnd - profileBegin);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        returnMass = Density * volume;
 | 
					        returnMass = Density * BSParam.DensityScaleFactor * volume;
 | 
				
			||||||
 | 
					        DetailLog("{0},BSPrim.CalculateMass,den={1},vol={2},mass={3}", LocalID, Density, volume, returnMass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass);
 | 
					        returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1607,6 +1650,8 @@ public class BSPrim : BSPhysObject
 | 
				
			||||||
    // the world that things have changed.
 | 
					    // the world that things have changed.
 | 
				
			||||||
    public override void UpdateProperties(EntityProperties entprop)
 | 
					    public override void UpdateProperties(EntityProperties entprop)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        TriggerPreUpdatePropertyAction(ref entprop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
 | 
					        // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
 | 
				
			||||||
        // TODO: handle physics introduced by Bullet with computed vehicle physics.
 | 
					        // TODO: handle physics introduced by Bullet with computed vehicle physics.
 | 
				
			||||||
        if (VehicleController.IsActive)
 | 
					        if (VehicleController.IsActive)
 | 
				
			||||||
| 
						 | 
					@ -1619,6 +1664,10 @@ public class BSPrim : BSPhysObject
 | 
				
			||||||
        // Assign directly to the local variables so the normal set actions do not happen
 | 
					        // Assign directly to the local variables so the normal set actions do not happen
 | 
				
			||||||
        _position = entprop.Position;
 | 
					        _position = entprop.Position;
 | 
				
			||||||
        _orientation = entprop.Rotation;
 | 
					        _orientation = entprop.Rotation;
 | 
				
			||||||
 | 
					        // _velocity = entprop.Velocity;
 | 
				
			||||||
 | 
					        // DEBUG DEBUG DEBUG -- smooth velocity changes a bit. The simulator seems to be
 | 
				
			||||||
 | 
					        //    very sensitive to velocity changes.
 | 
				
			||||||
 | 
					        if (!entprop.Velocity.ApproxEquals(_velocity, 0.1f))
 | 
				
			||||||
            _velocity = entprop.Velocity;
 | 
					            _velocity = entprop.Velocity;
 | 
				
			||||||
        _acceleration = entprop.Acceleration;
 | 
					        _acceleration = entprop.Acceleration;
 | 
				
			||||||
        _rotationalVelocity = entprop.RotationalVelocity;
 | 
					        _rotationalVelocity = entprop.RotationalVelocity;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,72 +44,107 @@ namespace OpenSim.Region.Physics.BulletSPlugin
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public class BSPrimDisplaced : BSPrim
 | 
					public class BSPrimDisplaced : BSPrim
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // 'Position' and 'Orientation' is what the simulator thinks the positions of the prim is.
 | 
					    // The purpose of this module is to do any mapping between what the simulator thinks
 | 
				
			||||||
    // Because Bullet needs the zero coordinate to be the center of mass of the linkset,
 | 
					    //    the prim position and orientation is and what the physical position/orientation.
 | 
				
			||||||
    //     sometimes it is necessary to displace the position the physics engine thinks
 | 
					    //    This difference happens because Bullet assumes the center-of-mass is the <0,0,0>
 | 
				
			||||||
    //     the position is. PositionDisplacement must be added and removed from the
 | 
					    //    of the prim/linkset. The simulator tracks the location of the prim/linkset by
 | 
				
			||||||
    //     position as the simulator position is stored and fetched from the physics
 | 
					    //    the location of the root prim. So, if center-of-mass is anywhere but the origin
 | 
				
			||||||
    //     engine. Similar to OrientationDisplacement.
 | 
					    //    of the root prim, the physical origin is displaced from the simulator origin.
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    // This routine works by capturing the Force* setting of position/orientation/... and
 | 
				
			||||||
 | 
					    //    adjusting the simulator values (being set) into the physical values.
 | 
				
			||||||
 | 
					    //    The conversion is also done in the opposite direction (physical origin -> simulator origin).
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    // The updateParameter call is also captured and the values from the physics engine
 | 
				
			||||||
 | 
					    //    are converted into simulator origin values before being passed to the base
 | 
				
			||||||
 | 
					    //    class.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public virtual OMV.Vector3 PositionDisplacement { get; set; }
 | 
					    public virtual OMV.Vector3 PositionDisplacement { get; set; }
 | 
				
			||||||
    public virtual OMV.Quaternion OrientationDisplacement { get; set; }
 | 
					    public virtual OMV.Quaternion OrientationDisplacement { get; set; }
 | 
				
			||||||
    public virtual OMV.Vector3 CenterOfMassLocation { get; set; }
 | 
					 | 
				
			||||||
    public virtual OMV.Vector3 GeometricCenterLocation { get; set; }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public BSPrimDisplaced(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
 | 
					    public BSPrimDisplaced(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
 | 
				
			||||||
                       OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
 | 
					                       OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
 | 
				
			||||||
        : base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical)
 | 
					        : base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        CenterOfMassLocation = RawPosition;
 | 
					        ClearDisplacement();
 | 
				
			||||||
        GeometricCenterLocation = RawPosition;
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void ClearDisplacement()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        PositionDisplacement = OMV.Vector3.Zero;
 | 
				
			||||||
 | 
					        OrientationDisplacement = OMV.Quaternion.Identity;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Set this sets and computes the displacement from the passed prim to the center-of-mass.
 | 
				
			||||||
 | 
					    // A user set value for center-of-mass overrides whatever might be passed in here.
 | 
				
			||||||
 | 
					    // The displacement is in local coordinates (relative to root prim in linkset oriented coordinates).
 | 
				
			||||||
 | 
					    public virtual void SetEffectiveCenterOfMassW(Vector3 centerOfMassDisplacement)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Vector3 comDisp;
 | 
				
			||||||
 | 
					        if (UserSetCenterOfMass.HasValue)
 | 
				
			||||||
 | 
					            comDisp = (OMV.Vector3)UserSetCenterOfMass;
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            comDisp = centerOfMassDisplacement;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (comDisp == Vector3.Zero)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // If there is no diplacement. Things get reset.
 | 
				
			||||||
 | 
					            PositionDisplacement = OMV.Vector3.Zero;
 | 
				
			||||||
 | 
					            OrientationDisplacement = OMV.Quaternion.Identity;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Remember the displacement from root as well as the origional rotation of the
 | 
				
			||||||
 | 
					            //    new center-of-mass.
 | 
				
			||||||
 | 
					            PositionDisplacement = comDisp;
 | 
				
			||||||
 | 
					            OrientationDisplacement = OMV.Quaternion.Identity;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public override Vector3 ForcePosition
 | 
					    public override Vector3 ForcePosition
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        get
 | 
					        get { return base.ForcePosition; }
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            return base.ForcePosition;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        set
 | 
					        set
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            if (PositionDisplacement != OMV.Vector3.Zero)
 | 
				
			||||||
 | 
					                base.ForcePosition = value - (PositionDisplacement * RawOrientation);
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
                base.ForcePosition = value;
 | 
					                base.ForcePosition = value;
 | 
				
			||||||
            CenterOfMassLocation = RawPosition;
 | 
					 | 
				
			||||||
            GeometricCenterLocation = RawPosition;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public override Quaternion ForceOrientation
 | 
					    public override Quaternion ForceOrientation
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        get
 | 
					        get { return base.ForceOrientation; }
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            return base.ForceOrientation;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        set
 | 
					        set
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            base.ForceOrientation = value;
 | 
					            base.ForceOrientation = value;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO: decide if this is the right place for these variables.
 | 
				
			||||||
 | 
					    //     Somehow incorporate the optional settability by the user.
 | 
				
			||||||
    // Is this used?
 | 
					    // Is this used?
 | 
				
			||||||
    public override OMV.Vector3 CenterOfMass
 | 
					    public override OMV.Vector3 CenterOfMass
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        get { return CenterOfMassLocation; }
 | 
					        get { return RawPosition; }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Is this used?
 | 
					    // Is this used?
 | 
				
			||||||
    public override OMV.Vector3 GeometricCenter
 | 
					    public override OMV.Vector3 GeometricCenter
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        get { return GeometricCenterLocation; }
 | 
					        get { return RawPosition; }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    public override void UpdateProperties(EntityProperties entprop)
 | 
					    public override void UpdateProperties(EntityProperties entprop)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // Undo any center-of-mass displacement that might have been done.
 | 
					        // Undo any center-of-mass displacement that might have been done.
 | 
				
			||||||
        if (PositionDisplacement != OMV.Vector3.Zero)
 | 
					        if (PositionDisplacement != OMV.Vector3.Zero || OrientationDisplacement != OMV.Quaternion.Identity)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            // Correct for any rotation around the center-of-mass
 | 
					            // Correct for any rotation around the center-of-mass
 | 
				
			||||||
            // TODO!!!
 | 
					            // TODO!!!
 | 
				
			||||||
            entprop.Position -= PositionDisplacement;
 | 
					            entprop.Position = entprop.Position + (PositionDisplacement * entprop.Rotation);
 | 
				
			||||||
 | 
					            // entprop.Rotation = something;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        base.UpdateProperties(entprop);
 | 
					        base.UpdateProperties(entprop);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,6 +38,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
 | 
				
			||||||
public class BSPrimLinkable : BSPrimDisplaced
 | 
					public class BSPrimLinkable : BSPrimDisplaced
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public BSLinkset Linkset { get; set; }
 | 
					    public BSLinkset Linkset { get; set; }
 | 
				
			||||||
 | 
					    // The index of this child prim.
 | 
				
			||||||
 | 
					    public int LinksetChildIndex { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public BSLinksetInfo LinksetInfo { get; set; }
 | 
					    public BSLinksetInfo LinksetInfo { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public BSPrimLinkable(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
 | 
					    public BSPrimLinkable(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
 | 
				
			||||||
| 
						 | 
					@ -90,7 +93,6 @@ public class BSPrimLinkable : BSPrimDisplaced
 | 
				
			||||||
        DetailLog("{0},BSPrimLinkset.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",
 | 
					        DetailLog("{0},BSPrimLinkset.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",
 | 
				
			||||||
            LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
 | 
					            LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
        base.delink();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // When simulator changes position, this might be moving a child of the linkset.
 | 
					    // When simulator changes position, this might be moving a child of the linkset.
 | 
				
			||||||
| 
						 | 
					@ -133,6 +135,7 @@ public class BSPrimLinkable : BSPrimDisplaced
 | 
				
			||||||
        // When going from non-physical to physical, this re-enables the constraints that
 | 
					        // When going from non-physical to physical, this re-enables the constraints that
 | 
				
			||||||
        //     had been automatically disabled when the mass was set to zero.
 | 
					        //     had been automatically disabled when the mass was set to zero.
 | 
				
			||||||
        // For compound based linksets, this enables and disables interactions of the children.
 | 
					        // For compound based linksets, this enables and disables interactions of the children.
 | 
				
			||||||
 | 
					        if (Linkset != null)    // null can happen during initialization
 | 
				
			||||||
            Linkset.Refresh(this);
 | 
					            Linkset.Refresh(this);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,7 +52,12 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        bool Cancel();
 | 
					        bool Cancel();
 | 
				
			||||||
        void Abort();
 | 
					        void Abort();
 | 
				
			||||||
        bool Wait(TimeSpan t);
 | 
					
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Wait for the work item to complete.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        /// <param name='t'>The number of milliseconds to wait.  Must be >= -1 (Timeout.Infinite).</param>
 | 
				
			||||||
 | 
					        bool Wait(int t);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// <summary>
 | 
					    /// <summary>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4479,6 +4479,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (pushAllowed)
 | 
					            if (pushAllowed)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                float distance = (PusheePos - m_host.AbsolutePosition).Length();
 | 
					                float distance = (PusheePos - m_host.AbsolutePosition).Length();
 | 
				
			||||||
| 
						 | 
					@ -4507,17 +4508,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
 | 
				
			||||||
                    applied_linear_impulse *= scaling_factor;
 | 
					                    applied_linear_impulse *= scaling_factor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (pusheeIsAvatar)
 | 
					                if (pusheeIsAvatar)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    if (pusheeav != null)
 | 
					                    if (pusheeav != null)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        if (pusheeav.PhysicsActor != null)
 | 
					                        PhysicsActor pa = pusheeav.PhysicsActor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        if (pa != null)
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            if (local != 0)
 | 
					                            if (local != 0)
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                applied_linear_impulse *= m_host.GetWorldRotation();
 | 
					                                applied_linear_impulse *= m_host.GetWorldRotation();
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            pusheeav.PhysicsActor.AddForce(applied_linear_impulse, true);
 | 
					
 | 
				
			||||||
 | 
					                            pa.AddForce(applied_linear_impulse, true);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -595,7 +595,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
 | 
				
			||||||
                if (!m_coopTermination)
 | 
					                if (!m_coopTermination)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    // If we're not co-operative terminating then try and wait for the event to complete before stopping
 | 
					                    // If we're not co-operative terminating then try and wait for the event to complete before stopping
 | 
				
			||||||
                    if (workItem.Wait(new TimeSpan((long)timeout * 100000)))
 | 
					                    if (workItem.Wait(timeout))
 | 
				
			||||||
                        return true;
 | 
					                        return true;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
| 
						 | 
					@ -610,7 +610,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    // For now, we will wait forever since the event should always cleanly terminate once LSL loop
 | 
					                    // For now, we will wait forever since the event should always cleanly terminate once LSL loop
 | 
				
			||||||
                    // checking is implemented.  May want to allow a shorter timeout option later.
 | 
					                    // checking is implemented.  May want to allow a shorter timeout option later.
 | 
				
			||||||
                    if (workItem.Wait(TimeSpan.MaxValue))
 | 
					                    if (workItem.Wait(Timeout.Infinite))
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        if (DebugLevel >= 1)
 | 
					                        if (DebugLevel >= 1)
 | 
				
			||||||
                            m_log.DebugFormat(
 | 
					                            m_log.DebugFormat(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,8 +57,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
 | 
				
			||||||
            wr.Abort();
 | 
					            wr.Abort();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public bool Wait(TimeSpan t)
 | 
					        public bool Wait(int t)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            // We use the integer version of WaitAll because the current version of SmartThreadPool has a bug with the
 | 
				
			||||||
 | 
					            // TimeSpan version.  The number of milliseconds in TimeSpan is an int64 so when STP casts it down to an 
 | 
				
			||||||
 | 
					            // int (32-bit) we can end up with bad values.  This occurs on Windows though curious not on Mono 2.10.8
 | 
				
			||||||
 | 
					            // (or very likely other versions of Mono at least up until 3.0.3).
 | 
				
			||||||
            return SmartThreadPool.WaitAll(new IWorkItemResult[] {wr}, t, false);
 | 
					            return SmartThreadPool.WaitAll(new IWorkItemResult[] {wr}, t, false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
		Loading…
	
		Reference in New Issue