Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
commit
5f741143fd
|
@ -1222,6 +1222,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
m_sceneGraph.Close();
|
m_sceneGraph.Close();
|
||||||
|
|
||||||
|
if (PhysicsScene != null)
|
||||||
|
{
|
||||||
|
PhysicsScene phys = PhysicsScene;
|
||||||
|
// remove the physics engine from both Scene and SceneGraph
|
||||||
|
PhysicsScene = null;
|
||||||
|
phys.Dispose();
|
||||||
|
phys = null;
|
||||||
|
}
|
||||||
|
|
||||||
if (!GridService.DeregisterRegion(RegionInfo.RegionID))
|
if (!GridService.DeregisterRegion(RegionInfo.RegionID))
|
||||||
m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name);
|
m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,308 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
|
{
|
||||||
|
public class BSLinkset
|
||||||
|
{
|
||||||
|
private static string LogHeader = "[BULLETSIM LINKSET]";
|
||||||
|
|
||||||
|
private BSPrim m_linksetRoot;
|
||||||
|
public BSPrim Root { get { return m_linksetRoot; } }
|
||||||
|
|
||||||
|
private BSScene m_scene;
|
||||||
|
|
||||||
|
private List<BSPrim> m_children;
|
||||||
|
|
||||||
|
// We lock the diddling of linkset classes to prevent any badness.
|
||||||
|
// This locks the modification of the instances of this class. Changes
|
||||||
|
// to the physical representation is done via the tainting mechenism.
|
||||||
|
private object m_linksetActivityLock = new Object();
|
||||||
|
|
||||||
|
// We keep the prim's mass in the linkset structure since it could be dependent on other prims
|
||||||
|
private float m_mass;
|
||||||
|
public float LinksetMass
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
m_mass = ComputeLinksetMass();
|
||||||
|
return m_mass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public OMV.Vector3 CenterOfMass
|
||||||
|
{
|
||||||
|
get { return ComputeLinksetCenterOfMass(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public OMV.Vector3 GeometricCenter
|
||||||
|
{
|
||||||
|
get { return ComputeLinksetGeometricCenter(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public BSLinkset(BSScene scene, BSPrim parent)
|
||||||
|
{
|
||||||
|
// A simple linkset of one (no children)
|
||||||
|
m_scene = scene;
|
||||||
|
m_linksetRoot = parent;
|
||||||
|
m_children = new List<BSPrim>();
|
||||||
|
m_mass = parent.MassRaw;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Link to a linkset where the child knows the parent.
|
||||||
|
// Parent changing should not happen so do some sanity checking.
|
||||||
|
// We return the parent's linkset so the child can track it's membership.
|
||||||
|
public BSLinkset AddMeToLinkset(BSPrim child, BSPrim parent)
|
||||||
|
{
|
||||||
|
lock (m_linksetActivityLock)
|
||||||
|
{
|
||||||
|
parent.Linkset.AddChildToLinkset(child);
|
||||||
|
}
|
||||||
|
return parent.Linkset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BSLinkset RemoveMeFromLinkset(BSPrim child)
|
||||||
|
{
|
||||||
|
lock (m_linksetActivityLock)
|
||||||
|
{
|
||||||
|
if (IsRoot(child))
|
||||||
|
{
|
||||||
|
// if root of linkset, take the linkset apart
|
||||||
|
while (m_children.Count > 0)
|
||||||
|
{
|
||||||
|
// Note that we don't do a foreach because the remove routine
|
||||||
|
// takes it out of the list.
|
||||||
|
RemoveChildFromLinkset(m_children[0]);
|
||||||
|
}
|
||||||
|
m_children.Clear(); // just to make sure
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Just removing a child from an existing linkset
|
||||||
|
RemoveChildFromLinkset(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The child is down to a linkset of just itself
|
||||||
|
return new BSLinkset(m_scene, child);
|
||||||
|
}
|
||||||
|
|
||||||
|
// An existing linkset had one of its members rebuilt or something.
|
||||||
|
// Undo all the physical linking and rebuild the physical linkset.
|
||||||
|
public bool RefreshLinkset(BSPrim requestor)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Return 'true' if the passed object is the root object of this linkset
|
||||||
|
public bool IsRoot(BSPrim requestor)
|
||||||
|
{
|
||||||
|
return (requestor.LocalID == m_linksetRoot.LocalID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return 'true' if this linkset has any children (more than the root member)
|
||||||
|
public bool HasAnyChildren { get { return (m_children.Count > 0); } }
|
||||||
|
|
||||||
|
// Return 'true' if this child is in this linkset
|
||||||
|
public bool HasChild(BSPrim child)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
foreach (BSPrim bp in m_children)
|
||||||
|
{
|
||||||
|
if (child.LocalID == bp.LocalID)
|
||||||
|
{
|
||||||
|
ret = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float ComputeLinksetMass()
|
||||||
|
{
|
||||||
|
float mass = m_linksetRoot.MassRaw;
|
||||||
|
foreach (BSPrim bp in m_children)
|
||||||
|
{
|
||||||
|
mass += bp.MassRaw;
|
||||||
|
}
|
||||||
|
return mass;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OMV.Vector3 ComputeLinksetCenterOfMass()
|
||||||
|
{
|
||||||
|
OMV.Vector3 com = m_linksetRoot.Position * m_linksetRoot.MassRaw;
|
||||||
|
float totalMass = m_linksetRoot.MassRaw;
|
||||||
|
|
||||||
|
foreach (BSPrim bp in m_children)
|
||||||
|
{
|
||||||
|
com += bp.Position * bp.MassRaw;
|
||||||
|
totalMass += bp.MassRaw;
|
||||||
|
}
|
||||||
|
com /= totalMass;
|
||||||
|
|
||||||
|
return com;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OMV.Vector3 ComputeLinksetGeometricCenter()
|
||||||
|
{
|
||||||
|
OMV.Vector3 com = m_linksetRoot.Position;
|
||||||
|
|
||||||
|
foreach (BSPrim bp in m_children)
|
||||||
|
{
|
||||||
|
com += bp.Position * bp.MassRaw;
|
||||||
|
}
|
||||||
|
com /= m_children.Count + 1;
|
||||||
|
|
||||||
|
return com;
|
||||||
|
}
|
||||||
|
|
||||||
|
// I am the root of a linkset and a new child is being added
|
||||||
|
public void AddChildToLinkset(BSPrim pchild)
|
||||||
|
{
|
||||||
|
BSPrim child = pchild;
|
||||||
|
if (!HasChild(child))
|
||||||
|
{
|
||||||
|
m_children.Add(child);
|
||||||
|
|
||||||
|
m_scene.TaintedObject(delegate()
|
||||||
|
{
|
||||||
|
DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID);
|
||||||
|
DetailLog("{0},AddChildToLinkset,child={1}", m_linksetRoot.LocalID, pchild.LocalID);
|
||||||
|
PhysicallyLinkAChildToRoot(pchild); // build the physical binding between me and the child
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
public void RemoveChildFromLinkset(BSPrim pchild)
|
||||||
|
{
|
||||||
|
BSPrim child = pchild;
|
||||||
|
|
||||||
|
if (m_children.Remove(child))
|
||||||
|
{
|
||||||
|
m_scene.TaintedObject(delegate()
|
||||||
|
{
|
||||||
|
DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID);
|
||||||
|
DetailLog("{0},RemoveChildFromLinkset,child={1}", m_linksetRoot.LocalID, pchild.LocalID);
|
||||||
|
|
||||||
|
if (m_children.Count == 0)
|
||||||
|
{
|
||||||
|
// if the linkset is empty, make sure all linkages have been removed
|
||||||
|
PhysicallyUnlinkAllChildrenFromRoot();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PhysicallyUnlinkAChildFromRoot(pchild);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This will happen if we remove the root of the linkset first. Non-fatal occurance.
|
||||||
|
// m_scene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a constraint between me (root of linkset) and the passed prim (the child).
|
||||||
|
// Called at taint time!
|
||||||
|
private void PhysicallyLinkAChildToRoot(BSPrim childPrim)
|
||||||
|
{
|
||||||
|
// Zero motion for children so they don't interpolate
|
||||||
|
childPrim.ZeroMotion();
|
||||||
|
|
||||||
|
// relative position normalized to the root prim
|
||||||
|
OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(m_linksetRoot.Orientation);
|
||||||
|
OMV.Vector3 childRelativePosition = (childPrim.Position - m_linksetRoot.Position) * invThisOrientation;
|
||||||
|
|
||||||
|
// relative rotation of the child to the parent
|
||||||
|
OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation;
|
||||||
|
|
||||||
|
// create a constraint that allows no freedom of movement between the two objects
|
||||||
|
// http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
|
||||||
|
// DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
|
||||||
|
DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID);
|
||||||
|
BSConstraint constrain = m_scene.Constraints.CreateConstraint(
|
||||||
|
m_scene.World, m_linksetRoot.Body, childPrim.Body,
|
||||||
|
childRelativePosition,
|
||||||
|
childRelativeRotation,
|
||||||
|
OMV.Vector3.Zero,
|
||||||
|
OMV.Quaternion.Identity);
|
||||||
|
constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
|
||||||
|
constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
|
||||||
|
|
||||||
|
// tweek the constraint to increase stability
|
||||||
|
constrain.UseFrameOffset(m_scene.BoolNumeric(m_scene.Params.linkConstraintUseFrameOffset));
|
||||||
|
constrain.TranslationalLimitMotor(m_scene.BoolNumeric(m_scene.Params.linkConstraintEnableTransMotor),
|
||||||
|
m_scene.Params.linkConstraintTransMotorMaxVel,
|
||||||
|
m_scene.Params.linkConstraintTransMotorMaxForce);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove linkage between myself and a particular child
|
||||||
|
// Called at taint time!
|
||||||
|
private void PhysicallyUnlinkAChildFromRoot(BSPrim childPrim)
|
||||||
|
{
|
||||||
|
DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}",
|
||||||
|
LogHeader, m_linksetRoot.LocalID, childPrim.LocalID);
|
||||||
|
DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID);
|
||||||
|
// BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, childPrim.LocalID);
|
||||||
|
m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body, childPrim.Body);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove linkage between myself and any possible children I might have
|
||||||
|
// Called at taint time!
|
||||||
|
private void PhysicallyUnlinkAllChildrenFromRoot()
|
||||||
|
{
|
||||||
|
// DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader);
|
||||||
|
DetailLog("{0},PhysicallyUnlinkAllChildren,taint", m_linksetRoot.LocalID);
|
||||||
|
m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body);
|
||||||
|
// BulletSimAPI.RemoveConstraintByID(_scene.WorldID, LocalID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke the detailed logger and output something if it's enabled.
|
||||||
|
private void DebugLog(string msg, params Object[] args)
|
||||||
|
{
|
||||||
|
m_scene.Logger.DebugFormat(msg, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke the detailed logger and output something if it's enabled.
|
||||||
|
private void DetailLog(string msg, params Object[] args)
|
||||||
|
{
|
||||||
|
m_scene.PhysicsLogging.Write(msg, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -66,7 +66,7 @@ public sealed class BSPrim : PhysicsActor
|
||||||
private bool _isSelected;
|
private bool _isSelected;
|
||||||
private bool _isVolumeDetect;
|
private bool _isVolumeDetect;
|
||||||
private OMV.Vector3 _position;
|
private OMV.Vector3 _position;
|
||||||
private float _mass;
|
private float _mass; // the mass of this object
|
||||||
private float _density;
|
private float _density;
|
||||||
private OMV.Vector3 _force;
|
private OMV.Vector3 _force;
|
||||||
private OMV.Vector3 _velocity;
|
private OMV.Vector3 _velocity;
|
||||||
|
@ -89,8 +89,13 @@ public sealed class BSPrim : PhysicsActor
|
||||||
private bool _kinematic;
|
private bool _kinematic;
|
||||||
private float _buoyancy;
|
private float _buoyancy;
|
||||||
|
|
||||||
private BSPrim _parentPrim;
|
// Membership in a linkset is controlled by this class.
|
||||||
private List<BSPrim> _childrenPrims;
|
private BSLinkset _linkset;
|
||||||
|
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;
|
||||||
|
@ -133,9 +138,8 @@ public sealed class BSPrim : PhysicsActor
|
||||||
_friction = _scene.Params.defaultFriction; // TODO: compute based on object material
|
_friction = _scene.Params.defaultFriction; // TODO: compute based on object material
|
||||||
_density = _scene.Params.defaultDensity; // TODO: compute based on object material
|
_density = _scene.Params.defaultDensity; // TODO: compute based on object material
|
||||||
_restitution = _scene.Params.defaultRestitution;
|
_restitution = _scene.Params.defaultRestitution;
|
||||||
_parentPrim = null; // not a child or a parent
|
_linkset = new BSLinkset(_scene, this); // a linkset of one
|
||||||
_vehicle = new BSDynamics(this); // add vehicleness
|
_vehicle = new BSDynamics(this); // add vehicleness
|
||||||
_childrenPrims = new List<BSPrim>();
|
|
||||||
_mass = CalculateMass();
|
_mass = CalculateMass();
|
||||||
// do the actual object creation at taint time
|
// do the actual object creation at taint time
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject(delegate()
|
||||||
|
@ -161,16 +165,8 @@ public sealed class BSPrim : PhysicsActor
|
||||||
|
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject(delegate()
|
||||||
{
|
{
|
||||||
// undo any dependance with/on other objects
|
// Undo any links between me and any other object
|
||||||
if (_parentPrim != null)
|
_linkset = _linkset.RemoveMeFromLinkset(this);
|
||||||
{
|
|
||||||
// If I'm someone's child, tell them to forget about me.
|
|
||||||
_parentPrim.RemoveChildFromLinkset(this);
|
|
||||||
_parentPrim = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure there are no other prims linked to me
|
|
||||||
UnlinkAllChildren();
|
|
||||||
|
|
||||||
// everything in the C# world will get garbage collected. Tell the C++ world to free stuff.
|
// everything in the C# world will get garbage collected. Tell the C++ world to free stuff.
|
||||||
BulletSimAPI.DestroyObject(_scene.WorldID, LocalID);
|
BulletSimAPI.DestroyObject(_scene.WorldID, LocalID);
|
||||||
|
@ -187,7 +183,7 @@ public sealed class BSPrim : PhysicsActor
|
||||||
_scene.TaintedObject(delegate()
|
_scene.TaintedObject(delegate()
|
||||||
{
|
{
|
||||||
_mass = CalculateMass(); // changing size changes the mass
|
_mass = CalculateMass(); // changing size changes the mass
|
||||||
BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, Mass, IsPhysical);
|
BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical);
|
||||||
RecreateGeomAndObject();
|
RecreateGeomAndObject();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -226,32 +222,8 @@ public sealed class BSPrim : PhysicsActor
|
||||||
BSPrim parent = obj as BSPrim;
|
BSPrim parent = obj as BSPrim;
|
||||||
DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID);
|
DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID);
|
||||||
DetailLog("{0},link,parent={1}", LocalID, obj.LocalID);
|
DetailLog("{0},link,parent={1}", LocalID, obj.LocalID);
|
||||||
// TODO: decide if this parent checking needs to happen at taint time
|
|
||||||
if (_parentPrim == null)
|
_linkset = _linkset.AddMeToLinkset(this, parent);
|
||||||
{
|
|
||||||
if (parent != null)
|
|
||||||
{
|
|
||||||
// I don't have a parent so I am joining a linkset
|
|
||||||
parent.AddChildToLinkset(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// I already have a parent, is parenting changing?
|
|
||||||
if (parent != _parentPrim)
|
|
||||||
{
|
|
||||||
if (parent == null)
|
|
||||||
{
|
|
||||||
// we are being removed from a linkset
|
|
||||||
_parentPrim.RemoveChildFromLinkset(this);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// asking to reparent a prim should not happen
|
|
||||||
m_log.ErrorFormat("{0}: link(): Reparenting a prim. ", LogHeader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,81 +232,18 @@ 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
|
||||||
DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID,
|
DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID,
|
||||||
(_parentPrim==null ? "NULL" : _parentPrim._avName+"/"+_parentPrim.LocalID.ToString()));
|
_linkset.Root._avName+"/"+_linkset.Root.LocalID.ToString());
|
||||||
DetailLog("{0},delink,parent={1}", LocalID, (_parentPrim==null ? "NULL" : _parentPrim.LocalID.ToString()));
|
DetailLog("{0},delink,parent={1}", LocalID, _linkset.Root.LocalID.ToString());
|
||||||
if (_parentPrim != null)
|
|
||||||
{
|
_linkset.RemoveMeFromLinkset(this);
|
||||||
_parentPrim.RemoveChildFromLinkset(this);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// I am the root of a linkset and a new child is being added
|
|
||||||
public void AddChildToLinkset(BSPrim pchild)
|
|
||||||
{
|
|
||||||
BSPrim child = pchild;
|
|
||||||
_scene.TaintedObject(delegate()
|
|
||||||
{
|
|
||||||
if (!_childrenPrims.Contains(child))
|
|
||||||
{
|
|
||||||
DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, this.LocalID);
|
|
||||||
DetailLog("{0},AddChildToLinkset,child={1}", LocalID, pchild.LocalID);
|
|
||||||
_childrenPrims.Add(child);
|
|
||||||
child._parentPrim = this; // the child has gained a parent
|
|
||||||
// RecreateGeomAndObject(); // rebuild my shape with the new child added
|
|
||||||
LinkAChildToMe(pchild); // build the physical binding between me and the child
|
|
||||||
|
|
||||||
_mass = CalculateMass();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
public void RemoveChildFromLinkset(BSPrim pchild)
|
|
||||||
{
|
|
||||||
BSPrim child = pchild;
|
|
||||||
_scene.TaintedObject(delegate()
|
|
||||||
{
|
|
||||||
if (_childrenPrims.Contains(child))
|
|
||||||
{
|
|
||||||
DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID);
|
|
||||||
DetailLog("{0},RemoveChildFromLinkset,child={1}", LocalID, pchild.LocalID);
|
|
||||||
_childrenPrims.Remove(child);
|
|
||||||
child._parentPrim = null; // the child has lost its parent
|
|
||||||
if (_childrenPrims.Count == 0)
|
|
||||||
{
|
|
||||||
// if the linkset is empty, make sure all linkages have been removed
|
|
||||||
UnlinkAllChildren();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// RecreateGeomAndObject(); // rebuild my shape with the child removed
|
|
||||||
UnlinkAChildFromMe(pchild);
|
|
||||||
}
|
|
||||||
|
|
||||||
_mass = CalculateMass();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// return true if we are the root of a linkset (there are children to manage)
|
|
||||||
public bool IsRootOfLinkset
|
|
||||||
{
|
|
||||||
get { return (_parentPrim == null && _childrenPrims.Count != 0); }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set motion values to zero.
|
// Set motion values to zero.
|
||||||
// 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!
|
||||||
private void ZeroMotion()
|
public void ZeroMotion()
|
||||||
{
|
{
|
||||||
_velocity = OMV.Vector3.Zero;
|
_velocity = OMV.Vector3.Zero;
|
||||||
_acceleration = OMV.Vector3.Zero;
|
_acceleration = OMV.Vector3.Zero;
|
||||||
|
@ -355,9 +264,10 @@ public sealed class BSPrim : PhysicsActor
|
||||||
|
|
||||||
public override OMV.Vector3 Position {
|
public override OMV.Vector3 Position {
|
||||||
get {
|
get {
|
||||||
// child prims move around based on their parent. Need to get the latest location
|
if (!_linkset.IsRoot(this))
|
||||||
if (_parentPrim != null)
|
// 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);
|
||||||
|
|
||||||
// don't do the GetObjectPosition for root elements because this function is called a zillion times
|
// don't do the GetObjectPosition for root elements because this function is called a zillion times
|
||||||
// _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
|
// _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
|
||||||
return _position;
|
return _position;
|
||||||
|
@ -373,16 +283,31 @@ public sealed class BSPrim : PhysicsActor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the effective mass of the object. Non-physical objects do not have mass.
|
// Return the effective mass of the object.
|
||||||
public override float Mass {
|
// If there are multiple items in the linkset, add them together for the root
|
||||||
get {
|
public override float Mass
|
||||||
if (IsPhysical)
|
{
|
||||||
return _mass;
|
get
|
||||||
else
|
{
|
||||||
return 0f;
|
return _linkset.LinksetMass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// used when we only want this prim's mass and not the linkset thing
|
||||||
|
public float MassRaw { get { return _mass; } }
|
||||||
|
|
||||||
|
// Is this used?
|
||||||
|
public override OMV.Vector3 CenterOfMass
|
||||||
|
{
|
||||||
|
get { return _linkset.CenterOfMass; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is this used?
|
||||||
|
public override OMV.Vector3 GeometricCenter
|
||||||
|
{
|
||||||
|
get { return _linkset.GeometricCenter; }
|
||||||
|
}
|
||||||
|
|
||||||
public override OMV.Vector3 Force {
|
public override OMV.Vector3 Force {
|
||||||
get { return _force; }
|
get { return _force; }
|
||||||
set {
|
set {
|
||||||
|
@ -473,8 +398,6 @@ public sealed class BSPrim : PhysicsActor
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override OMV.Vector3 GeometricCenter { get { return OMV.Vector3.Zero; } }
|
|
||||||
public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } }
|
|
||||||
public override OMV.Vector3 Velocity {
|
public override OMV.Vector3 Velocity {
|
||||||
get { return _velocity; }
|
get { return _velocity; }
|
||||||
set {
|
set {
|
||||||
|
@ -503,9 +426,9 @@ public sealed class BSPrim : PhysicsActor
|
||||||
}
|
}
|
||||||
public override OMV.Quaternion Orientation {
|
public override OMV.Quaternion Orientation {
|
||||||
get {
|
get {
|
||||||
if (_parentPrim != null)
|
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);
|
||||||
}
|
}
|
||||||
return _orientation;
|
return _orientation;
|
||||||
|
@ -555,14 +478,16 @@ public sealed class BSPrim : PhysicsActor
|
||||||
private void SetObjectDynamic()
|
private void SetObjectDynamic()
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("{0}: ID={1}, SetObjectDynamic: IsStatic={2}, IsSolid={3}", LogHeader, _localID, IsStatic, IsSolid);
|
// m_log.DebugFormat("{0}: ID={1}, SetObjectDynamic: IsStatic={2}, IsSolid={3}", LogHeader, _localID, IsStatic, IsSolid);
|
||||||
// non-physical things work best with a mass of zero
|
|
||||||
if (!IsStatic)
|
RecreateGeomAndObject();
|
||||||
{
|
|
||||||
_mass = CalculateMass();
|
float mass = _mass;
|
||||||
RecreateGeomAndObject();
|
// Bullet wants static objects have a mass of zero
|
||||||
}
|
if (IsStatic)
|
||||||
DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, Mass);
|
mass = 0f;
|
||||||
BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), Mass);
|
|
||||||
|
DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, mass);
|
||||||
|
BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass);
|
||||||
}
|
}
|
||||||
|
|
||||||
// prims don't fly
|
// prims don't fly
|
||||||
|
@ -1004,6 +929,9 @@ public sealed class BSPrim : PhysicsActor
|
||||||
|
|
||||||
returnMass = _density * volume;
|
returnMass = _density * volume;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This change means each object keeps its own mass and the Mass property
|
||||||
|
* will return the sum if we're part of a linkset.
|
||||||
if (IsRootOfLinkset)
|
if (IsRootOfLinkset)
|
||||||
{
|
{
|
||||||
foreach (BSPrim prim in _childrenPrims)
|
foreach (BSPrim prim in _childrenPrims)
|
||||||
|
@ -1011,6 +939,7 @@ public sealed class BSPrim : PhysicsActor
|
||||||
returnMass += prim.CalculateMass();
|
returnMass += prim.CalculateMass();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if (returnMass <= 0)
|
if (returnMass <= 0)
|
||||||
returnMass = 0.0001f;
|
returnMass = 0.0001f;
|
||||||
|
@ -1026,9 +955,11 @@ public sealed class BSPrim : PhysicsActor
|
||||||
// The objects needs a hull if it's physical otherwise a mesh is enough
|
// The objects needs a hull if it's physical otherwise a mesh is enough
|
||||||
// No locking here because this is done when we know physics is not simulating
|
// No locking here because this is done when we know physics is not simulating
|
||||||
// if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used
|
// if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used
|
||||||
private void CreateGeom(bool forceRebuild)
|
// Returns 'true' if the geometry was rebuilt
|
||||||
|
private bool CreateGeom(bool forceRebuild)
|
||||||
{
|
{
|
||||||
// the mesher thought this was too simple to mesh. Use a native Bullet collision shape.
|
// the mesher thought this was too simple to mesh. Use a native Bullet collision shape.
|
||||||
|
bool ret = false;
|
||||||
if (!_scene.NeedsMeshing(_pbs))
|
if (!_scene.NeedsMeshing(_pbs))
|
||||||
{
|
{
|
||||||
if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
|
if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
|
||||||
|
@ -1036,18 +967,26 @@ public sealed class BSPrim : PhysicsActor
|
||||||
if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
|
if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size);
|
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size);
|
||||||
_shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE;
|
if (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE)
|
||||||
DetailLog("{0},CreateGeom,sphere", LocalID);
|
{
|
||||||
// Bullet native objects are scaled by the Bullet engine so pass the size in
|
DetailLog("{0},CreateGeom,sphere", LocalID);
|
||||||
_scale = _size;
|
_shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE;
|
||||||
|
ret = true;
|
||||||
|
// Bullet native objects are scaled by the Bullet engine so pass the size in
|
||||||
|
_scale = _size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, size={2}", LogHeader, LocalID, _size);
|
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, size={2}", LogHeader, LocalID, _size);
|
||||||
DetailLog("{0},CreateGeom,box", LocalID);
|
if (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX)
|
||||||
_shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
|
{
|
||||||
_scale = _size;
|
DetailLog("{0},CreateGeom,box", LocalID);
|
||||||
|
_shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
|
||||||
|
ret = true;
|
||||||
|
_scale = _size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1059,6 +998,7 @@ public sealed class BSPrim : PhysicsActor
|
||||||
// physical objects require a hull for interaction.
|
// physical objects require a hull for interaction.
|
||||||
// This will create the mesh if it doesn't already exist
|
// This will create the mesh if it doesn't already exist
|
||||||
CreateGeomHull();
|
CreateGeomHull();
|
||||||
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1067,9 +1007,11 @@ public sealed class BSPrim : PhysicsActor
|
||||||
{
|
{
|
||||||
// Static (non-physical) objects only need a mesh for bumping into
|
// Static (non-physical) objects only need a mesh for bumping into
|
||||||
CreateGeomMesh();
|
CreateGeomMesh();
|
||||||
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No locking here because this is done when we know physics is not simulating
|
// No locking here because this is done when we know physics is not simulating
|
||||||
|
@ -1254,20 +1196,18 @@ public sealed class BSPrim : PhysicsActor
|
||||||
// No locking here because this is done when the physics engine is not simulating
|
// No locking here because this is done when the physics engine is not simulating
|
||||||
private void CreateObject()
|
private void CreateObject()
|
||||||
{
|
{
|
||||||
if (IsRootOfLinkset)
|
// this routine is called when objects are rebuilt.
|
||||||
{
|
|
||||||
// Create a linkset around this object
|
// the mesh or hull must have already been created in Bullet
|
||||||
CreateLinkset();
|
ShapeData shape;
|
||||||
}
|
FillShapeInfo(out shape);
|
||||||
else
|
// m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type);
|
||||||
{
|
BulletSimAPI.CreateObject(_scene.WorldID, shape);
|
||||||
// simple object
|
// the CreateObject() may have recreated the rigid body. Make sure we have the latest.
|
||||||
// the mesh or hull must have already been created in Bullet
|
m_body.Ptr = BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID);
|
||||||
ShapeData shape;
|
|
||||||
FillShapeInfo(out shape);
|
// The root object could have been recreated. Make sure everything linksety is up to date.
|
||||||
// m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type);
|
_linkset.RefreshLinkset(this);
|
||||||
BulletSimAPI.CreateObject(_scene.WorldID, shape);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy prim's info into the BulletSim shape description structure
|
// Copy prim's info into the BulletSim shape description structure
|
||||||
|
@ -1279,7 +1219,7 @@ public sealed class BSPrim : PhysicsActor
|
||||||
shape.Rotation = _orientation;
|
shape.Rotation = _orientation;
|
||||||
shape.Velocity = _velocity;
|
shape.Velocity = _velocity;
|
||||||
shape.Scale = _scale;
|
shape.Scale = _scale;
|
||||||
shape.Mass = Mass;
|
shape.Mass = _isPhysical ? _mass : 0f;
|
||||||
shape.Buoyancy = _buoyancy;
|
shape.Buoyancy = _buoyancy;
|
||||||
shape.HullKey = _hullKey;
|
shape.HullKey = _hullKey;
|
||||||
shape.MeshKey = _meshKey;
|
shape.MeshKey = _meshKey;
|
||||||
|
@ -1289,83 +1229,6 @@ public sealed class BSPrim : PhysicsActor
|
||||||
shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue;
|
shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Linkset creation and destruction
|
|
||||||
|
|
||||||
// Create the linkset by putting constraints between the objects of the set so they cannot move
|
|
||||||
// relative to each other.
|
|
||||||
void CreateLinkset()
|
|
||||||
{
|
|
||||||
// DebugLog("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1);
|
|
||||||
|
|
||||||
// remove any constraints that might be in place
|
|
||||||
UnlinkAllChildren();
|
|
||||||
|
|
||||||
// create constraints between the root prim and each of the children
|
|
||||||
foreach (BSPrim prim in _childrenPrims)
|
|
||||||
{
|
|
||||||
LinkAChildToMe(prim);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a constraint between me (root of linkset) and the passed prim (the child).
|
|
||||||
// Called at taint time!
|
|
||||||
private void LinkAChildToMe(BSPrim childPrim)
|
|
||||||
{
|
|
||||||
// Zero motion for children so they don't interpolate
|
|
||||||
childPrim.ZeroMotion();
|
|
||||||
|
|
||||||
// relative position normalized to the root prim
|
|
||||||
OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(this._orientation);
|
|
||||||
OMV.Vector3 childRelativePosition = (childPrim._position - this._position) * invThisOrientation;
|
|
||||||
|
|
||||||
// relative rotation of the child to the parent
|
|
||||||
OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim._orientation;
|
|
||||||
|
|
||||||
// create a constraint that allows no freedom of movement between the two objects
|
|
||||||
// http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
|
|
||||||
// DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
|
|
||||||
DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", LocalID, LocalID, childPrim.LocalID);
|
|
||||||
BSConstraint constrain = _scene.Constraints.CreateConstraint(
|
|
||||||
_scene.World, this.Body, childPrim.Body,
|
|
||||||
childRelativePosition,
|
|
||||||
childRelativeRotation,
|
|
||||||
OMV.Vector3.Zero,
|
|
||||||
OMV.Quaternion.Identity);
|
|
||||||
constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
|
|
||||||
constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero);
|
|
||||||
|
|
||||||
// tweek the constraint to increase stability
|
|
||||||
constrain.UseFrameOffset(_scene.BoolNumeric(_scene.Params.linkConstraintUseFrameOffset));
|
|
||||||
if (_scene.BoolNumeric(_scene.Params.linkConstraintEnableTransMotor))
|
|
||||||
{
|
|
||||||
constrain.TranslationalLimitMotor(true,
|
|
||||||
_scene.Params.linkConstraintTransMotorMaxVel,
|
|
||||||
_scene.Params.linkConstraintTransMotorMaxForce);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove linkage between myself and a particular child
|
|
||||||
// Called at taint time!
|
|
||||||
private void UnlinkAChildFromMe(BSPrim childPrim)
|
|
||||||
{
|
|
||||||
DebugLog("{0}: UnlinkAChildFromMe: RemoveConstraint between root prim {1} and child prim {2}",
|
|
||||||
LogHeader, LocalID, childPrim.LocalID);
|
|
||||||
DetailLog("{0},UnlinkAChildFromMe,taint,root={1},child={2}", LocalID, LocalID, childPrim.LocalID);
|
|
||||||
// BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, childPrim.LocalID);
|
|
||||||
_scene.Constraints.RemoveAndDestroyConstraint(this.Body, childPrim.Body);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove linkage between myself and any possible children I might have
|
|
||||||
// Called at taint time!
|
|
||||||
private void UnlinkAllChildren()
|
|
||||||
{
|
|
||||||
DebugLog("{0}: UnlinkAllChildren:", LogHeader);
|
|
||||||
DetailLog("{0},UnlinkAllChildren,taint", LocalID);
|
|
||||||
_scene.Constraints.RemoveAndDestroyConstraint(this.Body);
|
|
||||||
// BulletSimAPI.RemoveConstraintByID(_scene.WorldID, LocalID);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion // Linkset creation and destruction
|
|
||||||
|
|
||||||
// Rebuild the geometry and object.
|
// Rebuild the geometry and object.
|
||||||
// This is called when the shape changes so we need to recreate the mesh/hull.
|
// This is called when the shape changes so we need to recreate the mesh/hull.
|
||||||
|
@ -1443,7 +1306,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 (_parentPrim == null)
|
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;
|
||||||
|
|
|
@ -73,7 +73,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
private static readonly string LogHeader = "[BULLETS SCENE]";
|
private static readonly string LogHeader = "[BULLETS SCENE]";
|
||||||
|
|
||||||
private void DebugLog(string mm, params Object[] xx) { if (shouldDebugLog) m_log.DebugFormat(mm, xx); }
|
public void DebugLog(string mm, params Object[] xx) { if (shouldDebugLog) m_log.DebugFormat(mm, xx); }
|
||||||
|
|
||||||
public string BulletSimVersion = "?";
|
public string BulletSimVersion = "?";
|
||||||
|
|
||||||
|
@ -87,6 +87,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
private uint m_worldID;
|
private uint m_worldID;
|
||||||
public uint WorldID { get { return m_worldID; } }
|
public uint WorldID { get { return m_worldID; } }
|
||||||
|
|
||||||
|
// let my minuions use my logger
|
||||||
|
public ILog Logger { get { return m_log; } }
|
||||||
|
|
||||||
private bool m_initialized = false;
|
private bool m_initialized = false;
|
||||||
|
|
||||||
private int m_detailedStatsStep = 0;
|
private int m_detailedStatsStep = 0;
|
||||||
|
@ -1026,7 +1029,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
(s,p,l,v) => { s.m_params[0].numberOfSolverIterations = v; } ),
|
(s,p,l,v) => { s.m_params[0].numberOfSolverIterations = v; } ),
|
||||||
|
|
||||||
new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.",
|
new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.",
|
||||||
ConfigurationParameters.numericTrue,
|
ConfigurationParameters.numericFalse,
|
||||||
(s,cf,p,v) => { s.m_params[0].linkConstraintUseFrameOffset = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
|
(s,cf,p,v) => { s.m_params[0].linkConstraintUseFrameOffset = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); },
|
||||||
(s) => { return s.m_params[0].linkConstraintUseFrameOffset; },
|
(s) => { return s.m_params[0].linkConstraintUseFrameOffset; },
|
||||||
(s,p,l,v) => { s.m_params[0].linkConstraintUseFrameOffset = v; } ),
|
(s,p,l,v) => { s.m_params[0].linkConstraintUseFrameOffset = v; } ),
|
||||||
|
|
|
@ -239,10 +239,10 @@ public static extern bool DestroyMesh(uint worldID, System.UInt64 meshKey);
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern bool CreateObject(uint worldID, ShapeData shapeData);
|
public static extern bool CreateObject(uint worldID, ShapeData shapeData);
|
||||||
|
|
||||||
|
/* Remove old functionality
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern void CreateLinkset(uint worldID, int objectCount, ShapeData[] shapeDatas);
|
public static extern void CreateLinkset(uint worldID, int objectCount, ShapeData[] shapeDatas);
|
||||||
|
|
||||||
/* Remove old functionality
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern void AddConstraint(uint worldID, uint id1, uint id2,
|
public static extern void AddConstraint(uint worldID, uint id1, uint id2,
|
||||||
Vector3 frame1, Quaternion frame1rot,
|
Vector3 frame1, Quaternion frame1rot,
|
||||||
|
|
|
@ -489,6 +489,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal Object OdeLock = new Object();
|
internal Object OdeLock = new Object();
|
||||||
|
|
||||||
|
private bool _worldInitialized = false;
|
||||||
|
|
||||||
public IMesher mesher;
|
public IMesher mesher;
|
||||||
|
|
||||||
private IConfigSource m_config;
|
private IConfigSource m_config;
|
||||||
|
@ -875,6 +877,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
staticPrimspace[i, j] = IntPtr.Zero;
|
staticPrimspace[i, j] = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_worldInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// internal void waitForSpaceUnlock(IntPtr space)
|
// internal void waitForSpaceUnlock(IntPtr space)
|
||||||
|
@ -2896,6 +2900,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
/// <returns>The number of frames simulated over that period.</returns>
|
/// <returns>The number of frames simulated over that period.</returns>
|
||||||
public override float Simulate(float timeStep)
|
public override float Simulate(float timeStep)
|
||||||
{
|
{
|
||||||
|
if (!_worldInitialized) return 11f;
|
||||||
|
|
||||||
int startFrameTick = CollectStats ? Util.EnvironmentTickCount() : 0;
|
int startFrameTick = CollectStats ? Util.EnvironmentTickCount() : 0;
|
||||||
int tempTick = 0, tempTick2 = 0;
|
int tempTick = 0, tempTick2 = 0;
|
||||||
|
|
||||||
|
@ -4017,6 +4023,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
|
_worldInitialized = false;
|
||||||
|
|
||||||
m_rayCastManager.Dispose();
|
m_rayCastManager.Dispose();
|
||||||
m_rayCastManager = null;
|
m_rayCastManager = null;
|
||||||
|
|
||||||
|
@ -4037,6 +4045,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
d.WorldDestroy(world);
|
d.WorldDestroy(world);
|
||||||
//d.CloseODE();
|
//d.CloseODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Dictionary<uint, float> GetTopColliders()
|
public override Dictionary<uint, float> GetTopColliders()
|
||||||
|
|
|
@ -915,7 +915,7 @@
|
||||||
NumberOfSolverIterations = 0;
|
NumberOfSolverIterations = 0;
|
||||||
|
|
||||||
; Linkset constraint parameters
|
; Linkset constraint parameters
|
||||||
LinkConstraintUseFrameOffset = True;
|
LinkConstraintUseFrameOffset = False;
|
||||||
LinkConstraintEnableTransMotor = True;
|
LinkConstraintEnableTransMotor = True;
|
||||||
LinkConstraintTransMotorMaxVel = 5.0;
|
LinkConstraintTransMotorMaxVel = 5.0;
|
||||||
LinkConstraintTransMotorMaxForce = 0.1;
|
LinkConstraintTransMotorMaxForce = 0.1;
|
||||||
|
@ -937,7 +937,7 @@
|
||||||
FixedTimeStep = .01667
|
FixedTimeStep = .01667
|
||||||
|
|
||||||
MaxCollisionsPerFrame = 2048
|
MaxCollisionsPerFrame = 2048
|
||||||
MaxUpdatesPerFrame = 2048
|
MaxUpdatesPerFrame = 8192
|
||||||
|
|
||||||
[RemoteAdmin]
|
[RemoteAdmin]
|
||||||
enabled = false
|
enabled = false
|
||||||
|
|
Loading…
Reference in New Issue