BulletSim: include the linkage to the layered prim implementation. Separate layers for physical (vs simulator) location displacement and linksets.

user_profiles
Robert Adams 2013-02-07 21:57:31 -08:00
parent 2fd184e350
commit 1b203601f4
8 changed files with 115 additions and 231 deletions

View File

@ -901,7 +901,7 @@ public sealed class BSCharacter : BSPhysObject
CurrentEntityProperties = entprop; CurrentEntityProperties = entprop;
// Tell the linkset about value changes // Tell the linkset about value changes
Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this); // Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
// Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
// base.RequestPhysicsterseUpdate(); // base.RequestPhysicsterseUpdate();

View File

@ -597,7 +597,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
if (IsActive) if (IsActive)
{ {
// Remember the mass so we don't have to fetch it every step // Remember the mass so we don't have to fetch it every step
m_vehicleMass = Prim.Linkset.LinksetMass; m_vehicleMass = Prim.TotalMass;
// Friction affects are handled by this vehicle code // Friction affects are handled by this vehicle code
PhysicsScene.PE.SetFriction(Prim.PhysBody, BSParam.VehicleFriction); PhysicsScene.PE.SetFriction(Prim.PhysBody, BSParam.VehicleFriction);

View File

@ -52,7 +52,7 @@ public abstract class BSLinkset
Manual = 2 // linkset tied together manually (code moves all the pieces) Manual = 2 // linkset tied together manually (code moves all the pieces)
} }
// Create the correct type of linkset for this child // Create the correct type of linkset for this child
public static BSLinkset Factory(BSScene physScene, BSPhysObject parent) public static BSLinkset Factory(BSScene physScene, BSPrimLinkable parent)
{ {
BSLinkset ret = null; BSLinkset ret = null;
@ -74,7 +74,7 @@ public abstract class BSLinkset
return ret; return ret;
} }
public BSPhysObject LinksetRoot { get; protected set; } public BSPrimLinkable LinksetRoot { get; protected set; }
public BSScene PhysicsScene { get; private set; } public BSScene PhysicsScene { get; private set; }
@ -82,7 +82,7 @@ public abstract class BSLinkset
public int LinksetID { get; private set; } public int LinksetID { get; private set; }
// The children under the root in this linkset. // The children under the root in this linkset.
protected HashSet<BSPhysObject> m_children; protected HashSet<BSPrimLinkable> m_children;
// We lock the diddling of linkset classes to prevent any badness. // We lock the diddling of linkset classes to prevent any badness.
// This locks the modification of the instances of this class. Changes // This locks the modification of the instances of this class. Changes
@ -91,7 +91,7 @@ public abstract class BSLinkset
// Some linksets have a preferred physical shape. // Some linksets have a preferred physical shape.
// Returns SHAPE_UNKNOWN if there is no preference. Causes the correct shape to be selected. // Returns SHAPE_UNKNOWN if there is no preference. Causes the correct shape to be selected.
public virtual BSPhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor) public virtual BSPhysicsShapeType PreferredPhysicalShape(BSPrimLinkable requestor)
{ {
return BSPhysicsShapeType.SHAPE_UNKNOWN; return BSPhysicsShapeType.SHAPE_UNKNOWN;
} }
@ -111,7 +111,7 @@ public abstract class BSLinkset
get { return ComputeLinksetGeometricCenter(); } get { return ComputeLinksetGeometricCenter(); }
} }
protected BSLinkset(BSScene scene, BSPhysObject parent) protected BSLinkset(BSScene scene, BSPrimLinkable parent)
{ {
// A simple linkset of one (no children) // A simple linkset of one (no children)
LinksetID = m_nextLinksetID++; LinksetID = m_nextLinksetID++;
@ -120,7 +120,7 @@ public abstract class BSLinkset
m_nextLinksetID = 1; m_nextLinksetID = 1;
PhysicsScene = scene; PhysicsScene = scene;
LinksetRoot = parent; LinksetRoot = parent;
m_children = new HashSet<BSPhysObject>(); m_children = new HashSet<BSPrimLinkable>();
LinksetMass = parent.RawMass; LinksetMass = parent.RawMass;
Rebuilding = false; Rebuilding = false;
} }
@ -129,7 +129,7 @@ public abstract class BSLinkset
// Parent changing should not happen so do some sanity checking. // Parent changing should not happen so do some sanity checking.
// We return the parent's linkset so the child can track its membership. // We return the parent's linkset so the child can track its membership.
// Called at runtime. // Called at runtime.
public BSLinkset AddMeToLinkset(BSPhysObject child) public BSLinkset AddMeToLinkset(BSPrimLinkable child)
{ {
lock (m_linksetActivityLock) lock (m_linksetActivityLock)
{ {
@ -145,14 +145,13 @@ public abstract class BSLinkset
// Returns a new linkset for the child which is a linkset of one (just the // Returns a new linkset for the child which is a linkset of one (just the
// orphened child). // orphened child).
// Called at runtime. // Called at runtime.
public BSLinkset RemoveMeFromLinkset(BSPhysObject child) public BSLinkset RemoveMeFromLinkset(BSPrimLinkable child)
{ {
lock (m_linksetActivityLock) lock (m_linksetActivityLock)
{ {
if (IsRoot(child)) if (IsRoot(child))
{ {
// Cannot remove the root from a linkset. // Cannot remove the root from a linkset.
child.PositionDisplacement = OMV.Vector3.Zero;
return this; return this;
} }
RemoveChildFromLinkset(child); RemoveChildFromLinkset(child);
@ -160,12 +159,11 @@ public abstract class BSLinkset
} }
// The child is down to a linkset of just itself // The child is down to a linkset of just itself
child.PositionDisplacement = OMV.Vector3.Zero;
return BSLinkset.Factory(PhysicsScene, child); return BSLinkset.Factory(PhysicsScene, child);
} }
// Return 'true' if the passed object is the root object of this linkset // Return 'true' if the passed object is the root object of this linkset
public bool IsRoot(BSPhysObject requestor) public bool IsRoot(BSPrimLinkable requestor)
{ {
return (requestor.LocalID == LinksetRoot.LocalID); return (requestor.LocalID == LinksetRoot.LocalID);
} }
@ -176,14 +174,14 @@ public abstract class BSLinkset
public bool HasAnyChildren { get { return (m_children.Count > 0); } } public bool HasAnyChildren { get { return (m_children.Count > 0); } }
// Return 'true' if this child is in this linkset // Return 'true' if this child is in this linkset
public bool HasChild(BSPhysObject child) public bool HasChild(BSPrimLinkable child)
{ {
bool ret = false; bool ret = false;
lock (m_linksetActivityLock) lock (m_linksetActivityLock)
{ {
ret = m_children.Contains(child); ret = m_children.Contains(child);
/* Safer version but the above should work /* Safer version but the above should work
foreach (BSPhysObject bp in m_children) foreach (BSPrimLinkable bp in m_children)
{ {
if (child.LocalID == bp.LocalID) if (child.LocalID == bp.LocalID)
{ {
@ -198,14 +196,14 @@ public abstract class BSLinkset
// Perform an action on each member of the linkset including root prim. // Perform an action on each member of the linkset including root prim.
// Depends on the action on whether this should be done at taint time. // Depends on the action on whether this should be done at taint time.
public delegate bool ForEachMemberAction(BSPhysObject obj); public delegate bool ForEachMemberAction(BSPrimLinkable obj);
public virtual bool ForEachMember(ForEachMemberAction action) public virtual bool ForEachMember(ForEachMemberAction action)
{ {
bool ret = false; bool ret = false;
lock (m_linksetActivityLock) lock (m_linksetActivityLock)
{ {
action(LinksetRoot); action(LinksetRoot);
foreach (BSPhysObject po in m_children) foreach (BSPrimLinkable po in m_children)
{ {
if (action(po)) if (action(po))
break; break;
@ -216,16 +214,16 @@ public abstract class BSLinkset
// I am the root of a linkset and a new child is being added // I am the root of a linkset and a new child is being added
// Called while LinkActivity is locked. // Called while LinkActivity is locked.
protected abstract void AddChildToLinkset(BSPhysObject child); protected abstract void AddChildToLinkset(BSPrimLinkable child);
// I am the root of a linkset and one of my children is being removed. // I am the root of a linkset and one of my children is being removed.
// Safe to call even if the child is not really in my linkset. // Safe to call even if the child is not really in my linkset.
protected abstract void RemoveChildFromLinkset(BSPhysObject child); protected abstract void RemoveChildFromLinkset(BSPrimLinkable child);
// When physical properties are changed the linkset needs to recalculate // When physical properties are changed the linkset needs to recalculate
// its internal properties. // its internal properties.
// May be called at runtime or taint-time. // May be called at runtime or taint-time.
public virtual void Refresh(BSPhysObject requestor) public virtual void Refresh(BSPrimLinkable requestor)
{ {
LinksetMass = ComputeLinksetMass(); LinksetMass = ComputeLinksetMass();
} }
@ -240,26 +238,26 @@ public abstract class BSLinkset
// has not yet been fully constructed. // has not yet been fully constructed.
// Return 'true' if any properties updated on the passed object. // Return 'true' if any properties updated on the passed object.
// Called at taint-time! // Called at taint-time!
public abstract bool MakeDynamic(BSPhysObject child); public abstract bool MakeDynamic(BSPrimLinkable child);
// The object is going static (non-physical). Do any setup necessary // The object is going static (non-physical). Do any setup necessary
// for a static linkset. // for a static linkset.
// Return 'true' if any properties updated on the passed object. // Return 'true' if any properties updated on the passed object.
// Called at taint-time! // Called at taint-time!
public abstract bool MakeStatic(BSPhysObject child); public abstract bool MakeStatic(BSPrimLinkable child);
// Called when a parameter update comes from the physics engine for any object // Called when a parameter update comes from the physics engine for any object
// of the linkset is received. // of the linkset is received.
// Passed flag is update came from physics engine (true) or the user (false). // Passed flag is update came from physics engine (true) or the user (false).
// Called at taint-time!! // Called at taint-time!!
public abstract void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject physObject); public abstract void UpdateProperties(UpdatedProperties whichUpdated, BSPrimLinkable physObject);
// Routine used when rebuilding the body of the root of the linkset // Routine used when rebuilding the body of the root of the linkset
// Destroy all the constraints have have been made to root. // Destroy all the constraints have have been made to root.
// This is called when the root body is changing. // This is called when the root body is changing.
// Returns 'true' of something was actually removed and would need restoring // Returns 'true' of something was actually removed and would need restoring
// Called at taint-time!! // Called at taint-time!!
public abstract bool RemoveBodyDependencies(BSPrim child); public abstract bool RemoveBodyDependencies(BSPrimLinkable child);
// ================================================================ // ================================================================
protected virtual float ComputeLinksetMass() protected virtual float ComputeLinksetMass()
@ -269,7 +267,7 @@ public abstract class BSLinkset
{ {
lock (m_linksetActivityLock) lock (m_linksetActivityLock)
{ {
foreach (BSPhysObject bp in m_children) foreach (BSPrimLinkable bp in m_children)
{ {
mass += bp.RawMass; mass += bp.RawMass;
} }
@ -286,7 +284,7 @@ public abstract class BSLinkset
com = LinksetRoot.Position * LinksetRoot.RawMass; com = LinksetRoot.Position * LinksetRoot.RawMass;
float totalMass = LinksetRoot.RawMass; float totalMass = LinksetRoot.RawMass;
foreach (BSPhysObject bp in m_children) foreach (BSPrimLinkable bp in m_children)
{ {
com += bp.Position * bp.RawMass; com += bp.Position * bp.RawMass;
totalMass += bp.RawMass; totalMass += bp.RawMass;
@ -305,7 +303,7 @@ public abstract class BSLinkset
{ {
com = LinksetRoot.Position; com = LinksetRoot.Position;
foreach (BSPhysObject bp in m_children) foreach (BSPrimLinkable bp in m_children)
{ {
com += bp.Position; com += bp.Position;
} }

View File

@ -52,7 +52,7 @@ sealed class BSLinksetCompoundInfo : BSLinksetInfo
OffsetRot = r; OffsetRot = r;
} }
// 'centerDisplacement' is the distance from the root the the center-of-mass (Bullet 'zero' of the shape) // 'centerDisplacement' is the distance from the root the the center-of-mass (Bullet 'zero' of the shape)
public BSLinksetCompoundInfo(int indx, BSPhysObject root, BSPhysObject child, OMV.Vector3 centerDisplacement) public BSLinksetCompoundInfo(int indx, BSPrimLinkable root, BSPrimLinkable child, OMV.Vector3 centerDisplacement)
{ {
// Each child position and rotation is given relative to the center-of-mass. // Each child position and rotation is given relative to the center-of-mass.
OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(root.RawOrientation); OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(root.RawOrientation);
@ -93,12 +93,12 @@ public sealed class BSLinksetCompound : BSLinkset
{ {
private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]"; private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]";
public BSLinksetCompound(BSScene scene, BSPhysObject parent) : base(scene, parent) public BSLinksetCompound(BSScene scene, BSPrimLinkable parent) : base(scene, parent)
{ {
} }
// For compound implimented linksets, if there are children, use compound shape for the root. // For compound implimented linksets, if there are children, use compound shape for the root.
public override BSPhysicsShapeType PreferredPhysicalShape(BSPhysObject requestor) public override BSPhysicsShapeType PreferredPhysicalShape(BSPrimLinkable requestor)
{ {
// Returning 'unknown' means we don't have a preference. // Returning 'unknown' means we don't have a preference.
BSPhysicsShapeType ret = BSPhysicsShapeType.SHAPE_UNKNOWN; BSPhysicsShapeType ret = BSPhysicsShapeType.SHAPE_UNKNOWN;
@ -112,7 +112,7 @@ public sealed class BSLinksetCompound : BSLinkset
// When physical properties are changed the linkset needs to recalculate // When physical properties are changed the linkset needs to recalculate
// its internal properties. // its internal properties.
public override void Refresh(BSPhysObject requestor) public override void Refresh(BSPrimLinkable requestor)
{ {
base.Refresh(requestor); base.Refresh(requestor);
@ -121,7 +121,7 @@ public sealed class BSLinksetCompound : BSLinkset
} }
// Schedule a refresh to happen after all the other taint processing. // Schedule a refresh to happen after all the other taint processing.
private void ScheduleRebuild(BSPhysObject requestor) private void ScheduleRebuild(BSPrimLinkable requestor)
{ {
DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1},hasChildren={2},actuallyScheduling={3}", DetailLog("{0},BSLinksetCompound.ScheduleRebuild,,rebuilding={1},hasChildren={2},actuallyScheduling={3}",
requestor.LocalID, Rebuilding, HasAnyChildren, (!Rebuilding && HasAnyChildren)); requestor.LocalID, Rebuilding, HasAnyChildren, (!Rebuilding && HasAnyChildren));
@ -143,7 +143,7 @@ public sealed class BSLinksetCompound : BSLinkset
// has not yet been fully constructed. // has not yet been fully constructed.
// Return 'true' if any properties updated on the passed object. // Return 'true' if any properties updated on the passed object.
// Called at taint-time! // Called at taint-time!
public override bool MakeDynamic(BSPhysObject child) public override bool MakeDynamic(BSPrimLinkable child)
{ {
bool ret = false; bool ret = false;
DetailLog("{0},BSLinksetCompound.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child)); DetailLog("{0},BSLinksetCompound.MakeDynamic,call,IsRoot={1}", child.LocalID, IsRoot(child));
@ -173,7 +173,7 @@ public sealed class BSLinksetCompound : BSLinkset
// This doesn't normally happen -- OpenSim removes the objects from the physical // This doesn't normally happen -- OpenSim removes the objects from the physical
// world if it is a static linkset. // world if it is a static linkset.
// Called at taint-time! // Called at taint-time!
public override bool MakeStatic(BSPhysObject child) public override bool MakeStatic(BSPrimLinkable child)
{ {
bool ret = false; bool ret = false;
DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child)); DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child));
@ -197,7 +197,7 @@ public sealed class BSLinksetCompound : BSLinkset
// 'physicalUpdate' is true if these changes came directly from the physics engine. Don't need to rebuild then. // 'physicalUpdate' is true if these changes came directly from the physics engine. Don't need to rebuild then.
// Called at taint-time. // Called at taint-time.
public override void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject updated) public override void UpdateProperties(UpdatedProperties whichUpdated, BSPrimLinkable updated)
{ {
// The user moving a child around requires the rebuilding of the linkset compound shape // The user moving a child around requires the rebuilding of the linkset compound shape
// One problem is this happens when a border is crossed -- the simulator implementation // One problem is this happens when a border is crossed -- the simulator implementation
@ -222,7 +222,7 @@ public sealed class BSLinksetCompound : BSLinkset
if (lsi != null) if (lsi != null)
{ {
// Since the child moved or rotationed, it needs a new relative position within the linkset // Since the child moved or rotationed, it needs a new relative position within the linkset
BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, LinksetRoot.PositionDisplacement); BSLinksetCompoundInfo newLsi = new BSLinksetCompoundInfo(lsi.Index, LinksetRoot, updated, OMV.Vector3.Zero);
updated.LinksetInfo = newLsi; updated.LinksetInfo = newLsi;
// Find the physical instance of the child // Find the physical instance of the child
@ -291,7 +291,7 @@ public sealed class BSLinksetCompound : BSLinkset
// Since we don't keep in world relationships, do nothing unless it's a child changing. // Since we don't keep in world relationships, do nothing unless it's a child changing.
// Returns 'true' of something was actually removed and would need restoring // Returns 'true' of something was actually removed and would need restoring
// Called at taint-time!! // Called at taint-time!!
public override bool RemoveBodyDependencies(BSPrim child) public override bool RemoveBodyDependencies(BSPrimLinkable child)
{ {
bool ret = false; bool ret = false;
@ -316,7 +316,7 @@ public sealed class BSLinksetCompound : BSLinkset
// When the linkset is built, the child shape is added to the compound shape relative to the // When the linkset is built, the child shape is added to the compound shape relative to the
// root shape. The linkset then moves around but this does not move the actual child // root shape. The linkset then moves around but this does not move the actual child
// prim. The child prim's location must be recomputed based on the location of the root shape. // prim. The child prim's location must be recomputed based on the location of the root shape.
private void RecomputeChildWorldPosition(BSPhysObject child, bool inTaintTime) private void RecomputeChildWorldPosition(BSPrimLinkable child, bool inTaintTime)
{ {
// For the moment (20130201), disable this computation (converting the child physical addr back to // For the moment (20130201), disable this computation (converting the child physical addr back to
// a region address) until we have a good handle on center-of-mass offsets and what the physics // a region address) until we have a good handle on center-of-mass offsets and what the physics
@ -361,7 +361,7 @@ public sealed class BSLinksetCompound : BSLinkset
// Add a new child to the linkset. // Add a new child to the linkset.
// Called while LinkActivity is locked. // Called while LinkActivity is locked.
protected override void AddChildToLinkset(BSPhysObject child) protected override void AddChildToLinkset(BSPrimLinkable child)
{ {
if (!HasChild(child)) if (!HasChild(child))
{ {
@ -377,7 +377,7 @@ public sealed class BSLinksetCompound : BSLinkset
// Remove the specified child from the linkset. // Remove the specified child from the linkset.
// Safe to call even if the child is not really in the linkset. // Safe to call even if the child is not really in the linkset.
protected override void RemoveChildFromLinkset(BSPhysObject child) protected override void RemoveChildFromLinkset(BSPrimLinkable child)
{ {
if (m_children.Remove(child)) if (m_children.Remove(child))
{ {
@ -429,7 +429,7 @@ public sealed class BSLinksetCompound : BSLinkset
if (disableCOM) // DEBUG DEBUG if (disableCOM) // DEBUG DEBUG
{ // DEBUG DEBUG { // DEBUG DEBUG
centerOfMass = LinksetRoot.RawPosition; // DEBUG DEBUG centerOfMass = LinksetRoot.RawPosition; // DEBUG DEBUG
LinksetRoot.PositionDisplacement = OMV.Vector3.Zero; // LinksetRoot.PositionDisplacement = OMV.Vector3.Zero;
} // DEBUG DEBUG } // DEBUG DEBUG
else else
{ {
@ -438,7 +438,7 @@ public sealed class BSLinksetCompound : BSLinkset
centerDisplacement = LinksetRoot.RawPosition - centerOfMass; centerDisplacement = LinksetRoot.RawPosition - centerOfMass;
// Since we're displacing the center of the shape, we need to move the body in the world // Since we're displacing the center of the shape, we need to move the body in the world
LinksetRoot.PositionDisplacement = centerDisplacement; // LinksetRoot.PositionDisplacement = centerDisplacement;
// This causes the root prim position to be set properly based on the new PositionDisplacement // This causes the root prim position to be set properly based on the new PositionDisplacement
LinksetRoot.ForcePosition = LinksetRoot.RawPosition; LinksetRoot.ForcePosition = LinksetRoot.RawPosition;
@ -453,7 +453,7 @@ public sealed class BSLinksetCompound : BSLinkset
// Add a shape for each of the other children in the linkset // Add a shape for each of the other children in the linkset
int memberIndex = 1; int memberIndex = 1;
ForEachMember(delegate(BSPhysObject cPrim) ForEachMember(delegate(BSPrimLinkable cPrim)
{ {
if (!IsRoot(cPrim)) if (!IsRoot(cPrim))
{ {

View File

@ -36,7 +36,7 @@ public sealed class BSLinksetConstraints : BSLinkset
{ {
// private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]";
public BSLinksetConstraints(BSScene scene, BSPhysObject parent) : base(scene, parent) public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent)
{ {
} }
@ -44,7 +44,7 @@ public sealed class BSLinksetConstraints : BSLinkset
// its internal properties. // its internal properties.
// This is queued in the 'post taint' queue so the // This is queued in the 'post taint' queue so the
// refresh will happen once after all the other taints are applied. // refresh will happen once after all the other taints are applied.
public override void Refresh(BSPhysObject requestor) public override void Refresh(BSPrimLinkable requestor)
{ {
base.Refresh(requestor); base.Refresh(requestor);
@ -65,7 +65,7 @@ public sealed class BSLinksetConstraints : BSLinkset
// has not yet been fully constructed. // has not yet been fully constructed.
// Return 'true' if any properties updated on the passed object. // Return 'true' if any properties updated on the passed object.
// Called at taint-time! // Called at taint-time!
public override bool MakeDynamic(BSPhysObject child) public override bool MakeDynamic(BSPrimLinkable child)
{ {
// What is done for each object in BSPrim is what we want. // What is done for each object in BSPrim is what we want.
return false; return false;
@ -76,14 +76,14 @@ public sealed class BSLinksetConstraints : BSLinkset
// This doesn't normally happen -- OpenSim removes the objects from the physical // This doesn't normally happen -- OpenSim removes the objects from the physical
// world if it is a static linkset. // world if it is a static linkset.
// Called at taint-time! // Called at taint-time!
public override bool MakeStatic(BSPhysObject child) public override bool MakeStatic(BSPrimLinkable child)
{ {
// What is done for each object in BSPrim is what we want. // What is done for each object in BSPrim is what we want.
return false; return false;
} }
// Called at taint-time!! // Called at taint-time!!
public override void UpdateProperties(UpdatedProperties whichUpdated, BSPhysObject pObj) public override void UpdateProperties(UpdatedProperties whichUpdated, BSPrimLinkable pObj)
{ {
// Nothing to do for constraints on property updates // Nothing to do for constraints on property updates
} }
@ -93,7 +93,7 @@ public sealed class BSLinksetConstraints : BSLinkset
// up to rebuild the constraints before the next simulation step. // up to rebuild the constraints before the next simulation step.
// Returns 'true' of something was actually removed and would need restoring // Returns 'true' of something was actually removed and would need restoring
// Called at taint-time!! // Called at taint-time!!
public override bool RemoveBodyDependencies(BSPrim child) public override bool RemoveBodyDependencies(BSPrimLinkable child)
{ {
bool ret = false; bool ret = false;
@ -114,7 +114,7 @@ public sealed class BSLinksetConstraints : BSLinkset
// Add a new child to the linkset. // Add a new child to the linkset.
// Called while LinkActivity is locked. // Called while LinkActivity is locked.
protected override void AddChildToLinkset(BSPhysObject child) protected override void AddChildToLinkset(BSPrimLinkable child)
{ {
if (!HasChild(child)) if (!HasChild(child))
{ {
@ -130,12 +130,12 @@ public sealed class BSLinksetConstraints : BSLinkset
// Remove the specified child from the linkset. // Remove the specified child from the linkset.
// Safe to call even if the child is not really in my linkset. // Safe to call even if the child is not really in my linkset.
protected override void RemoveChildFromLinkset(BSPhysObject child) protected override void RemoveChildFromLinkset(BSPrimLinkable child)
{ {
if (m_children.Remove(child)) if (m_children.Remove(child))
{ {
BSPhysObject rootx = LinksetRoot; // capture the root and body as of now BSPrimLinkable rootx = LinksetRoot; // capture the root and body as of now
BSPhysObject childx = child; BSPrimLinkable childx = child;
DetailLog("{0},BSLinksetConstraints.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", DetailLog("{0},BSLinksetConstraints.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}",
childx.LocalID, childx.LocalID,
@ -159,13 +159,13 @@ public sealed class BSLinksetConstraints : BSLinkset
// Create a constraint between me (root of linkset) and the passed prim (the child). // Create a constraint between me (root of linkset) and the passed prim (the child).
// Called at taint time! // Called at taint time!
private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim) private void PhysicallyLinkAChildToRoot(BSPrimLinkable rootPrim, BSPrimLinkable childPrim)
{ {
// Don't build the constraint when asked. Put it off until just before the simulation step. // Don't build the constraint when asked. Put it off until just before the simulation step.
Refresh(rootPrim); Refresh(rootPrim);
} }
private BSConstraint BuildConstraint(BSPhysObject rootPrim, BSPhysObject childPrim) private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSPrimLinkable childPrim)
{ {
// Zero motion for children so they don't interpolate // Zero motion for children so they don't interpolate
childPrim.ZeroMotion(true); childPrim.ZeroMotion(true);
@ -239,7 +239,7 @@ public sealed class BSLinksetConstraints : BSLinkset
// The root and child bodies are passed in because we need to remove the constraint between // The root and child bodies are passed in because we need to remove the constraint between
// the bodies that were present at unlink time. // the bodies that were present at unlink time.
// Called at taint time! // Called at taint time!
private bool PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim) private bool PhysicallyUnlinkAChildFromRoot(BSPrimLinkable rootPrim, BSPrimLinkable childPrim)
{ {
bool ret = false; bool ret = false;
DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}", DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAChildFromRoot,taint,root={1},rBody={2},child={3},cBody={4}",
@ -261,7 +261,7 @@ public sealed class BSLinksetConstraints : BSLinkset
// Remove linkage between myself and any possible children I might have. // Remove linkage between myself and any possible children I might have.
// Returns 'true' of any constraints were destroyed. // Returns 'true' of any constraints were destroyed.
// Called at taint time! // Called at taint time!
private bool PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim) private bool PhysicallyUnlinkAllChildrenFromRoot(BSPrimLinkable rootPrim)
{ {
DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); DetailLog("{0},BSLinksetConstraint.PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
@ -281,7 +281,7 @@ public sealed class BSLinksetConstraints : BSLinkset
DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}", DetailLog("{0},BSLinksetConstraint.RecomputeLinksetConstraints,set,rBody={1},linksetMass={2}",
LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString, linksetMass); LinksetRoot.LocalID, LinksetRoot.PhysBody.AddrString, linksetMass);
foreach (BSPhysObject child in m_children) foreach (BSPrimLinkable child in m_children)
{ {
// A child in the linkset physically shows the mass of the whole linkset. // A child in the linkset physically shows the mass of the whole linkset.
// This allows Bullet to apply enough force on the child to move the whole linkset. // This allows Bullet to apply enough force on the child to move the whole linkset.

View File

@ -86,10 +86,6 @@ public abstract class BSPhysObject : PhysicsActor
PhysBody = new BulletBody(localID); PhysBody = new BulletBody(localID);
PhysShape = new BulletShape(); PhysShape = new BulletShape();
// A linkset of just me
Linkset = BSLinkset.Factory(PhysicsScene, this);
PositionDisplacement = OMV.Vector3.Zero;
LastAssetBuildFailed = false; LastAssetBuildFailed = false;
// Default material type. Also sets Friction, Restitution and Density. // Default material type. Also sets Friction, Restitution and Density.
@ -117,8 +113,6 @@ public abstract class BSPhysObject : PhysicsActor
public string PhysObjectName { get; protected set; } public string PhysObjectName { get; protected set; }
public string TypeName { get; protected set; } public string TypeName { get; protected set; }
public BSLinkset Linkset { get; set; }
public BSLinksetInfo LinksetInfo { get; set; }
// Return the object mass without calculating it or having side effects // Return the object mass without calculating it or having side effects
public abstract float RawMass { get; } public abstract float RawMass { get; }
@ -188,15 +182,6 @@ public abstract class BSPhysObject : PhysicsActor
public abstract OMV.Vector3 RawPosition { get; set; } public abstract OMV.Vector3 RawPosition { get; set; }
public abstract OMV.Vector3 ForcePosition { get; set; } public abstract OMV.Vector3 ForcePosition { get; set; }
// 'Position' and 'Orientation' is what the simulator thinks the positions of the prim is.
// Because Bullet needs the zero coordinate to be the center of mass of the linkset,
// sometimes it is necessary to displace the position the physics engine thinks
// the position is. PositionDisplacement must be added and removed from the
// position as the simulator position is stored and fetched from the physics
// engine. Similar to OrientationDisplacement.
public virtual OMV.Vector3 PositionDisplacement { get; set; }
public virtual OMV.Quaternion OrientationDisplacement { get; set; }
public abstract OMV.Quaternion RawOrientation { get; set; } public abstract OMV.Quaternion RawOrientation { get; set; }
public abstract OMV.Quaternion ForceOrientation { get; set; } public abstract OMV.Quaternion ForceOrientation { get; set; }
@ -302,12 +287,6 @@ public abstract class BSPhysObject : PhysicsActor
CollidingObjectStep = PhysicsScene.SimulationStep; CollidingObjectStep = PhysicsScene.SimulationStep;
} }
// prims in the same linkset cannot collide with each other
if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID))
{
return ret;
}
CollisionAccumulation++; CollisionAccumulation++;
// For movement tests, remember if we are colliding with an object that is moving. // For movement tests, remember if we are colliding with an object that is moving.

View File

@ -39,7 +39,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
{ {
[Serializable] [Serializable]
public sealed class BSPrim : BSPhysObject public class BSPrim : BSPhysObject
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string LogHeader = "[BULLETS PRIM]"; private static readonly string LogHeader = "[BULLETS PRIM]";
@ -102,9 +102,6 @@ public sealed class BSPrim : BSPhysObject
_mass = CalculateMass(); _mass = CalculateMass();
// Cause linkset variables to be initialized (like mass)
Linkset.Refresh(this);
DetailLog("{0},BSPrim.constructor,call", LocalID); DetailLog("{0},BSPrim.constructor,call", LocalID);
// do the actual object creation at taint time // do the actual object creation at taint time
PhysicsScene.TaintedObject("BSPrim.create", delegate() PhysicsScene.TaintedObject("BSPrim.create", delegate()
@ -121,15 +118,6 @@ public sealed class BSPrim : BSPhysObject
// m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID);
base.Destroy(); base.Destroy();
// Undo any links between me and any other object
BSPhysObject parentBefore = Linkset.LinksetRoot; // DEBUG DEBUG
int childrenBefore = Linkset.NumberOfChildren; // DEBUG DEBUG
Linkset = Linkset.RemoveMeFromLinkset(this);
DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}",
LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
// Undo any vehicle properties // Undo any vehicle properties
this.VehicleType = (int)Vehicle.TYPE_NONE; this.VehicleType = (int)Vehicle.TYPE_NONE;
@ -166,9 +154,9 @@ public sealed class BSPrim : BSPhysObject
ForceBodyShapeRebuild(false); ForceBodyShapeRebuild(false);
} }
} }
// Whatever the linkset wants is what I want. // 'unknown' says to choose the best type
public override BSPhysicsShapeType PreferredPhysicalShape public override BSPhysicsShapeType PreferredPhysicalShape
{ get { return Linkset.PreferredPhysicalShape(this); } } { get { return BSPhysicsShapeType.SHAPE_UNKNOWN; } }
public override bool ForceBodyShapeRebuild(bool inTaintTime) public override bool ForceBodyShapeRebuild(bool inTaintTime)
{ {
@ -213,33 +201,10 @@ public sealed class BSPrim : BSPhysObject
// link me to the specified parent // link me to the specified parent
public override void link(PhysicsActor obj) { public override void link(PhysicsActor obj) {
BSPrim parent = obj as BSPrim;
if (parent != null)
{
BSPhysObject parentBefore = Linkset.LinksetRoot;
int childrenBefore = Linkset.NumberOfChildren;
Linkset = parent.Linkset.AddMeToLinkset(this);
DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}",
LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
}
return;
} }
// delink me from my linkset // delink me from my linkset
public override void delink() { public override void delink() {
// TODO: decide if this parent checking needs to happen at taint time
// Race condition here: if link() and delink() in same simulation tick, the delink will not happen
BSPhysObject parentBefore = Linkset.LinksetRoot;
int childrenBefore = Linkset.NumberOfChildren;
Linkset = Linkset.RemoveMeFromLinkset(this);
DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",
LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
return;
} }
// Set motion values to zero. // Set motion values to zero.
@ -287,15 +252,8 @@ public sealed class BSPrim : BSPhysObject
} }
public override OMV.Vector3 Position { public override OMV.Vector3 Position {
get { get {
/* NOTE: this refetch is not necessary. The simulator knows about linkset children
* and does not fetch this position info for children. Thus this is commented out.
// child prims move around based on their parent. Need to get the latest location
if (!Linkset.IsRoot(this))
_position = Linkset.PositionGet(this);
*/
// don't do the GetObjectPosition for root elements because this function is called a zillion times. // don't do the GetObjectPosition for root elements because this function is called a zillion times.
// _position = PhysicsScene.PE.GetObjectPosition2(PhysicsScene.World, BSBody) - PositionDisplacement; // _position = ForcePosition;
return _position; return _position;
} }
set { set {
@ -313,24 +271,20 @@ public sealed class BSPrim : BSPhysObject
{ {
DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
ForcePosition = _position; ForcePosition = _position;
// A linkset might need to know if a component information changed.
Linkset.UpdateProperties(UpdatedProperties.Position, this);
}); });
} }
} }
public override OMV.Vector3 ForcePosition { public override OMV.Vector3 ForcePosition {
get { get {
_position = PhysicsScene.PE.GetPosition(PhysBody) - PositionDisplacement; _position = PhysicsScene.PE.GetPosition(PhysBody);
return _position; return _position;
} }
set { set {
_position = value; _position = value;
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
{ {
PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation); PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
ActivateIfPhysical(false); ActivateIfPhysical(false);
} }
} }
@ -398,12 +352,13 @@ public sealed class BSPrim : BSPhysObject
// If the simulator cares about the mass of the linkset, it will sum it itself. // If the simulator cares about the mass of the linkset, it will sum it itself.
public override float Mass public override float Mass
{ {
get get { return _mass; }
}
// TotalMass returns the mass of the large object the prim may be in (overridden by linkset code)
public virtual float TotalMass
{ {
return _mass; get { return _mass; }
} }
}
// used when we only want this prim's mass and not the linkset thing // used when we only want this prim's mass and not the linkset thing
public override float RawMass { public override float RawMass {
get { return _mass; } get { return _mass; }
@ -467,13 +422,13 @@ public sealed class BSPrim : BSPhysObject
// Is this used? // Is this used?
public override OMV.Vector3 CenterOfMass public override OMV.Vector3 CenterOfMass
{ {
get { return Linkset.CenterOfMass; } get { return RawPosition; }
} }
// Is this used? // Is this used?
public override OMV.Vector3 GeometricCenter public override OMV.Vector3 GeometricCenter
{ {
get { return Linkset.GeometricCenter; } get { return RawPosition; }
} }
public override OMV.Vector3 Force { public override OMV.Vector3 Force {
@ -721,14 +676,6 @@ public sealed class BSPrim : BSPhysObject
} }
public override OMV.Quaternion Orientation { public override OMV.Quaternion Orientation {
get { get {
/* NOTE: this refetch is not necessary. The simulator knows about linkset children
* and does not fetch this position info for children. Thus this is commented out.
// Children move around because tied to parent. Get a fresh value.
if (!Linkset.IsRoot(this))
{
_orientation = Linkset.OrientationGet(this);
}
*/
return _orientation; return _orientation;
} }
set { set {
@ -739,10 +686,6 @@ public sealed class BSPrim : BSPhysObject
PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate() PhysicsScene.TaintedObject("BSPrim.setOrientation", delegate()
{ {
ForceOrientation = _orientation; ForceOrientation = _orientation;
// A linkset might need to know if a component information changed.
Linkset.UpdateProperties(UpdatedProperties.Orientation, this);
}); });
} }
} }
@ -758,7 +701,7 @@ public sealed class BSPrim : BSPhysObject
{ {
_orientation = value; _orientation = value;
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation); PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
} }
} }
public override int PhysicsActorType { public override int PhysicsActorType {
@ -814,7 +757,7 @@ public sealed class BSPrim : BSPhysObject
// isSolid: other objects bounce off of this object // isSolid: other objects bounce off of this object
// isVolumeDetect: other objects pass through but can generate collisions // isVolumeDetect: other objects pass through but can generate collisions
// collisionEvents: whether this object returns collision events // collisionEvents: whether this object returns collision events
public void UpdatePhysicalParameters() public virtual void UpdatePhysicalParameters()
{ {
if (!PhysBody.HasPhysicalBody) if (!PhysBody.HasPhysicalBody)
{ {
@ -844,12 +787,6 @@ public sealed class BSPrim : BSPhysObject
// Rebuild its shape // Rebuild its shape
PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, PhysBody); PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, PhysBody);
// Recompute any linkset parameters.
// When going from non-physical to physical, this re-enables the constraints that
// had been automatically disabled when the mass was set to zero.
// For compound based linksets, this enables and disables interactions of the children.
Linkset.Refresh(this);
DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},cType={6},body={7},shape={8}", DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},cType={6},body={7},shape={8}",
LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody.collisionType, PhysBody, PhysShape); LocalID, IsStatic, IsSolid, Mass, SubscribedEvents(), CurrentCollisionFlags, PhysBody.collisionType, PhysBody, PhysShape);
} }
@ -859,7 +796,7 @@ public sealed class BSPrim : BSPhysObject
// When dynamic, the object can fall and be pushed by others. // When dynamic, the object can fall and be pushed by others.
// This is independent of its 'solidness' which controls what passes through // This is independent of its 'solidness' which controls what passes through
// this object and what interacts with it. // this object and what interacts with it.
private void MakeDynamic(bool makeStatic) protected virtual void MakeDynamic(bool makeStatic)
{ {
if (makeStatic) if (makeStatic)
{ {
@ -889,9 +826,6 @@ public sealed class BSPrim : BSPhysObject
// This collides like a static object // This collides like a static object
PhysBody.collisionType = CollisionType.Static; PhysBody.collisionType = CollisionType.Static;
// There can be special things needed for implementing linksets
Linkset.MakeStatic(this);
} }
else else
{ {
@ -908,10 +842,7 @@ public sealed class BSPrim : BSPhysObject
// PhysicsScene.PE.ClearAllForces(BSBody); // PhysicsScene.PE.ClearAllForces(BSBody);
// For good measure, make sure the transform is set through to the motion state // For good measure, make sure the transform is set through to the motion state
PhysicsScene.PE.SetTranslation(PhysBody, _position + PositionDisplacement, _orientation); ForcePosition = _position;
// Center of mass is at the center of the object
// DEBUG DEBUG PhysicsScene.PE.SetCenterOfMassByPosRot(Linkset.LinksetRoot.PhysBody, _position, _orientation);
// A dynamic object has mass // A dynamic object has mass
UpdatePhysicalMassProperties(RawMass, false); UpdatePhysicalMassProperties(RawMass, false);
@ -935,9 +866,6 @@ public sealed class BSPrim : BSPhysObject
// Force activation of the object so Bullet will act on it. // Force activation of the object so Bullet will act on it.
// Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects. // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects.
PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG); PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG);
// There might be special things needed for implementing linksets.
Linkset.MakeDynamic(this);
} }
} }
@ -1643,16 +1571,6 @@ public sealed class BSPrim : BSPhysObject
returnMass = Density * volume; returnMass = Density * volume;
/* Comment out code that computes the mass of the linkset. That is done in the Linkset class.
if (IsRootOfLinkset)
{
foreach (BSPrim prim in _childrenPrims)
{
returnMass += prim.CalculateMass();
}
}
*/
returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass); returnMass = Util.Clamp(returnMass, BSParam.MinimumObjectMass, BSParam.MaximumObjectMass);
return returnMass; return returnMass;
@ -1672,8 +1590,7 @@ public sealed class BSPrim : BSPhysObject
// Called if the current prim body is about to be destroyed. // Called if the current prim body is about to be destroyed.
// Remove all the physical dependencies on the old body. // Remove all the physical dependencies on the old body.
// (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...) // (Maybe someday make the changing of BSShape an event to be subscribed to by BSLinkset, ...)
Linkset.RemoveBodyDependencies(this); RemoveBodyDependencies();
VehicleController.RemoveBodyDependencies(this);
}); });
// Make sure the properties are set on the new object // Make sure the properties are set on the new object
@ -1681,12 +1598,14 @@ public sealed class BSPrim : BSPhysObject
return; return;
} }
protected virtual void RemoveBodyDependencies()
{
VehicleController.RemoveBodyDependencies(this);
}
// The physics engine says that properties have updated. Update same and inform // The physics engine says that properties have updated. Update same and inform
// the world that things have changed. // the world that things have changed.
public override void UpdateProperties(EntityProperties entprop) public override void UpdateProperties(EntityProperties entprop)
{
// Updates only for individual prims and for the root object of a linkset.
if (Linkset.IsRoot(this))
{ {
// A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet // A temporary kludge to suppress the rotational effects introduced on vehicles by Bullet
// TODO: handle physics introduced by Bullet with computed vehicle physics. // TODO: handle physics introduced by Bullet with computed vehicle physics.
@ -1697,14 +1616,6 @@ public sealed class BSPrim : BSPhysObject
// DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG // DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG
// Undo any center-of-mass displacement that might have been done.
if (PositionDisplacement != OMV.Vector3.Zero)
{
// Correct for any rotation around the center-of-mass
// TODO!!!
entprop.Position -= PositionDisplacement;
}
// Assign directly to the local variables so the normal set actions do not happen // Assign directly to the local variables so the normal set actions do not happen
_position = entprop.Position; _position = entprop.Position;
_orientation = entprop.Rotation; _orientation = entprop.Rotation;
@ -1731,7 +1642,6 @@ public sealed class BSPrim : BSPhysObject
CurrentEntityProperties = entprop; CurrentEntityProperties = entprop;
base.RequestPhysicsterseUpdate(); base.RequestPhysicsterseUpdate();
}
/* /*
else else
{ {
@ -1741,9 +1651,6 @@ public sealed class BSPrim : BSPhysObject
entprop.Acceleration, entprop.RotationalVelocity); entprop.Acceleration, entprop.RotationalVelocity);
} }
*/ */
// The linkset implimentation might want to know about this.
Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
} }
} }
} }

View File

@ -434,7 +434,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
{ {
if (!m_initialized) return; if (!m_initialized) return;
BSPrim bsprim = prim as BSPrim; BSPhysObject bsprim = prim as BSPhysObject;
if (bsprim != null) if (bsprim != null)
{ {
DetailLog("{0},RemovePrim,call", bsprim.LocalID); DetailLog("{0},RemovePrim,call", bsprim.LocalID);
@ -465,7 +465,7 @@ public sealed 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); BSPhysObject prim = new BSPrimLinkable(localID, primName, this, position, size, rotation, pbs, isPhysical);
lock (PhysObjects) PhysObjects.Add(localID, prim); lock (PhysObjects) PhysObjects.Add(localID, prim);
return prim; return prim;
} }