BulletSim: unify physical objects under BSPhysObjects. Now BSScene and BSLinkset only know of BSPhysObject's and there is only one list to search in BSScene.

integration
Robert Adams 2012-08-24 12:58:42 -07:00
parent 0376b8ddbc
commit 7b6987ce83
5 changed files with 200 additions and 160 deletions

View File

@ -34,7 +34,7 @@ using OpenSim.Region.Physics.Manager;
namespace OpenSim.Region.Physics.BulletSPlugin namespace OpenSim.Region.Physics.BulletSPlugin
{ {
public class BSCharacter : PhysicsActor public class BSCharacter : 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 CHAR]"; private static readonly string LogHeader = "[BULLETS CHAR]";
@ -74,11 +74,8 @@ public class BSCharacter : PhysicsActor
private bool _kinematic; private bool _kinematic;
private float _buoyancy; private float _buoyancy;
private BulletBody m_body; public override BulletBody Body { get; set; }
public BulletBody Body { public override BSLinkset Linkset { get; set; }
get { return m_body; }
set { m_body = value; }
}
private int _subscribedEventsMs = 0; private int _subscribedEventsMs = 0;
private int _nextCollisionOkTime = 0; private int _nextCollisionOkTime = 0;
@ -108,6 +105,8 @@ public class BSCharacter : PhysicsActor
_density = _scene.Params.avatarDensity; _density = _scene.Params.avatarDensity;
ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale
Linkset = new BSLinkset(_scene, this);
ShapeData shapeData = new ShapeData(); ShapeData shapeData = new ShapeData();
shapeData.ID = _localID; shapeData.ID = _localID;
shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR; shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR;
@ -130,7 +129,7 @@ public class BSCharacter : PhysicsActor
// Set the buoyancy for flying. This will be refactored when all the settings happen in C# // Set the buoyancy for flying. This will be refactored when all the settings happen in C#
BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy); BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy);
m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); Body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
// avatars get all collisions no matter what (makes walking on ground and such work) // avatars get all collisions no matter what (makes walking on ground and such work)
BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
}); });
@ -139,7 +138,7 @@ public class BSCharacter : PhysicsActor
} }
// called when this character is being destroyed and the resources should be released // called when this character is being destroyed and the resources should be released
public void Destroy() public override void Destroy()
{ {
DetailLog("{0},BSCharacter.Destroy", LocalID); DetailLog("{0},BSCharacter.Destroy", LocalID);
_scene.TaintedObject("BSCharacter.destroy", delegate() _scene.TaintedObject("BSCharacter.destroy", delegate()
@ -245,6 +244,10 @@ public class BSCharacter : PhysicsActor
return _mass; return _mass;
} }
} }
// used when we only want this prim's mass and not the linkset thing
public override float MassRaw { get {return _mass; } }
public override Vector3 Force { public override Vector3 Force {
get { return _force; } get { return _force; }
set { set {
@ -448,6 +451,12 @@ public class BSCharacter : PhysicsActor
}); });
} }
} }
public override void ZeroMotion()
{
return;
}
// Stop collision events // Stop collision events
public override void UnSubscribeEvents() { public override void UnSubscribeEvents() {
_subscribedEventsMs = 0; _subscribedEventsMs = 0;
@ -481,7 +490,7 @@ public class BSCharacter : PhysicsActor
// 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 void UpdateProperties(EntityProperties entprop) public override void UpdateProperties(EntityProperties entprop)
{ {
_position = entprop.Position; _position = entprop.Position;
_orientation = entprop.Rotation; _orientation = entprop.Rotation;
@ -500,7 +509,7 @@ public class BSCharacter : PhysicsActor
// The collision, if it should be reported to the character, is placed in a collection // The collision, if it should be reported to the character, is placed in a collection
// that will later be sent to the simulator when SendCollisions() is called. // that will later be sent to the simulator when SendCollisions() is called.
CollisionEventUpdate collisionCollection = null; CollisionEventUpdate collisionCollection = null;
public void Collide(uint collidingWith, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth) public override void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
{ {
// m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
@ -525,7 +534,7 @@ public class BSCharacter : PhysicsActor
} }
} }
public void SendCollisions() public override void SendCollisions()
{ {
/* /*
if (collisionCollection != null && collisionCollection.Count > 0) if (collisionCollection != null && collisionCollection.Count > 0)

View File

@ -36,8 +36,8 @@ public class BSLinkset
{ {
private static string LogHeader = "[BULLETSIM LINKSET]"; private static string LogHeader = "[BULLETSIM LINKSET]";
private BSPrim m_linksetRoot; private BSPhysObject m_linksetRoot;
public BSPrim LinksetRoot { get { return m_linksetRoot; } } public BSPhysObject LinksetRoot { get { return m_linksetRoot; } }
private BSScene m_physicsScene; private BSScene m_physicsScene;
public BSScene PhysicsScene { get { return m_physicsScene; } } public BSScene PhysicsScene { get { return m_physicsScene; } }
@ -46,7 +46,7 @@ public 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
private List<BSPrim> m_children; private List<BSPhysObject> 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
@ -74,7 +74,7 @@ public class BSLinkset
get { return ComputeLinksetGeometricCenter(); } get { return ComputeLinksetGeometricCenter(); }
} }
public BSLinkset(BSScene scene, BSPrim parent) public BSLinkset(BSScene scene, BSPhysObject parent)
{ {
// A simple linkset of one (no children) // A simple linkset of one (no children)
LinksetID = m_nextLinksetID++; LinksetID = m_nextLinksetID++;
@ -83,14 +83,14 @@ public class BSLinkset
m_nextLinksetID = 1; m_nextLinksetID = 1;
m_physicsScene = scene; m_physicsScene = scene;
m_linksetRoot = parent; m_linksetRoot = parent;
m_children = new List<BSPrim>(); m_children = new List<BSPhysObject>();
m_mass = parent.MassRaw; m_mass = parent.MassRaw;
} }
// Link to a linkset where the child knows the parent. // Link to a linkset where the child knows the parent.
// 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.
public BSLinkset AddMeToLinkset(BSPrim child) public BSLinkset AddMeToLinkset(BSPhysObject child)
{ {
lock (m_linksetActivityLock) lock (m_linksetActivityLock)
{ {
@ -102,7 +102,7 @@ public class BSLinkset
// Remove a child from a linkset. // Remove a child from a linkset.
// 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).
public BSLinkset RemoveMeFromLinkset(BSPrim child) public BSLinkset RemoveMeFromLinkset(BSPhysObject child)
{ {
lock (m_linksetActivityLock) lock (m_linksetActivityLock)
{ {
@ -129,7 +129,7 @@ public class BSLinkset
} }
// 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(BSPrim requestor) public bool IsRoot(BSPhysObject requestor)
{ {
return (requestor.LocalID == m_linksetRoot.LocalID); return (requestor.LocalID == m_linksetRoot.LocalID);
} }
@ -140,12 +140,12 @@ public 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(BSPrim child) public bool HasChild(BSPhysObject child)
{ {
bool ret = false; bool ret = false;
lock (m_linksetActivityLock) lock (m_linksetActivityLock)
{ {
foreach (BSPrim bp in m_children) foreach (BSPhysObject bp in m_children)
{ {
if (child.LocalID == bp.LocalID) if (child.LocalID == bp.LocalID)
{ {
@ -160,7 +160,7 @@ public class BSLinkset
private float ComputeLinksetMass() private float ComputeLinksetMass()
{ {
float mass = m_linksetRoot.MassRaw; float mass = m_linksetRoot.MassRaw;
foreach (BSPrim bp in m_children) foreach (BSPhysObject bp in m_children)
{ {
mass += bp.MassRaw; mass += bp.MassRaw;
} }
@ -174,7 +174,7 @@ public class BSLinkset
lock (m_linksetActivityLock) lock (m_linksetActivityLock)
{ {
foreach (BSPrim bp in m_children) foreach (BSPhysObject bp in m_children)
{ {
com += bp.Position * bp.MassRaw; com += bp.Position * bp.MassRaw;
totalMass += bp.MassRaw; totalMass += bp.MassRaw;
@ -192,7 +192,7 @@ public class BSLinkset
lock (m_linksetActivityLock) lock (m_linksetActivityLock)
{ {
foreach (BSPrim bp in m_children) foreach (BSPhysObject bp in m_children)
{ {
com += bp.Position * bp.MassRaw; com += bp.Position * bp.MassRaw;
} }
@ -204,7 +204,7 @@ public class 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 void Refresh(BSPrim requestor) public void Refresh(BSPhysObject requestor)
{ {
// If there are no children, there aren't any constraints to recompute // If there are no children, there aren't any constraints to recompute
if (!HasAnyChildren) if (!HasAnyChildren)
@ -230,7 +230,7 @@ public class BSLinkset
float linksetMass = LinksetMass; float linksetMass = LinksetMass;
lock (m_linksetActivityLock) lock (m_linksetActivityLock)
{ {
foreach (BSPrim child in m_children) foreach (BSPhysObject child in m_children)
{ {
BSConstraint constrain; BSConstraint constrain;
if (m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.Body, child.Body, out constrain)) if (m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.Body, child.Body, out constrain))
@ -255,14 +255,14 @@ public 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.
private void AddChildToLinkset(BSPrim child) private void AddChildToLinkset(BSPhysObject child)
{ {
if (!HasChild(child)) if (!HasChild(child))
{ {
m_children.Add(child); m_children.Add(child);
BSPrim rootx = LinksetRoot; // capture the root as of now BSPhysObject rootx = LinksetRoot; // capture the root as of now
BSPrim childx = child; BSPhysObject childx = child;
m_physicsScene.TaintedObject("AddChildToLinkset", delegate() m_physicsScene.TaintedObject("AddChildToLinkset", delegate()
{ {
DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID); DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
@ -277,7 +277,7 @@ public class BSLinkset
// it's still connected to the linkset. // it's still connected to the linkset.
// Normal OpenSimulator operation will never do this because other SceneObjectPart information // Normal OpenSimulator operation will never do this because other SceneObjectPart information
// has to be updated also (like pointer to prim's parent). // has to be updated also (like pointer to prim's parent).
private void RemoveChildFromOtherLinkset(BSPrim pchild) private void RemoveChildFromOtherLinkset(BSPhysObject pchild)
{ {
pchild.Linkset = new BSLinkset(m_physicsScene, pchild); pchild.Linkset = new BSLinkset(m_physicsScene, pchild);
RemoveChildFromLinkset(pchild); RemoveChildFromLinkset(pchild);
@ -285,12 +285,12 @@ public class BSLinkset
// 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.
private void RemoveChildFromLinkset(BSPrim child) private void RemoveChildFromLinkset(BSPhysObject child)
{ {
if (m_children.Remove(child)) if (m_children.Remove(child))
{ {
BSPrim rootx = LinksetRoot; // capture the root as of now BSPhysObject rootx = LinksetRoot; // capture the root as of now
BSPrim childx = child; BSPhysObject childx = child;
m_physicsScene.TaintedObject("RemoveChildFromLinkset", delegate() m_physicsScene.TaintedObject("RemoveChildFromLinkset", delegate()
{ {
DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID); DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
@ -310,7 +310,7 @@ public class 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(BSPrim rootPrim, BSPrim childPrim) private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim)
{ {
// Zero motion for children so they don't interpolate // Zero motion for children so they don't interpolate
childPrim.ZeroMotion(); childPrim.ZeroMotion();
@ -383,7 +383,7 @@ public class BSLinkset
// Remove linkage between myself and a particular child // Remove linkage between myself and a particular child
// Called at taint time! // Called at taint time!
private void PhysicallyUnlinkAChildFromRoot(BSPrim rootPrim, BSPrim childPrim) private void PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim)
{ {
DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
@ -396,7 +396,7 @@ public class BSLinkset
// Remove linkage between myself and any possible children I might have // Remove linkage between myself and any possible children I might have
// Called at taint time! // Called at taint time!
private void PhysicallyUnlinkAllChildrenFromRoot(BSPrim rootPrim) private void PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim)
{ {
DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);

View File

@ -0,0 +1,58 @@
/*
* 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.Text;
using OMV = OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Physics.Manager;
namespace OpenSim.Region.Physics.BulletSPlugin
{
// Class to wrap all objects.
// The rest of BulletSim doesn't need to keep checking for avatars or prims
// unless the difference is significant.
public abstract class BSPhysObject : PhysicsActor
{
public abstract BSLinkset Linkset { get; set; }
public abstract void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type,
OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth);
public abstract void SendCollisions();
// Return the object mass without calculating it or side effects
public abstract float MassRaw { get; }
public abstract BulletBody Body { get; set; }
public abstract void ZeroMotion();
public abstract void UpdateProperties(EntityProperties entprop);
public abstract void Destroy();
}
}

View File

@ -37,7 +37,7 @@ using OpenSim.Region.Physics.ConvexDecompositionDotNet;
namespace OpenSim.Region.Physics.BulletSPlugin namespace OpenSim.Region.Physics.BulletSPlugin
{ {
[Serializable] [Serializable]
public sealed class BSPrim : PhysicsActor public sealed 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]";
@ -88,23 +88,14 @@ public sealed class BSPrim : PhysicsActor
private float _buoyancy; private float _buoyancy;
// Membership in a linkset is controlled by this class. // Membership in a linkset is controlled by this class.
private BSLinkset _linkset; public override BSLinkset Linkset { get; set; }
public BSLinkset Linkset
{
get { return _linkset; }
set { _linkset = value; }
}
private int _subscribedEventsMs = 0; private int _subscribedEventsMs = 0;
private int _nextCollisionOkTime = 0; private int _nextCollisionOkTime = 0;
long _collidingStep; long _collidingStep;
long _collidingGroundStep; long _collidingGroundStep;
private BulletBody m_body; public override BulletBody Body { get; set; }
public BulletBody Body {
get { return m_body; }
set { m_body = value; }
}
private BSDynamics _vehicle; private BSDynamics _vehicle;
@ -139,7 +130,7 @@ public sealed class BSPrim : PhysicsActor
_friction = _scene.Params.defaultFriction; // TODO: compute based on object material _friction = _scene.Params.defaultFriction; // TODO: compute based on object material
_density = _scene.Params.defaultDensity; // TODO: compute based on object material _density = _scene.Params.defaultDensity; // TODO: compute based on object material
_restitution = _scene.Params.defaultRestitution; _restitution = _scene.Params.defaultRestitution;
_linkset = new BSLinkset(Scene, this); // a linkset of one Linkset = new BSLinkset(Scene, this); // a linkset of one
_vehicle = new BSDynamics(Scene, this); // add vehicleness _vehicle = new BSDynamics(Scene, this); // add vehicleness
_mass = CalculateMass(); _mass = CalculateMass();
// do the actual object creation at taint time // do the actual object creation at taint time
@ -151,23 +142,23 @@ public sealed class BSPrim : PhysicsActor
// Get the pointer to the physical body for this object. // Get the pointer to the physical body for this object.
// At the moment, we're still letting BulletSim manage the creation and destruction // At the moment, we're still letting BulletSim manage the creation and destruction
// of the object. Someday we'll move that into the C# code. // of the object. Someday we'll move that into the C# code.
m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); Body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
}); });
} }
// called when this prim is being destroyed and we should free all the resources // called when this prim is being destroyed and we should free all the resources
public void Destroy() public override void Destroy()
{ {
// m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID);
// Undo any links between me and any other object // Undo any links between me and any other object
BSPrim parentBefore = _linkset.LinksetRoot; BSPhysObject parentBefore = Linkset.LinksetRoot;
int childrenBefore = _linkset.NumberOfChildren; int childrenBefore = Linkset.NumberOfChildren;
_linkset = _linkset.RemoveMeFromLinkset(this); Linkset = Linkset.RemoveMeFromLinkset(this);
DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}", DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}",
LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren); LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
// Undo any vehicle properties // Undo any vehicle properties
this.VehicleType = (int)Vehicle.TYPE_NONE; this.VehicleType = (int)Vehicle.TYPE_NONE;
@ -230,13 +221,13 @@ public sealed class BSPrim : PhysicsActor
BSPrim parent = obj as BSPrim; BSPrim parent = obj as BSPrim;
if (parent != null) if (parent != null)
{ {
BSPrim parentBefore = _linkset.LinksetRoot; BSPhysObject parentBefore = Linkset.LinksetRoot;
int childrenBefore = _linkset.NumberOfChildren; int childrenBefore = Linkset.NumberOfChildren;
_linkset = parent.Linkset.AddMeToLinkset(this); Linkset = parent.Linkset.AddMeToLinkset(this);
DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}", DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}",
LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren); LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
} }
return; return;
} }
@ -246,13 +237,13 @@ public sealed class BSPrim : PhysicsActor
// TODO: decide if this parent checking needs to happen at taint time // TODO: decide if this parent checking needs to happen at taint time
// Race condition here: if link() and delink() in same simulation tick, the delink will not happen // Race condition here: if link() and delink() in same simulation tick, the delink will not happen
BSPrim parentBefore = _linkset.LinksetRoot; BSPhysObject parentBefore = Linkset.LinksetRoot;
int childrenBefore = _linkset.NumberOfChildren; int childrenBefore = Linkset.NumberOfChildren;
_linkset = _linkset.RemoveMeFromLinkset(this); Linkset = Linkset.RemoveMeFromLinkset(this);
DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ", DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",
LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren); LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
return; return;
} }
@ -260,7 +251,7 @@ public sealed class BSPrim : PhysicsActor
// Do it to the properties so the values get set in the physics engine. // Do it to the properties so the values get set in the physics engine.
// Push the setting of the values to the viewer. // Push the setting of the values to the viewer.
// Called at taint time! // Called at taint time!
public void ZeroMotion() public override void ZeroMotion()
{ {
_velocity = OMV.Vector3.Zero; _velocity = OMV.Vector3.Zero;
_acceleration = OMV.Vector3.Zero; _acceleration = OMV.Vector3.Zero;
@ -281,7 +272,7 @@ public sealed class BSPrim : PhysicsActor
public override OMV.Vector3 Position { public override OMV.Vector3 Position {
get { get {
if (!_linkset.IsRoot(this)) if (!Linkset.IsRoot(this))
// child prims move around based on their parent. Need to get the latest location // child prims move around based on their parent. Need to get the latest location
_position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
@ -306,23 +297,23 @@ public sealed class BSPrim : PhysicsActor
{ {
get get
{ {
return _linkset.LinksetMass; return Linkset.LinksetMass;
} }
} }
// 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 float MassRaw { get { return _mass; } } public override float MassRaw { get { return _mass; } }
// Is this used? // Is this used?
public override OMV.Vector3 CenterOfMass public override OMV.Vector3 CenterOfMass
{ {
get { return _linkset.CenterOfMass; } get { return Linkset.CenterOfMass; }
} }
// Is this used? // Is this used?
public override OMV.Vector3 GeometricCenter public override OMV.Vector3 GeometricCenter
{ {
get { return _linkset.GeometricCenter; } get { return Linkset.GeometricCenter; }
} }
public override OMV.Vector3 Force { public override OMV.Vector3 Force {
@ -431,7 +422,7 @@ public sealed class BSPrim : PhysicsActor
} }
public override OMV.Quaternion Orientation { public override OMV.Quaternion Orientation {
get { get {
if (!_linkset.IsRoot(this)) if (!Linkset.IsRoot(this))
{ {
// Children move around because tied to parent. Get a fresh value. // Children move around because tied to parent. Get a fresh value.
_orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID); _orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID);
@ -490,7 +481,7 @@ public sealed class BSPrim : PhysicsActor
BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass); BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass);
// recompute any linkset parameters // recompute any linkset parameters
_linkset.Refresh(this); Linkset.Refresh(this);
CollisionFlags cf = BulletSimAPI.GetCollisionFlags2(Body.Ptr); CollisionFlags cf = BulletSimAPI.GetCollisionFlags2(Body.Ptr);
DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, cf); DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, cf);
@ -1299,7 +1290,7 @@ public sealed class BSPrim : PhysicsActor
const float ACCELERATION_TOLERANCE = 0.01f; const float ACCELERATION_TOLERANCE = 0.01f;
const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f; const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f;
public void UpdateProperties(EntityProperties entprop) public override void UpdateProperties(EntityProperties entprop)
{ {
/* /*
UpdatedProperties changed = 0; UpdatedProperties changed = 0;
@ -1347,7 +1338,7 @@ public sealed class BSPrim : PhysicsActor
// Don't check for damping here -- it's done in BulletSim and SceneObjectPart. // Don't check for damping here -- it's done in BulletSim and SceneObjectPart.
// Updates only for individual prims and for the root object of a linkset. // Updates only for individual prims and for the root object of a linkset.
if (_linkset.IsRoot(this)) if (Linkset.IsRoot(this))
{ {
// Assign to the local variables so the normal set action does not happen // Assign to the local variables so the normal set action does not happen
_position = entprop.Position; _position = entprop.Position;
@ -1375,7 +1366,7 @@ public sealed class BSPrim : PhysicsActor
// I've collided with something // I've collided with something
// Called at taint time from within the Step() function // Called at taint time from within the Step() function
CollisionEventUpdate collisionCollection; CollisionEventUpdate collisionCollection;
public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) public override void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
{ {
// m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
@ -1387,18 +1378,15 @@ public sealed class BSPrim : PhysicsActor
} }
// DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith); // DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith);
BSPrim collidingWithPrim;
if (_scene.Prims.TryGetValue(collidingWith, out collidingWithPrim)) // prims in the same linkset cannot collide with each other
if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID))
{ {
// prims in the same linkset cannot collide with each other return;
if (this.Linkset.LinksetID == collidingWithPrim.Linkset.LinksetID)
{
return;
}
} }
// if someone is subscribed to collision events.... // if someone has subscribed for collision events....
if (_subscribedEventsMs != 0) { if (SubscribedEvents()) {
// throttle the collisions to the number of milliseconds specified in the subscription // throttle the collisions to the number of milliseconds specified in the subscription
int nowTime = _scene.SimulationNowTime; int nowTime = _scene.SimulationNowTime;
if (nowTime >= _nextCollisionOkTime) { if (nowTime >= _nextCollisionOkTime) {
@ -1412,7 +1400,7 @@ public sealed class BSPrim : PhysicsActor
} }
// The scene is telling us it's time to pass our collected collisions into the simulator // The scene is telling us it's time to pass our collected collisions into the simulator
public void SendCollisions() public override void SendCollisions()
{ {
if (collisionCollection != null && collisionCollection.Count > 0) if (collisionCollection != null && collisionCollection.Count > 0)
{ {

View File

@ -78,14 +78,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
public string BulletSimVersion = "?"; public string BulletSimVersion = "?";
private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>(); public Dictionary<uint, BSPhysObject> PhysObjects = new Dictionary<uint, BSPhysObject>();
public Dictionary<uint, BSCharacter> Characters { get { return m_avatars; } }
private Dictionary<uint, BSPrim> m_prims = new Dictionary<uint, BSPrim>();
public Dictionary<uint, BSPrim> Prims { get { return m_prims; } }
private HashSet<BSPhysObject> m_objectsWithCollisions = new HashSet<BSPhysObject>();
// Following is a kludge and can be removed when avatar animation updating is
// moved to a better place.
private HashSet<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>(); private HashSet<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>();
private HashSet<BSPrim> m_primsWithCollisions = new HashSet<BSPrim>();
private List<BSPrim> m_vehicles = new List<BSPrim>(); private List<BSPrim> m_vehicles = new List<BSPrim>();
@ -235,7 +233,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
// BulletSimVersion = BulletSimAPI.GetVersion(); // BulletSimVersion = BulletSimAPI.GetVersion();
// m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion); // m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion);
// if Debug, enable logging from the unmanaged code // If Debug logging level, enable logging from the unmanaged code
if (m_log.IsDebugEnabled || PhysicsLogging.Enabled) if (m_log.IsDebugEnabled || PhysicsLogging.Enabled)
{ {
m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader); m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader);
@ -243,13 +241,14 @@ public class BSScene : PhysicsScene, IPhysicsParameters
m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLoggerPhysLog); m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLoggerPhysLog);
else else
m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger); m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger);
// the handle is saved in a variable to make sure it doesn't get freed after this call // The handle is saved in a variable to make sure it doesn't get freed after this call
BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle); BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle);
} }
_taintedObjects = new List<TaintCallbackEntry>(); _taintedObjects = new List<TaintCallbackEntry>();
mesher = meshmerizer; mesher = meshmerizer;
// The bounding box for the simulated world // The bounding box for the simulated world
Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 8192f); Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 8192f);
@ -337,7 +336,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
if (!m_initialized) return null; if (!m_initialized) return null;
BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying); BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying);
lock (m_avatars) m_avatars.Add(localID, actor); lock (PhysObjects) PhysObjects.Add(localID, actor);
// Remove kludge someday
lock (m_avatarsWithCollisions) m_avatarsWithCollisions.Add(actor);
return actor; return actor;
} }
@ -352,7 +355,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
{ {
try try
{ {
lock (m_avatars) m_avatars.Remove(actor.LocalID); lock (PhysObjects) PhysObjects.Remove(actor.LocalID);
// Remove kludge someday
lock (m_avatarsWithCollisions) m_avatarsWithCollisions.Remove(bsactor);
} }
catch (Exception e) catch (Exception e)
{ {
@ -374,7 +379,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
// m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID); // m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID);
try try
{ {
lock (m_prims) m_prims.Remove(bsprim.LocalID); lock (PhysObjects) PhysObjects.Remove(bsprim.LocalID);
} }
catch (Exception e) catch (Exception e)
{ {
@ -399,7 +404,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
DetailLog("{0},AddPrimShape,call", localID); DetailLog("{0},AddPrimShape,call", localID);
BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical); BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical);
lock (m_prims) m_prims.Add(localID, prim); lock (PhysObjects) PhysObjects.Add(localID, prim);
return prim; return prim;
} }
@ -470,19 +475,16 @@ public class BSScene : PhysicsScene, IPhysicsParameters
// The above SendCollision's batch up the collisions on the objects. // The above SendCollision's batch up the collisions on the objects.
// Now push the collisions into the simulator. // Now push the collisions into the simulator.
foreach (BSPrim bsp in m_primsWithCollisions) foreach (BSPhysObject bsp in m_objectsWithCollisions)
bsp.SendCollisions(); bsp.SendCollisions();
m_primsWithCollisions.Clear(); m_objectsWithCollisions.Clear();
// This is a kludge to get avatar movement updated. // This is a kludge to get avatar movement updated.
// Don't send collisions only if there were collisions -- send everytime.
// ODE sends collisions even if there are none and this is used to update // ODE sends collisions even if there are none and this is used to update
// avatar animations and stuff. // avatar animations and stuff.
// foreach (BSCharacter bsc in m_avatarsWithCollisions) foreach (BSPhysObject bpo in m_avatarsWithCollisions)
// bsc.SendCollisions(); bpo.SendCollisions();
foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars) // m_avatarsWithCollisions.Clear();
kvp.Value.SendCollisions();
m_avatarsWithCollisions.Clear();
// If any of the objects had updated properties, tell the object it has been changed by the physics engine // If any of the objects had updated properties, tell the object it has been changed by the physics engine
if (updatedEntityCount > 0) if (updatedEntityCount > 0)
@ -490,16 +492,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
for (int ii = 0; ii < updatedEntityCount; ii++) for (int ii = 0; ii < updatedEntityCount; ii++)
{ {
EntityProperties entprop = m_updateArray[ii]; EntityProperties entprop = m_updateArray[ii];
BSPrim prim; BSPhysObject pobj;
if (m_prims.TryGetValue(entprop.ID, out prim)) if (PhysObjects.TryGetValue(entprop.ID, out pobj))
{ {
prim.UpdateProperties(entprop); pobj.UpdateProperties(entprop);
continue;
}
BSCharacter actor;
if (m_avatars.TryGetValue(entprop.ID, out actor))
{
actor.UpdateProperties(entprop);
continue; continue;
} }
} }
@ -529,33 +525,36 @@ public class BSScene : PhysicsScene, IPhysicsParameters
} }
// Something has collided // Something has collided
private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal, float penitration) private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal, float penetration)
{ {
if (localID == TERRAIN_ID || localID == GROUNDPLANE_ID) if (localID == TERRAIN_ID || localID == GROUNDPLANE_ID)
{ {
return; // don't send collisions to the terrain return; // don't send collisions to the terrain
} }
BSPhysObject collider = PhysObjects[localID];
// TODO: as of this code, terrain was not in the physical object list.
// When BSTerrain is created and it will be in the list, we can remove
// the possibility that it's not there and just fetch the collidee.
BSPhysObject collidee = null;
ActorTypes type = ActorTypes.Prim; ActorTypes type = ActorTypes.Prim;
if (collidingWith == TERRAIN_ID || collidingWith == GROUNDPLANE_ID) if (collidingWith == TERRAIN_ID || collidingWith == GROUNDPLANE_ID)
{
type = ActorTypes.Ground; type = ActorTypes.Ground;
else if (m_avatars.ContainsKey(collidingWith)) }
type = ActorTypes.Agent; else
{
collidee = PhysObjects[collidingWith];
if (collidee is BSCharacter)
type = ActorTypes.Agent;
}
// DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith); // DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith);
BSPrim prim; collider.Collide(collidingWith, collidee, type, collidePoint, collideNormal, penetration);
if (m_prims.TryGetValue(localID, out prim)) { m_objectsWithCollisions.Add(collider);
prim.Collide(collidingWith, type, collidePoint, collideNormal, penitration);
m_primsWithCollisions.Add(prim);
return;
}
BSCharacter actor;
if (m_avatars.TryGetValue(localID, out actor)) {
actor.Collide(collidingWith, type, collidePoint, collideNormal, penitration);
m_avatarsWithCollisions.Add(actor);
return;
}
return; return;
} }
@ -605,17 +604,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
// make sure no stepping happens while we're deleting stuff // make sure no stepping happens while we're deleting stuff
m_initialized = false; m_initialized = false;
foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars) foreach (KeyValuePair<uint, BSPhysObject> kvp in PhysObjects)
{ {
kvp.Value.Destroy(); kvp.Value.Destroy();
} }
m_avatars.Clear(); PhysObjects.Clear();
foreach (KeyValuePair<uint, BSPrim> kvp in m_prims)
{
kvp.Value.Destroy();
}
m_prims.Clear();
// Now that the prims are all cleaned up, there should be no constraints left // Now that the prims are all cleaned up, there should be no constraints left
if (m_constraintCollection != null) if (m_constraintCollection != null)
@ -996,42 +989,42 @@ public class BSScene : PhysicsScene, IPhysicsParameters
0f, 0f,
(s,cf,p,v) => { s.m_params[0].linearDamping = cf.GetFloat(p, v); }, (s,cf,p,v) => { s.m_params[0].linearDamping = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].linearDamping; }, (s) => { return s.m_params[0].linearDamping; },
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].linearDamping, p, l, v); } ), (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearDamping, p, l, v); } ),
new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)", new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)",
0f, 0f,
(s,cf,p,v) => { s.m_params[0].angularDamping = cf.GetFloat(p, v); }, (s,cf,p,v) => { s.m_params[0].angularDamping = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].angularDamping; }, (s) => { return s.m_params[0].angularDamping; },
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].angularDamping, p, l, v); } ), (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularDamping, p, l, v); } ),
new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static", new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static",
0.2f, 0.2f,
(s,cf,p,v) => { s.m_params[0].deactivationTime = cf.GetFloat(p, v); }, (s,cf,p,v) => { s.m_params[0].deactivationTime = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].deactivationTime; }, (s) => { return s.m_params[0].deactivationTime; },
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].deactivationTime, p, l, v); } ), (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].deactivationTime, p, l, v); } ),
new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static", new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static",
0.8f, 0.8f,
(s,cf,p,v) => { s.m_params[0].linearSleepingThreshold = cf.GetFloat(p, v); }, (s,cf,p,v) => { s.m_params[0].linearSleepingThreshold = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].linearSleepingThreshold; }, (s) => { return s.m_params[0].linearSleepingThreshold; },
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].linearSleepingThreshold, p, l, v); } ), (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearSleepingThreshold, p, l, v); } ),
new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static", new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static",
1.0f, 1.0f,
(s,cf,p,v) => { s.m_params[0].angularSleepingThreshold = cf.GetFloat(p, v); }, (s,cf,p,v) => { s.m_params[0].angularSleepingThreshold = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].angularSleepingThreshold; }, (s) => { return s.m_params[0].angularSleepingThreshold; },
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].angularSleepingThreshold, p, l, v); } ), (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularSleepingThreshold, p, l, v); } ),
new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ,
0f, // set to zero to disable 0f, // set to zero to disable
(s,cf,p,v) => { s.m_params[0].ccdMotionThreshold = cf.GetFloat(p, v); }, (s,cf,p,v) => { s.m_params[0].ccdMotionThreshold = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].ccdMotionThreshold; }, (s) => { return s.m_params[0].ccdMotionThreshold; },
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].ccdMotionThreshold, p, l, v); } ), (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdMotionThreshold, p, l, v); } ),
new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" ,
0f, 0f,
(s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); }, (s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].ccdSweptSphereRadius; }, (s) => { return s.m_params[0].ccdSweptSphereRadius; },
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); } ), (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); } ),
new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" , new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" ,
0.1f, 0.1f,
(s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); }, (s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].contactProcessingThreshold; }, (s) => { return s.m_params[0].contactProcessingThreshold; },
(s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].contactProcessingThreshold, p, l, v); } ), (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].contactProcessingThreshold, p, l, v); } ),
new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" ,
0.5f, 0.5f,
@ -1052,32 +1045,32 @@ public class BSScene : PhysicsScene, IPhysicsParameters
0.5f, 0.5f,
(s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); }, (s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].avatarFriction; }, (s) => { return s.m_params[0].avatarFriction; },
(s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarFriction, p, l, v); } ), (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarFriction, p, l, v); } ),
new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.", new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.",
60f, 60f,
(s,cf,p,v) => { s.m_params[0].avatarDensity = cf.GetFloat(p, v); }, (s,cf,p,v) => { s.m_params[0].avatarDensity = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].avatarDensity; }, (s) => { return s.m_params[0].avatarDensity; },
(s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarDensity, p, l, v); } ), (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarDensity, p, l, v); } ),
new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.", new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.",
0f, 0f,
(s,cf,p,v) => { s.m_params[0].avatarRestitution = cf.GetFloat(p, v); }, (s,cf,p,v) => { s.m_params[0].avatarRestitution = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].avatarRestitution; }, (s) => { return s.m_params[0].avatarRestitution; },
(s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarRestitution, p, l, v); } ), (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarRestitution, p, l, v); } ),
new ParameterDefn("AvatarCapsuleRadius", "Radius of space around an avatar", new ParameterDefn("AvatarCapsuleRadius", "Radius of space around an avatar",
0.37f, 0.37f,
(s,cf,p,v) => { s.m_params[0].avatarCapsuleRadius = cf.GetFloat(p, v); }, (s,cf,p,v) => { s.m_params[0].avatarCapsuleRadius = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].avatarCapsuleRadius; }, (s) => { return s.m_params[0].avatarCapsuleRadius; },
(s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarCapsuleRadius, p, l, v); } ), (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleRadius, p, l, v); } ),
new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar", new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar",
1.5f, 1.5f,
(s,cf,p,v) => { s.m_params[0].avatarCapsuleHeight = cf.GetFloat(p, v); }, (s,cf,p,v) => { s.m_params[0].avatarCapsuleHeight = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].avatarCapsuleHeight; }, (s) => { return s.m_params[0].avatarCapsuleHeight; },
(s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarCapsuleHeight, p, l, v); } ), (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleHeight, p, l, v); } ),
new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
0.1f, 0.1f,
(s,cf,p,v) => { s.m_params[0].avatarContactProcessingThreshold = cf.GetFloat(p, v); }, (s,cf,p,v) => { s.m_params[0].avatarContactProcessingThreshold = cf.GetFloat(p, v); },
(s) => { return s.m_params[0].avatarContactProcessingThreshold; }, (s) => { return s.m_params[0].avatarContactProcessingThreshold; },
(s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ), (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ),
new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
@ -1264,18 +1257,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
} }
// check to see if we are updating a parameter for a particular or all of the prims // check to see if we are updating a parameter for a particular or all of the prims
protected void UpdateParameterPrims(ref float loc, string parm, uint localID, float val) protected void UpdateParameterObject(ref float loc, string parm, uint localID, float val)
{ {
List<uint> operateOn; List<uint> operateOn;
lock (m_prims) operateOn = new List<uint>(m_prims.Keys); lock (PhysObjects) operateOn = new List<uint>(PhysObjects.Keys);
UpdateParameterSet(operateOn, ref loc, parm, localID, val);
}
// check to see if we are updating a parameter for a particular or all of the avatars
protected void UpdateParameterAvatars(ref float loc, string parm, uint localID, float val)
{
List<uint> operateOn;
lock (m_avatars) operateOn = new List<uint>(m_avatars.Keys);
UpdateParameterSet(operateOn, ref loc, parm, localID, val); UpdateParameterSet(operateOn, ref loc, parm, localID, val);
} }