Merge branch 'master' into careminster

Conflicts:
	OpenSim/Region/Framework/Scenes/Scene.cs
	OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
	OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
	OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
avinationmerge
Melanie 2012-08-18 13:17:39 +01:00
commit aee7a31bc3
23 changed files with 469 additions and 347 deletions

View File

@ -89,6 +89,17 @@ namespace OpenSim.Framework.Monitoring
FirstTick = Environment.TickCount & Int32.MaxValue; FirstTick = Environment.TickCount & Int32.MaxValue;
LastTick = FirstTick; LastTick = FirstTick;
} }
public ThreadWatchdogInfo(ThreadWatchdogInfo previousTwi)
{
Thread = previousTwi.Thread;
FirstTick = previousTwi.FirstTick;
LastTick = previousTwi.LastTick;
Timeout = previousTwi.Timeout;
IsTimedOut = previousTwi.IsTimedOut;
AlarmIfTimeout = previousTwi.AlarmIfTimeout;
AlarmMethod = previousTwi.AlarmMethod;
}
} }
/// <summary> /// <summary>
@ -335,7 +346,9 @@ namespace OpenSim.Framework.Monitoring
if (callbackInfos == null) if (callbackInfos == null)
callbackInfos = new List<ThreadWatchdogInfo>(); callbackInfos = new List<ThreadWatchdogInfo>();
callbackInfos.Add(threadInfo); // Send a copy of the watchdog info to prevent race conditions where the watchdog
// thread updates the monitoring info after an alarm has been sent out.
callbackInfos.Add(new ThreadWatchdogInfo(threadInfo));
} }
} }
} }

View File

@ -122,7 +122,9 @@ namespace OpenSim.Framework
public UUID lastMapUUID = UUID.Zero; public UUID lastMapUUID = UUID.Zero;
public string lastMapRefresh = "0"; public string lastMapRefresh = "0";
private float m_nonphysPrimMin = 0;
private int m_nonphysPrimMax = 0; private int m_nonphysPrimMax = 0;
private float m_physPrimMin = 0;
private int m_physPrimMax = 0; private int m_physPrimMax = 0;
private bool m_clampPrimSize = false; private bool m_clampPrimSize = false;
private int m_objectCapacity = 0; private int m_objectCapacity = 0;
@ -287,11 +289,21 @@ namespace OpenSim.Framework
set { m_windlight = value; } set { m_windlight = value; }
} }
public float NonphysPrimMin
{
get { return m_nonphysPrimMin; }
}
public int NonphysPrimMax public int NonphysPrimMax
{ {
get { return m_nonphysPrimMax; } get { return m_nonphysPrimMax; }
} }
public float PhysPrimMin
{
get { return m_physPrimMin; }
}
public int PhysPrimMax public int PhysPrimMax
{ {
get { return m_physPrimMax; } get { return m_physPrimMax; }
@ -625,16 +637,28 @@ namespace OpenSim.Framework
m_regionType = config.GetString("RegionType", String.Empty); m_regionType = config.GetString("RegionType", String.Empty);
allKeys.Remove("RegionType"); allKeys.Remove("RegionType");
// Prim stuff #region Prim stuff
//
m_nonphysPrimMin = config.GetFloat("NonphysicalPrimMin", 0);
allKeys.Remove("NonphysicalPrimMin");
m_nonphysPrimMax = config.GetInt("NonphysicalPrimMax", 0); m_nonphysPrimMax = config.GetInt("NonphysicalPrimMax", 0);
allKeys.Remove("NonphysicalPrimMax"); allKeys.Remove("NonphysicalPrimMax");
m_physPrimMin = config.GetFloat("PhysicalPrimMin", 0);
allKeys.Remove("PhysicalPrimMin");
m_physPrimMax = config.GetInt("PhysicalPrimMax", 0); m_physPrimMax = config.GetInt("PhysicalPrimMax", 0);
allKeys.Remove("PhysicalPrimMax"); allKeys.Remove("PhysicalPrimMax");
m_clampPrimSize = config.GetBoolean("ClampPrimSize", false); m_clampPrimSize = config.GetBoolean("ClampPrimSize", false);
allKeys.Remove("ClampPrimSize"); allKeys.Remove("ClampPrimSize");
m_objectCapacity = config.GetInt("MaxPrims", 15000); m_objectCapacity = config.GetInt("MaxPrims", 15000);
allKeys.Remove("MaxPrims"); allKeys.Remove("MaxPrims");
#endregion
m_agentCapacity = config.GetInt("MaxAgents", 100); m_agentCapacity = config.GetInt("MaxAgents", 100);
allKeys.Remove("MaxAgents"); allKeys.Remove("MaxAgents");
@ -673,10 +697,18 @@ namespace OpenSim.Framework
config.Set("ExternalHostName", m_externalHostName); config.Set("ExternalHostName", m_externalHostName);
if (m_nonphysPrimMin != 0)
config.Set("NonphysicalPrimMax", m_nonphysPrimMin);
if (m_nonphysPrimMax != 0) if (m_nonphysPrimMax != 0)
config.Set("NonphysicalPrimMax", m_nonphysPrimMax); config.Set("NonphysicalPrimMax", m_nonphysPrimMax);
if (m_physPrimMin != 0)
config.Set("PhysicalPrimMax", m_physPrimMin);
if (m_physPrimMax != 0) if (m_physPrimMax != 0)
config.Set("PhysicalPrimMax", m_physPrimMax); config.Set("PhysicalPrimMax", m_physPrimMax);
config.Set("ClampPrimSize", m_clampPrimSize.ToString()); config.Set("ClampPrimSize", m_clampPrimSize.ToString());
if (m_objectCapacity != 0) if (m_objectCapacity != 0)
@ -759,9 +791,15 @@ namespace OpenSim.Framework
configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
"Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true); "Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true);
configMember.addConfigurationOption("nonphysical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
"Minimum size for nonphysical prims", m_nonphysPrimMin.ToString(), true);
configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32, configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
"Maximum size for nonphysical prims", m_nonphysPrimMax.ToString(), true); "Maximum size for nonphysical prims", m_nonphysPrimMax.ToString(), true);
configMember.addConfigurationOption("physical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
"Minimum size for nonphysical prims", m_physPrimMin.ToString(), true);
configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32, configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
"Maximum size for physical prims", m_physPrimMax.ToString(), true); "Maximum size for physical prims", m_physPrimMax.ToString(), true);

View File

@ -862,6 +862,12 @@ namespace OpenSim.Framework
return Math.Min(Math.Max(x, min), max); return Math.Min(Math.Max(x, min), max);
} }
public static Vector3 Clip(Vector3 vec, float min, float max)
{
return new Vector3(Clip(vec.X, min, max), Clip(vec.Y, min, max),
Clip(vec.Z, min, max));
}
/// <summary> /// <summary>
/// Convert an UUID to a raw uuid string. Right now this is a string without hyphens. /// Convert an UUID to a raw uuid string. Right now this is a string without hyphens.
/// </summary> /// </summary>

View File

@ -103,8 +103,26 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
public bool CollidablePrims { get; private set; } public bool CollidablePrims { get; private set; }
/// <summary>
/// Minimum value of the size of a non-physical prim in each axis
/// </summary>
public float m_minNonphys = 0.01f;
/// <summary>
/// Maximum value of the size of a non-physical prim in each axis
/// </summary>
public float m_maxNonphys = 256; public float m_maxNonphys = 256;
/// <summary>
/// Minimum value of the size of a physical prim in each axis
/// </summary>
public float m_minPhys = 0.01f;
/// <summary>
/// Maximum value of the size of a physical prim in each axis
/// </summary>
public float m_maxPhys = 10; public float m_maxPhys = 10;
public bool m_clampPrimSize; public bool m_clampPrimSize;
public bool m_trustBinaries; public bool m_trustBinaries;
public bool m_allowScriptCrossings; public bool m_allowScriptCrossings;
@ -746,12 +764,24 @@ namespace OpenSim.Region.Framework.Scenes
PhysicalPrims = startupConfig.GetBoolean("physical_prim", true); PhysicalPrims = startupConfig.GetBoolean("physical_prim", true);
CollidablePrims = startupConfig.GetBoolean("collidable_prim", true); CollidablePrims = startupConfig.GetBoolean("collidable_prim", true);
m_minNonphys = startupConfig.GetFloat("NonphysicalPrimMin", m_minNonphys);
if (RegionInfo.NonphysPrimMin > 0)
{
m_minNonphys = RegionInfo.NonphysPrimMin;
}
m_maxNonphys = startupConfig.GetFloat("NonphysicalPrimMax", m_maxNonphys); m_maxNonphys = startupConfig.GetFloat("NonphysicalPrimMax", m_maxNonphys);
if (RegionInfo.NonphysPrimMax > 0) if (RegionInfo.NonphysPrimMax > 0)
{ {
m_maxNonphys = RegionInfo.NonphysPrimMax; m_maxNonphys = RegionInfo.NonphysPrimMax;
} }
m_minPhys = startupConfig.GetFloat("PhysicalPrimMin", m_minPhys);
if (RegionInfo.PhysPrimMin > 0)
{
m_minPhys = RegionInfo.PhysPrimMin;
}
m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys); m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys);
if (RegionInfo.PhysPrimMax > 0) if (RegionInfo.PhysPrimMax > 0)

View File

@ -421,12 +421,9 @@ namespace OpenSim.Region.Framework.Scenes
{ {
Vector3 scale = part.Shape.Scale; Vector3 scale = part.Shape.Scale;
if (scale.X > m_parentScene.m_maxNonphys) scale.X = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.X));
scale.X = m_parentScene.m_maxNonphys; scale.Y = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Y));
if (scale.Y > m_parentScene.m_maxNonphys) scale.Z = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Z));
scale.Y = m_parentScene.m_maxNonphys;
if (scale.Z > m_parentScene.m_maxNonphys)
scale.Z = m_parentScene.m_maxNonphys;
part.Shape.Scale = scale; part.Shape.Scale = scale;
} }

View File

@ -3436,17 +3436,17 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="scale"></param> /// <param name="scale"></param>
public void GroupResize(Vector3 scale) public void GroupResize(Vector3 scale)
{ {
scale.X = Math.Min(scale.X, Scene.m_maxNonphys); scale.X = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.X));
scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys); scale.Y = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Y));
scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys); scale.Z = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Z));
PhysicsActor pa = m_rootPart.PhysActor; PhysicsActor pa = m_rootPart.PhysActor;
if (pa != null && pa.IsPhysical) if (pa != null && pa.IsPhysical)
{ {
scale.X = Math.Min(scale.X, Scene.m_maxPhys); scale.X = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.X));
scale.Y = Math.Min(scale.Y, Scene.m_maxPhys); scale.Y = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Y));
scale.Z = Math.Min(scale.Z, Scene.m_maxPhys); scale.Z = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Z));
} }
float x = (scale.X / RootPart.Scale.X); float x = (scale.X / RootPart.Scale.X);
@ -3477,6 +3477,14 @@ namespace OpenSim.Region.Framework.Scenes
y *= a; y *= a;
z *= a; z *= a;
} }
else if (oldSize.X * x < m_scene.m_minPhys)
{
f = m_scene.m_minPhys / oldSize.X;
a = f / x;
x *= a;
y *= a;
z *= a;
}
if (oldSize.Y * y > m_scene.m_maxPhys) if (oldSize.Y * y > m_scene.m_maxPhys)
{ {
@ -3486,6 +3494,14 @@ namespace OpenSim.Region.Framework.Scenes
y *= a; y *= a;
z *= a; z *= a;
} }
else if (oldSize.Y * y < m_scene.m_minPhys)
{
f = m_scene.m_minPhys / oldSize.Y;
a = f / y;
x *= a;
y *= a;
z *= a;
}
if (oldSize.Z * z > m_scene.m_maxPhys) if (oldSize.Z * z > m_scene.m_maxPhys)
{ {
@ -3495,6 +3511,14 @@ namespace OpenSim.Region.Framework.Scenes
y *= a; y *= a;
z *= a; z *= a;
} }
else if (oldSize.Z * z < m_scene.m_minPhys)
{
f = m_scene.m_minPhys / oldSize.Z;
a = f / z;
x *= a;
y *= a;
z *= a;
}
} }
else else
{ {
@ -3506,6 +3530,14 @@ namespace OpenSim.Region.Framework.Scenes
y *= a; y *= a;
z *= a; z *= a;
} }
else if (oldSize.X * x < m_scene.m_minNonphys)
{
f = m_scene.m_minNonphys / oldSize.X;
a = f / x;
x *= a;
y *= a;
z *= a;
}
if (oldSize.Y * y > m_scene.m_maxNonphys) if (oldSize.Y * y > m_scene.m_maxNonphys)
{ {
@ -3515,6 +3547,14 @@ namespace OpenSim.Region.Framework.Scenes
y *= a; y *= a;
z *= a; z *= a;
} }
else if (oldSize.Y * y < m_scene.m_minNonphys)
{
f = m_scene.m_minNonphys / oldSize.Y;
a = f / y;
x *= a;
y *= a;
z *= a;
}
if (oldSize.Z * z > m_scene.m_maxNonphys) if (oldSize.Z * z > m_scene.m_maxNonphys)
{ {
@ -3524,6 +3564,14 @@ namespace OpenSim.Region.Framework.Scenes
y *= a; y *= a;
z *= a; z *= a;
} }
else if (oldSize.Z * z < m_scene.m_minNonphys)
{
f = m_scene.m_minNonphys / oldSize.Z;
a = f / z;
x *= a;
y *= a;
z *= a;
}
} }
} }
} }

View File

@ -790,7 +790,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
catch (Exception e) catch (Exception e)
{ {
m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message); m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e);
} }
} }
} }
@ -2969,17 +2969,16 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="scale"></param> /// <param name="scale"></param>
public void Resize(Vector3 scale) public void Resize(Vector3 scale)
{ {
scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxNonphys); scale.X = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.X));
scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxNonphys); scale.Y = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Y));
scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxNonphys); scale.Z = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Z));
PhysicsActor pa = PhysActor; PhysicsActor pa = PhysActor;
if (pa != null && pa.IsPhysical) if (pa != null && pa.IsPhysical)
{ {
scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxPhys); scale.X = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.X));
scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxPhys); scale.Y = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Y));
scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxPhys); scale.Z = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Z));
} }
// m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale); // m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale);
@ -4864,6 +4863,57 @@ namespace OpenSim.Region.Framework.Scenes
ScheduleFullUpdate(); ScheduleFullUpdate();
} }
public void UpdateSlice(float begin, float end)
{
if (end < begin)
{
float temp = begin;
begin = end;
end = temp;
}
end = Math.Min(1f, Math.Max(0f, end));
begin = Math.Min(Math.Min(1f, Math.Max(0f, begin)), end - 0.02f);
if (begin < 0.02f && end < 0.02f)
{
begin = 0f;
end = 0.02f;
}
ushort uBegin = (ushort)(50000.0 * begin);
ushort uEnd = (ushort)(50000.0 * (1f - end));
bool updatePossiblyNeeded = false;
PrimType primType = GetPrimType();
if (primType == PrimType.SPHERE || primType == PrimType.TORUS || primType == PrimType.TUBE || primType == PrimType.RING)
{
if (m_shape.ProfileBegin != uBegin || m_shape.ProfileEnd != uEnd)
{
m_shape.ProfileBegin = uBegin;
m_shape.ProfileEnd = uEnd;
updatePossiblyNeeded = true;
}
}
else if (m_shape.PathBegin != uBegin || m_shape.PathEnd != uEnd)
{
m_shape.PathBegin = uBegin;
m_shape.PathEnd = uEnd;
updatePossiblyNeeded = true;
}
if (updatePossiblyNeeded && ParentGroup != null)
{
ParentGroup.HasGroupChanged = true;
}
if (updatePossiblyNeeded && PhysActor != null)
{
PhysActor.Shape = m_shape;
ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
}
if (updatePossiblyNeeded)
{
ScheduleFullUpdate();
}
}
/// <summary> /// <summary>
/// If the part is a sculpt/mesh, retrieve the mesh data and reinsert it into the shape so that the physics /// If the part is a sculpt/mesh, retrieve the mesh data and reinsert it into the shape so that the physics
/// engine can use it. /// engine can use it.

View File

@ -1527,17 +1527,22 @@ namespace OpenSim.Region.Framework.Scenes
bool DCFlagKeyPressed = false; bool DCFlagKeyPressed = false;
Vector3 agent_control_v3 = Vector3.Zero; Vector3 agent_control_v3 = Vector3.Zero;
bool oldflying = Flying; bool newFlying = actor.Flying;
if (ForceFly) if (ForceFly)
actor.Flying = true; newFlying = true;
else if (FlyDisabled) else if (FlyDisabled)
actor.Flying = false; newFlying = false;
else else
actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); newFlying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
if (actor.Flying != oldflying) if (actor.Flying != newFlying)
{
// Note: ScenePresence.Flying is actually fetched from the physical actor
// so setting PhysActor.Flying here also sets the ScenePresence's value.
actor.Flying = newFlying;
update_movementflag = true; update_movementflag = true;
}
if (ParentID == 0) if (ParentID == 0)
{ {

View File

@ -124,10 +124,14 @@ public class BSCharacter : PhysicsActor
// do actual create at taint time // do actual create at taint time
_scene.TaintedObject("BSCharacter.create", delegate() _scene.TaintedObject("BSCharacter.create", delegate()
{ {
DetailLog("{0},BSCharacter.create", _localID);
BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData); BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData);
// Set the buoyancy for flying. This will be refactored when all the settings happen in C#
BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy);
m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
// avatars get all collisions no matter what // avatars get all collisions no matter what (makes walking on ground and such work)
BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
}); });
@ -137,7 +141,7 @@ public class BSCharacter : PhysicsActor
// called when this character is being destroyed and the resources should be released // called when this character is being destroyed and the resources should be released
public void Destroy() public void Destroy()
{ {
// DetailLog("{0},BSCharacter.Destroy", LocalID); DetailLog("{0},BSCharacter.Destroy", LocalID);
_scene.TaintedObject("BSCharacter.destroy", delegate() _scene.TaintedObject("BSCharacter.destroy", delegate()
{ {
BulletSimAPI.DestroyObject(_scene.WorldID, _localID); BulletSimAPI.DestroyObject(_scene.WorldID, _localID);
@ -319,14 +323,13 @@ public class BSCharacter : PhysicsActor
public override bool Flying { public override bool Flying {
get { return _flying; } get { return _flying; }
set { set {
if (_flying != value) _flying = value;
{ // simulate flying by changing the effect of gravity
_flying = value; this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
// simulate flying by changing the effect of gravity
this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
}
} }
} }
// Flying is implimented by changing the avatar's buoyancy.
// Would this be done better with a vehicle type?
private float ComputeBuoyancyFromFlying(bool ifFlying) { private float ComputeBuoyancyFromFlying(bool ifFlying) {
return ifFlying ? 1f : 0f; return ifFlying ? 1f : 0f;
} }
@ -488,11 +491,9 @@ public class BSCharacter : PhysicsActor
// Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
// base.RequestPhysicsterseUpdate(); // base.RequestPhysicsterseUpdate();
/*
DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,
entprop.Acceleration, entprop.RotationalVelocity); entprop.Acceleration, entprop.RotationalVelocity);
*/
} }
// Called by the scene when a collision with this object is reported // Called by the scene when a collision with this object is reported

View File

@ -57,6 +57,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
private int frcount = 0; // Used to limit dynamics debug output to private int frcount = 0; // Used to limit dynamics debug output to
// every 100th frame // every 100th frame
private BSScene m_physicsScene;
private BSPrim m_prim; // the prim this dynamic controller belongs to private BSPrim m_prim; // the prim this dynamic controller belongs to
// Vehicle properties // Vehicle properties
@ -74,7 +75,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// HOVER_UP_ONLY // HOVER_UP_ONLY
// LIMIT_MOTOR_UP // LIMIT_MOTOR_UP
// LIMIT_ROLL_ONLY // LIMIT_ROLL_ONLY
private VehicleFlag m_Hoverflags = (VehicleFlag)0;
private Vector3 m_BlockingEndPoint = Vector3.Zero; private Vector3 m_BlockingEndPoint = Vector3.Zero;
private Quaternion m_RollreferenceFrame = Quaternion.Identity; private Quaternion m_RollreferenceFrame = Quaternion.Identity;
// Linear properties // Linear properties
@ -124,15 +124,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
private float m_verticalAttractionEfficiency = 1.0f; // damped private float m_verticalAttractionEfficiency = 1.0f; // damped
private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor.
public BSDynamics(BSPrim myPrim) public BSDynamics(BSScene myScene, BSPrim myPrim)
{ {
m_physicsScene = myScene;
m_prim = myPrim; m_prim = myPrim;
m_type = Vehicle.TYPE_NONE; m_type = Vehicle.TYPE_NONE;
} }
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue, float timestep) internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue, float timestep)
{ {
DetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
switch (pParam) switch (pParam)
{ {
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
@ -231,7 +232,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue, float timestep) internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue, float timestep)
{ {
DetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
switch (pParam) switch (pParam)
{ {
case Vehicle.ANGULAR_FRICTION_TIMESCALE: case Vehicle.ANGULAR_FRICTION_TIMESCALE:
@ -266,7 +267,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
{ {
DetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); VDetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
switch (pParam) switch (pParam)
{ {
case Vehicle.REFERENCE_FRAME: case Vehicle.REFERENCE_FRAME:
@ -280,164 +281,27 @@ namespace OpenSim.Region.Physics.BulletSPlugin
internal void ProcessVehicleFlags(int pParam, bool remove) internal void ProcessVehicleFlags(int pParam, bool remove)
{ {
DetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", m_prim.LocalID, pParam, remove); VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", m_prim.LocalID, pParam, remove);
VehicleFlag parm = (VehicleFlag)pParam;
if (remove) if (remove)
{ {
if (pParam == -1) if (pParam == -1)
{ {
m_flags = (VehicleFlag)0; m_flags = (VehicleFlag)0;
m_Hoverflags = (VehicleFlag)0;
return;
} }
if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) else
{ {
if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != (VehicleFlag)0) m_flags &= ~parm;
m_Hoverflags &= ~(VehicleFlag.HOVER_GLOBAL_HEIGHT);
}
if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
{
if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != (VehicleFlag)0)
m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY);
}
if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
{
if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != (VehicleFlag)0)
m_Hoverflags &= ~(VehicleFlag.HOVER_UP_ONLY);
}
if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
{
if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != (VehicleFlag)0)
m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY);
}
if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
{
if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.LIMIT_MOTOR_UP);
}
if ((pParam & (int)VehicleFlag.LIMIT_ROLL_ONLY) == (int)VehicleFlag.LIMIT_ROLL_ONLY)
{
if ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
}
if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
{
if ((m_flags & VehicleFlag.MOUSELOOK_BANK) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.MOUSELOOK_BANK);
}
if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
{
if ((m_flags & VehicleFlag.MOUSELOOK_STEER) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.MOUSELOOK_STEER);
}
if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
{
if ((m_flags & VehicleFlag.NO_DEFLECTION_UP) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP);
}
if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
{
if ((m_flags & VehicleFlag.CAMERA_DECOUPLED) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.CAMERA_DECOUPLED);
}
if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
{
if ((m_flags & VehicleFlag.NO_X) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.NO_X);
}
if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
{
if ((m_flags & VehicleFlag.NO_Y) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.NO_Y);
}
if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
{
if ((m_flags & VehicleFlag.NO_Z) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.NO_Z);
}
if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT)
{
if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != (VehicleFlag)0)
m_Hoverflags &= ~(VehicleFlag.LOCK_HOVER_HEIGHT);
}
if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
{
if ((m_flags & VehicleFlag.NO_DEFLECTION) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.NO_DEFLECTION);
}
if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
{
if ((m_flags & VehicleFlag.LOCK_ROTATION) != (VehicleFlag)0)
m_flags &= ~(VehicleFlag.LOCK_ROTATION);
} }
} }
else else {
{ m_flags |= parm;
if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT)
{
m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT | m_flags);
}
if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
{
m_Hoverflags |= (VehicleFlag.HOVER_TERRAIN_ONLY | m_flags);
}
if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
{
m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY | m_flags);
}
if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
{
m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY | m_flags);
}
if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
{
m_flags |= (VehicleFlag.LIMIT_MOTOR_UP | m_flags);
}
if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
{
m_flags |= (VehicleFlag.MOUSELOOK_BANK | m_flags);
}
if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
{
m_flags |= (VehicleFlag.MOUSELOOK_STEER | m_flags);
}
if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
{
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | m_flags);
}
if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
{
m_flags |= (VehicleFlag.CAMERA_DECOUPLED | m_flags);
}
if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
{
m_flags |= (VehicleFlag.NO_X);
}
if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
{
m_flags |= (VehicleFlag.NO_Y);
}
if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
{
m_flags |= (VehicleFlag.NO_Z);
}
if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT)
{
m_Hoverflags |= (VehicleFlag.LOCK_HOVER_HEIGHT);
}
if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
{
m_flags |= (VehicleFlag.NO_DEFLECTION);
}
if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
{
m_flags |= (VehicleFlag.LOCK_ROTATION);
}
} }
}//end ProcessVehicleFlags }//end ProcessVehicleFlags
internal void ProcessTypeChange(Vehicle pType) internal void ProcessTypeChange(Vehicle pType, float stepSize)
{ {
DetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType); VDetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType);
// Set Defaults For Type // Set Defaults For Type
m_type = pType; m_type = pType;
switch (pType) switch (pType)
@ -478,10 +342,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// m_bankingMix = 1; // m_bankingMix = 1;
// m_bankingTimescale = 10; // m_bankingTimescale = 10;
// m_referenceFrame = Quaternion.Identity; // m_referenceFrame = Quaternion.Identity;
m_Hoverflags &= m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
m_flags &=
~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
break; break;
case Vehicle.TYPE_CAR: case Vehicle.TYPE_CAR:
m_linearFrictionTimescale = new Vector3(100, 2, 1000); m_linearFrictionTimescale = new Vector3(100, 2, 1000);
@ -506,10 +370,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// m_bankingMix = 1; // m_bankingMix = 1;
// m_bankingTimescale = 1; // m_bankingTimescale = 1;
// m_referenceFrame = Quaternion.Identity; // m_referenceFrame = Quaternion.Identity;
m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY |
VehicleFlag.LIMIT_MOTOR_UP); VehicleFlag.LIMIT_MOTOR_UP);
m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY); m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
m_flags |= (VehicleFlag.HOVER_UP_ONLY);
break; break;
case Vehicle.TYPE_BOAT: case Vehicle.TYPE_BOAT:
m_linearFrictionTimescale = new Vector3(10, 3, 2); m_linearFrictionTimescale = new Vector3(10, 3, 2);
@ -534,12 +398,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// m_bankingMix = 0.8f; // m_bankingMix = 0.8f;
// m_bankingTimescale = 1; // m_bankingTimescale = 1;
// m_referenceFrame = Quaternion.Identity; // m_referenceFrame = Quaternion.Identity;
m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY); m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
VehicleFlag.LIMIT_MOTOR_UP); VehicleFlag.LIMIT_MOTOR_UP);
m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY); m_flags |= (VehicleFlag.HOVER_WATER_ONLY);
break; break;
case Vehicle.TYPE_AIRPLANE: case Vehicle.TYPE_AIRPLANE:
m_linearFrictionTimescale = new Vector3(200, 10, 5); m_linearFrictionTimescale = new Vector3(200, 10, 5);
@ -564,7 +428,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// m_bankingMix = 0.7f; // m_bankingMix = 0.7f;
// m_bankingTimescale = 2; // m_bankingTimescale = 2;
// m_referenceFrame = Quaternion.Identity; // m_referenceFrame = Quaternion.Identity;
m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP); m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
@ -592,11 +456,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// m_bankingMix = 0.7f; // m_bankingMix = 0.7f;
// m_bankingTimescale = 5; // m_bankingTimescale = 5;
// m_referenceFrame = Quaternion.Identity; // m_referenceFrame = Quaternion.Identity;
m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
VehicleFlag.HOVER_UP_ONLY); VehicleFlag.HOVER_UP_ONLY);
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP); m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT); m_flags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT);
break; break;
} }
}//end SetDefaultsForType }//end SetDefaultsForType
@ -613,7 +477,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
MoveAngular(pTimestep); MoveAngular(pTimestep);
LimitRotation(pTimestep); LimitRotation(pTimestep);
DetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity); m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity);
}// end Step }// end Step
@ -657,7 +521,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
*/ */
DetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}", VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}",
m_prim.LocalID, origDir, origVel, addAmount, decayfraction, m_linearMotorDirection, m_lastLinearVelocityVector); m_prim.LocalID, origDir, origVel, addAmount, decayfraction, m_linearMotorDirection, m_lastLinearVelocityVector);
} }
else else
@ -669,7 +533,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
m_lastLinearVelocityVector = Vector3.Zero; m_lastLinearVelocityVector = Vector3.Zero;
} }
// convert requested object velocity to world-referenced vector // convert requested object velocity to object relative vector
Quaternion rotq = m_prim.Orientation; Quaternion rotq = m_prim.Orientation;
m_dir = m_lastLinearVelocityVector * rotq; m_dir = m_lastLinearVelocityVector * rotq;
@ -722,7 +586,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
if (changed) if (changed)
{ {
m_prim.Position = pos; m_prim.Position = pos;
DetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
m_prim.LocalID, m_BlockingEndPoint, posChange, pos); m_prim.LocalID, m_BlockingEndPoint, posChange, pos);
} }
} }
@ -732,32 +596,32 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{ {
pos.Z = m_prim.Scene.GetTerrainHeightAtXYZ(pos) + 2; pos.Z = m_prim.Scene.GetTerrainHeightAtXYZ(pos) + 2;
m_prim.Position = pos; m_prim.Position = pos;
DetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos); VDetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos);
} }
// Check if hovering // Check if hovering
if ((m_Hoverflags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
{ {
// We should hover, get the target height // We should hover, get the target height
if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != 0) if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
{ {
m_VhoverTargetHeight = m_prim.Scene.GetWaterLevel() + m_VhoverHeight; m_VhoverTargetHeight = m_prim.Scene.GetWaterLevel() + m_VhoverHeight;
} }
if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
{ {
m_VhoverTargetHeight = m_prim.Scene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight; m_VhoverTargetHeight = m_prim.Scene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
} }
if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0)
{ {
m_VhoverTargetHeight = m_VhoverHeight; m_VhoverTargetHeight = m_VhoverHeight;
} }
if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != 0) if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0)
{ {
// If body is aready heigher, use its height as target height // If body is aready heigher, use its height as target height
if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
} }
if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
{ {
if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2) if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2)
{ {
@ -779,7 +643,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
} }
} }
DetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight); VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight);
// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped // m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped
// m_VhoverTimescale = 0f; // time to acheive height // m_VhoverTimescale = 0f; // time to acheive height
@ -815,7 +679,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{ {
grav.Z = (float)(grav.Z * 1.037125); grav.Z = (float)(grav.Z * 1.037125);
} }
DetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav); VDetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav);
//End Experimental Values //End Experimental Values
} }
if ((m_flags & (VehicleFlag.NO_X)) != 0) if ((m_flags & (VehicleFlag.NO_X)) != 0)
@ -844,7 +708,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep);
m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount; m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount;
DetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}", VDetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}",
m_prim.LocalID, m_lastPositionVector, m_dir, grav, decayamount); m_prim.LocalID, m_lastPositionVector, m_dir, grav, decayamount);
} // end MoveLinear() } // end MoveLinear()
@ -870,13 +734,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// There are m_angularMotorApply steps. // There are m_angularMotorApply steps.
Vector3 origAngularVelocity = m_angularMotorVelocity; Vector3 origAngularVelocity = m_angularMotorVelocity;
// ramp up to new value // ramp up to new value
// current velocity += error / (time to get there / step interval) // current velocity += error / (time to get there / step interval)
// requested speed - last motor speed // requested speed - last motor speed
m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep); m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep);
m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep); m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep);
m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep); m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep);
DetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}", VDetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}",
m_prim.LocalID,m_angularMotorApply,origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity); m_prim.LocalID,m_angularMotorApply,origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity);
m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected
@ -887,6 +751,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// No motor recently applied, keep the body velocity // No motor recently applied, keep the body velocity
// and decay the velocity // and decay the velocity
m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep); m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep);
if (m_angularMotorVelocity.LengthSquared() < 0.00001)
m_angularMotorVelocity = Vector3.Zero;
} // end motor section } // end motor section
// Vertical attractor section // Vertical attractor section
@ -924,7 +790,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
vertattr.X += bounce * angularVelocity.X; vertattr.X += bounce * angularVelocity.X;
vertattr.Y += bounce * angularVelocity.Y; vertattr.Y += bounce * angularVelocity.Y;
DetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}", VDetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}",
m_prim.LocalID, verterr, bounce, vertattr); m_prim.LocalID, verterr, bounce, vertattr);
} // else vertical attractor is off } // else vertical attractor is off
@ -942,13 +808,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{ {
m_lastAngularVelocity.X = 0; m_lastAngularVelocity.X = 0;
m_lastAngularVelocity.Y = 0; m_lastAngularVelocity.Y = 0;
DetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity); VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
} }
if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
{ {
m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
DetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity); VDetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
} }
// apply friction // apply friction
@ -958,7 +824,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// Apply to the body // Apply to the body
m_prim.RotationalVelocity = m_lastAngularVelocity; m_prim.RotationalVelocity = m_lastAngularVelocity;
DetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", m_prim.LocalID, decayamount, m_lastAngularVelocity); VDetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", m_prim.LocalID, decayamount, m_lastAngularVelocity);
} //end MoveAngular } //end MoveAngular
internal void LimitRotation(float timestep) internal void LimitRotation(float timestep)
@ -1005,11 +871,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
if (changed) if (changed)
m_prim.Orientation = m_rot; m_prim.Orientation = m_rot;
DetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot); VDetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot);
} }
// Invoke the detailed logger and output something if it's enabled. // Invoke the detailed logger and output something if it's enabled.
private void DetailLog(string msg, params Object[] args) private void VDetailLog(string msg, params Object[] args)
{ {
if (m_prim.Scene.VehicleLoggingEnabled) if (m_prim.Scene.VehicleLoggingEnabled)
m_prim.Scene.PhysicsLogging.Write(msg, args); m_prim.Scene.PhysicsLogging.Write(msg, args);

View File

@ -42,6 +42,9 @@ public class BSLinkset
private BSScene m_physicsScene; private BSScene m_physicsScene;
public BSScene PhysicsScene { get { return m_physicsScene; } } public BSScene PhysicsScene { get { return m_physicsScene; } }
static int m_nextLinksetID = 1;
public int LinksetID { get; private set; }
// The children under the root in this linkset // The children under the root in this linkset
private List<BSPrim> m_children; private List<BSPrim> m_children;
@ -74,6 +77,10 @@ public class BSLinkset
public BSLinkset(BSScene scene, BSPrim parent) public BSLinkset(BSScene scene, BSPrim parent)
{ {
// A simple linkset of one (no children) // A simple linkset of one (no children)
LinksetID = m_nextLinksetID++;
// We create LOTS of linksets.
if (m_nextLinksetID < 0)
m_nextLinksetID = 1;
m_physicsScene = scene; m_physicsScene = scene;
m_linksetRoot = parent; m_linksetRoot = parent;
m_children = new List<BSPrim>(); m_children = new List<BSPrim>();
@ -258,8 +265,7 @@ public class BSLinkset
BSPrim childx = child; BSPrim childx = child;
m_physicsScene.TaintedObject("AddChildToLinkset", delegate() m_physicsScene.TaintedObject("AddChildToLinkset", delegate()
{ {
// DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID); DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
// DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
PhysicallyLinkAChildToRoot(rootx, childx); // build the physical binding between me and the child PhysicallyLinkAChildToRoot(rootx, childx); // build the physical binding between me and the child
}); });
} }
@ -287,8 +293,7 @@ public class BSLinkset
BSPrim childx = child; BSPrim childx = child;
m_physicsScene.TaintedObject("RemoveChildFromLinkset", delegate() m_physicsScene.TaintedObject("RemoveChildFromLinkset", delegate()
{ {
// DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID); DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
// DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
PhysicallyUnlinkAChildFromRoot(rootx, childx); PhysicallyUnlinkAChildFromRoot(rootx, childx);
}); });
@ -319,7 +324,6 @@ public class BSLinkset
// create a constraint that allows no freedom of movement between the two objects // create a constraint that allows no freedom of movement between the two objects
// http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
// DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2},rLoc={3},cLoc={4},midLoc={5}", DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2},rLoc={3},cLoc={4},midLoc={5}",
rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID, rootPrim.Position, childPrim.Position, midPoint); rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID, rootPrim.Position, childPrim.Position, midPoint);
BS6DofConstraint constrain = new BS6DofConstraint( BS6DofConstraint constrain = new BS6DofConstraint(
@ -328,10 +332,10 @@ public class BSLinkset
true, true,
true true
); );
/* NOTE: attempt to build constraint with full frame computation, etc. /* NOTE: below is an attempt to build constraint with full frame computation, etc.
* Using the midpoint is easier since it lets the Bullet code use the transforms * Using the midpoint is easier since it lets the Bullet code use the transforms
* of the objects. * of the objects.
* Code left here as an example. * Code left as a warning to future programmers.
// ================================================================================== // ==================================================================================
// relative position normalized to the root prim // relative position normalized to the root prim
OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation);
@ -343,7 +347,6 @@ public class BSLinkset
// create a constraint that allows no freedom of movement between the two objects // create a constraint that allows no freedom of movement between the two objects
// http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
// DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
BS6DofConstraint constrain = new BS6DofConstraint( BS6DofConstraint constrain = new BS6DofConstraint(
PhysicsScene.World, rootPrim.Body, childPrim.Body, PhysicsScene.World, rootPrim.Body, childPrim.Body,
@ -382,8 +385,6 @@ public class BSLinkset
// Called at taint time! // Called at taint time!
private void PhysicallyUnlinkAChildFromRoot(BSPrim rootPrim, BSPrim childPrim) private void PhysicallyUnlinkAChildFromRoot(BSPrim rootPrim, BSPrim childPrim)
{ {
// DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}",
// LogHeader, rootPrim.LocalID, childPrim.LocalID);
DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
// Find the constraint for this link and get rid of it from the overall collection and from my list // Find the constraint for this link and get rid of it from the overall collection and from my list
@ -397,19 +398,11 @@ public class BSLinkset
// Called at taint time! // Called at taint time!
private void PhysicallyUnlinkAllChildrenFromRoot(BSPrim rootPrim) private void PhysicallyUnlinkAllChildrenFromRoot(BSPrim rootPrim)
{ {
// DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader);
DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body); m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body);
} }
// Invoke the detailed logger and output something if it's enabled.
private void DebugLog(string msg, params Object[] args)
{
if (m_physicsScene.ShouldDebugLog)
m_physicsScene.Logger.DebugFormat(msg, args);
}
// Invoke the detailed logger and output something if it's enabled. // Invoke the detailed logger and output something if it's enabled.
private void DetailLog(string msg, params Object[] args) private void DetailLog(string msg, params Object[] args)
{ {

View File

@ -42,8 +42,6 @@ public sealed class BSPrim : PhysicsActor
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string LogHeader = "[BULLETS PRIM]"; private static readonly string LogHeader = "[BULLETS PRIM]";
private void DebugLog(string mm, params Object[] xx) { if (_scene.ShouldDebugLog) m_log.DebugFormat(mm, xx); }
private IMesh _mesh; private IMesh _mesh;
private PrimitiveBaseShape _pbs; private PrimitiveBaseShape _pbs;
private ShapeData.PhysicsShapeType _shapeType; private ShapeData.PhysicsShapeType _shapeType;
@ -141,8 +139,8 @@ public sealed class BSPrim : PhysicsActor
_friction = _scene.Params.defaultFriction; // TODO: compute based on object material _friction = _scene.Params.defaultFriction; // TODO: compute based on object material
_density = _scene.Params.defaultDensity; // TODO: compute based on object material _density = _scene.Params.defaultDensity; // TODO: compute based on object material
_restitution = _scene.Params.defaultRestitution; _restitution = _scene.Params.defaultRestitution;
_linkset = new BSLinkset(_scene, this); // a linkset of one _linkset = new BSLinkset(Scene, this); // a linkset of one
_vehicle = new BSDynamics(this); // add vehicleness _vehicle = new BSDynamics(Scene, this); // add vehicleness
_mass = CalculateMass(); _mass = CalculateMass();
// do the actual object creation at taint time // do the actual object creation at taint time
DetailLog("{0},BSPrim.constructor,call", LocalID); DetailLog("{0},BSPrim.constructor,call", LocalID);
@ -193,7 +191,7 @@ public sealed class BSPrim : PhysicsActor
{ {
_mass = CalculateMass(); // changing size changes the mass _mass = CalculateMass(); // changing size changes the mass
BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical); BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical);
// DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical); DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical);
RecreateGeomAndObject(); RecreateGeomAndObject();
}); });
} }
@ -232,7 +230,6 @@ public sealed class BSPrim : PhysicsActor
BSPrim parent = obj as BSPrim; BSPrim parent = obj as BSPrim;
if (parent != null) if (parent != null)
{ {
DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, parent.LocalID);
BSPrim parentBefore = _linkset.LinksetRoot; BSPrim parentBefore = _linkset.LinksetRoot;
int childrenBefore = _linkset.NumberOfChildren; int childrenBefore = _linkset.NumberOfChildren;
@ -248,8 +245,6 @@ public sealed class BSPrim : PhysicsActor
public override void delink() { public override void delink() {
// TODO: decide if this parent checking needs to happen at taint time // TODO: decide if this parent checking needs to happen at taint time
// Race condition here: if link() and delink() in same simulation tick, the delink will not happen // Race condition here: if link() and delink() in same simulation tick, the delink will not happen
DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID,
_linkset.LinksetRoot._avName+"/"+_linkset.LinksetRoot.LocalID.ToString());
BSPrim parentBefore = _linkset.LinksetRoot; BSPrim parentBefore = _linkset.LinksetRoot;
int childrenBefore = _linkset.NumberOfChildren; int childrenBefore = _linkset.NumberOfChildren;
@ -280,7 +275,7 @@ public sealed class BSPrim : PhysicsActor
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);
return; return;
} }
@ -299,7 +294,7 @@ public sealed class BSPrim : PhysicsActor
// TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint?
_scene.TaintedObject("BSPrim.setPosition", delegate() _scene.TaintedObject("BSPrim.setPosition", delegate()
{ {
// DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
}); });
} }
@ -336,7 +331,7 @@ public sealed class BSPrim : PhysicsActor
_force = value; _force = value;
_scene.TaintedObject("BSPrim.setForce", delegate() _scene.TaintedObject("BSPrim.setForce", delegate()
{ {
// DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force); DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force);
// BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); // BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
BulletSimAPI.SetObjectForce2(Body.Ptr, _force); BulletSimAPI.SetObjectForce2(Body.Ptr, _force);
}); });
@ -354,7 +349,7 @@ public sealed class BSPrim : PhysicsActor
{ {
// Done at taint time so we're sure the physics engine is not using the variables // 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 code changes the parameters for this vehicle type.
_vehicle.ProcessTypeChange(type); _vehicle.ProcessTypeChange(type, Scene.LastSimulatedTimestep);
// Tell the scene about the vehicle so it will get processing each frame. // Tell the scene about the vehicle so it will get processing each frame.
_scene.VehicleInSceneTypeChanged(this, type); _scene.VehicleInSceneTypeChanged(this, type);
}); });
@ -414,7 +409,7 @@ public sealed class BSPrim : PhysicsActor
_velocity = value; _velocity = value;
_scene.TaintedObject("BSPrim.setVelocity", delegate() _scene.TaintedObject("BSPrim.setVelocity", delegate()
{ {
// DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity);
BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity); BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity);
}); });
} }
@ -422,7 +417,7 @@ public sealed class BSPrim : PhysicsActor
public override OMV.Vector3 Torque { public override OMV.Vector3 Torque {
get { return _torque; } get { return _torque; }
set { _torque = value; set { _torque = value;
// DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque); DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque);
} }
} }
public override float CollisionScore { public override float CollisionScore {
@ -449,7 +444,7 @@ public sealed class BSPrim : PhysicsActor
_scene.TaintedObject("BSPrim.setOrientation", delegate() _scene.TaintedObject("BSPrim.setOrientation", delegate()
{ {
// _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
// DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
}); });
} }
@ -486,11 +481,8 @@ public sealed class BSPrim : PhysicsActor
// No locking here because only called when it is safe // No locking here because only called when it is safe
private void SetObjectDynamic() private void SetObjectDynamic()
{ {
// RA: remove this for the moment. // If it's becoming dynamic, it will need hullness
// The problem is that dynamic objects are hulls so if we are becoming physical VerifyCorrectPhysicalShape();
// the shape has to be checked and possibly built.
// Maybe a VerifyCorrectPhysicalShape() routine?
// RecreateGeomAndObject();
// Bullet wants static objects to have a mass of zero // Bullet wants static objects to have a mass of zero
float mass = IsStatic ? 0f : _mass; float mass = IsStatic ? 0f : _mass;
@ -501,13 +493,15 @@ public sealed class BSPrim : PhysicsActor
_linkset.Refresh(this); _linkset.Refresh(this);
CollisionFlags cf = BulletSimAPI.GetCollisionFlags2(Body.Ptr); CollisionFlags cf = BulletSimAPI.GetCollisionFlags2(Body.Ptr);
// DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, cf); DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, cf);
} }
// prims don't fly // prims don't fly
public override bool Flying { public override bool Flying {
get { return _flying; } get { return _flying; }
set { _flying = value; } set {
_flying = value;
}
} }
public override bool SetAlwaysRun { public override bool SetAlwaysRun {
get { return _setAlwaysRun; } get { return _setAlwaysRun; }
@ -558,7 +552,7 @@ public sealed class BSPrim : PhysicsActor
// m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
_scene.TaintedObject("BSPrim.setRotationalVelocity", delegate() _scene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
{ {
// DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity); BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity);
}); });
} }
@ -575,7 +569,7 @@ public sealed class BSPrim : PhysicsActor
_buoyancy = value; _buoyancy = value;
_scene.TaintedObject("BSPrim.setBuoyancy", delegate() _scene.TaintedObject("BSPrim.setBuoyancy", delegate()
{ {
// DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy); DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy); BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy);
}); });
} }
@ -638,17 +632,17 @@ public sealed class BSPrim : PhysicsActor
} }
m_accumulatedForces.Clear(); m_accumulatedForces.Clear();
} }
// DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force); DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force);
BulletSimAPI.AddObjectForce2(Body.Ptr, fSum); BulletSimAPI.AddObjectForce2(Body.Ptr, fSum);
}); });
} }
public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
// DetailLog("{0},BSPrim.AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce); DetailLog("{0},BSPrim.AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce);
// m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce); // m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce);
} }
public override void SetMomentum(OMV.Vector3 momentum) { public override void SetMomentum(OMV.Vector3 momentum) {
// DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum); DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum);
} }
public override void SubscribeEvents(int ms) { public override void SubscribeEvents(int ms) {
_subscribedEventsMs = ms; _subscribedEventsMs = ms;
@ -992,7 +986,7 @@ public sealed class BSPrim : PhysicsActor
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size); // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size);
if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE)) if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE))
{ {
// DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild); DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild);
_shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE;
// Bullet native objects are scaled by the Bullet engine so pass the size in // Bullet native objects are scaled by the Bullet engine so pass the size in
_scale = _size; _scale = _size;
@ -1006,7 +1000,7 @@ public sealed class BSPrim : PhysicsActor
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size); // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size);
if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX)) if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX))
{ {
// DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild); DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild);
_shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
_scale = _size; _scale = _size;
// TODO: do we need to check for and destroy a mesh or hull that might have been left from before? // TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
@ -1042,19 +1036,26 @@ public sealed class BSPrim : PhysicsActor
// No locking here because this is done when we know physics is not simulating // No locking here because this is done when we know physics is not simulating
private void CreateGeomMesh() private void CreateGeomMesh()
{ {
float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD; // level of detail based on size and type of the object
float lod = _scene.MeshLOD;
if (_pbs.SculptEntry)
lod = _scene.SculptLOD;
float maxAxis = Math.Max(_size.X, Math.Max(_size.Y, _size.Z));
if (maxAxis > _scene.MeshMegaPrimThreshold)
lod = _scene.MeshMegaPrimLOD;
ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod); ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod);
// m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey); // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey);
// if this new shape is the same as last time, don't recreate the mesh // if this new shape is the same as last time, don't recreate the mesh
if (_meshKey == newMeshKey) return; if (_meshKey == newMeshKey) return;
// DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey); DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey);
// Since we're recreating new, get rid of any previously generated shape // Since we're recreating new, get rid of any previously generated shape
if (_meshKey != 0) if (_meshKey != 0)
{ {
// m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey); // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey);
// DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey); DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey);
BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey);
_mesh = null; _mesh = null;
_meshKey = 0; _meshKey = 0;
@ -1084,7 +1085,7 @@ public sealed class BSPrim : PhysicsActor
_shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH; _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH;
// meshes are already scaled by the meshmerizer // meshes are already scaled by the meshmerizer
_scale = new OMV.Vector3(1f, 1f, 1f); _scale = new OMV.Vector3(1f, 1f, 1f);
// DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID); DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID);
return; return;
} }
@ -1098,13 +1099,13 @@ public sealed class BSPrim : PhysicsActor
// if the hull hasn't changed, don't rebuild it // if the hull hasn't changed, don't rebuild it
if (newHullKey == _hullKey) return; if (newHullKey == _hullKey) return;
// DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey); DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey);
// Since we're recreating new, get rid of any previously generated shape // Since we're recreating new, get rid of any previously generated shape
if (_hullKey != 0) if (_hullKey != 0)
{ {
// m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey); // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey);
// DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey); DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey);
BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey);
_hullKey = 0; _hullKey = 0;
} }
@ -1198,7 +1199,7 @@ public sealed class BSPrim : PhysicsActor
_shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL; _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL;
// meshes are already scaled by the meshmerizer // meshes are already scaled by the meshmerizer
_scale = new OMV.Vector3(1f, 1f, 1f); _scale = new OMV.Vector3(1f, 1f, 1f);
// DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID); DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID);
return; return;
} }
@ -1210,6 +1211,27 @@ public sealed class BSPrim : PhysicsActor
return; return;
} }
private void VerifyCorrectPhysicalShape()
{
if (IsStatic)
{
// if static, we don't need a hull so, if there is one, rebuild without it
if (_hullKey != 0)
{
RecreateGeomAndObject();
}
}
else
{
// if not static, it will need a hull to efficiently collide with things
if (_hullKey == 0)
{
RecreateGeomAndObject();
}
}
}
// Create an object in Bullet if it has not already been created // Create an object in Bullet if it has not already been created
// No locking here because this is done when the physics engine is not simulating // No locking here because this is done when the physics engine is not simulating
// Returns 'true' if an object was actually created. // Returns 'true' if an object was actually created.
@ -1334,10 +1356,8 @@ public sealed class BSPrim : PhysicsActor
_acceleration = entprop.Acceleration; _acceleration = entprop.Acceleration;
_rotationalVelocity = entprop.RotationalVelocity; _rotationalVelocity = entprop.RotationalVelocity;
// m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}, vel={5}, acc={6}, rvel={7}", DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
// LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
// DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
// LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
base.RequestPhysicsterseUpdate(); base.RequestPhysicsterseUpdate();
} }
@ -1353,6 +1373,7 @@ public sealed class BSPrim : PhysicsActor
} }
// I've collided with something // I've collided with something
// Called at taint time from within the Step() function
CollisionEventUpdate collisionCollection; CollisionEventUpdate collisionCollection;
public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
{ {
@ -1366,6 +1387,15 @@ public sealed class BSPrim : PhysicsActor
} }
// DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith); // DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith);
BSPrim collidingWithPrim;
if (_scene.Prims.TryGetValue(collidingWith, out collidingWithPrim))
{
// prims in the same linkset cannot collide with each other
if (this.Linkset.LinksetID == collidingWithPrim.Linkset.LinksetID)
{
return;
}
}
// if someone is subscribed to collision events.... // if someone is subscribed to collision events....
if (_subscribedEventsMs != 0) { if (_subscribedEventsMs != 0) {

View File

@ -73,15 +73,22 @@ public class BSScene : PhysicsScene, IPhysicsParameters
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string LogHeader = "[BULLETS SCENE]"; private static readonly string LogHeader = "[BULLETS SCENE]";
public void DebugLog(string mm, params Object[] xx) { if (ShouldDebugLog) m_log.DebugFormat(mm, xx); } // The name of the region we're working for.
public string RegionName { get; private set; }
public string BulletSimVersion = "?"; public string BulletSimVersion = "?";
private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>(); private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>();
public Dictionary<uint, BSCharacter> Characters { get { return m_avatars; } }
private Dictionary<uint, BSPrim> m_prims = new Dictionary<uint, BSPrim>(); private Dictionary<uint, BSPrim> m_prims = new Dictionary<uint, BSPrim>();
public Dictionary<uint, BSPrim> Prims { get { return m_prims; } }
private HashSet<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>(); private HashSet<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>();
private HashSet<BSPrim> m_primsWithCollisions = new HashSet<BSPrim>(); private HashSet<BSPrim> m_primsWithCollisions = new HashSet<BSPrim>();
private List<BSPrim> m_vehicles = new List<BSPrim>(); private List<BSPrim> m_vehicles = new List<BSPrim>();
private float[] m_heightMap; private float[] m_heightMap;
private float m_waterLevel; private float m_waterLevel;
private uint m_worldID; private uint m_worldID;
@ -95,16 +102,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
private int m_detailedStatsStep = 0; private int m_detailedStatsStep = 0;
public IMesher mesher; public IMesher mesher;
private float m_meshLOD; // Level of Detail values kept as float because that's what the Meshmerizer wants
public float MeshLOD public float MeshLOD { get; private set; }
{ public float MeshMegaPrimLOD { get; private set; }
get { return m_meshLOD; } public float MeshMegaPrimThreshold { get; private set; }
} public float SculptLOD { get; private set; }
private float m_sculptLOD;
public float SculptLOD
{
get { return m_sculptLOD; }
}
private BulletSim m_worldSim; private BulletSim m_worldSim;
public BulletSim World public BulletSim World
@ -179,8 +181,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
ConfigurationParameters[] m_params; ConfigurationParameters[] m_params;
GCHandle m_paramsHandle; GCHandle m_paramsHandle;
public bool ShouldDebugLog { get; private set; } // Handle to the callback used by the unmanaged code to call into the managed code.
// Used for debug logging.
// Need to store the handle in a persistant variable so it won't be freed.
private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle; private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle;
// Sometimes you just have to log everything. // Sometimes you just have to log everything.
@ -196,6 +199,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
public BSScene(string identifier) public BSScene(string identifier)
{ {
m_initialized = false; m_initialized = false;
// we are passed the name of the region we're working for.
RegionName = identifier;
} }
public override void Initialise(IMesher meshmerizer, IConfigSource config) public override void Initialise(IMesher meshmerizer, IConfigSource config)
@ -281,10 +286,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
// Very detailed logging for physics debugging // Very detailed logging for physics debugging
m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false); m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false);
m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", "."); m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", ".");
m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-"); m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-");
m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5); m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5);
// Very detailed logging for vehicle debugging // Very detailed logging for vehicle debugging
m_vehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false); m_vehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false);
// Do any replacements in the parameters
m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName);
} }
} }
} }
@ -362,7 +370,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
BSPrim bsprim = prim as BSPrim; BSPrim bsprim = prim as BSPrim;
if (bsprim != null) if (bsprim != null)
{ {
// DetailLog("{0},RemovePrim,call", bsprim.LocalID); DetailLog("{0},RemovePrim,call", bsprim.LocalID);
// m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID); // m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID);
try try
{ {
@ -388,7 +396,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
if (!m_initialized) return null; if (!m_initialized) return null;
// DetailLog("{0},AddPrimShape,call", localID); DetailLog("{0},AddPrimShape,call", localID);
BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical); BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical);
lock (m_prims) m_prims.Add(localID, prim); lock (m_prims) m_prims.Add(localID, prim);
@ -429,13 +437,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
{ {
numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep, numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep,
out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
// DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount); DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount);
} }
catch (Exception e) catch (Exception e)
{ {
m_log.WarnFormat("{0},PhysicsStep Exception: substeps={1}, updates={2}, colliders={3}, e={4}", LogHeader, numSubSteps, updatedEntityCount, collidersCount, e); m_log.WarnFormat("{0},PhysicsStep Exception: substeps={1}, updates={2}, colliders={3}, e={4}", LogHeader, numSubSteps, updatedEntityCount, collidersCount, e);
// DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount); // DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount);
// updatedEntityCount = 0; updatedEntityCount = 0;
collidersCount = 0; collidersCount = 0;
} }
@ -534,6 +542,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
else if (m_avatars.ContainsKey(collidingWith)) else if (m_avatars.ContainsKey(collidingWith))
type = ActorTypes.Agent; type = ActorTypes.Agent;
// DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith);
BSPrim prim; BSPrim prim;
if (m_prims.TryGetValue(localID, out prim)) { if (m_prims.TryGetValue(localID, out prim)) {
prim.Collide(collidingWith, type, collidePoint, collideNormal, penitration); prim.Collide(collidingWith, type, collidePoint, collideNormal, penitration);
@ -897,16 +907,26 @@ public class BSScene : PhysicsScene, IPhysicsParameters
(s) => { return s.NumericBool(s._forceSimplePrimMeshing); }, (s) => { return s.NumericBool(s._forceSimplePrimMeshing); },
(s,p,l,v) => { s._forceSimplePrimMeshing = s.BoolNumeric(v); } ), (s,p,l,v) => { s._forceSimplePrimMeshing = s.BoolNumeric(v); } ),
new ParameterDefn("MeshLOD", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)",
8f, 8f,
(s,cf,p,v) => { s.m_meshLOD = cf.GetInt(p, (int)v); }, (s,cf,p,v) => { s.MeshLOD = (float)cf.GetInt(p, (int)v); },
(s) => { return (float)s.m_meshLOD; }, (s) => { return s.MeshLOD; },
(s,p,l,v) => { s.m_meshLOD = (int)v; } ), (s,p,l,v) => { s.MeshLOD = v; } ),
new ParameterDefn("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters",
16f,
(s,cf,p,v) => { s.MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); },
(s) => { return s.MeshMegaPrimLOD; },
(s,p,l,v) => { s.MeshMegaPrimLOD = v; } ),
new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD",
10f,
(s,cf,p,v) => { s.MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); },
(s) => { return s.MeshMegaPrimThreshold; },
(s,p,l,v) => { s.MeshMegaPrimThreshold = v; } ),
new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)",
32f, 32f,
(s,cf,p,v) => { s.m_sculptLOD = cf.GetInt(p, (int)v); }, (s,cf,p,v) => { s.SculptLOD = (float)cf.GetInt(p, (int)v); },
(s) => { return (float)s.m_sculptLOD; }, (s) => { return s.SculptLOD; },
(s,p,l,v) => { s.m_sculptLOD = (int)v; } ), (s,p,l,v) => { s.SculptLOD = v; } ),
new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps", new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps",
10f, 10f,
@ -1137,12 +1157,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
(s,cf,p,v) => { s.m_detailedStatsStep = cf.GetInt(p, (int)v); }, (s,cf,p,v) => { s.m_detailedStatsStep = cf.GetInt(p, (int)v); },
(s) => { return (float)s.m_detailedStatsStep; }, (s) => { return (float)s.m_detailedStatsStep; },
(s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ), (s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ),
new ParameterDefn("ShouldDebugLog", "Enables detailed DEBUG log statements",
ConfigurationParameters.numericFalse,
(s,cf,p,v) => { s.ShouldDebugLog = cf.GetBoolean(p, s.BoolNumeric(v)); },
(s) => { return s.NumericBool(s.ShouldDebugLog); },
(s,p,l,v) => { s.ShouldDebugLog = s.BoolNumeric(v); } ),
}; };
// Convert a boolean to our numeric true and false values // Convert a boolean to our numeric true and false values

View File

@ -1492,31 +1492,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (part == null || part.ParentGroup.IsDeleted) if (part == null || part.ParentGroup.IsDeleted)
return; return;
if (scale.x < 0.01) // First we need to check whether or not we need to clamp the size of a physics-enabled prim
scale.x = 0.01;
if (scale.y < 0.01)
scale.y = 0.01;
if (scale.z < 0.01)
scale.z = 0.01;
PhysicsActor pa = part.ParentGroup.RootPart.PhysActor; PhysicsActor pa = part.ParentGroup.RootPart.PhysActor;
if (pa != null && pa.IsPhysical) if (pa != null && pa.IsPhysical)
{ {
if (scale.x > World.m_maxPhys) scale.x = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.x));
scale.x = World.m_maxPhys; scale.y = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.y));
if (scale.y > World.m_maxPhys) scale.z = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.z));
scale.y = World.m_maxPhys;
if (scale.z > World.m_maxPhys)
scale.z = World.m_maxPhys;
} }
if (scale.x > World.m_maxNonphys) // Next we clamp the scale to the non-physical min/max
scale.x = World.m_maxNonphys; scale.x = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.x));
if (scale.y > World.m_maxNonphys) scale.y = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.y));
scale.y = World.m_maxNonphys; scale.z = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.z));
if (scale.z > World.m_maxNonphys)
scale.z = World.m_maxNonphys;
Vector3 tmp = part.Scale; Vector3 tmp = part.Scale;
tmp.X = (float)scale.x; tmp.X = (float)scale.x;
@ -4398,9 +4386,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public void llSetText(string text, LSL_Vector color, double alpha) public void llSetText(string text, LSL_Vector color, double alpha)
{ {
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
Vector3 av3 = new Vector3(Util.Clip((float)color.x, 0.0f, 1.0f), Vector3 av3 = Util.Clip(new Vector3((float)color.x, (float)color.y,
Util.Clip((float)color.y, 0.0f, 1.0f), (float)color.z), 0.0f, 1.0f);
Util.Clip((float)color.z, 0.0f, 1.0f));
m_host.SetText(text.Length > 254 ? text.Remove(254) : text, av3, Util.Clip((float)alpha, 0.0f, 1.0f)); m_host.SetText(text.Length > 254 ? text.Remove(254) : text, av3, Util.Clip((float)alpha, 0.0f, 1.0f));
//m_host.ParentGroup.HasGroupChanged = true; //m_host.ParentGroup.HasGroupChanged = true;
//m_host.ParentGroup.ScheduleGroupForFullUpdate(); //m_host.ParentGroup.ScheduleGroupForFullUpdate();
@ -8425,9 +8412,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
string primText = rules.GetLSLStringItem(idx++); string primText = rules.GetLSLStringItem(idx++);
LSL_Vector primTextColor = rules.GetVector3Item(idx++); LSL_Vector primTextColor = rules.GetVector3Item(idx++);
LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++); LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++);
Vector3 av3 = new Vector3(Util.Clip((float)primTextColor.x, 0.0f, 1.0f), Vector3 av3 = Util.Clip(new Vector3((float)primTextColor.x,
Util.Clip((float)primTextColor.y, 0.0f, 1.0f), (float)primTextColor.y,
Util.Clip((float)primTextColor.z, 0.0f, 1.0f)); (float)primTextColor.z), 0.0f, 1.0f);
part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f)); part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f));
break; break;
@ -8457,7 +8444,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
LSL_Float gain = rules.GetLSLFloatItem(idx++); LSL_Float gain = rules.GetLSLFloatItem(idx++);
TargetOmega(part, axis, (double)spinrate, (double)gain); TargetOmega(part, axis, (double)spinrate, (double)gain);
break; break;
case (int)ScriptBaseClass.PRIM_SLICE:
if (remain < 1)
return null;
LSL_Vector slice = rules.GetVector3Item(idx++);
part.UpdateSlice((float)slice.x, (float)slice.y);
break;
case (int)ScriptBaseClass.PRIM_LINK_TARGET: case (int)ScriptBaseClass.PRIM_LINK_TARGET:
if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
return null; return null;
@ -8466,6 +8458,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
} }
} }
} }
catch (InvalidCastException e)
{
ShoutError(e.Message);
}
finally finally
{ {
if (positionChanged) if (positionChanged)
@ -9563,7 +9559,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_POS_LOCAL: case (int)ScriptBaseClass.PRIM_POS_LOCAL:
res.Add(new LSL_Vector(GetPartLocalPos(part))); res.Add(new LSL_Vector(GetPartLocalPos(part)));
break; break;
case (int)ScriptBaseClass.PRIM_LINK_TARGET: case (int)ScriptBaseClass.PRIM_LINK_TARGET:
if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
return res; return res;
@ -9572,6 +9567,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules); LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
res += tres; res += tres;
return res; return res;
case (int)ScriptBaseClass.PRIM_SLICE:
PrimType prim_type = part.GetPrimType();
bool useProfileBeginEnd = (prim_type == PrimType.SPHERE || prim_type == PrimType.TORUS || prim_type == PrimType.TUBE || prim_type == PrimType.RING);
res.Add(new LSL_Vector(
(useProfileBeginEnd ? part.Shape.ProfileBegin : part.Shape.PathBegin) / 50000.0,
1 - (useProfileBeginEnd ? part.Shape.ProfileEnd : part.Shape.PathEnd) / 50000.0,
0
));
break;
} }
} }
return res; return res;

View File

@ -329,6 +329,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public const int PRIM_OMEGA = 32; public const int PRIM_OMEGA = 32;
public const int PRIM_POS_LOCAL = 33; public const int PRIM_POS_LOCAL = 33;
public const int PRIM_LINK_TARGET = 34; public const int PRIM_LINK_TARGET = 34;
public const int PRIM_SLICE = 35;
public const int PRIM_TEXGEN_DEFAULT = 0; public const int PRIM_TEXGEN_DEFAULT = 0;
public const int PRIM_TEXGEN_PLANAR = 1; public const int PRIM_TEXGEN_PLANAR = 1;

View File

@ -562,12 +562,23 @@ namespace OpenSim.Region.ScriptEngine.Shared
else if (m_data[itemIndex] is LSL_Types.LSLString) else if (m_data[itemIndex] is LSL_Types.LSLString)
return new LSLInteger(m_data[itemIndex].ToString()); return new LSLInteger(m_data[itemIndex].ToString());
else else
throw new InvalidCastException(); throw new InvalidCastException(string.Format(
"{0} expected but {1} given",
typeof(LSL_Types.LSLInteger).Name,
m_data[itemIndex] != null ?
m_data[itemIndex].GetType().Name : "null"));
} }
public LSL_Types.Vector3 GetVector3Item(int itemIndex) public LSL_Types.Vector3 GetVector3Item(int itemIndex)
{ {
return (LSL_Types.Vector3)m_data[itemIndex]; if(m_data[itemIndex] is LSL_Types.Vector3)
return (LSL_Types.Vector3)m_data[itemIndex];
else
throw new InvalidCastException(string.Format(
"{0} expected but {1} given",
typeof(LSL_Types.Vector3).Name,
m_data[itemIndex] != null ?
m_data[itemIndex].GetType().Name : "null"));
} }
public LSL_Types.Quaternion GetQuaternionItem(int itemIndex) public LSL_Types.Quaternion GetQuaternionItem(int itemIndex)

View File

@ -1053,10 +1053,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
return false; return false;
} }
UUID assetID = item.AssetID; m_log.DebugFormat(
"[XEngine] Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
//m_log.DebugFormat("[XEngine] Compiling script {0} ({1} on object {2})", UUID assetID = item.AssetID;
// item.Name, itemID.ToString(), part.ParentGroup.RootPart.Name);
ScenePresence presence = m_Scene.GetScenePresence(item.OwnerID); ScenePresence presence = m_Scene.GetScenePresence(item.OwnerID);
@ -1235,10 +1237,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
item.Name, startParam, postOnRez, item.Name, startParam, postOnRez,
stateSource, m_MaxScriptQueue); stateSource, m_MaxScriptQueue);
m_log.DebugFormat( // m_log.DebugFormat(
"[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", // "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, // part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); // part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
if (presence != null) if (presence != null)
{ {

View File

@ -87,10 +87,18 @@
;; from the selected region_info_source. ;; from the selected region_info_source.
; allow_regionless = false ; allow_regionless = false
;# {NonPhysicalPrimMin} {} {Minimum size of nonphysical prims?} {} 0.01
;; Minimum size for non-physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonphysicalPrimMin!).
; NonphysicalPrimMin = 0.01
;# {NonPhysicalPrimMax} {} {Maximum size of nonphysical prims?} {} 256 ;# {NonPhysicalPrimMax} {} {Maximum size of nonphysical prims?} {} 256
;; Maximum size for non-physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonphysicalPrimMax!). ;; Maximum size for non-physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonphysicalPrimMax!).
; NonphysicalPrimMax = 256 ; NonphysicalPrimMax = 256
;# {PhysicalPrimMin} {} {Minimum size of physical prims?} {} 10
;; Maximum size where a prim can be physical. Affects resizing of existing prims. This can be overriden in the region config file.
; PhysicalPrimMin = 0.01
;# {PhysicalPrimMax} {} {Maximum size of physical prims?} {} 10 ;# {PhysicalPrimMax} {} {Maximum size of physical prims?} {} 10
;; Maximum size where a prim can be physical. Affects resizing of existing prims. This can be overriden in the region config file. ;; Maximum size where a prim can be physical. Affects resizing of existing prims. This can be overriden in the region config file.
; PhysicalPrimMax = 10 ; PhysicalPrimMax = 10
@ -675,7 +683,9 @@
;; Maximum number of events to queue for a script (excluding timers) ;; Maximum number of events to queue for a script (excluding timers)
; MaxScriptEventQueue = 300 ; MaxScriptEventQueue = 300
;; Stack size per thread created ;; Stack size per script engine thread in bytes.
;; If you are experiencing StackOverflowExceptions you may want to increase this (e.g. double it).
;; The trade-off may be increased memory usage by the script engine.
; ThreadStackSize = 262144 ; ThreadStackSize = 262144
;# {DeleteScriptsOnStartup} {} {Delete previously compiled script DLLs on startup?} (true false) true ;# {DeleteScriptsOnStartup} {} {Delete previously compiled script DLLs on startup?} (true false) true

View File

@ -931,6 +931,9 @@
; level of detail for physical meshes. 32,16,8 or 4 with 32 being full detail ; level of detail for physical meshes. 32,16,8 or 4 with 32 being full detail
MeshLevelOfDetail = 8 MeshLevelOfDetail = 8
; if mesh size is > threshold meters, we need to add more detail because people will notice
MeshLevelOfDetailMegaPrimThreshold = 10
MeshLevelOfDetailMegaPrim = 16
; number^2 non-physical level of detail of the sculpt texture. 32x32 - 1024 verticies ; number^2 non-physical level of detail of the sculpt texture. 32x32 - 1024 verticies
SculptLevelOfDetail = 32 SculptLevelOfDetail = 32

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.