Merge branch 'master' into careminster

Conflicts:
	OpenSim/Data/MySQL/MySQLSimulationData.cs
	OpenSim/Data/MySQL/Resources/RegionStore.migrations
avinationmerge
Melanie 2013-02-10 00:17:14 +00:00
commit 069e587841
28 changed files with 798 additions and 304 deletions

View File

@ -351,7 +351,8 @@ IF EXISTS (SELECT UUID FROM prims WHERE UUID = @UUID)
ScriptAccessPin = @ScriptAccessPin, AllowedDrop = @AllowedDrop, DieAtEdge = @DieAtEdge, SalePrice = @SalePrice, ScriptAccessPin = @ScriptAccessPin, AllowedDrop = @AllowedDrop, DieAtEdge = @DieAtEdge, SalePrice = @SalePrice,
SaleType = @SaleType, ColorR = @ColorR, ColorG = @ColorG, ColorB = @ColorB, ColorA = @ColorA, ParticleSystem = @ParticleSystem, SaleType = @SaleType, ColorR = @ColorR, ColorG = @ColorG, ColorB = @ColorB, ColorA = @ColorA, ParticleSystem = @ParticleSystem,
ClickAction = @ClickAction, Material = @Material, CollisionSound = @CollisionSound, CollisionSoundVolume = @CollisionSoundVolume, PassTouches = @PassTouches, ClickAction = @ClickAction, Material = @Material, CollisionSound = @CollisionSound, CollisionSoundVolume = @CollisionSoundVolume, PassTouches = @PassTouches,
LinkNumber = @LinkNumber, MediaURL = @MediaURL, DynAttrs = @DynAttrs LinkNumber = @LinkNumber, MediaURL = @MediaURL, DynAttrs = @DynAttrs,
PhysicsShapeType = @PhysicsShapeType, Density = @Density, GravityModifier = @GravityModifier, Friction = @Friction, Restitution = @Restitution
WHERE UUID = @UUID WHERE UUID = @UUID
END END
ELSE ELSE
@ -366,7 +367,8 @@ ELSE
PayPrice, PayButton1, PayButton2, PayButton3, PayButton4, LoopedSound, LoopedSoundGain, TextureAnimation, OmegaX, PayPrice, PayButton1, PayButton2, PayButton3, PayButton4, LoopedSound, LoopedSoundGain, TextureAnimation, OmegaX,
OmegaY, OmegaZ, CameraEyeOffsetX, CameraEyeOffsetY, CameraEyeOffsetZ, CameraAtOffsetX, CameraAtOffsetY, CameraAtOffsetZ, OmegaY, OmegaZ, CameraEyeOffsetX, CameraEyeOffsetY, CameraEyeOffsetZ, CameraAtOffsetX, CameraAtOffsetY, CameraAtOffsetZ,
ForceMouselook, ScriptAccessPin, AllowedDrop, DieAtEdge, SalePrice, SaleType, ColorR, ColorG, ColorB, ColorA, ForceMouselook, ScriptAccessPin, AllowedDrop, DieAtEdge, SalePrice, SaleType, ColorR, ColorG, ColorB, ColorA,
ParticleSystem, ClickAction, Material, CollisionSound, CollisionSoundVolume, PassTouches, LinkNumber, MediaURL, DynAttrs ParticleSystem, ClickAction, Material, CollisionSound, CollisionSoundVolume, PassTouches, LinkNumber, MediaURL, DynAttrs,
PhysicsShapeType, Density, GravityModifier, Friction, Restitution
) VALUES ( ) VALUES (
@UUID, @CreationDate, @Name, @Text, @Description, @SitName, @TouchName, @ObjectFlags, @OwnerMask, @NextOwnerMask, @GroupMask, @UUID, @CreationDate, @Name, @Text, @Description, @SitName, @TouchName, @ObjectFlags, @OwnerMask, @NextOwnerMask, @GroupMask,
@EveryoneMask, @BaseMask, @PositionX, @PositionY, @PositionZ, @GroupPositionX, @GroupPositionY, @GroupPositionZ, @VelocityX, @EveryoneMask, @BaseMask, @PositionX, @PositionY, @PositionZ, @GroupPositionX, @GroupPositionY, @GroupPositionZ, @VelocityX,
@ -376,7 +378,8 @@ ELSE
@PayPrice, @PayButton1, @PayButton2, @PayButton3, @PayButton4, @LoopedSound, @LoopedSoundGain, @TextureAnimation, @OmegaX, @PayPrice, @PayButton1, @PayButton2, @PayButton3, @PayButton4, @LoopedSound, @LoopedSoundGain, @TextureAnimation, @OmegaX,
@OmegaY, @OmegaZ, @CameraEyeOffsetX, @CameraEyeOffsetY, @CameraEyeOffsetZ, @CameraAtOffsetX, @CameraAtOffsetY, @CameraAtOffsetZ, @OmegaY, @OmegaZ, @CameraEyeOffsetX, @CameraEyeOffsetY, @CameraEyeOffsetZ, @CameraAtOffsetX, @CameraAtOffsetY, @CameraAtOffsetZ,
@ForceMouselook, @ScriptAccessPin, @AllowedDrop, @DieAtEdge, @SalePrice, @SaleType, @ColorR, @ColorG, @ColorB, @ColorA, @ForceMouselook, @ScriptAccessPin, @AllowedDrop, @DieAtEdge, @SalePrice, @SaleType, @ColorR, @ColorG, @ColorB, @ColorA,
@ParticleSystem, @ClickAction, @Material, @CollisionSound, @CollisionSoundVolume, @PassTouches, @LinkNumber, @MediaURL, @DynAttrs @ParticleSystem, @ClickAction, @Material, @CollisionSound, @CollisionSoundVolume, @PassTouches, @LinkNumber, @MediaURL, @DynAttrs,
@PhysicsShapeType, @Density, @GravityModifier, @Friction, @Restitution
) )
END"; END";
@ -1697,6 +1700,12 @@ VALUES
else else
prim.DynAttrs = new DAMap(); prim.DynAttrs = new DAMap();
prim.PhysicsShapeType = Convert.ToByte(primRow["PhysicsShapeType"]);
prim.Density = Convert.ToSingle(primRow["Density"]);
prim.GravityModifier = Convert.ToSingle(primRow["GravityModifier"]);
prim.Friction = Convert.ToSingle(primRow["Friction"]);
prim.Restitution = Convert.ToSingle(primRow["Restitution"]);
return prim; return prim;
} }
@ -2095,6 +2104,12 @@ VALUES
parameters.Add(_Database.CreateParameter("DynAttrs", prim.DynAttrs.ToXml())); parameters.Add(_Database.CreateParameter("DynAttrs", prim.DynAttrs.ToXml()));
else else
parameters.Add(_Database.CreateParameter("DynAttrs", null)); parameters.Add(_Database.CreateParameter("DynAttrs", null));
parameters.Add(_Database.CreateParameter("PhysicsShapeType", prim.PhysicsShapeType));
parameters.Add(_Database.CreateParameter("Density", (double)prim.Density));
parameters.Add(_Database.CreateParameter("GravityModifier", (double)prim.GravityModifier));
parameters.Add(_Database.CreateParameter("Friction", (double)prim.Friction));
parameters.Add(_Database.CreateParameter("Restitution", (double)prim.Restitution));
return parameters.ToArray(); return parameters.ToArray();
} }

View File

@ -1156,3 +1156,15 @@ BEGIN TRANSACTION
ALTER TABLE prims ADD COLUMN DynAttrs TEXT; ALTER TABLE prims ADD COLUMN DynAttrs TEXT;
COMMIT COMMIT
:VERSION 39 #---------------- Extra physics params
BEGIN TRANSACTION
ALTER TABLE prims ADD COLUMN `PhysicsShapeType` tinyint(4) NOT NULL default '0';
ALTER TABLE prims ADD COLUMN `Density` double NOT NULL default '1000';
ALTER TABLE prims ADD COLUMN `GravityModifier` double NOT NULL default '1';
ALTER TABLE prims ADD COLUMN `Friction` double NOT NULL default '0.6';
ALTER TABLE prims ADD COLUMN `Restitution` double NOT NULL default '0.5';
COMMIT

View File

@ -1727,12 +1727,6 @@ namespace OpenSim.Data.MySQL
else else
cmd.Parameters.AddWithValue("KeyframeMotion", new Byte[0]); cmd.Parameters.AddWithValue("KeyframeMotion", new Byte[0]);
cmd.Parameters.AddWithValue("PhysicsShapeType", prim.PhysicsShapeType);
cmd.Parameters.AddWithValue("Density", (double)prim.Density);
cmd.Parameters.AddWithValue("GravityModifier", (double)prim.GravityModifier);
cmd.Parameters.AddWithValue("Friction", (double)prim.Friction);
cmd.Parameters.AddWithValue("Restitution", (double)prim.Restitution);
if (prim.VehicleParams != null) if (prim.VehicleParams != null)
cmd.Parameters.AddWithValue("Vehicle", prim.VehicleParams.ToXml2()); cmd.Parameters.AddWithValue("Vehicle", prim.VehicleParams.ToXml2());
else else
@ -1742,6 +1736,12 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("DynAttrs", prim.DynAttrs.ToXml()); cmd.Parameters.AddWithValue("DynAttrs", prim.DynAttrs.ToXml());
else else
cmd.Parameters.AddWithValue("DynAttrs", null); cmd.Parameters.AddWithValue("DynAttrs", null);
cmd.Parameters.AddWithValue("PhysicsShapeType", prim.PhysicsShapeType);
cmd.Parameters.AddWithValue("Density", (double)prim.Density);
cmd.Parameters.AddWithValue("GravityModifier", (double)prim.GravityModifier);
cmd.Parameters.AddWithValue("Friction", (double)prim.Friction);
cmd.Parameters.AddWithValue("Restitution", (double)prim.Restitution);
} }
/// <summary> /// <summary>

View File

@ -910,3 +910,15 @@ BEGIN;
ALTER TABLE prims ADD COLUMN DynAttrs TEXT; ALTER TABLE prims ADD COLUMN DynAttrs TEXT;
COMMIT; COMMIT;
:VERSION 47 #---------------- Extra physics params
BEGIN;
ALTER TABLE prims ADD COLUMN `PhysicsShapeType` tinyint(4) NOT NULL default '0';
ALTER TABLE prims ADD COLUMN `Density` double NOT NULL default '1000';
ALTER TABLE prims ADD COLUMN `GravityModifier` double NOT NULL default '1';
ALTER TABLE prims ADD COLUMN `Friction` double NOT NULL default '0.6';
ALTER TABLE prims ADD COLUMN `Restitution` double NOT NULL default '0.5';
COMMIT;

View File

@ -580,3 +580,15 @@ COMMIT;
BEGIN; BEGIN;
ALTER TABLE prims ADD COLUMN DynAttrs TEXT; ALTER TABLE prims ADD COLUMN DynAttrs TEXT;
COMMIT; COMMIT;
:VERSION 28
BEGIN;
ALTER TABLE prims ADD COLUMN `PhysicsShapeType` tinyint(4) NOT NULL default '0';
ALTER TABLE prims ADD COLUMN `Density` double NOT NULL default '1000';
ALTER TABLE prims ADD COLUMN `GravityModifier` double NOT NULL default '1';
ALTER TABLE prims ADD COLUMN `Friction` double NOT NULL default '0.6';
ALTER TABLE prims ADD COLUMN `Restitution` double NOT NULL default '0.5';
COMMIT;

View File

@ -1235,6 +1235,12 @@ namespace OpenSim.Data.SQLite
createCol(prims, "DynAttrs", typeof(String)); createCol(prims, "DynAttrs", typeof(String));
createCol(prims, "PhysicsShapeType", typeof(Byte));
createCol(prims, "Density", typeof(Double));
createCol(prims, "GravityModifier", typeof(Double));
createCol(prims, "Friction", typeof(Double));
createCol(prims, "Restitution", typeof(Double));
// Add in contraints // Add in contraints
prims.PrimaryKey = new DataColumn[] { prims.Columns["UUID"] }; prims.PrimaryKey = new DataColumn[] { prims.Columns["UUID"] };
@ -1724,6 +1730,12 @@ namespace OpenSim.Data.SQLite
prim.DynAttrs = new DAMap(); prim.DynAttrs = new DAMap();
} }
prim.PhysicsShapeType = Convert.ToByte(row["PhysicsShapeType"]);
prim.Density = Convert.ToSingle(row["Density"]);
prim.GravityModifier = Convert.ToSingle(row["GravityModifier"]);
prim.Friction = Convert.ToSingle(row["Friction"]);
prim.Restitution = Convert.ToSingle(row["Restitution"]);
return prim; return prim;
} }
@ -2150,6 +2162,12 @@ namespace OpenSim.Data.SQLite
row["DynAttrs"] = prim.DynAttrs.ToXml(); row["DynAttrs"] = prim.DynAttrs.ToXml();
else else
row["DynAttrs"] = null; row["DynAttrs"] = null;
row["PhysicsShapeType"] = prim.PhysicsShapeType;
row["Density"] = (double)prim.Density;
row["GravityModifier"] = (double)prim.GravityModifier;
row["Friction"] = (double)prim.Friction;
row["Restitution"] = (double)prim.Restitution;
} }
/// <summary> /// <summary>

View File

@ -622,6 +622,8 @@ namespace OpenSim.Framework
} }
} }
// This is only used at runtime. For sculpties this holds the texture data, and for meshes
// the mesh data.
public byte[] SculptData public byte[] SculptData
{ {
get get
@ -1175,14 +1177,13 @@ namespace OpenSim.Framework
public void ReadSculptData(byte[] data, int pos) public void ReadSculptData(byte[] data, int pos)
{ {
byte[] SculptTextureUUID = new byte[16]; UUID SculptUUID;
UUID SculptUUID = UUID.Zero; byte SculptTypel;
byte SculptTypel = data[16+pos];
if (data.Length+pos >= 17) if (data.Length-pos >= 17)
{ {
_sculptEntry = true; _sculptEntry = true;
SculptTextureUUID = new byte[16]; byte[] SculptTextureUUID = new byte[16];
SculptTypel = data[16 + pos]; SculptTypel = data[16 + pos];
Array.Copy(data, pos, SculptTextureUUID,0, 16); Array.Copy(data, pos, SculptTextureUUID,0, 16);
SculptUUID = new UUID(SculptTextureUUID, 0); SculptUUID = new UUID(SculptTextureUUID, 0);

View File

@ -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)
{
}
}
}

View File

@ -81,7 +81,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
protected static Regex m_ParsePassFour = new Regex("\\.+"); protected static Regex m_ParsePassFour = new Regex("\\.+");
// expression used to validate the full path, this is canonical representation // expression used to validate the full path, this is canonical representation
protected static Regex m_ValidatePath = new Regex("^\\.(({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])\\.)+$"); protected static Regex m_ValidatePath = new Regex("^\\.(({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])\\.)*$");
// expression used to match path components // expression used to match path components
protected static Regex m_PathComponent = new Regex("\\.({[^}]+}|\\[[0-9]+\\]|\\[\\+\\]+)"); protected static Regex m_PathComponent = new Regex("\\.({[^}]+}|\\[[0-9]+\\]|\\[\\+\\]+)");
@ -107,9 +107,17 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
/// ///
/// </summary> /// </summary>
// ----------------------------------------------------------------- // -----------------------------------------------------------------
public static string CanonicalPathExpression(string path) public static bool CanonicalPathExpression(string ipath, out string opath)
{ {
return PathExpressionToKey(ParsePathExpression(path)); Stack<string> path;
if (! ParsePathExpression(ipath,out path))
{
opath = "";
return false;
}
opath = PathExpressionToKey(path);
return true;
} }
// ----------------------------------------------------------------- // -----------------------------------------------------------------
@ -139,13 +147,16 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
// ----------------------------------------------------------------- // -----------------------------------------------------------------
public bool TestPath(string expr, bool useJson) public bool TestPath(string expr, bool useJson)
{ {
Stack<string> path = ParsePathExpression(expr); Stack<string> path;
if (! ParsePathExpression(expr,out path))
return false;
OSD result = ProcessPathExpression(ValueStore,path); OSD result = ProcessPathExpression(ValueStore,path);
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;
@ -158,7 +169,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
// ----------------------------------------------------------------- // -----------------------------------------------------------------
public bool GetValue(string expr, out string value, bool useJson) public bool GetValue(string expr, out string value, bool useJson)
{ {
Stack<string> path = ParsePathExpression(expr); Stack<string> path;
if (! ParsePathExpression(expr,out path))
{
value = "";
return false;
}
OSD result = ProcessPathExpression(ValueStore,path); OSD result = ProcessPathExpression(ValueStore,path);
return ConvertOutputValue(result,out value,useJson); return ConvertOutputValue(result,out value,useJson);
} }
@ -192,7 +209,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
// ----------------------------------------------------------------- // -----------------------------------------------------------------
public bool TakeValue(string expr, bool useJson, TakeValueCallback cback) public bool TakeValue(string expr, bool useJson, TakeValueCallback cback)
{ {
Stack<string> path = ParsePathExpression(expr); Stack<string> path;
if (! ParsePathExpression(expr,out path))
return false;
string pexpr = PathExpressionToKey(path); string pexpr = PathExpressionToKey(path);
OSD result = ProcessPathExpression(ValueStore,path); OSD result = ProcessPathExpression(ValueStore,path);
@ -223,7 +243,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
// ----------------------------------------------------------------- // -----------------------------------------------------------------
public bool ReadValue(string expr, bool useJson, TakeValueCallback cback) public bool ReadValue(string expr, bool useJson, TakeValueCallback cback)
{ {
Stack<string> path = ParsePathExpression(expr); Stack<string> path;
if (! ParsePathExpression(expr,out path))
return false;
string pexpr = PathExpressionToKey(path); string pexpr = PathExpressionToKey(path);
OSD result = ProcessPathExpression(ValueStore,path); OSD result = ProcessPathExpression(ValueStore,path);
@ -253,7 +276,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
// ----------------------------------------------------------------- // -----------------------------------------------------------------
protected bool SetValueFromExpression(string expr, OSD ovalue) protected bool SetValueFromExpression(string expr, OSD ovalue)
{ {
Stack<string> path = ParsePathExpression(expr); Stack<string> path;
if (! ParsePathExpression(expr,out path))
return false;
if (path.Count == 0) if (path.Count == 0)
{ {
ValueStore = ovalue; ValueStore = ovalue;
@ -399,34 +425,36 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
/// use a stack because we process the path in inverse order later /// use a stack because we process the path in inverse order later
/// </summary> /// </summary>
// ----------------------------------------------------------------- // -----------------------------------------------------------------
protected static Stack<string> ParsePathExpression(string path) protected static bool ParsePathExpression(string expr, out Stack<string> path)
{ {
Stack<string> m_path = new Stack<string>(); path = new Stack<string>();
// add front and rear separators // add front and rear separators
path = "." + path + "."; expr = "." + expr + ".";
// add separators for quoted paths // add separators for quoted exprs
path = m_ParsePassOne.Replace(path,".$0.",-1,0); expr = m_ParsePassOne.Replace(expr,".$0.",-1,0);
// add separators for array references // add separators for array references
path = m_ParsePassTwo.Replace(path,".$0.",-1,0); expr = m_ParsePassTwo.Replace(expr,".$0.",-1,0);
// add quotes to bare identifier // add quotes to bare identifier
path = m_ParsePassThree.Replace(path,".{$1}",-1,0); expr = m_ParsePassThree.Replace(expr,".{$1}",-1,0);
// remove extra separators // remove extra separators
path = m_ParsePassFour.Replace(path,".",-1,0); expr = m_ParsePassFour.Replace(expr,".",-1,0);
// validate the results (catches extra quote characters for example) // validate the results (catches extra quote characters for example)
if (m_ValidatePath.IsMatch(path)) if (m_ValidatePath.IsMatch(expr))
{ {
MatchCollection matches = m_PathComponent.Matches(path,0); MatchCollection matches = m_PathComponent.Matches(expr,0);
foreach (Match match in matches) foreach (Match match in matches)
m_path.Push(match.Groups[1].Value); path.Push(match.Groups[1].Value);
return true;
} }
return m_path; return false;
} }
// ----------------------------------------------------------------- // -----------------------------------------------------------------
@ -531,7 +559,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;
@ -557,6 +585,33 @@ 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>
/// ///

View File

@ -301,7 +301,16 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
[ScriptInvocation] [ScriptInvocation]
public string JsonList2Path(UUID hostID, UUID scriptID, object[] pathlist) public string JsonList2Path(UUID hostID, UUID scriptID, object[] pathlist)
{ {
return JsonStore.CanonicalPathExpression(ConvertList2Path(pathlist)); string ipath = ConvertList2Path(pathlist);
string opath;
if (JsonStore.CanonicalPathExpression(ipath,out opath))
return opath;
// This won't parse if passed to the other routines as opposed to
// returning an empty string which is a valid path and would overwrite
// the entire store
return "**INVALID**";
} }
// ----------------------------------------------------------------- // -----------------------------------------------------------------
@ -421,6 +430,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
// ----------------------------------------------------------------- // -----------------------------------------------------------------
protected void GenerateRuntimeError(string msg) protected void GenerateRuntimeError(string msg)
{ {
m_log.InfoFormat("[JsonStore] runtime error: {0}",msg);
throw new Exception("JsonStore Runtime Error: " + msg); throw new Exception("JsonStore Runtime Error: " + msg);
} }

View File

@ -144,8 +144,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
int dsrv = (int)InvokeOp("JsonDestroyStore", fakeStoreId); int dsrv = (int)InvokeOp("JsonDestroyStore", fakeStoreId);
// XXX: Current returns 'true' even though no such store existed. Need to ask if this is best behaviour. Assert.That(dsrv, Is.EqualTo(0));
Assert.That(dsrv, Is.EqualTo(1));
} }
[Test] [Test]
@ -211,9 +210,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore.Tests
// Test remove of non-existing value // Test remove of non-existing value
int fakeValueRemove = (int)InvokeOp("JsonRemoveValue", storeId, "Hello"); int fakeValueRemove = (int)InvokeOp("JsonRemoveValue", storeId, "Hello");
Assert.That(fakeValueRemove, Is.EqualTo(0));
// XXX: Is this the best response to removing a value that isn't there?
Assert.That(fakeValueRemove, Is.EqualTo(1));
// Test get from non-existing store // Test get from non-existing store
UUID fakeStoreId = TestHelpers.ParseTail(0x500); UUID fakeStoreId = TestHelpers.ParseTail(0x500);

View File

@ -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;

View File

@ -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();

View File

@ -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);

View File

@ -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;
} }

View File

@ -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))
{ {

View File

@ -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.

View File

@ -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,

View File

@ -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;
} }

View File

@ -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);
} }
} }
} }

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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;
} }

View File

@ -162,7 +162,7 @@ namespace OpenSim.Services.Connectors
if (replyData != null) if (replyData != null)
{ {
if (replyData.ContainsKey("result") && replyData.ContainsKey("result").ToString() == "null") if (replyData.ContainsKey("result") && replyData["result"].ToString() == "null")
{ {
return accounts; return accounts;
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.