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.
parent
0376b8ddbc
commit
7b6987ce83
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue