Merge branch 'master' into careminster
Conflicts: OpenSim/Region/ClientStack/Linden/UDP/LLClientView.csavinationmerge
commit
9a4de546fe
|
@ -4964,7 +4964,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
// may improve movement smoothness.
|
||||
// acceleration = new Vector3(1, 0, 0);
|
||||
|
||||
angularVelocity = Vector3.Zero;
|
||||
angularVelocity = presence.AngularVelocity;
|
||||
rotation = presence.Rotation;
|
||||
|
||||
if (sendTexture)
|
||||
textureEntry = presence.Appearance.Texture.GetBytes();
|
||||
|
|
|
@ -214,9 +214,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
|||
public void HandleTaskItemUpdateFromTransaction(
|
||||
IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[ASSET TRANSACTION MODULE] Called HandleTaskItemUpdateFromTransaction with item {0} in {1} for {2} in {3}",
|
||||
item.Name, part.Name, remoteClient.Name, m_Scene.RegionInfo.RegionName);
|
||||
// m_log.DebugFormat(
|
||||
// "[ASSET TRANSACTION MODULE]: Called HandleTaskItemUpdateFromTransaction with item {0} in {1} for {2} in {3}",
|
||||
// item.Name, part.Name, remoteClient.Name, m_Scene.RegionInfo.RegionName);
|
||||
|
||||
AgentAssetTransactions transactions =
|
||||
GetUserTransactions(remoteClient.AgentId);
|
||||
|
@ -230,15 +230,17 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
|||
/// </summary>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <param name="assetID"></param>
|
||||
/// <param name="transaction"></param>
|
||||
/// <param name="transactionID"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="data"></param></param>
|
||||
/// <param name="tempFile"></param>
|
||||
public void HandleUDPUploadRequest(IClientAPI remoteClient,
|
||||
UUID assetID, UUID transaction, sbyte type, byte[] data,
|
||||
UUID assetID, UUID transactionID, sbyte type, byte[] data,
|
||||
bool storeLocal, bool tempFile)
|
||||
{
|
||||
// m_log.Debug("HandleUDPUploadRequest - assetID: " + assetID.ToString() + " transaction: " + transaction.ToString() + " type: " + type.ToString() + " storelocal: " + storeLocal + " tempFile: " + tempFile);
|
||||
// m_log.DebugFormat(
|
||||
// "[ASSET TRANSACTION MODULE]: HandleUDPUploadRequest - assetID: {0}, transaction {1}, type {2}, storeLocal {3}, tempFile {4}, data.Length {5}",
|
||||
// assetID, transactionID, type, storeLocal, tempFile, data.Length);
|
||||
|
||||
if (((AssetType)type == AssetType.Texture ||
|
||||
(AssetType)type == AssetType.Sound ||
|
||||
|
@ -274,8 +276,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
|||
}
|
||||
|
||||
AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId);
|
||||
AssetXferUploader uploader = transactions.RequestXferUploader(transaction);
|
||||
uploader.StartUpload(remoteClient, assetID, transaction, type, data, storeLocal, tempFile);
|
||||
AssetXferUploader uploader = transactions.RequestXferUploader(transactionID);
|
||||
uploader.StartUpload(remoteClient, assetID, transactionID, type, data, storeLocal, tempFile);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
{
|
||||
bool CreateStore(string value, ref UUID result);
|
||||
bool DestroyStore(UUID storeID);
|
||||
bool TestStore(UUID storeID);
|
||||
bool TestPath(UUID storeID, string path, bool useJson);
|
||||
bool SetValue(UUID storeID, string path, string value, bool useJson);
|
||||
bool RemoveValue(UUID storeID, string path);
|
||||
|
|
|
@ -204,6 +204,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
private const int LAND_VELOCITYMAG_MAX = 12;
|
||||
|
||||
private const float FLY_ROLL_MAX_RADIANS = 1.1f;
|
||||
|
||||
private const float FLY_ROLL_RADIANS_PER_UPDATE = 0.06f;
|
||||
private const float FLY_ROLL_RESET_RADIANS_PER_UPDATE = 0.02f;
|
||||
|
||||
private float m_health = 100f;
|
||||
|
||||
protected ulong crossingFromRegion;
|
||||
|
@ -604,6 +609,14 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
// Used for limited viewer 'fake' user rotations.
|
||||
private Vector3 m_AngularVelocity = Vector3.Zero;
|
||||
|
||||
public Vector3 AngularVelocity
|
||||
{
|
||||
get { return m_AngularVelocity; }
|
||||
}
|
||||
|
||||
public bool IsChildAgent { get; set; }
|
||||
public bool IsLoggingIn { get; set; }
|
||||
|
||||
|
@ -734,6 +747,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Constructor(s)
|
||||
|
||||
public ScenePresence(
|
||||
|
@ -1223,6 +1238,85 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
ControllingClient.StopFlying(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies a roll accumulator to the avatar's angular velocity for the avatar fly roll effect.
|
||||
/// </summary>
|
||||
/// <param name="amount">Postive or negative roll amount in radians</param>
|
||||
private void ApplyFlyingRoll(float amount, bool PressingUp, bool PressingDown)
|
||||
{
|
||||
|
||||
float rollAmount = Util.Clamp(m_AngularVelocity.Z + amount, -FLY_ROLL_MAX_RADIANS, FLY_ROLL_MAX_RADIANS);
|
||||
m_AngularVelocity.Z = rollAmount;
|
||||
|
||||
// APPLY EXTRA consideration for flying up and flying down during this time.
|
||||
// if we're turning left
|
||||
if (amount > 0)
|
||||
{
|
||||
|
||||
// If we're at the max roll and pressing up, we want to swing BACK a bit
|
||||
// Automatically adds noise
|
||||
if (PressingUp)
|
||||
{
|
||||
if (m_AngularVelocity.Z >= FLY_ROLL_MAX_RADIANS - 0.04f)
|
||||
m_AngularVelocity.Z -= 0.9f;
|
||||
}
|
||||
// If we're at the max roll and pressing down, we want to swing MORE a bit
|
||||
if (PressingDown)
|
||||
{
|
||||
if (m_AngularVelocity.Z >= FLY_ROLL_MAX_RADIANS && m_AngularVelocity.Z < FLY_ROLL_MAX_RADIANS + 0.6f)
|
||||
m_AngularVelocity.Z += 0.6f;
|
||||
}
|
||||
}
|
||||
else // we're turning right.
|
||||
{
|
||||
// If we're at the max roll and pressing up, we want to swing BACK a bit
|
||||
// Automatically adds noise
|
||||
if (PressingUp)
|
||||
{
|
||||
if (m_AngularVelocity.Z <= (-FLY_ROLL_MAX_RADIANS))
|
||||
m_AngularVelocity.Z += 0.6f;
|
||||
}
|
||||
// If we're at the max roll and pressing down, we want to swing MORE a bit
|
||||
if (PressingDown)
|
||||
{
|
||||
if (m_AngularVelocity.Z >= -FLY_ROLL_MAX_RADIANS - 0.6f)
|
||||
m_AngularVelocity.Z -= 0.6f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// incrementally sets roll amount to zero
|
||||
/// </summary>
|
||||
/// <param name="amount">Positive roll amount in radians</param>
|
||||
/// <returns></returns>
|
||||
private float CalculateFlyingRollResetToZero(float amount)
|
||||
{
|
||||
const float rollMinRadians = 0f;
|
||||
|
||||
if (m_AngularVelocity.Z > 0)
|
||||
{
|
||||
|
||||
float leftOverToMin = m_AngularVelocity.Z - rollMinRadians;
|
||||
if (amount > leftOverToMin)
|
||||
return -leftOverToMin;
|
||||
else
|
||||
return -amount;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
float leftOverToMin = -m_AngularVelocity.Z - rollMinRadians;
|
||||
if (amount > leftOverToMin)
|
||||
return leftOverToMin;
|
||||
else
|
||||
return amount;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// neighbouring regions we have enabled a child agent in
|
||||
// holds the seed cap for the child agent in that region
|
||||
private Dictionary<ulong, string> m_knownChildRegions = new Dictionary<ulong, string>();
|
||||
|
@ -1739,6 +1833,33 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) ||
|
||||
((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
|
||||
|
||||
|
||||
//m_log.Debug("[CONTROL]: " +flags);
|
||||
// Applies a satisfying roll effect to the avatar when flying.
|
||||
if (((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0) && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0))
|
||||
{
|
||||
|
||||
ApplyFlyingRoll(FLY_ROLL_RADIANS_PER_UPDATE, ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0), ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0));
|
||||
|
||||
|
||||
}
|
||||
else if (((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0) &&
|
||||
((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0))
|
||||
{
|
||||
ApplyFlyingRoll(-FLY_ROLL_RADIANS_PER_UPDATE, ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0), ((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0));
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_AngularVelocity.Z != 0)
|
||||
m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (Flying && IsColliding && controlland)
|
||||
{
|
||||
// nesting this check because LengthSquared() is expensive and we don't
|
||||
|
|
|
@ -216,6 +216,19 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
|||
return true;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
// -----------------------------------------------------------------
|
||||
public bool TestStore(UUID storeID)
|
||||
{
|
||||
if (! m_enabled) return false;
|
||||
|
||||
lock (m_JsonValueStore)
|
||||
return m_JsonValueStore.ContainsKey(storeID);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
/// <summary>
|
||||
///
|
||||
|
|
|
@ -167,6 +167,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
|||
{
|
||||
m_comms.RegisterScriptInvocation(this, "JsonCreateStore");
|
||||
m_comms.RegisterScriptInvocation(this, "JsonDestroyStore");
|
||||
m_comms.RegisterScriptInvocation(this, "JsonTestStore");
|
||||
|
||||
m_comms.RegisterScriptInvocation(this, "JsonReadNotecard");
|
||||
m_comms.RegisterScriptInvocation(this, "JsonWriteNotecard");
|
||||
|
@ -243,6 +244,16 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
|||
return m_store.DestroyStore(storeID) ? 1 : 0;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
// -----------------------------------------------------------------
|
||||
protected int JsonTestStore(UUID hostID, UUID scriptID, UUID storeID)
|
||||
{
|
||||
return m_store.TestStore(storeID) ? 1 : 0;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
/// <summary>
|
||||
///
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
|
|||
/// Tests for inventory functions in LSL
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class LSL_ApiInventoryTests : OpenSimTestCase
|
||||
public class JsonStoreScriptModuleTests : OpenSimTestCase
|
||||
{
|
||||
private Scene m_scene;
|
||||
private MockScriptEngine m_engine;
|
||||
|
@ -59,8 +59,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
|
|||
{
|
||||
base.SetUp();
|
||||
|
||||
TestHelpers.EnableLogging();
|
||||
|
||||
IConfigSource configSource = new IniConfigSource();
|
||||
IConfig jsonStoreConfig = configSource.AddConfig("JsonStore");
|
||||
jsonStoreConfig.Set("Enabled", "true");
|
||||
|
@ -72,74 +70,129 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
|
|||
|
||||
m_scene = new SceneHelpers().SetupScene();
|
||||
SceneHelpers.SetupSceneModules(m_scene, configSource, m_engine, m_smcm, jsm, jssm);
|
||||
|
||||
try
|
||||
{
|
||||
m_smcm.RegisterScriptInvocation(this, "DummyTestMethod");
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
Assert.Ignore("Ignoring test since running on .NET 3.5 or earlier.");
|
||||
}
|
||||
|
||||
// XXX: Unfortunately, ICommsModule currently has no way of deregistering methods.
|
||||
}
|
||||
|
||||
// [Test]
|
||||
private object InvokeOp(string name, params object[] args)
|
||||
{
|
||||
return m_smcm.InvokeOperation(UUID.Zero, UUID.Zero, name, args);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestJsonCreateStore()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
UUID storeId = (UUID)m_smcm.InvokeOperation(UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{}" });
|
||||
|
||||
UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
|
||||
Assert.That(storeId, Is.Not.EqualTo(UUID.Zero));
|
||||
}
|
||||
|
||||
// [Test]
|
||||
[Test]
|
||||
public void TestJsonDestroyStore()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }");
|
||||
int dsrv = (int)InvokeOp("JsonDestroyStore", storeId);
|
||||
|
||||
Assert.That(dsrv, Is.EqualTo(1));
|
||||
|
||||
int tprv = (int)InvokeOp("JsonTestPath", storeId, "Hello");
|
||||
Assert.That(tprv, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestJsonGetValue()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
UUID storeId
|
||||
= (UUID)m_smcm.InvokeOperation(
|
||||
UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ 'Hello' : 'World' }" });
|
||||
|
||||
string value
|
||||
= (string)m_smcm.InvokeOperation(
|
||||
UUID.Zero, UUID.Zero, "JsonGetValue", new object[] { storeId, "Hello" });
|
||||
UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }");
|
||||
|
||||
string value = (string)InvokeOp("JsonGetValue", storeId, "Hello");
|
||||
Assert.That(value, Is.EqualTo("World"));
|
||||
}
|
||||
|
||||
// [Test]
|
||||
// public void TestJsonTakeValue()
|
||||
// {
|
||||
// TestHelpers.InMethod();
|
||||
//// TestHelpers.EnableLogging();
|
||||
//
|
||||
// UUID storeId
|
||||
// = (UUID)m_smcm.InvokeOperation(
|
||||
// UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ 'Hello' : 'World' }" });
|
||||
//
|
||||
// string value
|
||||
// = (string)m_smcm.InvokeOperation(
|
||||
// UUID.Zero, UUID.Zero, "JsonTakeValue", new object[] { storeId, "Hello" });
|
||||
//
|
||||
// Assert.That(value, Is.EqualTo("World"));
|
||||
//
|
||||
// string value2
|
||||
// = (string)m_smcm.InvokeOperation(
|
||||
// UUID.Zero, UUID.Zero, "JsonGetValue", new object[] { storeId, "Hello" });
|
||||
//
|
||||
// Assert.That(value, Is.Null);
|
||||
// }
|
||||
|
||||
[Test]
|
||||
public void TestJsonRemoveValue()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }");
|
||||
|
||||
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("JsonGetValue", storeId, "Hello");
|
||||
Assert.That(returnValue2, Is.EqualTo(""));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestJsonTestPath()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
UUID storeId
|
||||
= (UUID)m_smcm.InvokeOperation(
|
||||
UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ 'Hello' : 'World' }" });
|
||||
|
||||
int result
|
||||
= (int)m_smcm.InvokeOperation(
|
||||
UUID.Zero, UUID.Zero, "JsonTestPath", new object[] { storeId, "Hello" });
|
||||
UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{ 'Hello' : 'World' }");
|
||||
|
||||
int result = (int)InvokeOp("JsonTestPath", storeId, "Hello");
|
||||
Assert.That(result, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
// [Test]
|
||||
[Test]
|
||||
public void TestJsonSetValue()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
UUID storeId
|
||||
= (UUID)m_smcm.InvokeOperation(
|
||||
UUID.Zero, UUID.Zero, "JsonCreateStore", new object[] { "{ }" });
|
||||
|
||||
int result
|
||||
= (int)m_smcm.InvokeOperation(
|
||||
UUID.Zero, UUID.Zero, "JsonSetValue", new object[] { storeId, "Hello", "World" });
|
||||
UUID storeId = (UUID)InvokeOp("JsonCreateStore", "{}");
|
||||
|
||||
int result = (int)InvokeOp("JsonSetValue", storeId, "Hello", "World");
|
||||
Assert.That(result, Is.EqualTo(1));
|
||||
|
||||
string value
|
||||
= (string)m_smcm.InvokeOperation(
|
||||
UUID.Zero, UUID.Zero, "JsonGetValue", new object[] { storeId, "Hello" });
|
||||
|
||||
string value = (string)InvokeOp("JsonGetValue", storeId, "Hello");
|
||||
Assert.That(value, Is.EqualTo("World"));
|
||||
}
|
||||
|
||||
public object DummyTestMethod(object o1, object o2, object o3, object o4, object o5) { return null; }
|
||||
}
|
||||
}
|
|
@ -87,7 +87,7 @@ public enum FixedShapeKey : ulong
|
|||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ShapeData
|
||||
{
|
||||
public uint ID;
|
||||
public UInt32 ID;
|
||||
public BSPhysicsShapeType Type;
|
||||
public Vector3 Position;
|
||||
public Quaternion Rotation;
|
||||
|
@ -111,7 +111,7 @@ public struct ShapeData
|
|||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SweepHit
|
||||
{
|
||||
public uint ID;
|
||||
public UInt32 ID;
|
||||
public float Fraction;
|
||||
public Vector3 Normal;
|
||||
public Vector3 Point;
|
||||
|
@ -119,15 +119,15 @@ public struct SweepHit
|
|||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RaycastHit
|
||||
{
|
||||
public uint ID;
|
||||
public UInt32 ID;
|
||||
public float Fraction;
|
||||
public Vector3 Normal;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct CollisionDesc
|
||||
{
|
||||
public uint aID;
|
||||
public uint bID;
|
||||
public UInt32 aID;
|
||||
public UInt32 bID;
|
||||
public Vector3 point;
|
||||
public Vector3 normal;
|
||||
public float penetration;
|
||||
|
@ -135,7 +135,7 @@ public struct CollisionDesc
|
|||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct EntityProperties
|
||||
{
|
||||
public uint ID;
|
||||
public UInt32 ID;
|
||||
public Vector3 Position;
|
||||
public Quaternion Rotation;
|
||||
public Vector3 Velocity;
|
||||
|
@ -325,7 +325,7 @@ public abstract BulletWorld Initialize(Vector3 maxPosition, ConfigurationParamet
|
|||
public abstract int PhysicsStep(BulletWorld world, float timeStep, int maxSubSteps, float fixedTimeStep,
|
||||
out int updatedEntityCount, out int collidersCount);
|
||||
|
||||
public abstract bool UpdateParameter(BulletWorld world, uint localID, String parm, float value);
|
||||
public abstract bool UpdateParameter(BulletWorld world, UInt32 localID, String parm, float value);
|
||||
|
||||
public abstract void Shutdown(BulletWorld sim);
|
||||
|
||||
|
@ -366,24 +366,24 @@ public abstract void UpdateChildTransform(BulletShape pShape, int childIndex, Ve
|
|||
|
||||
public abstract void RecalculateCompoundShapeLocalAabb(BulletShape cShape);
|
||||
|
||||
public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, uint id);
|
||||
public abstract BulletShape DuplicateCollisionShape(BulletWorld sim, BulletShape srcShape, UInt32 id);
|
||||
|
||||
public abstract bool DeleteCollisionShape(BulletWorld world, BulletShape shape);
|
||||
|
||||
public abstract CollisionObjectTypes GetBodyType(BulletBody obj);
|
||||
|
||||
public abstract BulletBody CreateBodyFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot);
|
||||
public abstract BulletBody CreateBodyFromShape(BulletWorld sim, BulletShape shape, UInt32 id, Vector3 pos, Quaternion rot);
|
||||
|
||||
public abstract BulletBody CreateBodyWithDefaultMotionState(BulletShape shape, uint id, Vector3 pos, Quaternion rot);
|
||||
public abstract BulletBody CreateBodyWithDefaultMotionState(BulletShape shape, UInt32 id, Vector3 pos, Quaternion rot);
|
||||
|
||||
public abstract BulletBody CreateGhostFromShape(BulletWorld sim, BulletShape shape, uint id, Vector3 pos, Quaternion rot);
|
||||
public abstract BulletBody CreateGhostFromShape(BulletWorld sim, BulletShape shape, UInt32 id, Vector3 pos, Quaternion rot);
|
||||
|
||||
public abstract void DestroyObject(BulletWorld sim, BulletBody obj);
|
||||
|
||||
// =====================================================================================
|
||||
public abstract BulletShape CreateGroundPlaneShape(uint id, float height, float collisionMargin);
|
||||
public abstract BulletShape CreateGroundPlaneShape(UInt32 id, float height, float collisionMargin);
|
||||
|
||||
public abstract BulletShape CreateTerrainShape(uint id, Vector3 size, float minHeight, float maxHeight, float[] heightMap,
|
||||
public abstract BulletShape CreateTerrainShape(UInt32 id, Vector3 size, float minHeight, float maxHeight, float[] heightMap,
|
||||
float scaleFactor, float collisionMargin);
|
||||
|
||||
// =====================================================================================
|
||||
|
@ -629,7 +629,7 @@ public abstract BulletConstraint GetConstraintRef(BulletBody obj, int index);
|
|||
|
||||
public abstract int GetNumConstraintRefs(BulletBody obj);
|
||||
|
||||
public abstract bool SetCollisionGroupMask(BulletBody body, uint filter, uint mask);
|
||||
public abstract bool SetCollisionGroupMask(BulletBody body, UInt32 filter, UInt32 mask);
|
||||
|
||||
// =====================================================================================
|
||||
// btCollisionShape entries
|
||||
|
|
|
@ -56,7 +56,6 @@ public sealed class BSCharacter : BSPhysObject
|
|||
private int _physicsActorType;
|
||||
private bool _isPhysical;
|
||||
private bool _flying;
|
||||
private bool _wasWalking; // 'true' if the avatar was walking/moving last frame
|
||||
private bool _setAlwaysRun;
|
||||
private bool _throttleUpdates;
|
||||
private bool _floatOnWater;
|
||||
|
@ -84,7 +83,6 @@ public sealed class BSCharacter : BSPhysObject
|
|||
_position = pos;
|
||||
|
||||
_flying = isFlying;
|
||||
_wasWalking = true; // causes first step to initialize standing
|
||||
_orientation = OMV.Quaternion.Identity;
|
||||
_velocity = OMV.Vector3.Zero;
|
||||
_buoyancy = ComputeBuoyancyFromFlying(isFlying);
|
||||
|
@ -220,7 +218,13 @@ public sealed class BSCharacter : BSPhysObject
|
|||
{
|
||||
// The avatar shouldn't be moving
|
||||
_velocityMotor.Zero();
|
||||
ZeroMotion(true /* inTaintTime */);
|
||||
|
||||
// If we are colliding with a stationary object, presume we're standing and don't move around
|
||||
if (!ColliderIsMoving)
|
||||
{
|
||||
DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", LocalID);
|
||||
ZeroMotion(true /* inTaintTime */);
|
||||
}
|
||||
|
||||
// Standing has more friction on the ground
|
||||
if (_currentFriction != BSParam.AvatarStandingFriction)
|
||||
|
@ -229,8 +233,6 @@ public sealed class BSCharacter : BSPhysObject
|
|||
PhysicsScene.PE.SetFriction(PhysBody, _currentFriction);
|
||||
}
|
||||
DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1}", LocalID, _velocityMotor.TargetValue);
|
||||
|
||||
_wasWalking = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -260,7 +262,6 @@ public sealed class BSCharacter : BSPhysObject
|
|||
|
||||
DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce);
|
||||
PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce);
|
||||
_wasWalking = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -125,9 +125,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
static readonly float PIOverTwo = ((float)Math.PI) / 2f;
|
||||
|
||||
// For debugging, flags to turn on and off individual corrections.
|
||||
private bool enableAngularVerticalAttraction;
|
||||
private bool enableAngularDeflection;
|
||||
private bool enableAngularBanking;
|
||||
public bool enableAngularVerticalAttraction;
|
||||
public bool enableAngularDeflection;
|
||||
public bool enableAngularBanking;
|
||||
|
||||
public BSDynamics(BSScene myScene, BSPrim myPrim)
|
||||
{
|
||||
|
@ -146,7 +146,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
enableAngularBanking = false;
|
||||
if (BSParam.VehicleDebuggingEnabled != ConfigurationParameters.numericFalse)
|
||||
{
|
||||
enableAngularVerticalAttraction = false;
|
||||
enableAngularVerticalAttraction = true;
|
||||
enableAngularDeflection = false;
|
||||
enableAngularBanking = false;
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
}
|
||||
|
||||
#region Vehicle parameter setting
|
||||
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
|
||||
public void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
|
||||
{
|
||||
VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue);
|
||||
switch (pParam)
|
||||
|
@ -591,14 +591,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
m_vehicleMass = Prim.Linkset.LinksetMass;
|
||||
|
||||
// Friction affects are handled by this vehicle code
|
||||
float friction = 0f;
|
||||
PhysicsScene.PE.SetFriction(Prim.PhysBody, friction);
|
||||
PhysicsScene.PE.SetFriction(Prim.PhysBody, BSParam.VehicleFriction);
|
||||
PhysicsScene.PE.SetRestitution(Prim.PhysBody, BSParam.VehicleRestitution);
|
||||
|
||||
// Moderate angular movement introduced by Bullet.
|
||||
// TODO: possibly set AngularFactor and LinearFactor for the type of vehicle.
|
||||
// Maybe compute linear and angular factor and damping from params.
|
||||
float angularDamping = BSParam.VehicleAngularDamping;
|
||||
PhysicsScene.PE.SetAngularDamping(Prim.PhysBody, angularDamping);
|
||||
PhysicsScene.PE.SetAngularDamping(Prim.PhysBody, BSParam.VehicleAngularDamping);
|
||||
PhysicsScene.PE.SetLinearFactor(Prim.PhysBody, BSParam.VehicleLinearFactorV);
|
||||
PhysicsScene.PE.SetAngularFactorV(Prim.PhysBody, BSParam.VehicleAngularFactorV);
|
||||
|
||||
// Vehicles report collision events so we know when it's on the ground
|
||||
PhysicsScene.PE.AddToCollisionFlags(Prim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
|
||||
|
@ -613,8 +614,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// The actual vehicle gravity is set to zero in Bullet so we can do all the application of same.
|
||||
PhysicsScene.PE.SetGravity(Prim.PhysBody, Vector3.Zero);
|
||||
|
||||
VDetailLog("{0},BSDynamics.Refresh,mass={1},frict={2},inert={3},aDamp={4},grav={5}",
|
||||
Prim.LocalID, m_vehicleMass, friction, Prim.Inertia, angularDamping, m_VehicleGravity);
|
||||
VDetailLog("{0},BSDynamics.Refresh,mass={1},inert={2},grav={3},aDamp={4},frict={5},rest={6},lFact={7},aFact={8}",
|
||||
Prim.LocalID, m_vehicleMass, Prim.Inertia, m_VehicleGravity,
|
||||
BSParam.VehicleAngularDamping, BSParam.VehicleFriction, BSParam.VehicleRestitution,
|
||||
BSParam.VehicleLinearFactor, BSParam.VehicleAngularFactor
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -673,13 +677,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
private const int m_knownChangedWaterLevel = 1 << 9;
|
||||
private const int m_knownChangedForwardVelocity = 1 <<10;
|
||||
|
||||
private void ForgetKnownVehicleProperties()
|
||||
public void ForgetKnownVehicleProperties()
|
||||
{
|
||||
m_knownHas = 0;
|
||||
m_knownChanged = 0;
|
||||
}
|
||||
// Push all the changed values back into the physics engine
|
||||
private void PushKnownChanged()
|
||||
public void PushKnownChanged()
|
||||
{
|
||||
if (m_knownChanged != 0)
|
||||
{
|
||||
|
@ -799,7 +803,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
m_knownVelocity = Prim.ForceVelocity;
|
||||
m_knownHas |= m_knownChangedVelocity;
|
||||
}
|
||||
return (Vector3)m_knownVelocity;
|
||||
return m_knownVelocity;
|
||||
}
|
||||
set
|
||||
{
|
||||
|
@ -898,9 +902,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
{
|
||||
if (!IsActive) return;
|
||||
|
||||
if (PhysicsScene.VehiclePhysicalLoggingEnabled)
|
||||
PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody);
|
||||
|
||||
ForgetKnownVehicleProperties();
|
||||
|
||||
MoveLinear(pTimestep);
|
||||
|
@ -922,6 +923,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
Prim.LocalID, VehiclePosition, m_knownForce, VehicleVelocity, VehicleRotationalVelocity);
|
||||
}
|
||||
|
||||
// Called after the simulation step
|
||||
internal void PostStep(float pTimestep)
|
||||
{
|
||||
if (!IsActive) return;
|
||||
|
||||
if (PhysicsScene.VehiclePhysicalLoggingEnabled)
|
||||
PhysicsScene.PE.DumpRigidBody(PhysicsScene.World, Prim.PhysBody);
|
||||
}
|
||||
|
||||
// Apply the effect of the linear motor and other linear motions (like hover and float).
|
||||
private void MoveLinear(float pTimestep)
|
||||
{
|
||||
|
@ -953,10 +963,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// ==================================================================
|
||||
// Clamp high or low velocities
|
||||
float newVelocityLengthSq = VehicleVelocity.LengthSquared();
|
||||
if (newVelocityLengthSq > BSParam.VehicleMaxLinearVelocity)
|
||||
if (newVelocityLengthSq > BSParam.VehicleMaxLinearVelocitySq)
|
||||
{
|
||||
Vector3 origVelW = VehicleVelocity; // DEBUG DEBUG
|
||||
VehicleVelocity /= VehicleVelocity.Length();
|
||||
VehicleVelocity *= BSParam.VehicleMaxLinearVelocity;
|
||||
VDetailLog("{0}, MoveLinear,clampMax,origVelW={1},lenSq={2},maxVelSq={3},,newVelW={4}",
|
||||
Prim.LocalID, origVelW, newVelocityLengthSq, BSParam.VehicleMaxLinearVelocitySq, VehicleVelocity);
|
||||
}
|
||||
else if (newVelocityLengthSq < 0.001f)
|
||||
VehicleVelocity = Vector3.Zero;
|
||||
|
@ -968,8 +981,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
public void ComputeLinearVelocity(float pTimestep)
|
||||
{
|
||||
// Step the motor from the current value. Get the correction needed this step.
|
||||
Vector3 currentVel = VehicleVelocity * Quaternion.Inverse(VehicleOrientation);
|
||||
Vector3 linearMotorCorrectionV = m_linearMotor.Step(pTimestep, currentVel);
|
||||
Vector3 origVelW = VehicleVelocity; // DEBUG
|
||||
Vector3 currentVelV = VehicleVelocity * Quaternion.Inverse(VehicleOrientation);
|
||||
Vector3 linearMotorCorrectionV = m_linearMotor.Step(pTimestep, currentVelV);
|
||||
|
||||
// Motor is vehicle coordinates. Rotate it to world coordinates
|
||||
Vector3 linearMotorVelocityW = linearMotorCorrectionV * VehicleOrientation;
|
||||
|
@ -984,8 +998,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// Add this correction to the velocity to make it faster/slower.
|
||||
VehicleVelocity += linearMotorVelocityW;
|
||||
|
||||
VDetailLog("{0}, MoveLinear,velocity,vehVel={1},correction={2},force={3}",
|
||||
Prim.LocalID, VehicleVelocity, linearMotorCorrectionV, linearMotorVelocityW);
|
||||
VDetailLog("{0}, MoveLinear,velocity,origVelW={1},velV={2},correctV={3},correctW={4},newVelW={5}",
|
||||
Prim.LocalID, origVelW, currentVelV, linearMotorCorrectionV, linearMotorVelocityW, VehicleVelocity);
|
||||
}
|
||||
|
||||
public void ComputeLinearTerrainHeightCorrection(float pTimestep)
|
||||
|
@ -1185,12 +1199,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
|
||||
// Hack to reduce downward force if the vehicle is probably sitting on the ground
|
||||
if (Prim.IsColliding && IsGroundVehicle)
|
||||
appliedGravity *= 0.2f;
|
||||
appliedGravity *= BSParam.VehicleGroundGravityFudge;
|
||||
|
||||
VehicleAddForce(appliedGravity);
|
||||
|
||||
VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},appliedForce-{2}",
|
||||
Prim.LocalID, m_VehicleGravity, appliedGravity);
|
||||
VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},appliedForce={3}",
|
||||
Prim.LocalID, m_VehicleGravity, Prim.IsColliding, appliedGravity);
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
|
@ -1292,6 +1306,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
|
||||
{
|
||||
Vector3 vertContributionV = Vector3.Zero;
|
||||
Vector3 origRotVelW = VehicleRotationalVelocity; // DEBUG DEBUG
|
||||
|
||||
// Take a vector pointing up and convert it from world to vehicle relative coords.
|
||||
Vector3 verticalError = Vector3.UnitZ * VehicleOrientation;
|
||||
|
@ -1319,13 +1334,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
|
||||
// 'vertContrbution' is now the necessary angular correction to correct tilt in one second.
|
||||
// Correction happens over a number of seconds.
|
||||
Vector3 unscaledContrib = vertContributionV; // DEBUG DEBUG
|
||||
Vector3 unscaledContribVerticalErrorV = vertContributionV; // DEBUG DEBUG
|
||||
vertContributionV /= m_verticalAttractionTimescale;
|
||||
|
||||
VehicleRotationalVelocity += vertContributionV * VehicleOrientation;
|
||||
|
||||
VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},eff={3},ts={4},vertAttr={5}",
|
||||
Prim.LocalID, verticalError, unscaledContrib, m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV);
|
||||
VDetailLog("{0}, MoveAngular,verticalAttraction,,origRotVW={1},vertError={2},unscaledV={3},eff={4},ts={5},vertContribV={6}",
|
||||
Prim.LocalID, origRotVelW, verticalError, unscaledContribVerticalErrorV,
|
||||
m_verticalAttractionEfficiency, m_verticalAttractionTimescale, vertContributionV);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -232,7 +232,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
newLsi.OffsetFromCenterOfMass,
|
||||
newLsi.OffsetRot,
|
||||
true /* shouldRecalculateLocalAabb */);
|
||||
DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1}newLsi={2}",
|
||||
DetailLog("{0},BSLinksetCompound.UpdateProperties,changeChildPosRot,whichUpdated={1},newLsi={2}",
|
||||
updated.LocalID, whichUpdated, newLsi);
|
||||
updated.LinksetInfo = newLsi;
|
||||
updatedChild = true;
|
||||
|
@ -377,7 +377,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
|||
// Constraint linksets are rebuilt every time.
|
||||
// Note that this works for rebuilding just the root after a linkset is taken apart.
|
||||
// Called at taint time!!
|
||||
private bool disableCOM = false; // disable until we get this debugged
|
||||
private bool disableCOM = true; // disable until we get this debugged
|
||||
private void RecomputeLinksetCompound()
|
||||
{
|
||||
try
|
||||
|
|
|
@ -82,9 +82,19 @@ public static class BSParam
|
|||
public static float AvatarStepApproachFactor { get; private set; }
|
||||
public static float AvatarStepForceFactor { get; private set; }
|
||||
|
||||
// Vehicle parameters
|
||||
public static float VehicleMaxLinearVelocity { get; private set; }
|
||||
public static float VehicleMaxLinearVelocitySq { get; private set; }
|
||||
public static float VehicleMaxAngularVelocity { get; private set; }
|
||||
public static float VehicleMaxAngularVelocitySq { get; private set; }
|
||||
public static float VehicleAngularDamping { get; private set; }
|
||||
public static float VehicleFriction { get; private set; }
|
||||
public static float VehicleRestitution { get; private set; }
|
||||
public static float VehicleLinearFactor { get; private set; }
|
||||
public static Vector3 VehicleLinearFactorV { get; private set; }
|
||||
public static float VehicleAngularFactor { get; private set; }
|
||||
public static Vector3 VehicleAngularFactorV { get; private set; }
|
||||
public static float VehicleGroundGravityFudge { get; private set; }
|
||||
public static float VehicleDebuggingEnabled { get; private set; }
|
||||
|
||||
public static float LinksetImplementation { get; private set; }
|
||||
|
@ -373,7 +383,7 @@ public static class BSParam
|
|||
(s) => { return TerrainRestitution; },
|
||||
(s,p,l,v) => { TerrainRestitution = v; /* TODO: set on real terrain */ } ),
|
||||
new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" ,
|
||||
0.04f,
|
||||
0.08f,
|
||||
(s,cf,p,v) => { TerrainCollisionMargin = cf.GetFloat(p, v); },
|
||||
(s) => { return TerrainCollisionMargin; },
|
||||
(s,p,l,v) => { TerrainCollisionMargin = v; /* TODO: set on real terrain */ } ),
|
||||
|
@ -443,17 +453,42 @@ public static class BSParam
|
|||
1000.0f,
|
||||
(s,cf,p,v) => { VehicleMaxLinearVelocity = cf.GetFloat(p, v); },
|
||||
(s) => { return (float)VehicleMaxLinearVelocity; },
|
||||
(s,p,l,v) => { VehicleMaxLinearVelocity = v; } ),
|
||||
(s,p,l,v) => { VehicleMaxLinearVelocity = v; VehicleMaxLinearVelocitySq = v * v; } ),
|
||||
new ParameterDefn("VehicleMaxAngularVelocity", "Maximum rotational velocity magnitude that can be assigned to a vehicle",
|
||||
12.0f,
|
||||
(s,cf,p,v) => { VehicleMaxAngularVelocity = cf.GetFloat(p, v); },
|
||||
(s) => { return (float)VehicleMaxAngularVelocity; },
|
||||
(s,p,l,v) => { VehicleMaxAngularVelocity = v; } ),
|
||||
(s,p,l,v) => { VehicleMaxAngularVelocity = v; VehicleMaxAngularVelocitySq = v * v; } ),
|
||||
new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)",
|
||||
0.0f,
|
||||
(s,cf,p,v) => { VehicleAngularDamping = cf.GetFloat(p, v); },
|
||||
(s) => { return VehicleAngularDamping; },
|
||||
(s,p,l,v) => { VehicleAngularDamping = v; } ),
|
||||
new ParameterDefn("VehicleLinearFactor", "Fraction of physical linear changes applied to vehicle (0.0 - 1.0)",
|
||||
1.0f,
|
||||
(s,cf,p,v) => { VehicleLinearFactor = cf.GetFloat(p, v); },
|
||||
(s) => { return VehicleLinearFactor; },
|
||||
(s,p,l,v) => { VehicleLinearFactor = v; VehicleLinearFactorV = new Vector3(v, v, v); } ),
|
||||
new ParameterDefn("VehicleAngularFactor", "Fraction of physical angular changes applied to vehicle (0.0 - 1.0)",
|
||||
1.0f,
|
||||
(s,cf,p,v) => { VehicleAngularFactor = cf.GetFloat(p, v); },
|
||||
(s) => { return VehicleAngularFactor; },
|
||||
(s,p,l,v) => { VehicleAngularFactor = v; VehicleAngularFactorV = new Vector3(v, v, v); } ),
|
||||
new ParameterDefn("VehicleFriction", "Friction of vehicle on the ground (0.0 - 1.0)",
|
||||
0.0f,
|
||||
(s,cf,p,v) => { VehicleFriction = cf.GetFloat(p, v); },
|
||||
(s) => { return VehicleFriction; },
|
||||
(s,p,l,v) => { VehicleFriction = v; } ),
|
||||
new ParameterDefn("VehicleRestitution", "Bouncyness factor for vehicles (0.0 - 1.0)",
|
||||
0.0f,
|
||||
(s,cf,p,v) => { VehicleRestitution = cf.GetFloat(p, v); },
|
||||
(s) => { return VehicleRestitution; },
|
||||
(s,p,l,v) => { VehicleRestitution = v; } ),
|
||||
new ParameterDefn("VehicleGroundGravityFudge", "Factor to multiple gravity if a ground vehicle is probably on the ground (0.0 - 1.0)",
|
||||
0.2f,
|
||||
(s,cf,p,v) => { VehicleGroundGravityFudge = cf.GetFloat(p, v); },
|
||||
(s) => { return VehicleGroundGravityFudge; },
|
||||
(s,p,l,v) => { VehicleGroundGravityFudge = v; } ),
|
||||
new ParameterDefn("VehicleDebuggingEnable", "Turn on/off vehicle debugging",
|
||||
ConfigurationParameters.numericFalse,
|
||||
(s,cf,p,v) => { VehicleDebuggingEnabled = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
|
||||
|
|
|
@ -95,12 +95,16 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
SubscribedEventsMs = 0;
|
||||
CollidingStep = 0;
|
||||
CollidingGroundStep = 0;
|
||||
CollisionAccumulation = 0;
|
||||
ColliderIsMoving = false;
|
||||
CollisionScore = 0;
|
||||
}
|
||||
|
||||
// Tell the object to clean up.
|
||||
public virtual void Destroy()
|
||||
{
|
||||
UnRegisterAllPreStepActions();
|
||||
UnRegisterAllPostStepActions();
|
||||
}
|
||||
|
||||
public BSScene PhysicsScene { get; protected set; }
|
||||
|
@ -174,13 +178,14 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
public abstract OMV.Vector3 RawPosition { get; set; }
|
||||
public abstract OMV.Vector3 ForcePosition { get; set; }
|
||||
|
||||
// Position is what the simulator thinks the positions of the prim is.
|
||||
// 'Position' and 'Orientation' is what the simulator thinks the positions of the prim is.
|
||||
// Because Bullet needs the zero coordinate to be the center of mass of the linkset,
|
||||
// sometimes it is necessary to displace the position the physics engine thinks
|
||||
// the position is. PositionDisplacement must be added and removed from the
|
||||
// position as the simulator position is stored and fetched from the physics
|
||||
// engine.
|
||||
// engine. Similar to OrientationDisplacement.
|
||||
public virtual OMV.Vector3 PositionDisplacement { get; set; }
|
||||
public virtual OMV.Quaternion OrientationDisplacement { get; set; }
|
||||
|
||||
public abstract OMV.Quaternion RawOrientation { get; set; }
|
||||
public abstract OMV.Quaternion ForceOrientation { get; set; }
|
||||
|
@ -237,6 +242,12 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
protected long CollidingObjectStep { get; set; }
|
||||
// The collision flags we think are set in Bullet
|
||||
protected CollisionFlags CurrentCollisionFlags { get; set; }
|
||||
// On a collision, check the collider and remember if the last collider was moving
|
||||
// Used to modify the standing of avatars (avatars on stationary things stand still)
|
||||
protected bool ColliderIsMoving;
|
||||
|
||||
// Count of collisions for this object
|
||||
protected long CollisionAccumulation { get; set; }
|
||||
|
||||
public override bool IsColliding {
|
||||
get { return (CollidingStep == PhysicsScene.SimulationStep); }
|
||||
|
@ -299,7 +310,12 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
return ret;
|
||||
}
|
||||
|
||||
// if someone has subscribed for collision events....
|
||||
CollisionAccumulation++;
|
||||
|
||||
// For movement tests, remember if we are colliding with an object that is moving.
|
||||
ColliderIsMoving = collidee != null ? collidee.RawVelocity != OMV.Vector3.Zero : false;
|
||||
|
||||
// If someone has subscribed for collision events log the collision so it will be reported up
|
||||
if (SubscribedEvents()) {
|
||||
CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
|
||||
DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5}",
|
||||
|
@ -385,6 +401,17 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
public override bool SubscribedEvents() {
|
||||
return (SubscribedEventsMs > 0);
|
||||
}
|
||||
// Because 'CollisionScore' is called many times while sorting, it should not be recomputed
|
||||
// each time called. So this is built to be light weight for each collision and to do
|
||||
// all the processing when the user asks for the info.
|
||||
public void ComputeCollisionScore()
|
||||
{
|
||||
// Scale the collision count by the time since the last collision.
|
||||
// The "+1" prevents dividing by zero.
|
||||
long timeAgo = PhysicsScene.SimulationStep - CollidingStep + 1;
|
||||
CollisionScore = CollisionAccumulation / timeAgo;
|
||||
}
|
||||
public override float CollisionScore { get; set; }
|
||||
|
||||
#endregion // Collisions
|
||||
|
||||
|
@ -393,52 +420,103 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
// These actions are optional so, rather than scanning all the physical objects and asking them
|
||||
// if they have anything to do, a physical object registers for an event call before the step is performed.
|
||||
// This bookkeeping makes it easy to add, remove and clean up after all these registrations.
|
||||
private Dictionary<string, BSScene.PreStepAction> RegisteredActions = new Dictionary<string, BSScene.PreStepAction>();
|
||||
private Dictionary<string, BSScene.PreStepAction> RegisteredPrestepActions = new Dictionary<string, BSScene.PreStepAction>();
|
||||
private Dictionary<string, BSScene.PostStepAction> RegisteredPoststepActions = new Dictionary<string, BSScene.PostStepAction>();
|
||||
protected void RegisterPreStepAction(string op, uint id, BSScene.PreStepAction actn)
|
||||
{
|
||||
string identifier = op + "-" + id.ToString();
|
||||
|
||||
lock (RegisteredActions)
|
||||
lock (RegisteredPrestepActions)
|
||||
{
|
||||
// Clean out any existing action
|
||||
UnRegisterPreStepAction(op, id);
|
||||
|
||||
RegisteredActions[identifier] = actn;
|
||||
RegisteredPrestepActions[identifier] = actn;
|
||||
|
||||
PhysicsScene.BeforeStep += actn;
|
||||
}
|
||||
PhysicsScene.BeforeStep += actn;
|
||||
DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier);
|
||||
}
|
||||
|
||||
// Unregister a pre step action. Safe to call if the action has not been registered.
|
||||
protected void UnRegisterPreStepAction(string op, uint id)
|
||||
// Returns 'true' if an action was actually removed
|
||||
protected bool UnRegisterPreStepAction(string op, uint id)
|
||||
{
|
||||
string identifier = op + "-" + id.ToString();
|
||||
bool removed = false;
|
||||
lock (RegisteredActions)
|
||||
lock (RegisteredPrestepActions)
|
||||
{
|
||||
if (RegisteredActions.ContainsKey(identifier))
|
||||
if (RegisteredPrestepActions.ContainsKey(identifier))
|
||||
{
|
||||
PhysicsScene.BeforeStep -= RegisteredActions[identifier];
|
||||
RegisteredActions.Remove(identifier);
|
||||
PhysicsScene.BeforeStep -= RegisteredPrestepActions[identifier];
|
||||
RegisteredPrestepActions.Remove(identifier);
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed);
|
||||
return removed;
|
||||
}
|
||||
|
||||
protected void UnRegisterAllPreStepActions()
|
||||
{
|
||||
lock (RegisteredActions)
|
||||
lock (RegisteredPrestepActions)
|
||||
{
|
||||
foreach (KeyValuePair<string, BSScene.PreStepAction> kvp in RegisteredActions)
|
||||
foreach (KeyValuePair<string, BSScene.PreStepAction> kvp in RegisteredPrestepActions)
|
||||
{
|
||||
PhysicsScene.BeforeStep -= kvp.Value;
|
||||
}
|
||||
RegisteredActions.Clear();
|
||||
RegisteredPrestepActions.Clear();
|
||||
}
|
||||
DetailLog("{0},BSPhysObject.UnRegisterAllPreStepActions,", LocalID);
|
||||
}
|
||||
|
||||
protected void RegisterPostStepAction(string op, uint id, BSScene.PostStepAction actn)
|
||||
{
|
||||
string identifier = op + "-" + id.ToString();
|
||||
|
||||
lock (RegisteredPoststepActions)
|
||||
{
|
||||
// Clean out any existing action
|
||||
UnRegisterPostStepAction(op, id);
|
||||
|
||||
RegisteredPoststepActions[identifier] = actn;
|
||||
|
||||
PhysicsScene.AfterStep += actn;
|
||||
}
|
||||
DetailLog("{0},BSPhysObject.RegisterPostStepAction,id={1}", LocalID, identifier);
|
||||
}
|
||||
|
||||
// Unregister a pre step action. Safe to call if the action has not been registered.
|
||||
// Returns 'true' if an action was actually removed.
|
||||
protected bool UnRegisterPostStepAction(string op, uint id)
|
||||
{
|
||||
string identifier = op + "-" + id.ToString();
|
||||
bool removed = false;
|
||||
lock (RegisteredPoststepActions)
|
||||
{
|
||||
if (RegisteredPoststepActions.ContainsKey(identifier))
|
||||
{
|
||||
PhysicsScene.AfterStep -= RegisteredPoststepActions[identifier];
|
||||
RegisteredPoststepActions.Remove(identifier);
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
DetailLog("{0},BSPhysObject.UnRegisterPostStepAction,id={1},removed={2}", LocalID, identifier, removed);
|
||||
return removed;
|
||||
}
|
||||
|
||||
protected void UnRegisterAllPostStepActions()
|
||||
{
|
||||
lock (RegisteredPoststepActions)
|
||||
{
|
||||
foreach (KeyValuePair<string, BSScene.PostStepAction> kvp in RegisteredPoststepActions)
|
||||
{
|
||||
PhysicsScene.AfterStep -= kvp.Value;
|
||||
}
|
||||
RegisteredPoststepActions.Clear();
|
||||
}
|
||||
DetailLog("{0},BSPhysObject.UnRegisterAllPostStepActions,", LocalID);
|
||||
}
|
||||
|
||||
#endregion // Per Simulation Step actions
|
||||
|
||||
|
|
|
@ -59,7 +59,6 @@ public sealed class BSPrim : BSPhysObject
|
|||
private OMV.Vector3 _force;
|
||||
private OMV.Vector3 _velocity;
|
||||
private OMV.Vector3 _torque;
|
||||
private float _collisionScore;
|
||||
private OMV.Vector3 _acceleration;
|
||||
private OMV.Quaternion _orientation;
|
||||
private int _physicsActorType;
|
||||
|
@ -74,7 +73,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
private bool _kinematic;
|
||||
private float _buoyancy;
|
||||
|
||||
private BSDynamics _vehicle;
|
||||
public BSDynamics VehicleController { get; private set; }
|
||||
|
||||
private BSVMotor _targetMotor;
|
||||
private OMV.Vector3 _PIDTarget;
|
||||
|
@ -108,7 +107,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
_friction = PhysicsScene.Params.defaultFriction;
|
||||
_restitution = PhysicsScene.Params.defaultRestitution;
|
||||
|
||||
_vehicle = new BSDynamics(PhysicsScene, this); // add vehicleness
|
||||
VehicleController = new BSDynamics(PhysicsScene, this); // add vehicleness
|
||||
|
||||
_mass = CalculateMass();
|
||||
|
||||
|
@ -345,6 +344,10 @@ public sealed class BSPrim : BSPhysObject
|
|||
{
|
||||
bool ret = false;
|
||||
|
||||
// We don't care where non-physical items are placed
|
||||
if (!IsPhysicallyActive)
|
||||
return ret;
|
||||
|
||||
if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(RawPosition))
|
||||
{
|
||||
// The physical object is out of the known/simulated area.
|
||||
|
@ -513,7 +516,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
|
||||
public override int VehicleType {
|
||||
get {
|
||||
return (int)_vehicle.Type; // if we are a vehicle, return that type
|
||||
return (int)VehicleController.Type; // if we are a vehicle, return that type
|
||||
}
|
||||
set {
|
||||
Vehicle type = (Vehicle)value;
|
||||
|
@ -522,14 +525,20 @@ public sealed class BSPrim : BSPhysObject
|
|||
{
|
||||
// Done at taint time so we're sure the physics engine is not using the variables
|
||||
// Vehicle code changes the parameters for this vehicle type.
|
||||
_vehicle.ProcessTypeChange(type);
|
||||
VehicleController.ProcessTypeChange(type);
|
||||
ActivateIfPhysical(false);
|
||||
|
||||
// If an active vehicle, register the vehicle code to be called before each step
|
||||
if (_vehicle.Type == Vehicle.TYPE_NONE)
|
||||
if (VehicleController.Type == Vehicle.TYPE_NONE)
|
||||
{
|
||||
UnRegisterPreStepAction("BSPrim.Vehicle", LocalID);
|
||||
PhysicsScene.AfterStep -= VehicleController.PostStep;
|
||||
}
|
||||
else
|
||||
RegisterPreStepAction("BSPrim.Vehicle", LocalID, _vehicle.Step);
|
||||
{
|
||||
RegisterPreStepAction("BSPrim.Vehicle", LocalID, VehicleController.Step);
|
||||
PhysicsScene.AfterStep += VehicleController.PostStep;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -537,7 +546,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
{
|
||||
PhysicsScene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
|
||||
{
|
||||
_vehicle.ProcessFloatVehicleParam((Vehicle)param, value);
|
||||
VehicleController.ProcessFloatVehicleParam((Vehicle)param, value);
|
||||
ActivateIfPhysical(false);
|
||||
});
|
||||
}
|
||||
|
@ -545,7 +554,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
{
|
||||
PhysicsScene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
|
||||
{
|
||||
_vehicle.ProcessVectorVehicleParam((Vehicle)param, value);
|
||||
VehicleController.ProcessVectorVehicleParam((Vehicle)param, value);
|
||||
ActivateIfPhysical(false);
|
||||
});
|
||||
}
|
||||
|
@ -553,7 +562,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
{
|
||||
PhysicsScene.TaintedObject("BSPrim.VehicleRotationParam", delegate()
|
||||
{
|
||||
_vehicle.ProcessRotationVehicleParam((Vehicle)param, rotation);
|
||||
VehicleController.ProcessRotationVehicleParam((Vehicle)param, rotation);
|
||||
ActivateIfPhysical(false);
|
||||
});
|
||||
}
|
||||
|
@ -561,7 +570,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
{
|
||||
PhysicsScene.TaintedObject("BSPrim.VehicleFlags", delegate()
|
||||
{
|
||||
_vehicle.ProcessVehicleFlags(param, remove);
|
||||
VehicleController.ProcessVehicleFlags(param, remove);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -638,11 +647,6 @@ public sealed class BSPrim : BSPhysObject
|
|||
// DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque);
|
||||
}
|
||||
}
|
||||
public override float CollisionScore {
|
||||
get { return _collisionScore; }
|
||||
set { _collisionScore = value;
|
||||
}
|
||||
}
|
||||
public override OMV.Vector3 Acceleration {
|
||||
get { return _acceleration; }
|
||||
set { _acceleration = value; }
|
||||
|
@ -747,7 +751,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
// isSolid: other objects bounce off of this object
|
||||
// isVolumeDetect: other objects pass through but can generate collisions
|
||||
// collisionEvents: whether this object returns collision events
|
||||
private void UpdatePhysicalParameters()
|
||||
public void UpdatePhysicalParameters()
|
||||
{
|
||||
// DetailLog("{0},BSPrim.UpdatePhysicalParameters,entry,body={1},shape={2}", LocalID, BSBody, BSShape);
|
||||
|
||||
|
@ -759,7 +763,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
MakeDynamic(IsStatic);
|
||||
|
||||
// Update vehicle specific parameters (after MakeDynamic() so can change physical parameters)
|
||||
_vehicle.Refresh();
|
||||
VehicleController.Refresh();
|
||||
|
||||
// Arrange for collision events if the simulator wants them
|
||||
EnableCollisions(SubscribedEvents());
|
||||
|
@ -1601,7 +1605,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
// Remove all the physical dependencies on the old body.
|
||||
// (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...)
|
||||
Linkset.RemoveBodyDependencies(this);
|
||||
_vehicle.RemoveBodyDependencies(this);
|
||||
VehicleController.RemoveBodyDependencies(this);
|
||||
});
|
||||
|
||||
// Make sure the properties are set on the new object
|
||||
|
@ -1618,9 +1622,9 @@ public sealed class BSPrim : BSPhysObject
|
|||
{
|
||||
// A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
|
||||
// TODO: handle physics introduced by Bullet with computed vehicle physics.
|
||||
if (_vehicle.IsActive)
|
||||
if (VehicleController.IsActive)
|
||||
{
|
||||
// entprop.RotationalVelocity = OMV.Vector3.Zero;
|
||||
entprop.RotationalVelocity = OMV.Vector3.Zero;
|
||||
}
|
||||
|
||||
// DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG
|
||||
|
@ -1643,7 +1647,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
// DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG
|
||||
|
||||
// The sanity check can change the velocity and/or position.
|
||||
if (IsPhysical && PositionSanityCheck(true /* inTaintTime */ ))
|
||||
if (PositionSanityCheck(true /* inTaintTime */ ))
|
||||
{
|
||||
entprop.Position = _position;
|
||||
entprop.Velocity = _velocity;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
@ -87,7 +88,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
|||
public delegate void PreStepAction(float timeStep);
|
||||
public delegate void PostStepAction(float timeStep);
|
||||
public event PreStepAction BeforeStep;
|
||||
public event PreStepAction AfterStep;
|
||||
public event PostStepAction AfterStep;
|
||||
|
||||
// A value of the time now so all the collision and update routines do not have to get their own
|
||||
// Set to 'now' just before all the prims and actors are called for collisions and updates
|
||||
|
@ -697,7 +698,21 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
|||
|
||||
public override Dictionary<uint, float> GetTopColliders()
|
||||
{
|
||||
return new Dictionary<uint, float>();
|
||||
Dictionary<uint, float> topColliders;
|
||||
|
||||
lock (PhysObjects)
|
||||
{
|
||||
foreach (KeyValuePair<uint, BSPhysObject> kvp in PhysObjects)
|
||||
{
|
||||
kvp.Value.ComputeCollisionScore();
|
||||
}
|
||||
|
||||
List<BSPhysObject> orderedPrims = new List<BSPhysObject>(PhysObjects.Values);
|
||||
orderedPrims.OrderByDescending(p => p.CollisionScore);
|
||||
topColliders = orderedPrims.Take(25).ToDictionary(p => p.LocalID, p => p.CollisionScore);
|
||||
}
|
||||
|
||||
return topColliders;
|
||||
}
|
||||
|
||||
public override bool IsThreaded { get { return false; } }
|
||||
|
@ -748,7 +763,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
|||
|
||||
private void TriggerPostStepEvent(float timeStep)
|
||||
{
|
||||
PreStepAction actions = AfterStep;
|
||||
PostStepAction actions = AfterStep;
|
||||
if (actions != null)
|
||||
actions(timeStep);
|
||||
|
||||
|
@ -840,7 +855,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
|||
{
|
||||
DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom);
|
||||
m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom);
|
||||
Util.PrintCallStack(DetailLog);
|
||||
// Util.PrintCallStack(DetailLog);
|
||||
}
|
||||
return InTaintTime;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
CURRENT PRIORITIES
|
||||
=================================================
|
||||
One sided meshes? Should terrain be built into a closed shape?
|
||||
When meshes get partially wedged into the terrain, they cannot push themselves out.
|
||||
It is possible that Bullet processes collisions whether entering or leaving a mesh.
|
||||
Ref: http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4869
|
||||
Deleting a linkset while standing on the root will leave the physical shape of the root behind.
|
||||
Not sure if it is because standing on it. Done with large prim linksets.
|
||||
Child movement in linkset (don't rebuild linkset)
|
||||
Vehicle angular vertical attraction
|
||||
vehicle angular banking
|
||||
Center-of-gravity
|
||||
|
@ -12,6 +15,7 @@ when should angular and linear motor targets be zeroed? when selected?
|
|||
Need a vehicle.clear()? Or an 'else' in prestep if not physical.
|
||||
Teravus llMoveToTarget script debug
|
||||
Mixing of hover, buoyancy/gravity, moveToTarget, into one force
|
||||
Setting hover height to zero disables hover even if hover flags are on (from SL wiki)
|
||||
Nebadon vehicles turning funny in arena
|
||||
limitMotorUp calibration (more down?)
|
||||
llRotLookAt
|
||||
|
@ -72,7 +76,11 @@ Incorporate inter-relationship of angular corrections. For instance, angularDefl
|
|||
|
||||
GENERAL TODO LIST:
|
||||
=================================================
|
||||
Avatar standing on a moving object should start to move with the object.
|
||||
llMoveToTarget objects are not effected by gravity until target is removed.
|
||||
Compute CCD parameters based on body size
|
||||
Can solver iterations be changed per body/shape? Can be for constraints but what
|
||||
about regular vehicles?
|
||||
Implement llSetPhysicalMaterial.
|
||||
extend it with Center-of-mass, rolling friction, density
|
||||
Implement llSetForceAndTorque.
|
||||
|
@ -322,3 +330,4 @@ Boats float low in the water (DONE)
|
|||
Boats floating at proper level (DONE)
|
||||
When is force introduced by SetForce removed? The prestep action could go forever. (DONE)
|
||||
(Resolution: setForce registers a prestep action which keeps applying the force)
|
||||
Child movement in linkset (don't rebuild linkset) (DONE 20130122))
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using NUnit.Framework;
|
||||
using log4net;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.BulletSPlugin;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
using OpenSim.Tests.Common;
|
||||
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class BasicVehicles : OpenSimTestCase
|
||||
{
|
||||
// Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1
|
||||
// Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1
|
||||
|
||||
BSScene PhysicsScene { get; set; }
|
||||
BSPrim TestVehicle { get; set; }
|
||||
Vector3 TestVehicleInitPosition { get; set; }
|
||||
float simulationTimeStep = 0.089f;
|
||||
|
||||
[TestFixtureSetUp]
|
||||
public void Init()
|
||||
{
|
||||
Dictionary<string, string> engineParams = new Dictionary<string, string>();
|
||||
PhysicsScene = BulletSimTestsUtil.CreateBasicPhysicsEngine(engineParams);
|
||||
|
||||
PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateSphere();
|
||||
Vector3 pos = new Vector3(100.0f, 100.0f, 0f);
|
||||
pos.Z = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos) + 2f;
|
||||
TestVehicleInitPosition = pos;
|
||||
Vector3 size = new Vector3(1f, 1f, 1f);
|
||||
pbs.Scale = size;
|
||||
Quaternion rot = Quaternion.Identity;
|
||||
bool isPhys = false;
|
||||
uint localID = 123;
|
||||
|
||||
PhysicsScene.AddPrimShape("testPrim", pbs, pos, size, rot, isPhys, localID);
|
||||
TestVehicle = (BSPrim)PhysicsScene.PhysObjects[localID];
|
||||
// The actual prim shape creation happens at taint time
|
||||
PhysicsScene.ProcessTaints();
|
||||
|
||||
}
|
||||
|
||||
[TestFixtureTearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
if (PhysicsScene != null)
|
||||
{
|
||||
// The Dispose() will also free any physical objects in the scene
|
||||
PhysicsScene.Dispose();
|
||||
PhysicsScene = null;
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase(2f, 0.2f, 0.25f, 0.25f, 0.25f)]
|
||||
[TestCase(2f, 0.2f, -0.25f, 0.25f, 0.25f)]
|
||||
[TestCase(2f, 0.2f, 0.25f, -0.25f, 0.25f)]
|
||||
[TestCase(2f, 0.2f, -0.25f, -0.25f, 0.25f)]
|
||||
// [TestCase(2f, 0.2f, 0.785f, 0.0f, 0.25f) /*, "Leaning 45 degrees to the side" */]
|
||||
// [TestCase(2f, 0.2f, 1.650f, 0.0f, 0.25f) /*, "Leaning more than 90 degrees to the side" */]
|
||||
// [TestCase(2f, 0.2f, 2.750f, 0.0f, 0.25f) /*, "Almost upside down, tipped right" */]
|
||||
// [TestCase(2f, 0.2f,-2.750f, 0.0f, 0.25f) /*, "Almost upside down, tipped left" */]
|
||||
// [TestCase(2f, 0.2f, 0.0f, 0.785f, 0.25f) /*, "Tipped back 45 degrees" */]
|
||||
// [TestCase(2f, 0.2f, 0.0f, 1.650f, 0.25f) /*, "Tipped back more than 90 degrees" */]
|
||||
// [TestCase(2f, 0.2f, 0.0f, 2.750f, 0.25f) /*, "Almost upside down, tipped back" */]
|
||||
// [TestCase(2f, 0.2f, 0.0f,-2.750f, 0.25f) /*, "Almost upside down, tipped forward" */]
|
||||
public void AngularVerticalAttraction(float timeScale, float efficiency, float initRoll, float initPitch, float initYaw)
|
||||
{
|
||||
// Enough simulation steps to cover the timescale the operation should take
|
||||
int simSteps = (int)(timeScale / simulationTimeStep) + 1;
|
||||
|
||||
// Tip the vehicle
|
||||
Quaternion initOrientation = Quaternion.CreateFromEulers(initRoll, initPitch, initYaw);
|
||||
TestVehicle.Orientation = initOrientation;
|
||||
|
||||
TestVehicle.Position = TestVehicleInitPosition;
|
||||
|
||||
// The vehicle controller is not enabled directly (by setting a vehicle type).
|
||||
// Instead the appropriate values are set and calls are made just the parts of the
|
||||
// controller we want to exercise. Stepping the physics engine then applies
|
||||
// the actions of that one feature.
|
||||
TestVehicle.VehicleController.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_EFFICIENCY, efficiency);
|
||||
TestVehicle.VehicleController.ProcessFloatVehicleParam(Vehicle.VERTICAL_ATTRACTION_TIMESCALE, timeScale);
|
||||
TestVehicle.VehicleController.enableAngularVerticalAttraction = true;
|
||||
|
||||
TestVehicle.IsPhysical = true;
|
||||
PhysicsScene.ProcessTaints();
|
||||
|
||||
// Step the simulator a bunch of times and vertical attraction should orient the vehicle up
|
||||
for (int ii = 0; ii < simSteps; ii++)
|
||||
{
|
||||
TestVehicle.VehicleController.ForgetKnownVehicleProperties();
|
||||
TestVehicle.VehicleController.ComputeAngularVerticalAttraction();
|
||||
TestVehicle.VehicleController.PushKnownChanged();
|
||||
|
||||
PhysicsScene.Simulate(simulationTimeStep);
|
||||
}
|
||||
|
||||
TestVehicle.IsPhysical = false;
|
||||
PhysicsScene.ProcessTaints();
|
||||
|
||||
// After these steps, the vehicle should be upright
|
||||
/*
|
||||
float finalRoll, finalPitch, finalYaw;
|
||||
TestVehicle.Orientation.GetEulerAngles(out finalRoll, out finalPitch, out finalYaw);
|
||||
Assert.That(finalRoll, Is.InRange(-0.01f, 0.01f));
|
||||
Assert.That(finalPitch, Is.InRange(-0.01f, 0.01f));
|
||||
Assert.That(finalYaw, Is.InRange(initYaw - 0.1f, initYaw + 0.1f));
|
||||
*/
|
||||
|
||||
Vector3 upPointer = Vector3.UnitZ * TestVehicle.Orientation;
|
||||
Assert.That(upPointer.Z, Is.GreaterThan(0.99f));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using NUnit.Framework;
|
||||
using log4net;
|
||||
|
||||
using OpenSim.Tests.Common;
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class BulletSimTests : OpenSimTestCase
|
||||
{
|
||||
// Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1
|
||||
// Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1
|
||||
|
||||
[TestFixtureSetUp]
|
||||
public void Init()
|
||||
{
|
||||
}
|
||||
|
||||
[TestFixtureTearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Nini.Config;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Physics.BulletSPlugin;
|
||||
using OpenSim.Region.Physics.Meshing;
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin.Tests
|
||||
{
|
||||
// Utility functions for building up and tearing down the sample physics environments
|
||||
public static class BulletSimTestsUtil
|
||||
{
|
||||
// 'engineName' is the Bullet engine to use. Either null (for unmanaged), "BulletUnmanaged" or "BulletXNA"
|
||||
// 'params' is a set of keyValue pairs to set in the engine's configuration file (override defaults)
|
||||
// May be 'null' if there are no overrides.
|
||||
public static BSScene CreateBasicPhysicsEngine(Dictionary<string,string> paramOverrides)
|
||||
{
|
||||
IConfigSource openSimINI = new IniConfigSource();
|
||||
IConfig startupConfig = openSimINI.AddConfig("Startup");
|
||||
startupConfig.Set("physics", "BulletSim");
|
||||
startupConfig.Set("meshing", "Meshmerizer");
|
||||
startupConfig.Set("cacheSculptMaps", "false"); // meshmerizer shouldn't save maps
|
||||
|
||||
IConfig bulletSimConfig = openSimINI.AddConfig("BulletSim");
|
||||
// If the caller cares, specify the bullet engine otherwise it will default to "BulletUnmanaged".
|
||||
// bulletSimConfig.Set("BulletEngine", "BulletUnmanaged");
|
||||
// bulletSimConfig.Set("BulletEngine", "BulletXNA");
|
||||
bulletSimConfig.Set("MeshSculptedPrim", "false");
|
||||
bulletSimConfig.Set("ForceSimplePrimMeshing", "true");
|
||||
if (paramOverrides != null)
|
||||
{
|
||||
foreach (KeyValuePair<string, string> kvp in paramOverrides)
|
||||
{
|
||||
bulletSimConfig.Set(kvp.Key, kvp.Value);
|
||||
}
|
||||
}
|
||||
|
||||
// If a special directory exists, put detailed logging therein.
|
||||
// This allows local testing/debugging without having to worry that the build engine will output logs.
|
||||
if (Directory.Exists("physlogs"))
|
||||
{
|
||||
bulletSimConfig.Set("PhysicsLoggingDir","./physlogs");
|
||||
bulletSimConfig.Set("PhysicsLoggingEnabled","True");
|
||||
bulletSimConfig.Set("PhysicsLoggingDoFlush","True");
|
||||
bulletSimConfig.Set("VehicleLoggingEnabled","True");
|
||||
}
|
||||
|
||||
BSPlugin bsPlugin = new BSPlugin();
|
||||
|
||||
BSScene bsScene = (BSScene)bsPlugin.GetScene("BSTestRegion");
|
||||
|
||||
// Since the asset requestor is not initialized, any mesh or sculptie will be a cube.
|
||||
// In the future, add a fake asset fetcher to get meshes and sculpts.
|
||||
// bsScene.RequestAssetMethod = ???;
|
||||
|
||||
Meshing.Meshmerizer mesher = new Meshmerizer(openSimINI);
|
||||
bsScene.Initialise(mesher, openSimINI);
|
||||
|
||||
return bsScene;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -4096,8 +4096,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
lock (_prims)
|
||||
{
|
||||
List<OdePrim> orderedPrims = new List<OdePrim>(_prims);
|
||||
orderedPrims.OrderByDescending(p => p.CollisionScore).Take(25);
|
||||
topColliders = orderedPrims.ToDictionary(p => p.LocalID, p => p.CollisionScore);
|
||||
orderedPrims.OrderByDescending(p => p.CollisionScore);
|
||||
topColliders = orderedPrims.Take(25).ToDictionary(p => p.LocalID, p => p.CollisionScore);
|
||||
|
||||
foreach (OdePrim p in _prims)
|
||||
p.CollisionScore = 0;
|
||||
|
|
|
@ -31,7 +31,6 @@ using System.Collections.Generic;
|
|||
using System.Reflection;
|
||||
using log4net;
|
||||
using Tools;
|
||||
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
|
||||
|
@ -479,20 +478,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
|
|||
{
|
||||
string retstr = String.Empty;
|
||||
bool printSemicolon = true;
|
||||
|
||||
retstr += Indent();
|
||||
bool transformToBlock = false;
|
||||
|
||||
if (m_insertCoopTerminationChecks)
|
||||
{
|
||||
// We have to check in event functions as well because the user can manually call these.
|
||||
if (previousSymbol is GlobalFunctionDefinition
|
||||
|| previousSymbol is WhileStatement
|
||||
// A non-braced single line do while structure cannot contain multiple statements.
|
||||
// So to insert the termination check we change this to a braced control structure instead.
|
||||
if (previousSymbol is WhileStatement
|
||||
|| previousSymbol is DoWhileStatement
|
||||
|| previousSymbol is ForLoop
|
||||
|| previousSymbol is StateEvent)
|
||||
retstr += Generate(m_coopTerminationCheck);
|
||||
|| previousSymbol is ForLoop)
|
||||
{
|
||||
transformToBlock = true;
|
||||
|
||||
// FIXME: This will be wrongly indented because the previous for/while/dowhile will have already indented.
|
||||
retstr += GenerateIndentedLine("{");
|
||||
|
||||
retstr += GenerateIndentedLine(m_coopTerminationCheck);
|
||||
}
|
||||
}
|
||||
|
||||
retstr += Indent();
|
||||
|
||||
if (0 < s.kids.Count)
|
||||
{
|
||||
// Jump label prints its own colon, we don't need a semicolon.
|
||||
|
@ -508,6 +514,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
|
|||
if (printSemicolon)
|
||||
retstr += GenerateLine(";");
|
||||
|
||||
if (transformToBlock)
|
||||
{
|
||||
// FIXME: This will be wrongly indented because the for/while/dowhile is currently handling the unindent
|
||||
retstr += GenerateIndentedLine("}");
|
||||
}
|
||||
|
||||
return retstr;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,10 +55,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
|
|||
|
||||
private OSChatMessage m_osChatMessageReceived;
|
||||
|
||||
/// <summary>
|
||||
/// Number of chat messages received so far. Reset before each test.
|
||||
/// </summary>
|
||||
private int m_chatMessagesReceived;
|
||||
|
||||
/// <summary>
|
||||
/// Number of chat messages expected. m_chatEvent is not fired until this number is reached or exceeded.
|
||||
/// </summary>
|
||||
private int m_chatMessagesThreshold;
|
||||
|
||||
[SetUp]
|
||||
public void Init()
|
||||
{
|
||||
m_osChatMessageReceived = null;
|
||||
m_chatMessagesReceived = 0;
|
||||
m_chatMessagesThreshold = 0;
|
||||
m_chatEvent = new AutoResetEvent(false);
|
||||
m_stoppedEvent = new AutoResetEvent(false);
|
||||
|
||||
|
@ -125,6 +137,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
|
|||
TestStop(script);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestNoStopOnSingleStatementForLoop()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
string script =
|
||||
@"default
|
||||
{
|
||||
state_entry()
|
||||
{
|
||||
integer i = 0;
|
||||
for (i = 0; i <= 1; i++) llSay(0, ""Iter "" + (string)i);
|
||||
}
|
||||
}";
|
||||
|
||||
TestSingleStatementNoStop(script);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestStopOnLongSingleStatementForLoop()
|
||||
{
|
||||
|
@ -139,8 +170,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
|
|||
integer i = 0;
|
||||
llSay(0, ""Thin Lizzy"");
|
||||
|
||||
for (i = 0; i < 2147483647; i++)
|
||||
llSay(0, ""Iter "" + (string)i);
|
||||
for (i = 0; i < 2147483647; i++) llSay(0, ""Iter "" + (string)i);
|
||||
}
|
||||
}";
|
||||
|
||||
|
@ -171,6 +201,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
|
|||
TestStop(script);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestNoStopOnSingleStatementWhileLoop()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
string script =
|
||||
@"default
|
||||
{
|
||||
state_entry()
|
||||
{
|
||||
integer i = 0;
|
||||
while (i < 2) llSay(0, ""Iter "" + (string)i++);
|
||||
}
|
||||
}";
|
||||
|
||||
TestSingleStatementNoStop(script);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestStopOnLongSingleStatementWhileLoop()
|
||||
{
|
||||
|
@ -218,7 +267,50 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
|
|||
}
|
||||
|
||||
[Test]
|
||||
public void TestStopOnLongDoWhileLoop()
|
||||
public void TestNoStopOnSingleStatementDoWhileLoop()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
string script =
|
||||
@"default
|
||||
{
|
||||
state_entry()
|
||||
{
|
||||
integer i = 0;
|
||||
|
||||
do llSay(0, ""Iter "" + (string)i++);
|
||||
while (i < 2);
|
||||
}
|
||||
}";
|
||||
|
||||
TestSingleStatementNoStop(script);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestStopOnLongSingleStatementDoWhileLoop()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
string script =
|
||||
@"default
|
||||
{
|
||||
state_entry()
|
||||
{
|
||||
integer i = 0;
|
||||
llSay(0, ""Thin Lizzy"");
|
||||
|
||||
do llSay(0, ""Iter "" + (string)i++);
|
||||
while (1 == 1);
|
||||
}
|
||||
}";
|
||||
|
||||
TestStop(script);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestStopOnLongCompoundStatementDoWhileLoop()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
@ -234,7 +326,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
|
|||
do
|
||||
{
|
||||
llSay(0, ""Iter "" + (string)i++);
|
||||
} while (1 == 1);
|
||||
} while (1 == 1);
|
||||
}
|
||||
}";
|
||||
|
||||
|
@ -245,7 +337,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests
|
|||
public void TestStopOnInfiniteJumpLoop()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
TestHelpers.EnableLogging();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
string script =
|
||||
@"default
|
||||
|
@ -320,14 +412,13 @@ default
|
|||
TestStop(script);
|
||||
}
|
||||
|
||||
private void TestStop(string script)
|
||||
private SceneObjectPart CreateScript(string script, string itemName, UUID userId)
|
||||
{
|
||||
UUID userId = TestHelpers.ParseTail(0x1);
|
||||
// UUID objectId = TestHelpers.ParseTail(0x100);
|
||||
// UUID itemId = TestHelpers.ParseTail(0x3);
|
||||
string itemName = "TestStop() Item";
|
||||
|
||||
SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, "TestStop", 0x100);
|
||||
SceneObjectGroup so
|
||||
= SceneHelpers.CreateSceneObject(1, userId, string.Format("Object for {0}", itemName), 0x100);
|
||||
m_scene.AddNewSceneObject(so, true);
|
||||
|
||||
InventoryItemBase itemTemplate = new InventoryItemBase();
|
||||
|
@ -338,14 +429,57 @@ default
|
|||
|
||||
m_scene.EventManager.OnChatFromWorld += OnChatFromWorld;
|
||||
|
||||
SceneObjectPart partWhereRezzed = m_scene.RezNewScript(userId, itemTemplate, script);
|
||||
return m_scene.RezNewScript(userId, itemTemplate, script);
|
||||
}
|
||||
|
||||
private void TestSingleStatementNoStop(string script)
|
||||
{
|
||||
// In these tests we expect to see at least 2 chat messages to confirm that the loop is working properly.
|
||||
m_chatMessagesThreshold = 2;
|
||||
|
||||
UUID userId = TestHelpers.ParseTail(0x1);
|
||||
// UUID objectId = TestHelpers.ParseTail(0x100);
|
||||
// UUID itemId = TestHelpers.ParseTail(0x3);
|
||||
string itemName = "TestNoStop";
|
||||
|
||||
SceneObjectPart partWhereRezzed = CreateScript(script, itemName, userId);
|
||||
TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName);
|
||||
|
||||
// Wait for the script to start the event before we try stopping it.
|
||||
m_chatEvent.WaitOne(60000);
|
||||
|
||||
Console.WriteLine("Script started with message [{0}]", m_osChatMessageReceived.Message);
|
||||
if (m_osChatMessageReceived == null)
|
||||
Assert.Fail("Script did not start");
|
||||
else
|
||||
Assert.That(m_chatMessagesReceived, Is.EqualTo(2));
|
||||
|
||||
bool running;
|
||||
TaskInventoryItem scriptItem = partWhereRezzed.Inventory.GetInventoryItem(itemName);
|
||||
Assert.That(
|
||||
SceneObjectPartInventory.TryGetScriptInstanceRunning(m_scene, scriptItem, out running), Is.True);
|
||||
Assert.That(running, Is.True);
|
||||
}
|
||||
|
||||
private void TestStop(string script)
|
||||
{
|
||||
// In these tests we're only interested in the first message to confirm that the script has started.
|
||||
m_chatMessagesThreshold = 1;
|
||||
|
||||
UUID userId = TestHelpers.ParseTail(0x1);
|
||||
// UUID objectId = TestHelpers.ParseTail(0x100);
|
||||
// UUID itemId = TestHelpers.ParseTail(0x3);
|
||||
string itemName = "TestStop";
|
||||
|
||||
SceneObjectPart partWhereRezzed = CreateScript(script, itemName, userId);
|
||||
TaskInventoryItem rezzedItem = partWhereRezzed.Inventory.GetInventoryItem(itemName);
|
||||
|
||||
// Wait for the script to start the event before we try stopping it.
|
||||
m_chatEvent.WaitOne(60000);
|
||||
|
||||
if (m_osChatMessageReceived != null)
|
||||
Console.WriteLine("Script started with message [{0}]", m_osChatMessageReceived.Message);
|
||||
else
|
||||
Assert.Fail("Script did not start");
|
||||
|
||||
// FIXME: This is a very poor way of trying to avoid a low-probability race condition where the script
|
||||
// executes llSay() but has not started the next statement before we try to stop it.
|
||||
|
@ -367,11 +501,14 @@ default
|
|||
|
||||
private void OnChatFromWorld(object sender, OSChatMessage oscm)
|
||||
{
|
||||
m_scene.EventManager.OnChatFromWorld -= OnChatFromWorld;
|
||||
Console.WriteLine("Got chat [{0}]", oscm.Message);
|
||||
|
||||
m_osChatMessageReceived = oscm;
|
||||
m_chatEvent.Set();
|
||||
|
||||
if (++m_chatMessagesReceived >= m_chatMessagesThreshold)
|
||||
{
|
||||
m_scene.EventManager.OnChatFromWorld -= OnChatFromWorld;
|
||||
m_chatEvent.Set();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -49,7 +49,6 @@ using OpenSim.Region.Framework.Scenes;
|
|||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.ScriptEngine.Interfaces;
|
||||
using OpenSim.Region.ScriptEngine.Shared;
|
||||
using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
|
||||
using OpenSim.Region.ScriptEngine.Shared.CodeTools;
|
||||
using OpenSim.Region.ScriptEngine.Shared.Instance;
|
||||
using OpenSim.Region.ScriptEngine.Shared.Api;
|
||||
|
@ -698,7 +697,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Queue eq = instance.EventQueue;
|
||||
|
||||
sb.AppendFormat("Script name : {0}\n", instance.ScriptName);
|
||||
sb.AppendFormat("Status : {0}\n", status);
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
34
prebuild.xml
34
prebuild.xml
|
@ -3484,6 +3484,40 @@
|
|||
</Files>
|
||||
</Project>
|
||||
|
||||
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.BulletSPlugin.Tests" path="OpenSim/Region/Physics/BulletSPlugin/Tests" type="Library">
|
||||
<Configuration name="Debug">
|
||||
<Options>
|
||||
<OutputPath>../../../../../bin/</OutputPath>
|
||||
</Options>
|
||||
</Configuration>
|
||||
<Configuration name="Release">
|
||||
<Options>
|
||||
<OutputPath>../../../../../bin/</OutputPath>
|
||||
</Options>
|
||||
</Configuration>
|
||||
|
||||
<ReferencePath>../../../../../bin/</ReferencePath>
|
||||
<Reference name="System"/>
|
||||
<Reference name="System.Core"/>
|
||||
<Reference name="System.Data"/>
|
||||
<Reference name="Nini" path="../../../../../bin/"/>
|
||||
<Reference name="log4net" path="../../../../../bin/"/>
|
||||
<Reference name="nunit.framework" path="../../../../../bin/"/>
|
||||
<Reference name="OpenMetaverse" path="../../../../../bin/"/>
|
||||
<Reference name="OpenMetaverseTypes" path="../../../../../bin/"/>
|
||||
<Reference name="OpenSim.Framework"/>
|
||||
<Reference name="OpenSim.Tests.Common"/>
|
||||
<Reference name="OpenSim.Region.CoreModules"/>
|
||||
<Reference name="OpenSim.Region.Physics.Meshing" path="../../../../../bin/Physics/"/>
|
||||
<Reference name="OpenSim.Region.Physics.Manager"/>
|
||||
<Reference name="OpenSim.Region.Physics.BulletSPlugin" path="../../../../../bin/Physics/"/>
|
||||
|
||||
<Files>
|
||||
<Match pattern="*.cs" recurse="false"/>
|
||||
</Files>
|
||||
</Project>
|
||||
|
||||
|
||||
<Project frameworkVersion="v3_5" name="OpenSim.Server.Handlers.Tests" path="OpenSim/Server/Handlers" type="Library">
|
||||
<Configuration name="Debug">
|
||||
<Options>
|
||||
|
|
Loading…
Reference in New Issue