Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
commit
6935bec0ab
|
@ -0,0 +1,171 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyrightD
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Framework;
|
||||||
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
using OpenSim.Region.CoreModules;
|
||||||
|
|
||||||
|
using Mono.Addins;
|
||||||
|
using Nini.Config;
|
||||||
|
using log4net;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.OptionalModules.Scripting
|
||||||
|
{
|
||||||
|
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||||
|
public class ExtendedPhysics : INonSharedRegionModule
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
private static string LogHeader = "[EXTENDED PHYSICS]";
|
||||||
|
|
||||||
|
private IConfig Configuration { get; set; }
|
||||||
|
private bool Enabled { get; set; }
|
||||||
|
private Scene BaseScene { get; set; }
|
||||||
|
private IScriptModuleComms Comms { get; set; }
|
||||||
|
|
||||||
|
#region INonSharedRegionModule
|
||||||
|
|
||||||
|
public string Name { get { return this.GetType().Name; } }
|
||||||
|
|
||||||
|
public void Initialise(IConfigSource config)
|
||||||
|
{
|
||||||
|
BaseScene = null;
|
||||||
|
Enabled = false;
|
||||||
|
Configuration = null;
|
||||||
|
Comms = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ((Configuration = config.Configs["ExtendedPhysics"]) != null)
|
||||||
|
{
|
||||||
|
Enabled = Configuration.GetBoolean("Enabled", Enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.ErrorFormat("{0} Initialization error: {0}", LogHeader, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_log.InfoFormat("{0} module {1} enabled", LogHeader, (Enabled ? "is" : "is not"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
if (BaseScene != null)
|
||||||
|
{
|
||||||
|
BaseScene.EventManager.OnObjectAddedToScene -= EventManager_OnObjectAddedToScene;
|
||||||
|
BaseScene.EventManager.OnSceneObjectPartUpdated -= EventManager_OnSceneObjectPartUpdated;
|
||||||
|
BaseScene = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRegion(Scene scene)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveRegion(Scene scene)
|
||||||
|
{
|
||||||
|
if (BaseScene != null && BaseScene == scene)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegionLoaded(Scene scene)
|
||||||
|
{
|
||||||
|
if (!Enabled) return;
|
||||||
|
|
||||||
|
BaseScene = scene;
|
||||||
|
|
||||||
|
Comms = BaseScene.RequestModuleInterface<IScriptModuleComms>();
|
||||||
|
if (Comms == null)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("{0} ScriptModuleComms interface not defined", LogHeader);
|
||||||
|
Enabled = false;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register as LSL functions all the [ScriptInvocation] marked methods.
|
||||||
|
Comms.RegisterScriptInvocations(this);
|
||||||
|
|
||||||
|
// When an object is modified, we might need to update its extended physics parameters
|
||||||
|
BaseScene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene;
|
||||||
|
BaseScene.EventManager.OnSceneObjectPartUpdated += EventManager_OnSceneObjectPartUpdated;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type ReplaceableInterface { get { return null; } }
|
||||||
|
|
||||||
|
#endregion // INonSharedRegionModule
|
||||||
|
|
||||||
|
private void EventManager_OnObjectAddedToScene(SceneObjectGroup obj)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event generated when some property of a prim changes.
|
||||||
|
private void EventManager_OnSceneObjectPartUpdated(SceneObjectPart sop, bool isFullUpdate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[ScriptConstant]
|
||||||
|
public static int PHYS_CENTER_OF_MASS = 1 << 0;
|
||||||
|
|
||||||
|
[ScriptConstant]
|
||||||
|
public static int PHYS_LINKSET_TYPE_CONSTRAINT = 1;
|
||||||
|
[ScriptConstant]
|
||||||
|
public static int PHYS_LINKSET_TYPE_COMPOUND = 2;
|
||||||
|
[ScriptConstant]
|
||||||
|
public static int PHYS_LINKSET_TYPE_MANUAL = 3;
|
||||||
|
|
||||||
|
[ScriptInvocation]
|
||||||
|
public string physGetEngineType(UUID hostID, UUID scriptID)
|
||||||
|
{
|
||||||
|
string ret = string.Empty;
|
||||||
|
|
||||||
|
if (BaseScene.PhysicsScene != null)
|
||||||
|
{
|
||||||
|
ret = BaseScene.PhysicsScene.EngineType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
[ScriptInvocation]
|
||||||
|
public void physSetLinksetType(UUID hostID, UUID scriptID, int linksetType)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -93,6 +93,15 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
// extract the internals of a has reference
|
// extract the internals of a has reference
|
||||||
protected static Regex m_HashPattern = new Regex("{([^}]+)}");
|
protected static Regex m_HashPattern = new Regex("{([^}]+)}");
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
/// <summary>
|
||||||
|
/// This is a simple estimator for the size of the stored data, it
|
||||||
|
/// is not precise, but should be close enough to implement reasonable
|
||||||
|
/// limits on the storage space used
|
||||||
|
/// </summary>
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
public int StringSpace { get; set; }
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
@ -110,6 +119,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
public JsonStore()
|
public JsonStore()
|
||||||
{
|
{
|
||||||
|
StringSpace = 0;
|
||||||
m_TakeStore = new List<TakeValueCallbackClass>();
|
m_TakeStore = new List<TakeValueCallbackClass>();
|
||||||
m_ReadStore = new List<TakeValueCallbackClass>();
|
m_ReadStore = new List<TakeValueCallbackClass>();
|
||||||
}
|
}
|
||||||
|
@ -135,7 +145,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
if (result == null)
|
if (result == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (useJson || result.Type == OSDType.String)
|
if (useJson || OSDBaseType(result.Type))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -247,6 +257,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
if (path.Count == 0)
|
if (path.Count == 0)
|
||||||
{
|
{
|
||||||
ValueStore = ovalue;
|
ValueStore = ovalue;
|
||||||
|
StringSpace = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,8 +289,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
{
|
{
|
||||||
string npkey = String.Format("[{0}]",amap.Count);
|
string npkey = String.Format("[{0}]",amap.Count);
|
||||||
|
|
||||||
amap.Add(ovalue);
|
if (ovalue != null)
|
||||||
InvokeNextCallback(pexpr + npkey);
|
{
|
||||||
|
StringSpace += ComputeSizeOf(ovalue);
|
||||||
|
|
||||||
|
amap.Add(ovalue);
|
||||||
|
InvokeNextCallback(pexpr + npkey);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,9 +303,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
if (0 <= aval && aval < amap.Count)
|
if (0 <= aval && aval < amap.Count)
|
||||||
{
|
{
|
||||||
if (ovalue == null)
|
if (ovalue == null)
|
||||||
|
{
|
||||||
|
StringSpace -= ComputeSizeOf(amap[aval]);
|
||||||
amap.RemoveAt(aval);
|
amap.RemoveAt(aval);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
StringSpace -= ComputeSizeOf(amap[aval]);
|
||||||
|
StringSpace += ComputeSizeOf(ovalue);
|
||||||
amap[aval] = ovalue;
|
amap[aval] = ovalue;
|
||||||
InvokeNextCallback(pexpr + pkey);
|
InvokeNextCallback(pexpr + pkey);
|
||||||
}
|
}
|
||||||
|
@ -313,6 +334,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
OSDMap hmap = result as OSDMap;
|
OSDMap hmap = result as OSDMap;
|
||||||
if (ovalue != null)
|
if (ovalue != null)
|
||||||
{
|
{
|
||||||
|
StringSpace -= ComputeSizeOf(hmap[hkey]);
|
||||||
|
StringSpace += ComputeSizeOf(ovalue);
|
||||||
|
|
||||||
hmap[hkey] = ovalue;
|
hmap[hkey] = ovalue;
|
||||||
InvokeNextCallback(pexpr + pkey);
|
InvokeNextCallback(pexpr + pkey);
|
||||||
return true;
|
return true;
|
||||||
|
@ -321,6 +345,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
// this is the remove case
|
// this is the remove case
|
||||||
if (hmap.ContainsKey(hkey))
|
if (hmap.ContainsKey(hkey))
|
||||||
{
|
{
|
||||||
|
StringSpace -= ComputeSizeOf(hmap[hkey]);
|
||||||
hmap.Remove(hkey);
|
hmap.Remove(hkey);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -506,7 +531,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.Type == OSDType.String)
|
if (OSDBaseType(result.Type))
|
||||||
{
|
{
|
||||||
value = result.AsString();
|
value = result.AsString();
|
||||||
return true;
|
return true;
|
||||||
|
@ -531,8 +556,54 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
|
|
||||||
return pkey;
|
return pkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
protected static bool OSDBaseType(OSDType type)
|
||||||
|
{
|
||||||
|
// Should be the list of base types for which AsString() returns
|
||||||
|
// something useful
|
||||||
|
if (type == OSDType.Boolean)
|
||||||
|
return true;
|
||||||
|
if (type == OSDType.Integer)
|
||||||
|
return true;
|
||||||
|
if (type == OSDType.Real)
|
||||||
|
return true;
|
||||||
|
if (type == OSDType.String)
|
||||||
|
return true;
|
||||||
|
if (type == OSDType.UUID)
|
||||||
|
return true;
|
||||||
|
if (type == OSDType.Date)
|
||||||
|
return true;
|
||||||
|
if (type == OSDType.URI)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
protected static int ComputeSizeOf(OSD value)
|
||||||
|
{
|
||||||
|
string sval;
|
||||||
|
|
||||||
|
if (ConvertOutputValue(value,out sval,true))
|
||||||
|
return sval.Length;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
/// <summary>
|
||||||
|
/// </summary>
|
||||||
|
// -----------------------------------------------------------------
|
||||||
public class JsonObjectStore : JsonStore
|
public class JsonObjectStore : JsonStore
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log =
|
private static readonly ILog m_log =
|
||||||
|
@ -566,6 +637,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
{
|
{
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
m_objectID = oid;
|
m_objectID = oid;
|
||||||
|
|
||||||
|
// the size limit is imposed on whatever is already in the store
|
||||||
|
StringSpace = ComputeSizeOf(ValueStore);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
|
|
||||||
private IConfig m_config = null;
|
private IConfig m_config = null;
|
||||||
private bool m_enabled = false;
|
private bool m_enabled = false;
|
||||||
|
private bool m_enableObjectStore = false;
|
||||||
|
private int m_maxStringSpace = Int32.MaxValue;
|
||||||
|
|
||||||
private Scene m_scene = null;
|
private Scene m_scene = null;
|
||||||
|
|
||||||
private Dictionary<UUID,JsonStore> m_JsonValueStore;
|
private Dictionary<UUID,JsonStore> m_JsonValueStore;
|
||||||
|
@ -90,6 +93,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
}
|
}
|
||||||
|
|
||||||
m_enabled = m_config.GetBoolean("Enabled", m_enabled);
|
m_enabled = m_config.GetBoolean("Enabled", m_enabled);
|
||||||
|
m_enableObjectStore = m_config.GetBoolean("EnableObjectStore", m_enableObjectStore);
|
||||||
|
m_maxStringSpace = m_config.GetInt("MaxStringSpace", m_maxStringSpace);
|
||||||
|
if (m_maxStringSpace == 0)
|
||||||
|
m_maxStringSpace = Int32.MaxValue;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -178,6 +185,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
public bool AttachObjectStore(UUID objectID)
|
public bool AttachObjectStore(UUID objectID)
|
||||||
{
|
{
|
||||||
if (! m_enabled) return false;
|
if (! m_enabled) return false;
|
||||||
|
if (! m_enableObjectStore) return false;
|
||||||
|
|
||||||
SceneObjectPart sop = m_scene.GetSceneObjectPart(objectID);
|
SceneObjectPart sop = m_scene.GetSceneObjectPart(objectID);
|
||||||
if (sop == null)
|
if (sop == null)
|
||||||
|
@ -311,7 +319,16 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
lock (map)
|
lock (map)
|
||||||
|
{
|
||||||
|
if (map.StringSpace > m_maxStringSpace)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[JsonStore] {0} exceeded string size; {1} bytes used of {2} limit",
|
||||||
|
storeID,map.StringSpace,m_maxStringSpace);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return map.SetValue(path,value,useJson);
|
return map.SetValue(path,value,useJson);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -183,6 +183,7 @@ public struct ConfigurationParameters
|
||||||
public float shouldEnableFrictionCaching;
|
public float shouldEnableFrictionCaching;
|
||||||
public float numberOfSolverIterations;
|
public float numberOfSolverIterations;
|
||||||
public float useSingleSidedMeshes;
|
public float useSingleSidedMeshes;
|
||||||
|
public float globalContactBreakingThreshold;
|
||||||
|
|
||||||
public float physicsLoggingFrames;
|
public float physicsLoggingFrames;
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,6 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
private bool _selected;
|
private bool _selected;
|
||||||
private OMV.Vector3 _position;
|
private OMV.Vector3 _position;
|
||||||
private float _mass;
|
private float _mass;
|
||||||
private float _avatarDensity;
|
|
||||||
private float _avatarVolume;
|
private float _avatarVolume;
|
||||||
private OMV.Vector3 _force;
|
private OMV.Vector3 _force;
|
||||||
private OMV.Vector3 _velocity;
|
private OMV.Vector3 _velocity;
|
||||||
|
@ -63,9 +62,6 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
private bool _kinematic;
|
private bool _kinematic;
|
||||||
private float _buoyancy;
|
private float _buoyancy;
|
||||||
|
|
||||||
// The friction and velocity of the avatar is modified depending on whether walking or not.
|
|
||||||
private float _currentFriction; // the friction currently being used (changed by setVelocity).
|
|
||||||
|
|
||||||
private BSVMotor _velocityMotor;
|
private BSVMotor _velocityMotor;
|
||||||
|
|
||||||
private OMV.Vector3 _PIDTarget;
|
private OMV.Vector3 _PIDTarget;
|
||||||
|
@ -86,8 +82,8 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
_orientation = OMV.Quaternion.Identity;
|
_orientation = OMV.Quaternion.Identity;
|
||||||
_velocity = OMV.Vector3.Zero;
|
_velocity = OMV.Vector3.Zero;
|
||||||
_buoyancy = ComputeBuoyancyFromFlying(isFlying);
|
_buoyancy = ComputeBuoyancyFromFlying(isFlying);
|
||||||
_currentFriction = BSParam.AvatarStandingFriction;
|
Friction = BSParam.AvatarStandingFriction;
|
||||||
_avatarDensity = BSParam.AvatarDensity;
|
Density = BSParam.AvatarDensity;
|
||||||
|
|
||||||
// Old versions of ScenePresence passed only the height. If width and/or depth are zero,
|
// Old versions of ScenePresence passed only the height. If width and/or depth are zero,
|
||||||
// replace with the default values.
|
// replace with the default values.
|
||||||
|
@ -104,7 +100,7 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
SetupMovementMotor();
|
SetupMovementMotor();
|
||||||
|
|
||||||
DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}",
|
DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}",
|
||||||
LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass);
|
LocalID, _size, Scale, Density, _avatarVolume, RawMass);
|
||||||
|
|
||||||
// do actual creation in taint time
|
// do actual creation in taint time
|
||||||
PhysicsScene.TaintedObject("BSCharacter.create", delegate()
|
PhysicsScene.TaintedObject("BSCharacter.create", delegate()
|
||||||
|
@ -140,7 +136,7 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
ZeroMotion(true);
|
ZeroMotion(true);
|
||||||
ForcePosition = _position;
|
ForcePosition = _position;
|
||||||
|
|
||||||
// Set the velocity and compute the proper friction
|
// Set the velocity
|
||||||
_velocityMotor.Reset();
|
_velocityMotor.Reset();
|
||||||
_velocityMotor.SetTarget(_velocity);
|
_velocityMotor.SetTarget(_velocity);
|
||||||
_velocityMotor.SetCurrent(_velocity);
|
_velocityMotor.SetCurrent(_velocity);
|
||||||
|
@ -214,35 +210,38 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
_velocityMotor.Step(timeStep);
|
_velocityMotor.Step(timeStep);
|
||||||
|
|
||||||
// If we're not supposed to be moving, make sure things are zero.
|
// If we're not supposed to be moving, make sure things are zero.
|
||||||
if (_velocityMotor.ErrorIsZero() && _velocityMotor.TargetValue == OMV.Vector3.Zero && IsColliding)
|
if (_velocityMotor.ErrorIsZero() && _velocityMotor.TargetValue == OMV.Vector3.Zero)
|
||||||
{
|
{
|
||||||
// The avatar shouldn't be moving
|
// The avatar shouldn't be moving
|
||||||
_velocityMotor.Zero();
|
_velocityMotor.Zero();
|
||||||
|
|
||||||
// If we are colliding with a stationary object, presume we're standing and don't move around
|
if (IsColliding)
|
||||||
if (!ColliderIsMoving)
|
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", LocalID);
|
// If we are colliding with a stationary object, presume we're standing and don't move around
|
||||||
ZeroMotion(true /* inTaintTime */);
|
if (!ColliderIsMoving)
|
||||||
}
|
{
|
||||||
|
DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", LocalID);
|
||||||
|
ZeroMotion(true /* inTaintTime */);
|
||||||
|
}
|
||||||
|
|
||||||
// Standing has more friction on the ground
|
// Standing has more friction on the ground
|
||||||
if (_currentFriction != BSParam.AvatarStandingFriction)
|
if (Friction != BSParam.AvatarStandingFriction)
|
||||||
{
|
{
|
||||||
_currentFriction = BSParam.AvatarStandingFriction;
|
Friction = BSParam.AvatarStandingFriction;
|
||||||
PhysicsScene.PE.SetFriction(PhysBody, _currentFriction);
|
PhysicsScene.PE.SetFriction(PhysBody, Friction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1}", LocalID, _velocityMotor.TargetValue);
|
DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1},colliding={2}", LocalID, _velocityMotor.TargetValue, IsColliding);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OMV.Vector3 stepVelocity = _velocityMotor.CurrentValue;
|
OMV.Vector3 stepVelocity = _velocityMotor.CurrentValue;
|
||||||
|
|
||||||
if (_currentFriction != BSParam.AvatarFriction)
|
if (Friction != BSParam.AvatarFriction)
|
||||||
{
|
{
|
||||||
// Probably starting up walking. Set friction to moving friction.
|
// Probably starting up walking. Set friction to moving friction.
|
||||||
_currentFriction = BSParam.AvatarFriction;
|
Friction = BSParam.AvatarFriction;
|
||||||
PhysicsScene.PE.SetFriction(PhysBody, _currentFriction);
|
PhysicsScene.PE.SetFriction(PhysBody, Friction);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If falling, we keep the world's downward vector no matter what the other axis specify.
|
// If falling, we keep the world's downward vector no matter what the other axis specify.
|
||||||
|
@ -342,7 +341,7 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
Scale = ComputeAvatarScale(_size);
|
Scale = ComputeAvatarScale(_size);
|
||||||
ComputeAvatarVolumeAndMass();
|
ComputeAvatarVolumeAndMass();
|
||||||
DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}",
|
DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}",
|
||||||
LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass);
|
LocalID, _size, Scale, Density, _avatarVolume, RawMass);
|
||||||
|
|
||||||
PhysicsScene.TaintedObject("BSCharacter.setSize", delegate()
|
PhysicsScene.TaintedObject("BSCharacter.setSize", delegate()
|
||||||
{
|
{
|
||||||
|
@ -870,7 +869,7 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
* Math.Min(Size.X, Size.Y) / 2
|
* Math.Min(Size.X, Size.Y) / 2
|
||||||
* Size.Y / 2f // plus the volume of the capsule end caps
|
* Size.Y / 2f // plus the volume of the capsule end caps
|
||||||
);
|
);
|
||||||
_mass = _avatarDensity * _avatarVolume;
|
_mass = Density * _avatarVolume;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The physics engine says that properties have updated. Update same and inform
|
// The physics engine says that properties have updated. Update same and inform
|
||||||
|
@ -901,7 +900,7 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
CurrentEntityProperties = entprop;
|
CurrentEntityProperties = entprop;
|
||||||
|
|
||||||
// Tell the linkset about value changes
|
// Tell the linkset about value changes
|
||||||
Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
|
// Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
|
||||||
|
|
||||||
// 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();
|
||||||
|
|
|
@ -597,7 +597,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
if (IsActive)
|
if (IsActive)
|
||||||
{
|
{
|
||||||
// Remember the mass so we don't have to fetch it every step
|
// Remember the mass so we don't have to fetch it every step
|
||||||
m_vehicleMass = Prim.Linkset.LinksetMass;
|
m_vehicleMass = Prim.TotalMass;
|
||||||
|
|
||||||
// Friction affects are handled by this vehicle code
|
// Friction affects are handled by this vehicle code
|
||||||
PhysicsScene.PE.SetFriction(Prim.PhysBody, BSParam.VehicleFriction);
|
PhysicsScene.PE.SetFriction(Prim.PhysBody, BSParam.VehicleFriction);
|
||||||
|
|
|
@ -52,7 +52,7 @@ public abstract class BSLinkset
|
||||||
Manual = 2 // linkset tied together manually (code moves all the pieces)
|
Manual = 2 // linkset tied together manually (code moves all the pieces)
|
||||||
}
|
}
|
||||||
// Create the correct type of linkset for this child
|
// Create the correct type of linkset for this child
|
||||||
public static BSLinkset Factory(BSScene physScene, BSPhysObject parent)
|
public static BSLinkset Factory(BSScene physScene, BSPrimLinkable parent)
|
||||||
{
|
{
|
||||||
BSLinkset ret = null;
|
BSLinkset ret = null;
|
||||||
|
|
||||||
|
@ -71,10 +71,14 @@ public abstract class BSLinkset
|
||||||
ret = new BSLinksetCompound(physScene, parent);
|
ret = new BSLinksetCompound(physScene, parent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (ret == null)
|
||||||
|
{
|
||||||
|
physScene.Logger.ErrorFormat("[BULLETSIM LINKSET] Factory could not create linkset. Parent name={1}, ID={2}", parent.Name, parent.LocalID);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BSPhysObject LinksetRoot { get; protected set; }
|
public BSPrimLinkable LinksetRoot { get; protected set; }
|
||||||
|
|
||||||
public BSScene PhysicsScene { get; private set; }
|
public BSScene PhysicsScene { get; private set; }
|
||||||
|
|
||||||
|
@ -82,7 +86,7 @@ public abstract class BSLinkset
|
||||||
public int LinksetID { get; private set; }
|
public int LinksetID { get; private set; }
|
||||||
|
|
||||||
// The children under the root in this linkset.
|
// The children under the root in this linkset.
|
||||||
protected HashSet<BSPhysObject> m_children;
|
protected HashSet<BSPrimLinkable> m_children;
|
||||||
|
|
||||||
// We lock the diddling of linkset classes to prevent any badness.
|
// We lock the diddling of linkset classes to prevent any badness.
|
||||||
// This locks the modification of the instances of this class. Changes
|
// This locks the modification of the instances of this class. Changes
|
||||||
|
@ -91,7 +95,7 @@ public abstract class BSLinkset
|
||||||
|
|
||||||
// Some linksets have a preferred physical shape.
|
// Some linksets have a preferred physical shape.
|
||||||
// Returns SHAPE_UNKNOWN if there is no preference. Causes the correct shape to be selected.
|
// Returns SHAPE_UNKNOWN if there is no preference. Causes the correct shape to be selected.
|
||||||
public virtual BSPhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor)
|
public virtual BSPhysicsShapeType PreferredPhysicalShape(BSPrimLinkable requestor)
|
||||||
{
|
{
|
||||||
return BSPhysicsShapeType.SHAPE_UNKNOWN;
|
return BSPhysicsShapeType.SHAPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
@ -111,7 +115,7 @@ public abstract class BSLinkset
|
||||||
get { return ComputeLinksetGeometricCenter(); }
|
get { return ComputeLinksetGeometricCenter(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected BSLinkset(BSScene scene, BSPhysObject parent)
|
protected BSLinkset(BSScene scene, BSPrimLinkable parent)
|
||||||
{
|
{
|
||||||
// A simple linkset of one (no children)
|
// A simple linkset of one (no children)
|
||||||
LinksetID = m_nextLinksetID++;
|
LinksetID = m_nextLinksetID++;
|
||||||
|
@ -120,7 +124,7 @@ public abstract class BSLinkset
|
||||||
m_nextLinksetID = 1;
|
m_nextLinksetID = 1;
|
||||||
PhysicsScene = scene;
|
PhysicsScene = scene;
|
||||||
LinksetRoot = parent;
|
LinksetRoot = parent;
|
||||||
m_children = new HashSet<BSPhysObject>();
|
m_children = new HashSet<BSPrimLinkable>();
|
||||||
LinksetMass = parent.RawMass;
|
LinksetMass = parent.RawMass;
|
||||||
Rebuilding = false;
|
Rebuilding = false;
|
||||||
}
|
}
|
||||||
|
@ -129,7 +133,7 @@ public abstract class BSLinkset
|
||||||
// Parent changing should not happen so do some sanity checking.
|
// Parent changing should not happen so do some sanity checking.
|
||||||
// We return the parent's linkset so the child can track its membership.
|
// We return the parent's linkset so the child can track its membership.
|
||||||
// Called at runtime.
|
// Called at runtime.
|
||||||
public BSLinkset AddMeToLinkset(BSPhysObject child)
|
public BSLinkset AddMeToLinkset(BSPrimLinkable child)
|
||||||
{
|
{
|
||||||
lock (m_linksetActivityLock)
|
lock (m_linksetActivityLock)
|
||||||
{
|
{
|
||||||
|
@ -145,14 +149,13 @@ public abstract class BSLinkset
|
||||||
// Returns a new linkset for the child which is a linkset of one (just the
|
// Returns a new linkset for the child which is a linkset of one (just the
|
||||||
// orphened child).
|
// orphened child).
|
||||||
// Called at runtime.
|
// Called at runtime.
|
||||||
public BSLinkset RemoveMeFromLinkset(BSPhysObject child)
|
public BSLinkset RemoveMeFromLinkset(BSPrimLinkable child)
|
||||||
{
|
{
|
||||||
lock (m_linksetActivityLock)
|
lock (m_linksetActivityLock)
|
||||||
{
|
{
|
||||||
if (IsRoot(child))
|
if (IsRoot(child))
|
||||||
{
|
{
|
||||||
// Cannot remove the root from a linkset.
|
// Cannot remove the root from a linkset.
|
||||||
child.PositionDisplacement = OMV.Vector3.Zero;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
RemoveChildFromLinkset(child);
|
RemoveChildFromLinkset(child);
|
||||||
|
@ -160,12 +163,11 @@ public abstract class BSLinkset
|
||||||
}
|
}
|
||||||
|
|
||||||
// The child is down to a linkset of just itself
|
// The child is down to a linkset of just itself
|
||||||
child.PositionDisplacement = OMV.Vector3.Zero;
|
|
||||||
return BSLinkset.Factory(PhysicsScene, child);
|
return BSLinkset.Factory(PhysicsScene, child);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return 'true' if the passed object is the root object of this linkset
|
// Return 'true' if the passed object is the root object of this linkset
|
||||||
public bool IsRoot(BSPhysObject requestor)
|
public bool IsRoot(BSPrimLinkable requestor)
|
||||||
{
|
{
|
||||||
return (requestor.LocalID == LinksetRoot.LocalID);
|
return (requestor.LocalID == LinksetRoot.LocalID);
|
||||||
}
|
}
|
||||||
|
@ -176,14 +178,14 @@ public abstract class BSLinkset
|
||||||
public bool HasAnyChildren { get { return (m_children.Count > 0); } }
|
public bool HasAnyChildren { get { return (m_children.Count > 0); } }
|
||||||
|
|
||||||
// Return 'true' if this child is in this linkset
|
// Return 'true' if this child is in this linkset
|
||||||
public bool HasChild(BSPhysObject child)
|
public bool HasChild(BSPrimLinkable child)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
lock (m_linksetActivityLock)
|
lock (m_linksetActivityLock)
|
||||||
{
|
{
|
||||||
ret = m_children.Contains(child);
|
ret = m_children.Contains(child);
|
||||||
/* Safer version but the above should work
|
/* Safer version but the above should work
|
||||||
foreach (BSPhysObject bp in m_children)
|
foreach (BSPrimLinkable bp in m_children)
|
||||||
{
|
{
|
||||||
if (child.LocalID == bp.LocalID)
|
if (child.LocalID == bp.LocalID)
|
||||||
{
|
{
|
||||||
|
@ -198,14 +200,14 @@ public abstract class BSLinkset
|
||||||
|
|
||||||
// Perform an action on each member of the linkset including root prim.
|
// Perform an action on each member of the linkset including root prim.
|
||||||
// Depends on the action on whether this should be done at taint time.
|
// Depends on the action on whether this should be done at taint time.
|
||||||
public delegate bool ForEachMemberAction(BSPhysObject obj);
|
public delegate bool ForEachMemberAction(BSPrimLinkable obj);
|
||||||
public virtual bool ForEachMember(ForEachMemberAction action)
|
public virtual bool ForEachMember(ForEachMemberAction action)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
lock (m_linksetActivityLock)
|
lock (m_linksetActivityLock)
|
||||||
{
|
{
|
||||||
action(LinksetRoot);
|
action(LinksetRoot);
|
||||||
foreach (BSPhysObject po in m_children)
|
foreach (BSPrimLinkable po in m_children)
|
||||||
{
|
{
|
||||||
if (action(po))
|
if (action(po))
|
||||||
break;
|
break;
|
||||||
|
@ -216,16 +218,16 @@ public abstract class BSLinkset
|
||||||
|
|
||||||
// I am the root of a linkset and a new child is being added
|
// I am the root of a linkset and a new child is being added
|
||||||
// Called while LinkActivity is locked.
|
// Called while LinkActivity is locked.
|
||||||
protected abstract void AddChildToLinkset(BSPhysObject child);
|
protected abstract void AddChildToLinkset(BSPrimLinkable child);
|
||||||
|
|
||||||
// I am the root of a linkset and one of my children is being removed.
|
// I am the root of a linkset and one of my children is being removed.
|
||||||
// Safe to call even if the child is not really in my linkset.
|
// Safe to call even if the child is not really in my linkset.
|
||||||
protected abstract void RemoveChildFromLinkset(BSPhysObject child);
|
protected abstract void RemoveChildFromLinkset(BSPrimLinkable child);
|
||||||
|
|
||||||
// When physical properties are changed the linkset needs to recalculate
|
// When physical properties are changed the linkset needs to recalculate
|
||||||
// its internal properties.
|
// its internal properties.
|
||||||
// May be called at runtime or taint-time.
|
// May be called at runtime or taint-time.
|
||||||
public virtual void Refresh(BSPhysObject requestor)
|
public virtual void Refresh(BSPrimLinkable requestor)
|
||||||
{
|
{
|
||||||
LinksetMass = ComputeLinksetMass();
|
LinksetMass = ComputeLinksetMass();
|
||||||
}
|
}
|
||||||
|
@ -240,26 +242,26 @@ public abstract class BSLinkset
|
||||||
// has not yet been fully constructed.
|
// has not yet been fully constructed.
|
||||||
// Return 'true' if any properties updated on the passed object.
|
// Return 'true' if any properties updated on the passed object.
|
||||||
// Called at taint-time!
|
// Called at taint-time!
|
||||||
public abstract bool MakeDynamic(BSPhysObject child);
|
public abstract bool MakeDynamic(BSPrimLinkable child);
|
||||||
|
|
||||||
// The object is going static (non-physical). Do any setup necessary
|
// The object is going static (non-physical). Do any setup necessary
|
||||||
// for a static linkset.
|
// for a static linkset.
|
||||||
// Return 'true' if any properties updated on the passed object.
|
// Return 'true' if any properties updated on the passed object.
|
||||||
// Called at taint-time!
|
// Called at taint-time!
|
||||||
public abstract bool MakeStatic(BSPhysObject child);
|
public abstract bool MakeStatic(BSPrimLinkable child);
|
||||||
|
|
||||||
// Called when a parameter update comes from the physics engine for any object
|
// Called when a parameter update comes from the physics engine for any object
|
||||||
// of the linkset is received.
|
// of the linkset is received.
|
||||||
// Passed flag is update came from physics engine (true) or the user (false).
|
// Passed flag is update came from physics engine (true) or the user (false).
|
||||||
// Called at taint-time!!
|
// Called at taint-time!!
|
||||||
public abstract void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject physObject);
|
public abstract void UpdateProperties(UpdatedProperties whichUpdated, BSPrimLinkable physObject);
|
||||||
|
|
||||||
// Routine used when rebuilding the body of the root of the linkset
|
// Routine used when rebuilding the body of the root of the linkset
|
||||||
// Destroy all the constraints have have been made to root.
|
// Destroy all the constraints have have been made to root.
|
||||||
// This is called when the root body is changing.
|
// This is called when the root body is changing.
|
||||||
// Returns 'true' of something was actually removed and would need restoring
|
// Returns 'true' of something was actually removed and would need restoring
|
||||||
// Called at taint-time!!
|
// Called at taint-time!!
|
||||||
public abstract bool RemoveBodyDependencies(BSPrim child);
|
public abstract bool RemoveBodyDependencies(BSPrimLinkable child);
|
||||||
|
|
||||||
// ================================================================
|
// ================================================================
|
||||||
protected virtual float ComputeLinksetMass()
|
protected virtual float ComputeLinksetMass()
|
||||||
|
@ -269,7 +271,7 @@ public abstract class BSLinkset
|
||||||
{
|
{
|
||||||
lock (m_linksetActivityLock)
|
lock (m_linksetActivityLock)
|
||||||
{
|
{
|
||||||
foreach (BSPhysObject bp in m_children)
|
foreach (BSPrimLinkable bp in m_children)
|
||||||
{
|
{
|
||||||
mass += bp.RawMass;
|
mass += bp.RawMass;
|
||||||
}
|
}
|
||||||
|
@ -286,7 +288,7 @@ public abstract class BSLinkset
|
||||||
com = LinksetRoot.Position * LinksetRoot.RawMass;
|
com = LinksetRoot.Position * LinksetRoot.RawMass;
|
||||||
float totalMass = LinksetRoot.RawMass;
|
float totalMass = LinksetRoot.RawMass;
|
||||||
|
|
||||||
foreach (BSPhysObject bp in m_children)
|
foreach (BSPrimLinkable bp in m_children)
|
||||||
{
|
{
|
||||||
com += bp.Position * bp.RawMass;
|
com += bp.Position * bp.RawMass;
|
||||||
totalMass += bp.RawMass;
|
totalMass += bp.RawMass;
|
||||||
|
@ -305,7 +307,7 @@ public abstract class BSLinkset
|
||||||
{
|
{
|
||||||
com = LinksetRoot.Position;
|
com = LinksetRoot.Position;
|
||||||
|
|
||||||
foreach (BSPhysObject bp in m_children)
|
foreach (BSPrimLinkable bp in m_children)
|
||||||
{
|
{
|
||||||
com += bp.Position;
|
com += bp.Position;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ sealed class BSLinksetCompoundInfo : BSLinksetInfo
|
||||||
OffsetRot = r;
|
OffsetRot = r;
|
||||||
}
|
}
|
||||||
// 'centerDisplacement' is the distance from the root the the center-of-mass (Bullet 'zero' of the shape)
|
// 'centerDisplacement' is the distance from the root the the center-of-mass (Bullet 'zero' of the shape)
|
||||||
public BSLinksetCompoundInfo(int indx, BSPhysObject root, BSPhysObject child, OMV.Vector3 centerDisplacement)
|
public BSLinksetCompoundInfo(int indx, BSPrimLinkable root, BSPrimLinkable child, OMV.Vector3 centerDisplacement)
|
||||||
{
|
{
|
||||||
// Each child position and rotation is given relative to the center-of-mass.
|
// Each child position and rotation is given relative to the center-of-mass.
|
||||||
OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(root.RawOrientation);
|
OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(root.RawOrientation);
|
||||||
|
@ -93,12 +93,12 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
{
|
{
|
||||||
private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]";
|
private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]";
|
||||||
|
|
||||||
public BSLinksetCompound(BSScene scene, BSPhysObject parent) : base(scene, parent)
|
public BSLinksetCompound(BSScene scene, BSPrimLinkable parent) : base(scene, parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// For compound implimented linksets, if there are children, use compound shape for the root.
|
// For compound implimented linksets, if there are children, use compound shape for the root.
|
||||||
public override BSPhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor)
|
public override BSPhysicsShapeType PreferredPhysicalShape(BSPrimLinkable requestor)
|
||||||
{
|
{
|
||||||
// Returning 'unknown' means we don't have a preference.
|
// Returning 'unknown' means we don't have a preference.
|
||||||
BSPhysicsShapeType ret = BSPhysicsShapeType.SHAPE_UNKNOWN;
|
BSPhysicsShapeType ret = BSPhysicsShapeType.SHAPE_UNKNOWN;
|
||||||
|
@ -112,7 +112,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
|
|
||||||
// When physical properties are changed the linkset needs to recalculate
|
// When physical properties are changed the linkset needs to recalculate
|
||||||
// its internal properties.
|
// its internal properties.
|
||||||
public override void Refresh(BSPhysObject requestor)
|
public override void Refresh(BSPrimLinkable requestor)
|
||||||
{
|
{
|
||||||
base.Refresh(requestor);
|
base.Refresh(requestor);
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schedule a refresh to happen after all the other taint processing.
|
// Schedule a refresh to happen after all the other taint processing.
|
||||||
private void ScheduleRebuild(BSPhysObject requestor)
|
private void ScheduleRebuild(BSPrimLinkable requestor)
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1},hasChildren={2},actuallyScheduling={3}",
|
DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1},hasChildren={2},actuallyScheduling={3}",
|
||||||
requestor.LocalID, Rebuilding, HasAnyChildren, (!Rebuilding && HasAnyChildren));
|
requestor.LocalID, Rebuilding, HasAnyChildren, (!Rebuilding && HasAnyChildren));
|
||||||
|
@ -143,7 +143,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
// has not yet been fully constructed.
|
// has not yet been fully constructed.
|
||||||
// Return 'true' if any properties updated on the passed object.
|
// Return 'true' if any properties updated on the passed object.
|
||||||
// Called at taint-time!
|
// Called at taint-time!
|
||||||
public override bool MakeDynamic(BSPhysObject child)
|
public override bool MakeDynamic(BSPrimLinkable child)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
DetailLog("{0},BSLinksetCompound.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child));
|
DetailLog("{0},BSLinksetCompound.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child));
|
||||||
|
@ -173,7 +173,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
// This doesn't normally happen -- OpenSim removes the objects from the physical
|
// This doesn't normally happen -- OpenSim removes the objects from the physical
|
||||||
// world if it is a static linkset.
|
// world if it is a static linkset.
|
||||||
// Called at taint-time!
|
// Called at taint-time!
|
||||||
public override bool MakeStatic(BSPhysObject child)
|
public override bool MakeStatic(BSPrimLinkable child)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child));
|
DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child));
|
||||||
|
@ -197,7 +197,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
|
|
||||||
// 'physicalUpdate' is true if these changes came directly from the physics engine. Don't need to rebuild then.
|
// 'physicalUpdate' is true if these changes came directly from the physics engine. Don't need to rebuild then.
|
||||||
// Called at taint-time.
|
// Called at taint-time.
|
||||||
public override void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject updated)
|
public override void UpdateProperties(UpdatedProperties whichUpdated, BSPrimLinkable updated)
|
||||||
{
|
{
|
||||||
// The user moving a child around requires the rebuilding of the linkset compound shape
|
// The user moving a child around requires the rebuilding of the linkset compound shape
|
||||||
// One problem is this happens when a border is crossed -- the simulator implementation
|
// One problem is this happens when a border is crossed -- the simulator implementation
|
||||||
|
@ -222,7 +222,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
if (lsi != null)
|
if (lsi != null)
|
||||||
{
|
{
|
||||||
// Since the child moved or rotationed, it needs a new relative position within the linkset
|
// Since the child moved or rotationed, it needs a new relative position within the linkset
|
||||||
BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, LinksetRoot.PositionDisplacement);
|
BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, OMV.Vector3.Zero);
|
||||||
updated.LinksetInfo = newLsi;
|
updated.LinksetInfo = newLsi;
|
||||||
|
|
||||||
// Find the physical instance of the child
|
// Find the physical instance of the child
|
||||||
|
@ -291,7 +291,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
// Since we don't keep in world relationships, do nothing unless it's a child changing.
|
// Since we don't keep in world relationships, do nothing unless it's a child changing.
|
||||||
// Returns 'true' of something was actually removed and would need restoring
|
// Returns 'true' of something was actually removed and would need restoring
|
||||||
// Called at taint-time!!
|
// Called at taint-time!!
|
||||||
public override bool RemoveBodyDependencies(BSPrim child)
|
public override bool RemoveBodyDependencies(BSPrimLinkable child)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
|
@ -316,7 +316,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
// When the linkset is built, the child shape is added to the compound shape relative to the
|
// When the linkset is built, the child shape is added to the compound shape relative to the
|
||||||
// root shape. The linkset then moves around but this does not move the actual child
|
// root shape. The linkset then moves around but this does not move the actual child
|
||||||
// prim. The child prim's location must be recomputed based on the location of the root shape.
|
// prim. The child prim's location must be recomputed based on the location of the root shape.
|
||||||
private void RecomputeChildWorldPosition(BSPhysObject child, bool inTaintTime)
|
private void RecomputeChildWorldPosition(BSPrimLinkable child, bool inTaintTime)
|
||||||
{
|
{
|
||||||
// For the moment (20130201), disable this computation (converting the child physical addr back to
|
// For the moment (20130201), disable this computation (converting the child physical addr back to
|
||||||
// a region address) until we have a good handle on center-of-mass offsets and what the physics
|
// a region address) until we have a good handle on center-of-mass offsets and what the physics
|
||||||
|
@ -361,7 +361,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
|
|
||||||
// Add a new child to the linkset.
|
// Add a new child to the linkset.
|
||||||
// Called while LinkActivity is locked.
|
// Called while LinkActivity is locked.
|
||||||
protected override void AddChildToLinkset(BSPhysObject child)
|
protected override void AddChildToLinkset(BSPrimLinkable child)
|
||||||
{
|
{
|
||||||
if (!HasChild(child))
|
if (!HasChild(child))
|
||||||
{
|
{
|
||||||
|
@ -377,7 +377,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
|
|
||||||
// Remove the specified child from the linkset.
|
// Remove the specified child from the linkset.
|
||||||
// Safe to call even if the child is not really in the linkset.
|
// Safe to call even if the child is not really in the linkset.
|
||||||
protected override void RemoveChildFromLinkset(BSPhysObject child)
|
protected override void RemoveChildFromLinkset(BSPrimLinkable child)
|
||||||
{
|
{
|
||||||
if (m_children.Remove(child))
|
if (m_children.Remove(child))
|
||||||
{
|
{
|
||||||
|
@ -429,7 +429,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
if (disableCOM) // DEBUG DEBUG
|
if (disableCOM) // DEBUG DEBUG
|
||||||
{ // DEBUG DEBUG
|
{ // DEBUG DEBUG
|
||||||
centerOfMass = LinksetRoot.RawPosition; // DEBUG DEBUG
|
centerOfMass = LinksetRoot.RawPosition; // DEBUG DEBUG
|
||||||
LinksetRoot.PositionDisplacement = OMV.Vector3.Zero;
|
// LinksetRoot.PositionDisplacement = OMV.Vector3.Zero;
|
||||||
} // DEBUG DEBUG
|
} // DEBUG DEBUG
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -438,7 +438,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
centerDisplacement = LinksetRoot.RawPosition - centerOfMass;
|
centerDisplacement = LinksetRoot.RawPosition - centerOfMass;
|
||||||
|
|
||||||
// Since we're displacing the center of the shape, we need to move the body in the world
|
// Since we're displacing the center of the shape, we need to move the body in the world
|
||||||
LinksetRoot.PositionDisplacement = centerDisplacement;
|
// LinksetRoot.PositionDisplacement = centerDisplacement;
|
||||||
|
|
||||||
// This causes the root prim position to be set properly based on the new PositionDisplacement
|
// This causes the root prim position to be set properly based on the new PositionDisplacement
|
||||||
LinksetRoot.ForcePosition = LinksetRoot.RawPosition;
|
LinksetRoot.ForcePosition = LinksetRoot.RawPosition;
|
||||||
|
@ -453,7 +453,7 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
|
|
||||||
// Add a shape for each of the other children in the linkset
|
// Add a shape for each of the other children in the linkset
|
||||||
int memberIndex = 1;
|
int memberIndex = 1;
|
||||||
ForEachMember(delegate(BSPhysObject cPrim)
|
ForEachMember(delegate(BSPrimLinkable cPrim)
|
||||||
{
|
{
|
||||||
if (!IsRoot(cPrim))
|
if (!IsRoot(cPrim))
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,7 +36,7 @@ public sealed class BSLinksetConstraints : BSLinkset
|
||||||
{
|
{
|
||||||
// private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]";
|
// private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]";
|
||||||
|
|
||||||
public BSLinksetConstraints(BSScene scene, BSPhysObject parent) : base(scene, parent)
|
public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ public sealed class BSLinksetConstraints : BSLinkset
|
||||||
// its internal properties.
|
// its internal properties.
|
||||||
// This is queued in the 'post taint' queue so the
|
// This is queued in the 'post taint' queue so the
|
||||||
// refresh will happen once after all the other taints are applied.
|
// refresh will happen once after all the other taints are applied.
|
||||||
public override void Refresh(BSPhysObject requestor)
|
public override void Refresh(BSPrimLinkable requestor)
|
||||||
{
|
{
|
||||||
base.Refresh(requestor);
|
base.Refresh(requestor);
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ public sealed class BSLinksetConstraints : BSLinkset
|
||||||
// has not yet been fully constructed.
|
// has not yet been fully constructed.
|
||||||
// Return 'true' if any properties updated on the passed object.
|
// Return 'true' if any properties updated on the passed object.
|
||||||
// Called at taint-time!
|
// Called at taint-time!
|
||||||
public override bool MakeDynamic(BSPhysObject child)
|
public override bool MakeDynamic(BSPrimLinkable child)
|
||||||
{
|
{
|
||||||
// What is done for each object in BSPrim is what we want.
|
// What is done for each object in BSPrim is what we want.
|
||||||
return false;
|
return false;
|
||||||
|
@ -76,14 +76,14 @@ public sealed class BSLinksetConstraints : BSLinkset
|
||||||
// This doesn't normally happen -- OpenSim removes the objects from the physical
|
// This doesn't normally happen -- OpenSim removes the objects from the physical
|
||||||
// world if it is a static linkset.
|
// world if it is a static linkset.
|
||||||
// Called at taint-time!
|
// Called at taint-time!
|
||||||
public override bool MakeStatic(BSPhysObject child)
|
public override bool MakeStatic(BSPrimLinkable child)
|
||||||
{
|
{
|
||||||
// What is done for each object in BSPrim is what we want.
|
// What is done for each object in BSPrim is what we want.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called at taint-time!!
|
// Called at taint-time!!
|
||||||
public override void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject pObj)
|
public override void UpdateProperties(UpdatedProperties whichUpdated, BSPrimLinkable pObj)
|
||||||
{
|
{
|
||||||
// Nothing to do for constraints on property updates
|
// Nothing to do for constraints on property updates
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ public sealed class BSLinksetConstraints : BSLinkset
|
||||||
// up to rebuild the constraints before the next simulation step.
|
// up to rebuild the constraints before the next simulation step.
|
||||||
// Returns 'true' of something was actually removed and would need restoring
|
// Returns 'true' of something was actually removed and would need restoring
|
||||||
// Called at taint-time!!
|
// Called at taint-time!!
|
||||||
public override bool RemoveBodyDependencies(BSPrim child)
|
public override bool RemoveBodyDependencies(BSPrimLinkable child)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ public sealed class BSLinksetConstraints : BSLinkset
|
||||||
|
|
||||||
// Add a new child to the linkset.
|
// Add a new child to the linkset.
|
||||||
// Called while LinkActivity is locked.
|
// Called while LinkActivity is locked.
|
||||||
protected override void AddChildToLinkset(BSPhysObject child)
|
protected override void AddChildToLinkset(BSPrimLinkable child)
|
||||||
{
|
{
|
||||||
if (!HasChild(child))
|
if (!HasChild(child))
|
||||||
{
|
{
|
||||||
|
@ -130,12 +130,12 @@ public sealed class BSLinksetConstraints : BSLinkset
|
||||||
|
|
||||||
// Remove the specified child from the linkset.
|
// Remove the specified child from the linkset.
|
||||||
// Safe to call even if the child is not really in my linkset.
|
// Safe to call even if the child is not really in my linkset.
|
||||||
protected override void RemoveChildFromLinkset(BSPhysObject child)
|
protected override void RemoveChildFromLinkset(BSPrimLinkable child)
|
||||||
{
|
{
|
||||||
if (m_children.Remove(child))
|
if (m_children.Remove(child))
|
||||||
{
|
{
|
||||||
BSPhysObject rootx = LinksetRoot; // capture the root and body as of now
|
BSPrimLinkable rootx = LinksetRoot; // capture the root and body as of now
|
||||||
BSPhysObject childx = child;
|
BSPrimLinkable childx = child;
|
||||||
|
|
||||||
DetailLog("{0},BSLinksetConstraints.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}",
|
DetailLog("{0},BSLinksetConstraints.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}",
|
||||||
childx.LocalID,
|
childx.LocalID,
|
||||||
|
@ -159,13 +159,13 @@ public sealed class BSLinksetConstraints : BSLinkset
|
||||||
|
|
||||||
// Create a constraint between me (root of linkset) and the passed prim (the child).
|
// Create a constraint between me (root of linkset) and the passed prim (the child).
|
||||||
// Called at taint time!
|
// Called at taint time!
|
||||||
private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim)
|
private void PhysicallyLinkAChildToRoot(BSPrimLinkable rootPrim, BSPrimLinkable childPrim)
|
||||||
{
|
{
|
||||||
// Don't build the constraint when asked. Put it off until just before the simulation step.
|
// Don't build the constraint when asked. Put it off until just before the simulation step.
|
||||||
Refresh(rootPrim);
|
Refresh(rootPrim);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BSConstraint BuildConstraint(BSPhysObject rootPrim, BSPhysObject childPrim)
|
private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSPrimLinkable childPrim)
|
||||||
{
|
{
|
||||||
// Zero motion for children so they don't interpolate
|
// Zero motion for children so they don't interpolate
|
||||||
childPrim.ZeroMotion(true);
|
childPrim.ZeroMotion(true);
|
||||||
|
@ -239,7 +239,7 @@ public sealed class BSLinksetConstraints : BSLinkset
|
||||||
// The root and child bodies are passed in because we need to remove the constraint between
|
// The root and child bodies are passed in because we need to remove the constraint between
|
||||||
// the bodies that were present at unlink time.
|
// the bodies that were present at unlink time.
|
||||||
// Called at taint time!
|
// Called at taint time!
|
||||||
private bool PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim)
|
private bool PhysicallyUnlinkAChildFromRoot(BSPrimLinkable rootPrim, BSPrimLinkable childPrim)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}",
|
DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}",
|
||||||
|
@ -261,7 +261,7 @@ public sealed class BSLinksetConstraints : BSLinkset
|
||||||
// Remove linkage between myself and any possible children I might have.
|
// Remove linkage between myself and any possible children I might have.
|
||||||
// Returns 'true' of any constraints were destroyed.
|
// Returns 'true' of any constraints were destroyed.
|
||||||
// Called at taint time!
|
// Called at taint time!
|
||||||
private bool PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim)
|
private bool PhysicallyUnlinkAllChildrenFromRoot(BSPrimLinkable rootPrim)
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
|
DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
|
||||||
|
|
||||||
|
@ -281,7 +281,7 @@ public sealed class BSLinksetConstraints : BSLinkset
|
||||||
DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}",
|
DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}",
|
||||||
LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString, linksetMass);
|
LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString, linksetMass);
|
||||||
|
|
||||||
foreach (BSPhysObject child in m_children)
|
foreach (BSPrimLinkable child in m_children)
|
||||||
{
|
{
|
||||||
// A child in the linkset physically shows the mass of the whole linkset.
|
// A child in the linkset physically shows the mass of the whole linkset.
|
||||||
// This allows Bullet to apply enough force on the child to move the whole linkset.
|
// This allows Bullet to apply enough force on the child to move the whole linkset.
|
||||||
|
|
|
@ -87,6 +87,7 @@ public static class BSParam
|
||||||
public static float NumberOfSolverIterations;
|
public static float NumberOfSolverIterations;
|
||||||
public static bool UseSingleSidedMeshes { get { return UseSingleSidedMeshesF != ConfigurationParameters.numericFalse; } }
|
public static bool UseSingleSidedMeshes { get { return UseSingleSidedMeshesF != ConfigurationParameters.numericFalse; } }
|
||||||
public static float UseSingleSidedMeshesF;
|
public static float UseSingleSidedMeshesF;
|
||||||
|
public static float GlobalContactBreakingThreshold;
|
||||||
|
|
||||||
// Avatar parameters
|
// Avatar parameters
|
||||||
public static float AvatarFriction { get; private set; }
|
public static float AvatarFriction { get; private set; }
|
||||||
|
@ -424,7 +425,7 @@ public static class BSParam
|
||||||
(s) => { return AvatarFriction; },
|
(s) => { return AvatarFriction; },
|
||||||
(s,p,l,v) => { AvatarFriction = v; } ),
|
(s,p,l,v) => { AvatarFriction = v; } ),
|
||||||
new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.",
|
new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.",
|
||||||
10.0f,
|
0.95f,
|
||||||
(s,cf,p,v) => { AvatarStandingFriction = cf.GetFloat(p, v); },
|
(s,cf,p,v) => { AvatarStandingFriction = cf.GetFloat(p, v); },
|
||||||
(s) => { return AvatarStandingFriction; },
|
(s) => { return AvatarStandingFriction; },
|
||||||
(s,p,l,v) => { AvatarStandingFriction = v; } ),
|
(s,p,l,v) => { AvatarStandingFriction = v; } ),
|
||||||
|
@ -570,6 +571,11 @@ public static class BSParam
|
||||||
(s,cf,p,v) => { UseSingleSidedMeshesF = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
|
(s,cf,p,v) => { UseSingleSidedMeshesF = BSParam.NumericBool(cf.GetBoolean(p, BSParam.BoolNumeric(v))); },
|
||||||
(s) => { return UseSingleSidedMeshesF; },
|
(s) => { return UseSingleSidedMeshesF; },
|
||||||
(s,p,l,v) => { UseSingleSidedMeshesF = v; s.UnmanagedParams[0].useSingleSidedMeshes = v; } ),
|
(s,p,l,v) => { UseSingleSidedMeshesF = v; s.UnmanagedParams[0].useSingleSidedMeshes = v; } ),
|
||||||
|
new ParameterDefn("GlobalContactBreakingThreshold", "Amount of shape radius before breaking a collision contact (0 says Bullet default (0.2))",
|
||||||
|
0f,
|
||||||
|
(s,cf,p,v) => { GlobalContactBreakingThreshold = cf.GetFloat(p, v); },
|
||||||
|
(s) => { return GlobalContactBreakingThreshold; },
|
||||||
|
(s,p,l,v) => { GlobalContactBreakingThreshold = v; s.UnmanagedParams[0].globalContactBreakingThreshold = v; } ),
|
||||||
|
|
||||||
new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)",
|
new ParameterDefn("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)",
|
||||||
(float)BSLinkset.LinksetImplementation.Compound,
|
(float)BSLinkset.LinksetImplementation.Compound,
|
||||||
|
|
|
@ -86,10 +86,6 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
PhysBody = new BulletBody(localID);
|
PhysBody = new BulletBody(localID);
|
||||||
PhysShape = new BulletShape();
|
PhysShape = new BulletShape();
|
||||||
|
|
||||||
// A linkset of just me
|
|
||||||
Linkset = BSLinkset.Factory(PhysicsScene, this);
|
|
||||||
PositionDisplacement = OMV.Vector3.Zero;
|
|
||||||
|
|
||||||
LastAssetBuildFailed = false;
|
LastAssetBuildFailed = false;
|
||||||
|
|
||||||
// Default material type. Also sets Friction, Restitution and Density.
|
// Default material type. Also sets Friction, Restitution and Density.
|
||||||
|
@ -117,8 +113,6 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
public string PhysObjectName { get; protected set; }
|
public string PhysObjectName { get; protected set; }
|
||||||
public string TypeName { get; protected set; }
|
public string TypeName { get; protected set; }
|
||||||
|
|
||||||
public BSLinkset Linkset { get; set; }
|
|
||||||
public BSLinksetInfo LinksetInfo { get; set; }
|
|
||||||
|
|
||||||
// Return the object mass without calculating it or having side effects
|
// Return the object mass without calculating it or having side effects
|
||||||
public abstract float RawMass { get; }
|
public abstract float RawMass { get; }
|
||||||
|
@ -188,15 +182,6 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
public abstract OMV.Vector3 RawPosition { get; set; }
|
public abstract OMV.Vector3 RawPosition { get; set; }
|
||||||
public abstract OMV.Vector3 ForcePosition { get; set; }
|
public abstract OMV.Vector3 ForcePosition { get; set; }
|
||||||
|
|
||||||
// 'Position' and 'Orientation' is what the simulator thinks the positions of the prim is.
|
|
||||||
// Because Bullet needs the zero coordinate to be the center of mass of the linkset,
|
|
||||||
// sometimes it is necessary to displace the position the physics engine thinks
|
|
||||||
// the position is. PositionDisplacement must be added and removed from the
|
|
||||||
// position as the simulator position is stored and fetched from the physics
|
|
||||||
// engine. Similar to OrientationDisplacement.
|
|
||||||
public virtual OMV.Vector3 PositionDisplacement { get; set; }
|
|
||||||
public virtual OMV.Quaternion OrientationDisplacement { get; set; }
|
|
||||||
|
|
||||||
public abstract OMV.Quaternion RawOrientation { get; set; }
|
public abstract OMV.Quaternion RawOrientation { get; set; }
|
||||||
public abstract OMV.Quaternion ForceOrientation { get; set; }
|
public abstract OMV.Quaternion ForceOrientation { get; set; }
|
||||||
|
|
||||||
|
@ -302,22 +287,16 @@ public abstract class BSPhysObject : PhysicsActor
|
||||||
CollidingObjectStep = PhysicsScene.SimulationStep;
|
CollidingObjectStep = PhysicsScene.SimulationStep;
|
||||||
}
|
}
|
||||||
|
|
||||||
// prims in the same linkset cannot collide with each other
|
|
||||||
if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID))
|
|
||||||
{
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
CollisionAccumulation++;
|
CollisionAccumulation++;
|
||||||
|
|
||||||
// For movement tests, remember if we are colliding with an object that is moving.
|
// For movement tests, remember if we are colliding with an object that is moving.
|
||||||
ColliderIsMoving = collidee != null ? collidee.RawVelocity != OMV.Vector3.Zero : false;
|
ColliderIsMoving = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero) : false;
|
||||||
|
|
||||||
// If someone has subscribed for collision events log the collision so it will be reported up
|
// If someone has subscribed for collision events log the collision so it will be reported up
|
||||||
if (SubscribedEvents()) {
|
if (SubscribedEvents()) {
|
||||||
CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
|
CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
|
||||||
DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5}",
|
DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5},colliderMoving={6}",
|
||||||
LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth);
|
LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth, ColliderIsMoving);
|
||||||
|
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
{
|
{
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public sealed class BSPrim : BSPhysObject
|
public class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
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]";
|
||||||
|
@ -102,9 +102,6 @@ public sealed class BSPrim : BSPhysObject
|
||||||
|
|
||||||
_mass = CalculateMass();
|
_mass = CalculateMass();
|
||||||
|
|
||||||
// Cause linkset variables to be initialized (like mass)
|
|
||||||
Linkset.Refresh(this);
|
|
||||||
|
|
||||||
DetailLog("{0},BSPrim.constructor,call", LocalID);
|
DetailLog("{0},BSPrim.constructor,call", LocalID);
|
||||||
// do the actual object creation at taint time
|
// do the actual object creation at taint time
|
||||||
PhysicsScene.TaintedObject("BSPrim.create", delegate()
|
PhysicsScene.TaintedObject("BSPrim.create", delegate()
|
||||||
|
@ -121,15 +118,6 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID);
|
// m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID);
|
||||||
base.Destroy();
|
base.Destroy();
|
||||||
|
|
||||||
// Undo any links between me and any other object
|
|
||||||
BSPhysObject parentBefore = Linkset.LinksetRoot; // DEBUG DEBUG
|
|
||||||
int childrenBefore = Linkset.NumberOfChildren; // DEBUG DEBUG
|
|
||||||
|
|
||||||
Linkset = Linkset.RemoveMeFromLinkset(this);
|
|
||||||
|
|
||||||
DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}",
|
|
||||||
LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
|
|
||||||
|
|
||||||
// Undo any vehicle properties
|
// Undo any vehicle properties
|
||||||
this.VehicleType = (int)Vehicle.TYPE_NONE;
|
this.VehicleType = (int)Vehicle.TYPE_NONE;
|
||||||
|
|
||||||
|
@ -166,9 +154,9 @@ public sealed class BSPrim : BSPhysObject
|
||||||
ForceBodyShapeRebuild(false);
|
ForceBodyShapeRebuild(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Whatever the linkset wants is what I want.
|
// 'unknown' says to choose the best type
|
||||||
public override BSPhysicsShapeType PreferredPhysicalShape
|
public override BSPhysicsShapeType PreferredPhysicalShape
|
||||||
{ get { return Linkset.PreferredPhysicalShape(this); } }
|
{ get { return BSPhysicsShapeType.SHAPE_UNKNOWN; } }
|
||||||
|
|
||||||
public override bool ForceBodyShapeRebuild(bool inTaintTime)
|
public override bool ForceBodyShapeRebuild(bool inTaintTime)
|
||||||
{
|
{
|
||||||
|
@ -213,33 +201,10 @@ public sealed class BSPrim : BSPhysObject
|
||||||
|
|
||||||
// link me to the specified parent
|
// link me to the specified parent
|
||||||
public override void link(PhysicsActor obj) {
|
public override void link(PhysicsActor obj) {
|
||||||
BSPrim parent = obj as BSPrim;
|
|
||||||
if (parent != null)
|
|
||||||
{
|
|
||||||
BSPhysObject parentBefore = Linkset.LinksetRoot;
|
|
||||||
int childrenBefore = Linkset.NumberOfChildren;
|
|
||||||
|
|
||||||
Linkset = parent.Linkset.AddMeToLinkset(this);
|
|
||||||
|
|
||||||
DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}",
|
|
||||||
LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// delink me from my linkset
|
// delink me from my linkset
|
||||||
public override void delink() {
|
public override void delink() {
|
||||||
// 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
|
|
||||||
|
|
||||||
BSPhysObject parentBefore = Linkset.LinksetRoot;
|
|
||||||
int childrenBefore = Linkset.NumberOfChildren;
|
|
||||||
|
|
||||||
Linkset = Linkset.RemoveMeFromLinkset(this);
|
|
||||||
|
|
||||||
DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",
|
|
||||||
LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set motion values to zero.
|
// Set motion values to zero.
|
||||||
|
@ -287,15 +252,8 @@ public sealed class BSPrim : BSPhysObject
|
||||||
}
|
}
|
||||||
public override OMV.Vector3 Position {
|
public override OMV.Vector3 Position {
|
||||||
get {
|
get {
|
||||||
/* NOTE: this refetch is not necessary. The simulator knows about linkset children
|
|
||||||
* and does not fetch this position info for children. Thus this is commented out.
|
|
||||||
// child prims move around based on their parent. Need to get the latest location
|
|
||||||
if (!Linkset.IsRoot(this))
|
|
||||||
_position = Linkset.PositionGet(this);
|
|
||||||
*/
|
|
||||||
|
|
||||||
// don't do the GetObjectPosition for root elements because this function is called a zillion times.
|
// don't do the GetObjectPosition for root elements because this function is called a zillion times.
|
||||||
// _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody) - PositionDisplacement;
|
// _position = ForcePosition;
|
||||||
return _position;
|
return _position;
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
|
@ -313,24 +271,20 @@ public sealed class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||||
ForcePosition = _position;
|
ForcePosition = _position;
|
||||||
|
|
||||||
// A linkset might need to know if a component information changed.
|
|
||||||
Linkset.UpdateProperties(UpdatedProperties.Position, this);
|
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override OMV.Vector3 ForcePosition {
|
public override OMV.Vector3 ForcePosition {
|
||||||
get {
|
get {
|
||||||
_position = PhysicsScene.PE.GetPosition(PhysBody) - PositionDisplacement;
|
_position = PhysicsScene.PE.GetPosition(PhysBody);
|
||||||
return _position;
|
return _position;
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
_position = value;
|
_position = value;
|
||||||
if (PhysBody.HasPhysicalBody)
|
if (PhysBody.HasPhysicalBody)
|
||||||
{
|
{
|
||||||
PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation);
|
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
|
||||||
ActivateIfPhysical(false);
|
ActivateIfPhysical(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -398,12 +352,13 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// If the simulator cares about the mass of the linkset, it will sum it itself.
|
// If the simulator cares about the mass of the linkset, it will sum it itself.
|
||||||
public override float Mass
|
public override float Mass
|
||||||
{
|
{
|
||||||
get
|
get { return _mass; }
|
||||||
{
|
}
|
||||||
return _mass;
|
// TotalMass returns the mass of the large object the prim may be in (overridden by linkset code)
|
||||||
}
|
public virtual float TotalMass
|
||||||
|
{
|
||||||
|
get { return _mass; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// used when we only want this prim's mass and not the linkset thing
|
// used when we only want this prim's mass and not the linkset thing
|
||||||
public override float RawMass {
|
public override float RawMass {
|
||||||
get { return _mass; }
|
get { return _mass; }
|
||||||
|
@ -467,13 +422,13 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// Is this used?
|
// Is this used?
|
||||||
public override OMV.Vector3 CenterOfMass
|
public override OMV.Vector3 CenterOfMass
|
||||||
{
|
{
|
||||||
get { return Linkset.CenterOfMass; }
|
get { return RawPosition; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is this used?
|
// Is this used?
|
||||||
public override OMV.Vector3 GeometricCenter
|
public override OMV.Vector3 GeometricCenter
|
||||||
{
|
{
|
||||||
get { return Linkset.GeometricCenter; }
|
get { return RawPosition; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override OMV.Vector3 Force {
|
public override OMV.Vector3 Force {
|
||||||
|
@ -721,14 +676,6 @@ public sealed class BSPrim : BSPhysObject
|
||||||
}
|
}
|
||||||
public override OMV.Quaternion Orientation {
|
public override OMV.Quaternion Orientation {
|
||||||
get {
|
get {
|
||||||
/* NOTE: this refetch is not necessary. The simulator knows about linkset children
|
|
||||||
* and does not fetch this position info for children. Thus this is commented out.
|
|
||||||
// Children move around because tied to parent. Get a fresh value.
|
|
||||||
if (!Linkset.IsRoot(this))
|
|
||||||
{
|
|
||||||
_orientation = Linkset.OrientationGet(this);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return _orientation;
|
return _orientation;
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
|
@ -739,10 +686,6 @@ public sealed class BSPrim : BSPhysObject
|
||||||
PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate()
|
PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate()
|
||||||
{
|
{
|
||||||
ForceOrientation = _orientation;
|
ForceOrientation = _orientation;
|
||||||
|
|
||||||
// A linkset might need to know if a component information changed.
|
|
||||||
Linkset.UpdateProperties(UpdatedProperties.Orientation, this);
|
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -758,7 +701,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
{
|
{
|
||||||
_orientation = value;
|
_orientation = value;
|
||||||
if (PhysBody.HasPhysicalBody)
|
if (PhysBody.HasPhysicalBody)
|
||||||
PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation);
|
PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public override int PhysicsActorType {
|
public override int PhysicsActorType {
|
||||||
|
@ -814,7 +757,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// isSolid: other objects bounce off of this object
|
// isSolid: other objects bounce off of this object
|
||||||
// isVolumeDetect: other objects pass through but can generate collisions
|
// isVolumeDetect: other objects pass through but can generate collisions
|
||||||
// collisionEvents: whether this object returns collision events
|
// collisionEvents: whether this object returns collision events
|
||||||
public void UpdatePhysicalParameters()
|
public virtual void UpdatePhysicalParameters()
|
||||||
{
|
{
|
||||||
if (!PhysBody.HasPhysicalBody)
|
if (!PhysBody.HasPhysicalBody)
|
||||||
{
|
{
|
||||||
|
@ -844,12 +787,6 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// Rebuild its shape
|
// Rebuild its shape
|
||||||
PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, PhysBody);
|
PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, PhysBody);
|
||||||
|
|
||||||
// Recompute any linkset parameters.
|
|
||||||
// When going from non-physical to physical, this re-enables the constraints that
|
|
||||||
// had been automatically disabled when the mass was set to zero.
|
|
||||||
// For compound based linksets, this enables and disables interactions of the children.
|
|
||||||
Linkset.Refresh(this);
|
|
||||||
|
|
||||||
DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},cType={6},body={7},shape={8}",
|
DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},cType={6},body={7},shape={8}",
|
||||||
LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody.collisionType, PhysBody, PhysShape);
|
LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody.collisionType, PhysBody, PhysShape);
|
||||||
}
|
}
|
||||||
|
@ -859,7 +796,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// When dynamic, the object can fall and be pushed by others.
|
// When dynamic, the object can fall and be pushed by others.
|
||||||
// This is independent of its 'solidness' which controls what passes through
|
// This is independent of its 'solidness' which controls what passes through
|
||||||
// this object and what interacts with it.
|
// this object and what interacts with it.
|
||||||
private void MakeDynamic(bool makeStatic)
|
protected virtual void MakeDynamic(bool makeStatic)
|
||||||
{
|
{
|
||||||
if (makeStatic)
|
if (makeStatic)
|
||||||
{
|
{
|
||||||
|
@ -889,9 +826,6 @@ public sealed class BSPrim : BSPhysObject
|
||||||
|
|
||||||
// This collides like a static object
|
// This collides like a static object
|
||||||
PhysBody.collisionType = CollisionType.Static;
|
PhysBody.collisionType = CollisionType.Static;
|
||||||
|
|
||||||
// There can be special things needed for implementing linksets
|
|
||||||
Linkset.MakeStatic(this);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -908,10 +842,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// PhysicsScene.PE.ClearAllForces(BSBody);
|
// PhysicsScene.PE.ClearAllForces(BSBody);
|
||||||
|
|
||||||
// For good measure, make sure the transform is set through to the motion state
|
// For good measure, make sure the transform is set through to the motion state
|
||||||
PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation);
|
ForcePosition = _position;
|
||||||
|
|
||||||
// Center of mass is at the center of the object
|
|
||||||
// DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(Linkset.LinksetRoot.PhysBody, _position, _orientation);
|
|
||||||
|
|
||||||
// A dynamic object has mass
|
// A dynamic object has mass
|
||||||
UpdatePhysicalMassProperties(RawMass, false);
|
UpdatePhysicalMassProperties(RawMass, false);
|
||||||
|
@ -935,9 +866,6 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// Force activation of the object so Bullet will act on it.
|
// Force activation of the object so Bullet will act on it.
|
||||||
// Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects.
|
// Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects.
|
||||||
PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG);
|
PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG);
|
||||||
|
|
||||||
// There might be special things needed for implementing linksets.
|
|
||||||
Linkset.MakeDynamic(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1643,16 +1571,6 @@ public sealed class BSPrim : BSPhysObject
|
||||||
|
|
||||||
returnMass = Density * volume;
|
returnMass = Density * volume;
|
||||||
|
|
||||||
/* Comment out code that computes the mass of the linkset. That is done in the Linkset class.
|
|
||||||
if (IsRootOfLinkset)
|
|
||||||
{
|
|
||||||
foreach (BSPrim prim in _childrenPrims)
|
|
||||||
{
|
|
||||||
returnMass += prim.CalculateMass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass);
|
returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass);
|
||||||
|
|
||||||
return returnMass;
|
return returnMass;
|
||||||
|
@ -1672,8 +1590,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// Called if the current prim body is about to be destroyed.
|
// Called if the current prim body is about to be destroyed.
|
||||||
// Remove all the physical dependencies on the old body.
|
// Remove all the physical dependencies on the old body.
|
||||||
// (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...)
|
// (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...)
|
||||||
Linkset.RemoveBodyDependencies(this);
|
RemoveBodyDependencies();
|
||||||
VehicleController.RemoveBodyDependencies(this);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Make sure the properties are set on the new object
|
// Make sure the properties are set on the new object
|
||||||
|
@ -1681,57 +1598,50 @@ public sealed class BSPrim : BSPhysObject
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void RemoveBodyDependencies()
|
||||||
|
{
|
||||||
|
VehicleController.RemoveBodyDependencies(this);
|
||||||
|
}
|
||||||
|
|
||||||
// The physics engine says that properties have updated. Update same and inform
|
// The physics engine says that properties have updated. Update same and inform
|
||||||
// the world that things have changed.
|
// the world that things have changed.
|
||||||
public override void UpdateProperties(EntityProperties entprop)
|
public override void UpdateProperties(EntityProperties entprop)
|
||||||
{
|
{
|
||||||
// Updates only for individual prims and for the root object of a linkset.
|
// A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
|
||||||
if (Linkset.IsRoot(this))
|
// TODO: handle physics introduced by Bullet with computed vehicle physics.
|
||||||
|
if (VehicleController.IsActive)
|
||||||
{
|
{
|
||||||
// A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
|
entprop.RotationalVelocity = OMV.Vector3.Zero;
|
||||||
// TODO: handle physics introduced by Bullet with computed vehicle physics.
|
|
||||||
if (VehicleController.IsActive)
|
|
||||||
{
|
|
||||||
entprop.RotationalVelocity = OMV.Vector3.Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
// DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG
|
|
||||||
|
|
||||||
// Undo any center-of-mass displacement that might have been done.
|
|
||||||
if (PositionDisplacement != OMV.Vector3.Zero)
|
|
||||||
{
|
|
||||||
// Correct for any rotation around the center-of-mass
|
|
||||||
// TODO!!!
|
|
||||||
entprop.Position -= PositionDisplacement;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign directly to the local variables so the normal set actions do not happen
|
|
||||||
_position = entprop.Position;
|
|
||||||
_orientation = entprop.Rotation;
|
|
||||||
_velocity = entprop.Velocity;
|
|
||||||
_acceleration = entprop.Acceleration;
|
|
||||||
_rotationalVelocity = entprop.RotationalVelocity;
|
|
||||||
|
|
||||||
// DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG
|
|
||||||
|
|
||||||
// The sanity check can change the velocity and/or position.
|
|
||||||
if (PositionSanityCheck(true /* inTaintTime */ ))
|
|
||||||
{
|
|
||||||
entprop.Position = _position;
|
|
||||||
entprop.Velocity = _velocity;
|
|
||||||
entprop.RotationalVelocity = _rotationalVelocity;
|
|
||||||
entprop.Acceleration = _acceleration;
|
|
||||||
}
|
|
||||||
|
|
||||||
OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG
|
|
||||||
DetailLog("{0},BSPrim.UpdateProperties,call,entProp={1},dir={2}", LocalID, entprop, direction);
|
|
||||||
|
|
||||||
// remember the current and last set values
|
|
||||||
LastEntityProperties = CurrentEntityProperties;
|
|
||||||
CurrentEntityProperties = entprop;
|
|
||||||
|
|
||||||
base.RequestPhysicsterseUpdate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG
|
||||||
|
|
||||||
|
// Assign directly to the local variables so the normal set actions do not happen
|
||||||
|
_position = entprop.Position;
|
||||||
|
_orientation = entprop.Rotation;
|
||||||
|
_velocity = entprop.Velocity;
|
||||||
|
_acceleration = entprop.Acceleration;
|
||||||
|
_rotationalVelocity = entprop.RotationalVelocity;
|
||||||
|
|
||||||
|
// DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG
|
||||||
|
|
||||||
|
// The sanity check can change the velocity and/or position.
|
||||||
|
if (PositionSanityCheck(true /* inTaintTime */ ))
|
||||||
|
{
|
||||||
|
entprop.Position = _position;
|
||||||
|
entprop.Velocity = _velocity;
|
||||||
|
entprop.RotationalVelocity = _rotationalVelocity;
|
||||||
|
entprop.Acceleration = _acceleration;
|
||||||
|
}
|
||||||
|
|
||||||
|
OMV.Vector3 direction = OMV.Vector3.UnitX * _orientation; // DEBUG DEBUG DEBUG
|
||||||
|
DetailLog("{0},BSPrim.UpdateProperties,call,entProp={1},dir={2}", LocalID, entprop, direction);
|
||||||
|
|
||||||
|
// remember the current and last set values
|
||||||
|
LastEntityProperties = CurrentEntityProperties;
|
||||||
|
CurrentEntityProperties = entprop;
|
||||||
|
|
||||||
|
base.RequestPhysicsterseUpdate();
|
||||||
/*
|
/*
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1741,9 +1651,6 @@ public sealed class BSPrim : BSPhysObject
|
||||||
entprop.Acceleration, entprop.RotationalVelocity);
|
entprop.Acceleration, entprop.RotationalVelocity);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// The linkset implimentation might want to know about this.
|
|
||||||
Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* The quotations from http://wiki.secondlife.com/wiki/Linden_Vehicle_Tutorial
|
||||||
|
* are Copyright (c) 2009 Linden Research, Inc and are used under their license
|
||||||
|
* of Creative Commons Attribution-Share Alike 3.0
|
||||||
|
* (http://creativecommons.org/licenses/by-sa/3.0/).
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Physics.Manager;
|
||||||
|
|
||||||
|
using OMV = OpenMetaverse;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
|
{
|
||||||
|
public class BSPrimDisplaced : BSPrim
|
||||||
|
{
|
||||||
|
// 'Position' and 'Orientation' is what the simulator thinks the positions of the prim is.
|
||||||
|
// Because Bullet needs the zero coordinate to be the center of mass of the linkset,
|
||||||
|
// sometimes it is necessary to displace the position the physics engine thinks
|
||||||
|
// the position is. PositionDisplacement must be added and removed from the
|
||||||
|
// position as the simulator position is stored and fetched from the physics
|
||||||
|
// engine. Similar to OrientationDisplacement.
|
||||||
|
public virtual OMV.Vector3 PositionDisplacement { get; set; }
|
||||||
|
public virtual OMV.Quaternion OrientationDisplacement { get; set; }
|
||||||
|
public virtual OMV.Vector3 CenterOfMassLocation { get; set; }
|
||||||
|
public virtual OMV.Vector3 GeometricCenterLocation { get; set; }
|
||||||
|
|
||||||
|
public BSPrimDisplaced(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
|
||||||
|
OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
|
||||||
|
: base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical)
|
||||||
|
{
|
||||||
|
CenterOfMassLocation = RawPosition;
|
||||||
|
GeometricCenterLocation = RawPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Vector3 ForcePosition
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return base.ForcePosition;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
base.ForcePosition = value;
|
||||||
|
CenterOfMassLocation = RawPosition;
|
||||||
|
GeometricCenterLocation = RawPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Quaternion ForceOrientation
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return base.ForceOrientation;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
base.ForceOrientation = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is this used?
|
||||||
|
public override OMV.Vector3 CenterOfMass
|
||||||
|
{
|
||||||
|
get { return CenterOfMassLocation; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is this used?
|
||||||
|
public override OMV.Vector3 GeometricCenter
|
||||||
|
{
|
||||||
|
get { return GeometricCenterLocation; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override void UpdateProperties(EntityProperties entprop)
|
||||||
|
{
|
||||||
|
// Undo any center-of-mass displacement that might have been done.
|
||||||
|
if (PositionDisplacement != OMV.Vector3.Zero)
|
||||||
|
{
|
||||||
|
// Correct for any rotation around the center-of-mass
|
||||||
|
// TODO!!!
|
||||||
|
entprop.Position -= PositionDisplacement;
|
||||||
|
}
|
||||||
|
|
||||||
|
base.UpdateProperties(entprop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,179 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyrightD
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
using OpenSim.Framework;
|
||||||
|
|
||||||
|
using OMV = OpenMetaverse;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
|
{
|
||||||
|
public class BSPrimLinkable : BSPrimDisplaced
|
||||||
|
{
|
||||||
|
public BSLinkset Linkset { get; set; }
|
||||||
|
public BSLinksetInfo LinksetInfo { get; set; }
|
||||||
|
|
||||||
|
public BSPrimLinkable(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
|
||||||
|
OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
|
||||||
|
: base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical)
|
||||||
|
{
|
||||||
|
Linkset = BSLinkset.Factory(PhysicsScene, this);
|
||||||
|
|
||||||
|
PhysicsScene.TaintedObject("BSPrimLinksetCompound.Refresh", delegate()
|
||||||
|
{
|
||||||
|
Linkset.Refresh(this);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Destroy()
|
||||||
|
{
|
||||||
|
Linkset = Linkset.RemoveMeFromLinkset(this);
|
||||||
|
base.Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override BSPhysicsShapeType PreferredPhysicalShape
|
||||||
|
{ get { return Linkset.PreferredPhysicalShape(this); } }
|
||||||
|
|
||||||
|
public override void link(Manager.PhysicsActor obj)
|
||||||
|
{
|
||||||
|
BSPrimLinkable parent = obj as BSPrimLinkable;
|
||||||
|
if (parent != null)
|
||||||
|
{
|
||||||
|
BSPhysObject parentBefore = Linkset.LinksetRoot;
|
||||||
|
int childrenBefore = Linkset.NumberOfChildren;
|
||||||
|
|
||||||
|
Linkset = parent.Linkset.AddMeToLinkset(this);
|
||||||
|
|
||||||
|
DetailLog("{0},BSPrimLinkset.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}",
|
||||||
|
LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void delink()
|
||||||
|
{
|
||||||
|
// 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
|
||||||
|
|
||||||
|
BSPhysObject parentBefore = Linkset.LinksetRoot;
|
||||||
|
int childrenBefore = Linkset.NumberOfChildren;
|
||||||
|
|
||||||
|
Linkset = Linkset.RemoveMeFromLinkset(this);
|
||||||
|
|
||||||
|
DetailLog("{0},BSPrimLinkset.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",
|
||||||
|
LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
|
||||||
|
return;
|
||||||
|
base.delink();
|
||||||
|
}
|
||||||
|
|
||||||
|
// When simulator changes position, this might be moving a child of the linkset.
|
||||||
|
public override OMV.Vector3 Position
|
||||||
|
{
|
||||||
|
get { return base.Position; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
base.Position = value;
|
||||||
|
PhysicsScene.TaintedObject("BSPrimLinkset.setPosition", delegate()
|
||||||
|
{
|
||||||
|
Linkset.UpdateProperties(UpdatedProperties.Position, this);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// When simulator changes orientation, this might be moving a child of the linkset.
|
||||||
|
public override OMV.Quaternion Orientation
|
||||||
|
{
|
||||||
|
get { return base.Orientation; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
base.Orientation = value;
|
||||||
|
PhysicsScene.TaintedObject("BSPrimLinkset.setOrientation", delegate()
|
||||||
|
{
|
||||||
|
Linkset.UpdateProperties(UpdatedProperties.Orientation, this);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override float TotalMass
|
||||||
|
{
|
||||||
|
get { return Linkset.LinksetMass; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdatePhysicalParameters()
|
||||||
|
{
|
||||||
|
base.UpdatePhysicalParameters();
|
||||||
|
// Recompute any linkset parameters.
|
||||||
|
// When going from non-physical to physical, this re-enables the constraints that
|
||||||
|
// had been automatically disabled when the mass was set to zero.
|
||||||
|
// For compound based linksets, this enables and disables interactions of the children.
|
||||||
|
Linkset.Refresh(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void MakeDynamic(bool makeStatic)
|
||||||
|
{
|
||||||
|
base.MakeDynamic(makeStatic);
|
||||||
|
if (makeStatic)
|
||||||
|
Linkset.MakeStatic(this);
|
||||||
|
else
|
||||||
|
Linkset.MakeDynamic(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Body is being taken apart. Remove physical dependencies and schedule a rebuild.
|
||||||
|
protected override void RemoveBodyDependencies()
|
||||||
|
{
|
||||||
|
Linkset.RemoveBodyDependencies(this);
|
||||||
|
base.RemoveBodyDependencies();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void UpdateProperties(EntityProperties entprop)
|
||||||
|
{
|
||||||
|
if (Linkset.IsRoot(this))
|
||||||
|
{
|
||||||
|
// Properties are only updated for the roots of a linkset.
|
||||||
|
// TODO: this will have to change when linksets are articulated.
|
||||||
|
base.UpdateProperties(entprop);
|
||||||
|
}
|
||||||
|
// The linkset might like to know about changing locations
|
||||||
|
Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Collide(uint collidingWith, BSPhysObject collidee,
|
||||||
|
OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
|
||||||
|
{
|
||||||
|
// prims in the same linkset cannot collide with each other
|
||||||
|
BSPrimLinkable convCollidee = collidee as BSPrimLinkable;
|
||||||
|
if (convCollidee != null && (this.Linkset.LinksetID == convCollidee.Linkset.LinksetID))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return base.Collide(collidingWith, collidee, contactPoint, contactNormal, pentrationDepth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -434,7 +434,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
{
|
{
|
||||||
if (!m_initialized) return;
|
if (!m_initialized) return;
|
||||||
|
|
||||||
BSPrim bsprim = prim as BSPrim;
|
BSPhysObject bsprim = prim as BSPhysObject;
|
||||||
if (bsprim != null)
|
if (bsprim != null)
|
||||||
{
|
{
|
||||||
DetailLog("{0},RemovePrim,call", bsprim.LocalID);
|
DetailLog("{0},RemovePrim,call", bsprim.LocalID);
|
||||||
|
@ -463,9 +463,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
|
|
||||||
if (!m_initialized) return null;
|
if (!m_initialized) return null;
|
||||||
|
|
||||||
DetailLog("{0},AddPrimShape,call", localID);
|
DetailLog("{0},BSScene.AddPrimShape,call", localID);
|
||||||
|
|
||||||
BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical);
|
BSPhysObject prim = new BSPrimLinkable(localID, primName, this, position, size, rotation, pbs, isPhysical);
|
||||||
lock (PhysObjects) PhysObjects.Add(localID, prim);
|
lock (PhysObjects) PhysObjects.Add(localID, prim);
|
||||||
return prim;
|
return prim;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1652,6 +1652,10 @@
|
||||||
[JsonStore]
|
[JsonStore]
|
||||||
Enabled = False
|
Enabled = False
|
||||||
|
|
||||||
|
;; Enable direct access to the SOP dynamic attributes
|
||||||
|
EnableObjectStore = False
|
||||||
|
MaxStringSpace = 0
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;; These are defaults that are overwritten below in [Architecture].
|
;; These are defaults that are overwritten below in [Architecture].
|
||||||
;; These defaults allow OpenSim to work out of the box with
|
;; These defaults allow OpenSim to work out of the box with
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue