Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
commit
2816551215
|
@ -167,9 +167,8 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr);
|
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr);
|
||||||
|
|
||||||
// Do this after the object has been added to the world
|
// Do this after the object has been added to the world
|
||||||
BulletSimAPI.SetCollisionGroupMask2(PhysBody.ptr,
|
PhysBody.collisionType = CollisionType.Avatar;
|
||||||
(uint)CollisionFilterGroups.AvatarGroup,
|
PhysBody.ApplyCollisionMask();
|
||||||
(uint)CollisionFilterGroups.AvatarMask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void RequestPhysicsterseUpdate()
|
public override void RequestPhysicsterseUpdate()
|
||||||
|
|
|
@ -124,7 +124,7 @@ public abstract class BSLinkset
|
||||||
get { return ComputeLinksetGeometricCenter(); }
|
get { return ComputeLinksetGeometricCenter(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Initialize(BSScene scene, BSPhysObject parent)
|
protected BSLinkset(BSScene scene, BSPhysObject parent)
|
||||||
{
|
{
|
||||||
// A simple linkset of one (no children)
|
// A simple linkset of one (no children)
|
||||||
LinksetID = m_nextLinksetID++;
|
LinksetID = m_nextLinksetID++;
|
||||||
|
@ -135,6 +135,7 @@ public abstract class BSLinkset
|
||||||
LinksetRoot = parent;
|
LinksetRoot = parent;
|
||||||
m_children = new HashSet<BSPhysObject>();
|
m_children = new HashSet<BSPhysObject>();
|
||||||
m_mass = parent.RawMass;
|
m_mass = parent.RawMass;
|
||||||
|
Rebuilding = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Link to a linkset where the child knows the parent.
|
// Link to a linkset where the child knows the parent.
|
||||||
|
@ -237,6 +238,10 @@ public abstract class BSLinkset
|
||||||
// May be called at runtime or taint-time.
|
// May be called at runtime or taint-time.
|
||||||
public abstract void Refresh(BSPhysObject requestor);
|
public abstract void Refresh(BSPhysObject requestor);
|
||||||
|
|
||||||
|
// Flag denoting the linkset is in the process of being rebuilt.
|
||||||
|
// Used to know not the schedule a rebuild in the middle of a rebuild.
|
||||||
|
protected bool Rebuilding { get; set; }
|
||||||
|
|
||||||
// The object is going dynamic (physical). Do any setup necessary
|
// The object is going dynamic (physical). Do any setup necessary
|
||||||
// for a dynamic linkset.
|
// for a dynamic linkset.
|
||||||
// Only the state of the passed object can be modified. The rest of the linkset
|
// Only the state of the passed object can be modified. The rest of the linkset
|
||||||
|
|
|
@ -61,9 +61,8 @@ 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)
|
public BSLinksetCompound(BSScene scene, BSPhysObject parent) : base(scene, parent)
|
||||||
{
|
{
|
||||||
base.Initialize(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.
|
||||||
|
@ -81,8 +80,6 @@ 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.
|
||||||
// This is queued in the 'post taint' queue so the
|
|
||||||
// refresh will happen once after all the other taints are applied.
|
|
||||||
public override void Refresh(BSPhysObject requestor)
|
public override void Refresh(BSPhysObject requestor)
|
||||||
{
|
{
|
||||||
// External request for Refresh (from BSPrim) doesn't need to do anything
|
// External request for Refresh (from BSPrim) doesn't need to do anything
|
||||||
|
@ -92,12 +89,18 @@ 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 InternalRefresh(BSPhysObject requestor)
|
private void InternalRefresh(BSPhysObject requestor)
|
||||||
{
|
{
|
||||||
DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,requestor={1}", LinksetRoot.LocalID, requestor.LocalID);
|
DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,requestor={1},rebuilding={2}",
|
||||||
PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", requestor.LocalID, delegate()
|
LinksetRoot.LocalID, requestor.LocalID, Rebuilding);
|
||||||
|
// When rebuilding, it is possible to set properties that would normally require a rebuild.
|
||||||
|
// If already rebuilding, don't request another rebuild.
|
||||||
|
if (!Rebuilding)
|
||||||
{
|
{
|
||||||
if (IsRoot(requestor) && HasAnyChildren)
|
PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", requestor.LocalID, delegate()
|
||||||
RecomputeLinksetCompound();
|
{
|
||||||
});
|
if (IsRoot(requestor) && HasAnyChildren)
|
||||||
|
RecomputeLinksetCompound();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The object is going dynamic (physical). Do any setup necessary
|
// The object is going dynamic (physical). Do any setup necessary
|
||||||
|
@ -114,6 +117,8 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
{
|
{
|
||||||
// The root is going dynamic. Make sure mass is properly set.
|
// The root is going dynamic. Make sure mass is properly set.
|
||||||
m_mass = ComputeLinksetMass();
|
m_mass = ComputeLinksetMass();
|
||||||
|
if (HasAnyChildren)
|
||||||
|
InternalRefresh(LinksetRoot);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -123,6 +128,9 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
BulletSimAPI.ForceActivationState2(child.PhysBody.ptr, ActivationState.DISABLE_SIMULATION);
|
BulletSimAPI.ForceActivationState2(child.PhysBody.ptr, ActivationState.DISABLE_SIMULATION);
|
||||||
// We don't want collisions from the old linkset children.
|
// We don't want collisions from the old linkset children.
|
||||||
BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||||
|
|
||||||
|
child.PhysBody.collisionType = CollisionType.LinksetChild;
|
||||||
|
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -137,10 +145,18 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
{
|
{
|
||||||
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));
|
||||||
if (!IsRoot(child))
|
if (IsRoot(child))
|
||||||
|
{
|
||||||
|
if (HasAnyChildren)
|
||||||
|
InternalRefresh(LinksetRoot);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// The non-physical children can come back to life.
|
// The non-physical children can come back to life.
|
||||||
BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
|
BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
|
||||||
|
|
||||||
|
child.PhysBody.collisionType = CollisionType.LinksetChild;
|
||||||
|
|
||||||
// Don't force activation so setting of DISABLE_SIMULATION can stay if used.
|
// Don't force activation so setting of DISABLE_SIMULATION can stay if used.
|
||||||
BulletSimAPI.Activate2(child.PhysBody.ptr, false);
|
BulletSimAPI.Activate2(child.PhysBody.ptr, false);
|
||||||
ret = true;
|
ret = true;
|
||||||
|
@ -182,19 +198,25 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
// Because it is a convenient time, recompute child world position and rotation based on
|
// Because it is a convenient time, recompute child world position and rotation based on
|
||||||
// its position in the linkset.
|
// its position in the linkset.
|
||||||
RecomputeChildWorldPosition(child, true);
|
RecomputeChildWorldPosition(child, true);
|
||||||
|
|
||||||
// Cause the current shape to be freed and the new one to be built.
|
|
||||||
InternalRefresh(LinksetRoot);
|
|
||||||
ret = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cannot schedule a refresh/rebuild here because this routine is called when
|
||||||
|
// the linkset is being rebuilt.
|
||||||
|
// InternalRefresh(LinksetRoot);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the linkset is built, the child shape is added
|
// Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true',
|
||||||
// to the compound shape relative to the root shape. The linkset then moves around but
|
// this routine will restore the removed constraints.
|
||||||
// this does not move the actual child prim. The child prim's location must be recomputed
|
// Called at taint-time!!
|
||||||
// based on the location of the root shape.
|
public override void RestoreBodyDependencies(BSPrim child)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// 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(BSPhysObject child, bool inTaintTime)
|
||||||
{
|
{
|
||||||
BSLinksetCompoundInfo lci = child.LinksetInfo as BSLinksetCompoundInfo;
|
BSLinksetCompoundInfo lci = child.LinksetInfo as BSLinksetCompoundInfo;
|
||||||
|
@ -227,14 +249,6 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true',
|
|
||||||
// this routine will restore the removed constraints.
|
|
||||||
// Called at taint-time!!
|
|
||||||
public override void RestoreBodyDependencies(BSPrim child)
|
|
||||||
{
|
|
||||||
// The Refresh operation queued by RemoveBodyDependencies() will build any missing constraints.
|
|
||||||
}
|
|
||||||
|
|
||||||
// ================================================================
|
// ================================================================
|
||||||
|
|
||||||
// Add a new child to the linkset.
|
// Add a new child to the linkset.
|
||||||
|
@ -254,7 +268,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 my linkset.
|
// Safe to call even if the child is not really in the linkset.
|
||||||
protected override void RemoveChildFromLinkset(BSPhysObject child)
|
protected override void RemoveChildFromLinkset(BSPhysObject child)
|
||||||
{
|
{
|
||||||
if (m_children.Remove(child))
|
if (m_children.Remove(child))
|
||||||
|
@ -289,74 +303,83 @@ public sealed class BSLinksetCompound : BSLinkset
|
||||||
// Called at taint time!!
|
// Called at taint time!!
|
||||||
private void RecomputeLinksetCompound()
|
private void RecomputeLinksetCompound()
|
||||||
{
|
{
|
||||||
// Cause the root shape to be rebuilt as a compound object with just the root in it
|
try
|
||||||
LinksetRoot.ForceBodyShapeRebuild(true);
|
|
||||||
|
|
||||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}",
|
|
||||||
LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren);
|
|
||||||
|
|
||||||
// Add a shape for each of the other children in the linkset
|
|
||||||
ForEachMember(delegate(BSPhysObject cPrim)
|
|
||||||
{
|
{
|
||||||
if (!IsRoot(cPrim))
|
// Suppress rebuilding while rebuilding
|
||||||
|
Rebuilding = true;
|
||||||
|
|
||||||
|
// Cause the root shape to be rebuilt as a compound object with just the root in it
|
||||||
|
LinksetRoot.ForceBodyShapeRebuild(true);
|
||||||
|
|
||||||
|
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}",
|
||||||
|
LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren);
|
||||||
|
|
||||||
|
// Add a shape for each of the other children in the linkset
|
||||||
|
ForEachMember(delegate(BSPhysObject cPrim)
|
||||||
{
|
{
|
||||||
// Compute the displacement of the child from the root of the linkset.
|
if (!IsRoot(cPrim))
|
||||||
// This info is saved in the child prim so the relationship does not
|
|
||||||
// change over time and the new child position can be computed
|
|
||||||
// when the linkset is being disassembled (the linkset may have moved).
|
|
||||||
BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo;
|
|
||||||
if (lci == null)
|
|
||||||
{
|
{
|
||||||
// Each child position and rotation is given relative to the root.
|
// Compute the displacement of the child from the root of the linkset.
|
||||||
OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation);
|
// This info is saved in the child prim so the relationship does not
|
||||||
OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation;
|
// change over time and the new child position can be computed
|
||||||
OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation;
|
// when the linkset is being disassembled (the linkset may have moved).
|
||||||
|
BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo;
|
||||||
// Save relative position for recomputing child's world position after moving linkset.
|
if (lci == null)
|
||||||
lci = new BSLinksetCompoundInfo(displacementPos, displacementRot);
|
|
||||||
cPrim.LinksetInfo = lci;
|
|
||||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci);
|
|
||||||
}
|
|
||||||
|
|
||||||
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}",
|
|
||||||
LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot);
|
|
||||||
|
|
||||||
if (cPrim.PhysShape.isNativeShape)
|
|
||||||
{
|
|
||||||
// A native shape is turning into a hull collision shape because native
|
|
||||||
// shapes are not shared so we have to hullify it so it will be tracked
|
|
||||||
// and freed at the correct time. This also solves the scaling problem
|
|
||||||
// (native shapes scaled but hull/meshes are assumed to not be).
|
|
||||||
// TODO: decide of the native shape can just be used in the compound shape.
|
|
||||||
// Use call to CreateGeomNonSpecial().
|
|
||||||
BulletShape saveShape = cPrim.PhysShape;
|
|
||||||
cPrim.PhysShape.Clear(); // Don't let the create free the child's shape
|
|
||||||
// PhysicsScene.Shapes.CreateGeomNonSpecial(true, cPrim, null);
|
|
||||||
PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null);
|
|
||||||
BulletShape newShape = cPrim.PhysShape;
|
|
||||||
cPrim.PhysShape = saveShape;
|
|
||||||
BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, newShape.ptr, lci.OffsetPos , lci.OffsetRot);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// For the shared shapes (meshes and hulls), just use the shape in the child.
|
|
||||||
// The reference count added here will be decremented when the compound shape
|
|
||||||
// is destroyed in BSShapeCollection (the child shapes are looped over and dereferenced).
|
|
||||||
if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape))
|
|
||||||
{
|
{
|
||||||
PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}",
|
// Each child position and rotation is given relative to the root.
|
||||||
LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape);
|
OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation);
|
||||||
|
OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation;
|
||||||
|
OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation;
|
||||||
|
|
||||||
|
// Save relative position for recomputing child's world position after moving linkset.
|
||||||
|
lci = new BSLinksetCompoundInfo(displacementPos, displacementRot);
|
||||||
|
cPrim.LinksetInfo = lci;
|
||||||
|
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci);
|
||||||
|
}
|
||||||
|
|
||||||
|
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}",
|
||||||
|
LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot);
|
||||||
|
|
||||||
|
if (cPrim.PhysShape.isNativeShape)
|
||||||
|
{
|
||||||
|
// A native shape is turning into a hull collision shape because native
|
||||||
|
// shapes are not shared so we have to hullify it so it will be tracked
|
||||||
|
// and freed at the correct time. This also solves the scaling problem
|
||||||
|
// (native shapes scaled but hull/meshes are assumed to not be).
|
||||||
|
// TODO: decide of the native shape can just be used in the compound shape.
|
||||||
|
// Use call to CreateGeomNonSpecial().
|
||||||
|
BulletShape saveShape = cPrim.PhysShape;
|
||||||
|
cPrim.PhysShape.Clear(); // Don't let the create free the child's shape
|
||||||
|
// PhysicsScene.Shapes.CreateGeomNonSpecial(true, cPrim, null);
|
||||||
|
PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null);
|
||||||
|
BulletShape newShape = cPrim.PhysShape;
|
||||||
|
cPrim.PhysShape = saveShape;
|
||||||
|
BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, newShape.ptr, lci.OffsetPos, lci.OffsetRot);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// For the shared shapes (meshes and hulls), just use the shape in the child.
|
||||||
|
// The reference count added here will be decremented when the compound shape
|
||||||
|
// is destroyed in BSShapeCollection (the child shapes are looped over and dereferenced).
|
||||||
|
if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape))
|
||||||
|
{
|
||||||
|
PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}",
|
||||||
|
LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape);
|
||||||
|
}
|
||||||
|
BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, lci.OffsetPos, lci.OffsetRot);
|
||||||
}
|
}
|
||||||
BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, lci.OffsetPos , lci.OffsetRot);
|
|
||||||
}
|
}
|
||||||
}
|
return false; // 'false' says to move onto the next child in the list
|
||||||
|
});
|
||||||
|
|
||||||
return false; // 'false' says to move onto the next child in the list
|
// With all of the linkset packed into the root prim, it has the mass of everyone.
|
||||||
});
|
float linksetMass = LinksetMass;
|
||||||
|
LinksetRoot.UpdatePhysicalMassProperties(linksetMass);
|
||||||
// With all of the linkset packed into the root prim, it has the mass of everyone.
|
}
|
||||||
float linksetMass = LinksetMass;
|
finally
|
||||||
LinksetRoot.UpdatePhysicalMassProperties(linksetMass);
|
{
|
||||||
|
Rebuilding = false;
|
||||||
|
}
|
||||||
|
|
||||||
BulletSimAPI.RecalculateCompoundShapeLocalAabb2(LinksetRoot.PhysShape.ptr);
|
BulletSimAPI.RecalculateCompoundShapeLocalAabb2(LinksetRoot.PhysShape.ptr);
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,8 @@ 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)
|
public BSLinksetConstraints(BSScene scene, BSPhysObject parent) : base(scene, parent)
|
||||||
{
|
{
|
||||||
base.Initialize(scene, parent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When physical properties are changed the linkset needs to recalculate
|
// When physical properties are changed the linkset needs to recalculate
|
||||||
|
|
|
@ -661,14 +661,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr);
|
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr);
|
||||||
|
|
||||||
// Collision filter can be set only when the object is in the world
|
// Collision filter can be set only when the object is in the world
|
||||||
if (PhysBody.collisionGroup != 0 || PhysBody.collisionMask != 0)
|
PhysBody.ApplyCollisionMask();
|
||||||
{
|
|
||||||
if (!BulletSimAPI.SetCollisionGroupMask2(PhysBody.ptr, (uint)PhysBody.collisionGroup, (uint)PhysBody.collisionMask))
|
|
||||||
{
|
|
||||||
PhysicsScene.Logger.ErrorFormat("{0} Failure setting prim collision mask. localID={1}, grp={2:X}, mask={3:X}",
|
|
||||||
LogHeader, LocalID, PhysBody.collisionGroup, PhysBody.collisionMask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recompute any linkset parameters.
|
// Recompute any linkset parameters.
|
||||||
// When going from non-physical to physical, this re-enables the constraints that
|
// When going from non-physical to physical, this re-enables the constraints that
|
||||||
|
@ -713,11 +706,11 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// Start it out sleeping and physical actions could wake it up.
|
// Start it out sleeping and physical actions could wake it up.
|
||||||
BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ISLAND_SLEEPING);
|
BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ISLAND_SLEEPING);
|
||||||
|
|
||||||
|
// This collides like a static object
|
||||||
|
PhysBody.collisionType = CollisionType.Static;
|
||||||
|
|
||||||
// There can be special things needed for implementing linksets
|
// There can be special things needed for implementing linksets
|
||||||
Linkset.MakeStatic(this);
|
Linkset.MakeStatic(this);
|
||||||
|
|
||||||
PhysBody.collisionGroup = CollisionFilterGroups.StaticObjectGroup;
|
|
||||||
PhysBody.collisionMask = CollisionFilterGroups.StaticObjectMask;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -755,16 +748,15 @@ public sealed class BSPrim : BSPhysObject
|
||||||
BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold);
|
BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold);
|
||||||
BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, PhysicsScene.Params.contactProcessingThreshold);
|
BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, PhysicsScene.Params.contactProcessingThreshold);
|
||||||
|
|
||||||
// There might be special things needed for implementing linksets.
|
// This collides like an object.
|
||||||
Linkset.MakeDynamic(this);
|
PhysBody.collisionType = CollisionType.Dynamic;
|
||||||
|
|
||||||
// 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.
|
||||||
BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ACTIVE_TAG);
|
BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ACTIVE_TAG);
|
||||||
// BulletSimAPI.Activate2(BSBody.ptr, true);
|
|
||||||
|
|
||||||
PhysBody.collisionGroup = CollisionFilterGroups.ObjectGroup;
|
// There might be special things needed for implementing linksets.
|
||||||
PhysBody.collisionMask = CollisionFilterGroups.ObjectMask;
|
Linkset.MakeDynamic(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -791,8 +783,9 @@ public sealed class BSPrim : BSPhysObject
|
||||||
m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType);
|
m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType);
|
||||||
}
|
}
|
||||||
CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
|
CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
|
||||||
PhysBody.collisionGroup = CollisionFilterGroups.VolumeDetectGroup;
|
|
||||||
PhysBody.collisionMask = CollisionFilterGroups.VolumeDetectMask;
|
// Change collision info from a static object to a ghosty collision object
|
||||||
|
PhysBody.collisionType = CollisionType.VolumeDetect;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,9 +121,8 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
|
||||||
// redo its bounding box now that it is in the world
|
// redo its bounding box now that it is in the world
|
||||||
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr);
|
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr);
|
||||||
|
|
||||||
BulletSimAPI.SetCollisionGroupMask2(m_mapInfo.terrainBody.ptr,
|
m_mapInfo.terrainBody.collisionType = CollisionType.Terrain;
|
||||||
(uint)CollisionFilterGroups.TerrainGroup,
|
m_mapInfo.terrainBody.ApplyCollisionMask();
|
||||||
(uint)CollisionFilterGroups.TerrainMask);
|
|
||||||
|
|
||||||
// Make it so the terrain will not move or be considered for movement.
|
// Make it so the terrain will not move or be considered for movement.
|
||||||
BulletSimAPI.ForceActivationState2(m_mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION);
|
BulletSimAPI.ForceActivationState2(m_mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION);
|
||||||
|
|
|
@ -140,8 +140,8 @@ public sealed class BSTerrainManager
|
||||||
// Ground plane does not move
|
// Ground plane does not move
|
||||||
BulletSimAPI.ForceActivationState2(m_groundPlane.ptr, ActivationState.DISABLE_SIMULATION);
|
BulletSimAPI.ForceActivationState2(m_groundPlane.ptr, ActivationState.DISABLE_SIMULATION);
|
||||||
// Everything collides with the ground plane.
|
// Everything collides with the ground plane.
|
||||||
BulletSimAPI.SetCollisionGroupMask2(m_groundPlane.ptr,
|
m_groundPlane.collisionType = CollisionType.Groundplane;
|
||||||
(uint)CollisionFilterGroups.GroundPlaneGroup, (uint)CollisionFilterGroups.GroundPlaneMask);
|
m_groundPlane.ApplyCollisionMask();
|
||||||
|
|
||||||
// Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain.
|
// Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain.
|
||||||
BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize);
|
BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize);
|
||||||
|
|
|
@ -130,9 +130,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
||||||
// Redo its bounding box now that it is in the world
|
// Redo its bounding box now that it is in the world
|
||||||
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr);
|
BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr);
|
||||||
|
|
||||||
BulletSimAPI.SetCollisionGroupMask2(m_terrainBody.ptr,
|
m_terrainBody.collisionType = CollisionType.Terrain;
|
||||||
(uint)CollisionFilterGroups.TerrainGroup,
|
m_terrainBody.ApplyCollisionMask();
|
||||||
(uint)CollisionFilterGroups.TerrainMask);
|
|
||||||
|
|
||||||
// Make it so the terrain will not move or be considered for movement.
|
// Make it so the terrain will not move or be considered for movement.
|
||||||
BulletSimAPI.ForceActivationState2(m_terrainBody.ptr, ActivationState.DISABLE_SIMULATION);
|
BulletSimAPI.ForceActivationState2(m_terrainBody.ptr, ActivationState.DISABLE_SIMULATION);
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
@ -32,110 +33,6 @@ using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Region.Physics.BulletSPlugin {
|
namespace OpenSim.Region.Physics.BulletSPlugin {
|
||||||
|
|
||||||
// Classes to allow some type checking for the API
|
|
||||||
// These hold pointers to allocated objects in the unmanaged space.
|
|
||||||
|
|
||||||
// The physics engine controller class created at initialization
|
|
||||||
public struct BulletSim
|
|
||||||
{
|
|
||||||
public BulletSim(uint worldId, BSScene bss, IntPtr xx)
|
|
||||||
{
|
|
||||||
ptr = xx;
|
|
||||||
worldID = worldId;
|
|
||||||
physicsScene = bss;
|
|
||||||
}
|
|
||||||
public IntPtr ptr;
|
|
||||||
public uint worldID;
|
|
||||||
// The scene is only in here so very low level routines have a handle to print debug/error messages
|
|
||||||
public BSScene physicsScene;
|
|
||||||
}
|
|
||||||
|
|
||||||
// An allocated Bullet btRigidBody
|
|
||||||
public struct BulletBody
|
|
||||||
{
|
|
||||||
public BulletBody(uint id) : this(id, IntPtr.Zero)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
public BulletBody(uint id, IntPtr xx)
|
|
||||||
{
|
|
||||||
ID = id;
|
|
||||||
ptr = xx;
|
|
||||||
collisionGroup = 0;
|
|
||||||
collisionMask = 0;
|
|
||||||
}
|
|
||||||
public IntPtr ptr;
|
|
||||||
public uint ID;
|
|
||||||
public CollisionFilterGroups collisionGroup;
|
|
||||||
public CollisionFilterGroups collisionMask;
|
|
||||||
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
ptr = IntPtr.Zero;
|
|
||||||
}
|
|
||||||
public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } }
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
StringBuilder buff = new StringBuilder();
|
|
||||||
buff.Append("<id=");
|
|
||||||
buff.Append(ID.ToString());
|
|
||||||
buff.Append(",p=");
|
|
||||||
buff.Append(ptr.ToString("X"));
|
|
||||||
if (collisionGroup != 0 || collisionMask != 0)
|
|
||||||
{
|
|
||||||
buff.Append(",g=");
|
|
||||||
buff.Append(collisionGroup.ToString("X"));
|
|
||||||
buff.Append(",m=");
|
|
||||||
buff.Append(collisionMask.ToString("X"));
|
|
||||||
}
|
|
||||||
buff.Append(">");
|
|
||||||
return buff.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct BulletShape
|
|
||||||
{
|
|
||||||
public BulletShape(IntPtr xx)
|
|
||||||
{
|
|
||||||
ptr = xx;
|
|
||||||
type=BSPhysicsShapeType.SHAPE_UNKNOWN;
|
|
||||||
shapeKey = (System.UInt64)FixedShapeKey.KEY_NONE;
|
|
||||||
isNativeShape = false;
|
|
||||||
}
|
|
||||||
public BulletShape(IntPtr xx, BSPhysicsShapeType typ)
|
|
||||||
{
|
|
||||||
ptr = xx;
|
|
||||||
type = typ;
|
|
||||||
shapeKey = 0;
|
|
||||||
isNativeShape = false;
|
|
||||||
}
|
|
||||||
public IntPtr ptr;
|
|
||||||
public BSPhysicsShapeType type;
|
|
||||||
public System.UInt64 shapeKey;
|
|
||||||
public bool isNativeShape;
|
|
||||||
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
ptr = IntPtr.Zero;
|
|
||||||
}
|
|
||||||
public bool HasPhysicalShape { get { return ptr != IntPtr.Zero; } }
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
StringBuilder buff = new StringBuilder();
|
|
||||||
buff.Append("<p=");
|
|
||||||
buff.Append(ptr.ToString("X"));
|
|
||||||
buff.Append(",s=");
|
|
||||||
buff.Append(type.ToString());
|
|
||||||
buff.Append(",k=");
|
|
||||||
buff.Append(shapeKey.ToString("X"));
|
|
||||||
buff.Append(",n=");
|
|
||||||
buff.Append(isNativeShape.ToString());
|
|
||||||
buff.Append(">");
|
|
||||||
return buff.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constraint type values as defined by Bullet
|
// Constraint type values as defined by Bullet
|
||||||
public enum ConstraintType : int
|
public enum ConstraintType : int
|
||||||
{
|
{
|
||||||
|
@ -149,50 +46,6 @@ public enum ConstraintType : int
|
||||||
MAX_CONSTRAINT_TYPE
|
MAX_CONSTRAINT_TYPE
|
||||||
}
|
}
|
||||||
|
|
||||||
// An allocated Bullet btConstraint
|
|
||||||
public struct BulletConstraint
|
|
||||||
{
|
|
||||||
public BulletConstraint(IntPtr xx)
|
|
||||||
{
|
|
||||||
ptr = xx;
|
|
||||||
}
|
|
||||||
public IntPtr ptr;
|
|
||||||
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
ptr = IntPtr.Zero;
|
|
||||||
}
|
|
||||||
public bool HasPhysicalConstraint { get { return ptr != IntPtr.Zero; } }
|
|
||||||
}
|
|
||||||
|
|
||||||
// An allocated HeightMapThing which holds various heightmap info.
|
|
||||||
// Made a class rather than a struct so there would be only one
|
|
||||||
// instance of this and C# will pass around pointers rather
|
|
||||||
// than making copies.
|
|
||||||
public class BulletHeightMapInfo
|
|
||||||
{
|
|
||||||
public BulletHeightMapInfo(uint id, float[] hm, IntPtr xx) {
|
|
||||||
ID = id;
|
|
||||||
Ptr = xx;
|
|
||||||
heightMap = hm;
|
|
||||||
terrainRegionBase = Vector3.Zero;
|
|
||||||
minCoords = new Vector3(100f, 100f, 25f);
|
|
||||||
maxCoords = new Vector3(101f, 101f, 26f);
|
|
||||||
minZ = maxZ = 0f;
|
|
||||||
sizeX = sizeY = 256f;
|
|
||||||
}
|
|
||||||
public uint ID;
|
|
||||||
public IntPtr Ptr;
|
|
||||||
public float[] heightMap;
|
|
||||||
public Vector3 terrainRegionBase;
|
|
||||||
public Vector3 minCoords;
|
|
||||||
public Vector3 maxCoords;
|
|
||||||
public float sizeX, sizeY;
|
|
||||||
public float minZ, maxZ;
|
|
||||||
public BulletShape terrainShape;
|
|
||||||
public BulletBody terrainBody;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===============================================================================
|
// ===============================================================================
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct ConvexHull
|
public struct ConvexHull
|
||||||
|
@ -385,21 +238,15 @@ public enum CollisionFlags : uint
|
||||||
BS_FLOATS_ON_WATER = 1 << 11,
|
BS_FLOATS_ON_WATER = 1 << 11,
|
||||||
BS_VEHICLE_COLLISIONS = 1 << 12,
|
BS_VEHICLE_COLLISIONS = 1 << 12,
|
||||||
BS_NONE = 0,
|
BS_NONE = 0,
|
||||||
BS_ALL = 0xFFFFFFFF,
|
BS_ALL = 0xFFFFFFFF
|
||||||
|
|
||||||
// These are the collision flags switched depending on physical state.
|
|
||||||
// The other flags are used for other things and should not be fooled with.
|
|
||||||
BS_ACTIVE = CF_STATIC_OBJECT
|
|
||||||
| CF_KINEMATIC_OBJECT
|
|
||||||
| CF_NO_CONTACT_RESPONSE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Values for collisions groups and masks
|
// Values f collisions groups and masks
|
||||||
public enum CollisionFilterGroups : uint
|
public enum CollisionFilterGroups : uint
|
||||||
{
|
{
|
||||||
// Don't use the bit definitions!! Define the use in a
|
// Don't use the bit definitions!! Define the use in a
|
||||||
// filter/mask definition below. This way collision interactions
|
// filter/mask definition below. This way collision interactions
|
||||||
// are more easily debugged.
|
// are more easily found and debugged.
|
||||||
BNoneGroup = 0,
|
BNoneGroup = 0,
|
||||||
BDefaultGroup = 1 << 0,
|
BDefaultGroup = 1 << 0,
|
||||||
BStaticGroup = 1 << 1,
|
BStaticGroup = 1 << 1,
|
||||||
|
@ -413,24 +260,8 @@ public enum CollisionFilterGroups : uint
|
||||||
BTerrainGroup = 1 << 11,
|
BTerrainGroup = 1 << 11,
|
||||||
BRaycastGroup = 1 << 12,
|
BRaycastGroup = 1 << 12,
|
||||||
BSolidGroup = 1 << 13,
|
BSolidGroup = 1 << 13,
|
||||||
BLinksetGroup = 1 << 14,
|
// BLinksetGroup = xx // a linkset proper is either static or dynamic
|
||||||
|
BLinksetChildGroup = 1 << 14,
|
||||||
// The collsion filters and masked are defined in one place -- don't want them scattered
|
|
||||||
AvatarGroup = BCharacterGroup,
|
|
||||||
AvatarMask = BAllGroup,
|
|
||||||
ObjectGroup = BSolidGroup,
|
|
||||||
ObjectMask = BAllGroup,
|
|
||||||
StaticObjectGroup = BStaticGroup,
|
|
||||||
StaticObjectMask = AvatarGroup | ObjectGroup, // static things don't interact with much
|
|
||||||
LinksetGroup = BLinksetGroup,
|
|
||||||
LinksetMask = BAllGroup & ~BLinksetGroup, // linkset objects don't collide with each other
|
|
||||||
VolumeDetectGroup = BSensorTrigger,
|
|
||||||
VolumeDetectMask = ~BSensorTrigger,
|
|
||||||
TerrainGroup = BTerrainGroup,
|
|
||||||
TerrainMask = BAllGroup & ~BStaticGroup, // static objects on the ground don't collide
|
|
||||||
GroundPlaneGroup = BGroundPlaneGroup,
|
|
||||||
GroundPlaneMask = BAllGroup
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0
|
// CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0
|
||||||
|
@ -457,7 +288,7 @@ public enum ConstraintParamAxis : int
|
||||||
|
|
||||||
// ===============================================================================
|
// ===============================================================================
|
||||||
static class BulletSimAPI {
|
static class BulletSimAPI {
|
||||||
|
// ===============================================================================
|
||||||
// Link back to the managed code for outputting log messages
|
// Link back to the managed code for outputting log messages
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg);
|
public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg);
|
||||||
|
|
|
@ -0,0 +1,278 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
// Classes to allow some type checking for the API
|
||||||
|
// These hold pointers to allocated objects in the unmanaged space.
|
||||||
|
|
||||||
|
// The physics engine controller class created at initialization
|
||||||
|
public struct BulletSim
|
||||||
|
{
|
||||||
|
public BulletSim(uint worldId, BSScene bss, IntPtr xx)
|
||||||
|
{
|
||||||
|
ptr = xx;
|
||||||
|
worldID = worldId;
|
||||||
|
physicsScene = bss;
|
||||||
|
}
|
||||||
|
public IntPtr ptr;
|
||||||
|
public uint worldID;
|
||||||
|
// The scene is only in here so very low level routines have a handle to print debug/error messages
|
||||||
|
public BSScene physicsScene;
|
||||||
|
}
|
||||||
|
|
||||||
|
// An allocated Bullet btRigidBody
|
||||||
|
public struct BulletBody
|
||||||
|
{
|
||||||
|
public BulletBody(uint id) : this(id, IntPtr.Zero)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public BulletBody(uint id, IntPtr xx)
|
||||||
|
{
|
||||||
|
ID = id;
|
||||||
|
ptr = xx;
|
||||||
|
collisionType = CollisionType.Static;
|
||||||
|
}
|
||||||
|
public IntPtr ptr;
|
||||||
|
public uint ID;
|
||||||
|
public CollisionType collisionType;
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
ptr = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } }
|
||||||
|
|
||||||
|
// Apply the specificed collision mask into the physical world
|
||||||
|
public void ApplyCollisionMask()
|
||||||
|
{
|
||||||
|
// Should assert the body has been added to the physical world.
|
||||||
|
// (The collision masks are stored in the collision proxy cache which only exists for
|
||||||
|
// a collision body that is in the world.)
|
||||||
|
BulletSimAPI.SetCollisionGroupMask2(ptr,
|
||||||
|
BulletSimData.CollisionTypeMasks[collisionType].group,
|
||||||
|
BulletSimData.CollisionTypeMasks[collisionType].mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
StringBuilder buff = new StringBuilder();
|
||||||
|
buff.Append("<id=");
|
||||||
|
buff.Append(ID.ToString());
|
||||||
|
buff.Append(",p=");
|
||||||
|
buff.Append(ptr.ToString("X"));
|
||||||
|
buff.Append(",c=");
|
||||||
|
buff.Append(collisionType);
|
||||||
|
buff.Append(">");
|
||||||
|
return buff.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct BulletShape
|
||||||
|
{
|
||||||
|
public BulletShape(IntPtr xx) : this(xx, BSPhysicsShapeType.SHAPE_UNKNOWN)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public BulletShape(IntPtr xx, BSPhysicsShapeType typ)
|
||||||
|
{
|
||||||
|
ptr = xx;
|
||||||
|
type = typ;
|
||||||
|
shapeKey = (System.UInt64)FixedShapeKey.KEY_NONE;
|
||||||
|
isNativeShape = false;
|
||||||
|
}
|
||||||
|
public IntPtr ptr;
|
||||||
|
public BSPhysicsShapeType type;
|
||||||
|
public System.UInt64 shapeKey;
|
||||||
|
public bool isNativeShape;
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
ptr = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
public bool HasPhysicalShape { get { return ptr != IntPtr.Zero; } }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
StringBuilder buff = new StringBuilder();
|
||||||
|
buff.Append("<p=");
|
||||||
|
buff.Append(ptr.ToString("X"));
|
||||||
|
buff.Append(",s=");
|
||||||
|
buff.Append(type.ToString());
|
||||||
|
buff.Append(",k=");
|
||||||
|
buff.Append(shapeKey.ToString("X"));
|
||||||
|
buff.Append(",n=");
|
||||||
|
buff.Append(isNativeShape.ToString());
|
||||||
|
buff.Append(">");
|
||||||
|
return buff.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// An allocated Bullet btConstraint
|
||||||
|
public struct BulletConstraint
|
||||||
|
{
|
||||||
|
public BulletConstraint(IntPtr xx)
|
||||||
|
{
|
||||||
|
ptr = xx;
|
||||||
|
}
|
||||||
|
public IntPtr ptr;
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
ptr = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
public bool HasPhysicalConstraint { get { return ptr != IntPtr.Zero; } }
|
||||||
|
}
|
||||||
|
|
||||||
|
// An allocated HeightMapThing which holds various heightmap info.
|
||||||
|
// Made a class rather than a struct so there would be only one
|
||||||
|
// instance of this and C# will pass around pointers rather
|
||||||
|
// than making copies.
|
||||||
|
public class BulletHeightMapInfo
|
||||||
|
{
|
||||||
|
public BulletHeightMapInfo(uint id, float[] hm, IntPtr xx) {
|
||||||
|
ID = id;
|
||||||
|
Ptr = xx;
|
||||||
|
heightMap = hm;
|
||||||
|
terrainRegionBase = OMV.Vector3.Zero;
|
||||||
|
minCoords = new OMV.Vector3(100f, 100f, 25f);
|
||||||
|
maxCoords = new OMV.Vector3(101f, 101f, 26f);
|
||||||
|
minZ = maxZ = 0f;
|
||||||
|
sizeX = sizeY = 256f;
|
||||||
|
}
|
||||||
|
public uint ID;
|
||||||
|
public IntPtr Ptr;
|
||||||
|
public float[] heightMap;
|
||||||
|
public OMV.Vector3 terrainRegionBase;
|
||||||
|
public OMV.Vector3 minCoords;
|
||||||
|
public OMV.Vector3 maxCoords;
|
||||||
|
public float sizeX, sizeY;
|
||||||
|
public float minZ, maxZ;
|
||||||
|
public BulletShape terrainShape;
|
||||||
|
public BulletBody terrainBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The general class of collsion object.
|
||||||
|
public enum CollisionType
|
||||||
|
{
|
||||||
|
Avatar,
|
||||||
|
Groundplane,
|
||||||
|
Terrain,
|
||||||
|
Static,
|
||||||
|
Dynamic,
|
||||||
|
VolumeDetect,
|
||||||
|
// Linkset, // A linkset should be either Static or Dynamic
|
||||||
|
LinksetChild,
|
||||||
|
Unknown
|
||||||
|
};
|
||||||
|
|
||||||
|
// Hold specification of group and mask collision flags for a CollisionType
|
||||||
|
public struct CollisionTypeFilterGroup
|
||||||
|
{
|
||||||
|
public CollisionTypeFilterGroup(CollisionType t, uint g, uint m)
|
||||||
|
{
|
||||||
|
type = t;
|
||||||
|
group = g;
|
||||||
|
mask = m;
|
||||||
|
}
|
||||||
|
public CollisionType type;
|
||||||
|
public uint group;
|
||||||
|
public uint mask;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* NOTE: old definitions kept for reference. Delete when things are working.
|
||||||
|
// The collsion filters and masked are defined in one place -- don't want them scattered
|
||||||
|
AvatarGroup = BCharacterGroup,
|
||||||
|
AvatarMask = BAllGroup,
|
||||||
|
ObjectGroup = BSolidGroup,
|
||||||
|
ObjectMask = BAllGroup,
|
||||||
|
StaticObjectGroup = BStaticGroup,
|
||||||
|
StaticObjectMask = AvatarGroup | ObjectGroup, // static things don't interact with much
|
||||||
|
LinksetGroup = BLinksetGroup,
|
||||||
|
LinksetMask = BAllGroup,
|
||||||
|
LinksetChildGroup = BLinksetChildGroup,
|
||||||
|
LinksetChildMask = BNoneGroup, // Linkset children disappear from the world
|
||||||
|
VolumeDetectGroup = BSensorTrigger,
|
||||||
|
VolumeDetectMask = ~BSensorTrigger,
|
||||||
|
TerrainGroup = BTerrainGroup,
|
||||||
|
TerrainMask = BAllGroup & ~BStaticGroup, // static objects on the ground don't collide
|
||||||
|
GroundPlaneGroup = BGroundPlaneGroup,
|
||||||
|
GroundPlaneMask = BAllGroup
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static class BulletSimData
|
||||||
|
{
|
||||||
|
|
||||||
|
// Map of collisionTypes to flags for collision groups and masks.
|
||||||
|
// As mentioned above, don't use the CollisionFilterGroups definitions directly in the code
|
||||||
|
// but, instead, use references to this dictionary. Finding and debugging
|
||||||
|
// collision flag problems will be made easier.
|
||||||
|
public static Dictionary<CollisionType, CollisionTypeFilterGroup> CollisionTypeMasks
|
||||||
|
= new Dictionary<CollisionType, CollisionTypeFilterGroup>()
|
||||||
|
{
|
||||||
|
{ CollisionType.Avatar,
|
||||||
|
new CollisionTypeFilterGroup(CollisionType.Avatar,
|
||||||
|
(uint)CollisionFilterGroups.BCharacterGroup,
|
||||||
|
(uint)CollisionFilterGroups.BAllGroup)
|
||||||
|
},
|
||||||
|
{ CollisionType.Groundplane,
|
||||||
|
new CollisionTypeFilterGroup(CollisionType.Groundplane,
|
||||||
|
(uint)CollisionFilterGroups.BGroundPlaneGroup,
|
||||||
|
(uint)CollisionFilterGroups.BAllGroup)
|
||||||
|
},
|
||||||
|
{ CollisionType.Terrain,
|
||||||
|
new CollisionTypeFilterGroup(CollisionType.Terrain,
|
||||||
|
(uint)CollisionFilterGroups.BTerrainGroup,
|
||||||
|
(uint)(CollisionFilterGroups.BAllGroup & ~CollisionFilterGroups.BStaticGroup))
|
||||||
|
},
|
||||||
|
{ CollisionType.Static,
|
||||||
|
new CollisionTypeFilterGroup(CollisionType.Static,
|
||||||
|
(uint)CollisionFilterGroups.BStaticGroup,
|
||||||
|
(uint)(CollisionFilterGroups.BCharacterGroup | CollisionFilterGroups.BSolidGroup))
|
||||||
|
},
|
||||||
|
{ CollisionType.Dynamic,
|
||||||
|
new CollisionTypeFilterGroup(CollisionType.Dynamic,
|
||||||
|
(uint)CollisionFilterGroups.BSolidGroup,
|
||||||
|
(uint)(CollisionFilterGroups.BAllGroup))
|
||||||
|
},
|
||||||
|
{ CollisionType.VolumeDetect,
|
||||||
|
new CollisionTypeFilterGroup(CollisionType.VolumeDetect,
|
||||||
|
(uint)CollisionFilterGroups.BSensorTrigger,
|
||||||
|
(uint)(~CollisionFilterGroups.BSensorTrigger))
|
||||||
|
},
|
||||||
|
{ CollisionType.LinksetChild,
|
||||||
|
new CollisionTypeFilterGroup(CollisionType.LinksetChild,
|
||||||
|
(uint)CollisionFilterGroups.BTerrainGroup,
|
||||||
|
(uint)(CollisionFilterGroups.BNoneGroup))
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ Some vehicles should not be able to turn if no speed or off ground.
|
||||||
Neb car jiggling left and right
|
Neb car jiggling left and right
|
||||||
Happens on terrain and any other mesh object. Flat cubes are much smoother.
|
Happens on terrain and any other mesh object. Flat cubes are much smoother.
|
||||||
This has been reduced but not eliminated.
|
This has been reduced but not eliminated.
|
||||||
|
Light cycle falling over when driving
|
||||||
For limitMotorUp, use raycast down to find if vehicle is in the air.
|
For limitMotorUp, use raycast down to find if vehicle is in the air.
|
||||||
Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE.
|
Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE.
|
||||||
Verify that angular motion specified around Z moves in the vehicle coordinates.
|
Verify that angular motion specified around Z moves in the vehicle coordinates.
|
||||||
|
@ -121,6 +122,9 @@ Remove unused fields from ShapeData (not used in API2)
|
||||||
Breakout code for mesh/hull/compound/native into separate BSShape* classes
|
Breakout code for mesh/hull/compound/native into separate BSShape* classes
|
||||||
Standardize access to building and reference code.
|
Standardize access to building and reference code.
|
||||||
The skeleton classes are in the sources but are not complete or linked in.
|
The skeleton classes are in the sources but are not complete or linked in.
|
||||||
|
Make BSBody and BSShape real classes to centralize creation/changin/destruction
|
||||||
|
Convert state and parameter calls from BulletSimAPI direct calls to
|
||||||
|
calls on BSBody and BSShape
|
||||||
Generalize Dynamics and PID with standardized motors.
|
Generalize Dynamics and PID with standardized motors.
|
||||||
Generalize Linkset and vehicles into PropertyManagers
|
Generalize Linkset and vehicles into PropertyManagers
|
||||||
Methods for Refresh, RemoveBodyDependencies, RestoreBodyDependencies
|
Methods for Refresh, RemoveBodyDependencies, RestoreBodyDependencies
|
||||||
|
@ -132,7 +136,7 @@ Implement linkset by setting position of children when root updated. (LinksetMan
|
||||||
Linkset implementation using manual prim movement.
|
Linkset implementation using manual prim movement.
|
||||||
LinkablePrim class? Would that simplify/centralize the linkset logic?
|
LinkablePrim class? Would that simplify/centralize the linkset logic?
|
||||||
BSScene.UpdateParameterSet() is broken. How to set params on objects?
|
BSScene.UpdateParameterSet() is broken. How to set params on objects?
|
||||||
Remove HeightmapInfo from terrain specification.
|
Remove HeightmapInfo from terrain specification
|
||||||
Since C++ code does not need terrain height, this structure et al are not needed.
|
Since C++ code does not need terrain height, this structure et al are not needed.
|
||||||
Add floating motor for BS_FLOATS_ON_WATER so prim and avatar will
|
Add floating motor for BS_FLOATS_ON_WATER so prim and avatar will
|
||||||
bob at the water level. BSPrim.PositionSanityCheck().
|
bob at the water level. BSPrim.PositionSanityCheck().
|
||||||
|
@ -164,7 +168,6 @@ Do prim hash codes work for sculpties and meshes? (Resolution: yes)
|
||||||
Linkset implementation using compound shapes. (Resolution: implemented LinksetCompound)
|
Linkset implementation using compound shapes. (Resolution: implemented LinksetCompound)
|
||||||
Compound shapes will need the LocalID in the shapes and collision
|
Compound shapes will need the LocalID in the shapes and collision
|
||||||
processing to get it from there.
|
processing to get it from there.
|
||||||
Light cycle falling over when driving (Resolution: implemented VerticalAttractor)
|
|
||||||
Light cycle not banking (Resolution: It doesn't. Banking is roll adding yaw.)
|
Light cycle not banking (Resolution: It doesn't. Banking is roll adding yaw.)
|
||||||
Package Bullet source mods for Bullet internal stats output
|
Package Bullet source mods for Bullet internal stats output
|
||||||
(Resolution: move code into WorldData.h rather than relying on patches)
|
(Resolution: move code into WorldData.h rather than relying on patches)
|
||||||
|
|
|
@ -250,17 +250,20 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
public abstract Vector3 CenterOfMass { get; }
|
public abstract Vector3 CenterOfMass { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Velocity of this actor.
|
/// The desired velocity of this actor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Setting this provides a target velocity for physics scene updates.
|
/// Setting this provides a target velocity for physics scene updates.
|
||||||
/// Getting this returns the velocity calculated by physics scene updates, using factors such as target velocity,
|
/// Getting this returns the last set target. Fetch Velocity to get the current velocity.
|
||||||
/// time to accelerate and collisions.
|
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
|
protected Vector3 m_targetVelocity;
|
||||||
public virtual Vector3 TargetVelocity
|
public virtual Vector3 TargetVelocity
|
||||||
{
|
{
|
||||||
get { return Velocity; }
|
get { return m_targetVelocity; }
|
||||||
set { Velocity = value; }
|
set {
|
||||||
|
m_targetVelocity = value;
|
||||||
|
Velocity = m_targetVelocity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Vector3 Velocity { get; set; }
|
public abstract Vector3 Velocity { get; set; }
|
||||||
|
|
|
@ -32,9 +32,15 @@
|
||||||
<appender-ref ref="LogFileAppender" />
|
<appender-ref ref="LogFileAppender" />
|
||||||
</root>
|
</root>
|
||||||
|
|
||||||
|
<!-- Independently control logging level for XEngine -->
|
||||||
<logger name="OpenSim.Region.ScriptEngine.XEngine">
|
<logger name="OpenSim.Region.ScriptEngine.XEngine">
|
||||||
<level value="INFO"/>
|
<level value="INFO"/>
|
||||||
</logger>
|
</logger>
|
||||||
|
|
||||||
|
<!-- Independently control logging level for per region module loading -->
|
||||||
|
<logger name="OpenSim.ApplicationPlugins.RegionModulesController.RegionModulesControllerPlugin">
|
||||||
|
<level value="INFO"/>
|
||||||
|
</logger>
|
||||||
|
|
||||||
</log4net>
|
</log4net>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
Loading…
Reference in New Issue