Revert "Revert "BulletSim: move collision processing for linksets from BSPrimLinkable""

Found that the vehicle movement problem was not caused by these physics changes.

This reverts commit c45659863d.
TeleportWork
Robert Adams 2013-07-23 08:13:01 -07:00
parent 401c2e2f2e
commit aec8852af7
5 changed files with 121 additions and 18 deletions

View File

@ -1001,7 +1001,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
else if (newVelocityLengthSq < 0.001f)
VehicleVelocity = Vector3.Zero;
VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", ControllingPrim.LocalID, ControllingPrim.IsColliding, VehicleVelocity );
VDetailLog("{0}, MoveLinear,done,isColl={1},newVel={2}", ControllingPrim.LocalID, ControllingPrim.HasSomeCollision, VehicleVelocity );
} // end MoveLinear()
@ -1062,7 +1062,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
Vector3 linearDeflectionW = linearDeflectionV * VehicleOrientation;
// Optionally, if not colliding, don't effect world downward velocity. Let falling things fall.
if (BSParam.VehicleLinearDeflectionNotCollidingNoZ && !m_controllingPrim.IsColliding)
if (BSParam.VehicleLinearDeflectionNotCollidingNoZ && !m_controllingPrim.HasSomeCollision)
{
linearDeflectionW.Z = 0f;
}
@ -1222,7 +1222,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
float targetHeight = Type == Vehicle.TYPE_BOAT ? GetWaterLevel(VehiclePosition) : GetTerrainHeight(VehiclePosition);
distanceAboveGround = VehiclePosition.Z - targetHeight;
// Not colliding if the vehicle is off the ground
if (!Prim.IsColliding)
if (!Prim.HasSomeCollision)
{
// downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale);
VehicleVelocity += new Vector3(0, 0, -distanceAboveGround);
@ -1233,12 +1233,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
// be computed with a motor.
// TODO: add interaction with banking.
VDetailLog("{0}, MoveLinear,limitMotorUp,distAbove={1},colliding={2},ret={3}",
Prim.LocalID, distanceAboveGround, Prim.IsColliding, ret);
Prim.LocalID, distanceAboveGround, Prim.HasSomeCollision, ret);
*/
// Another approach is to measure if we're going up. If going up and not colliding,
// the vehicle is in the air. Fix that by pushing down.
if (!ControllingPrim.IsColliding && VehicleVelocity.Z > 0.1)
if (!ControllingPrim.HasSomeCollision && VehicleVelocity.Z > 0.1)
{
// Get rid of any of the velocity vector that is pushing us up.
float upVelocity = VehicleVelocity.Z;
@ -1260,7 +1260,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
}
*/
VDetailLog("{0}, MoveLinear,limitMotorUp,collide={1},upVel={2},newVel={3}",
ControllingPrim.LocalID, ControllingPrim.IsColliding, upVelocity, VehicleVelocity);
ControllingPrim.LocalID, ControllingPrim.HasSomeCollision, upVelocity, VehicleVelocity);
}
}
}
@ -1270,14 +1270,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
Vector3 appliedGravity = m_VehicleGravity * m_vehicleMass;
// Hack to reduce downward force if the vehicle is probably sitting on the ground
if (ControllingPrim.IsColliding && IsGroundVehicle)
if (ControllingPrim.HasSomeCollision && IsGroundVehicle)
appliedGravity *= BSParam.VehicleGroundGravityFudge;
VehicleAddForce(appliedGravity);
VDetailLog("{0}, MoveLinear,applyGravity,vehGrav={1},collid={2},fudge={3},mass={4},appliedForce={5}",
ControllingPrim.LocalID, m_VehicleGravity,
ControllingPrim.IsColliding, BSParam.VehicleGroundGravityFudge, m_vehicleMass, appliedGravity);
ControllingPrim.HasSomeCollision, BSParam.VehicleGroundGravityFudge, m_vehicleMass, appliedGravity);
}
// =======================================================================

View File

@ -203,6 +203,33 @@ public abstract class BSLinkset
return ret;
}
// Called after a simulation step to post a collision with this object.
// Return 'true' if linkset processed the collision. 'false' says the linkset didn't have
// anything to add for the collision and it should be passed through normal processing.
// Default processing for a linkset.
public virtual bool HandleCollide(uint collidingWith, BSPhysObject collidee,
OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
{
bool ret = false;
// prims in the same linkset cannot collide with each other
BSPrimLinkable convCollidee = collidee as BSPrimLinkable;
if (convCollidee != null && (LinksetID == convCollidee.Linkset.LinksetID))
{
// By returning 'true', we tell the caller the collision has been 'handled' so it won't
// do anything about this collision and thus, effectivily, ignoring the collision.
ret = true;
}
else
{
// Not a collision between members of the linkset. Must be a real collision.
// So the linkset root can know if there is a collision anywhere in the linkset.
LinksetRoot.SomeCollisionSimulationStep = m_physicsScene.SimulationStep;
}
return ret;
}
// I am the root of a linkset and a new child is being added
// Called while LinkActivity is locked.
protected abstract void AddChildToLinkset(BSPrimLinkable child);
@ -250,6 +277,53 @@ public abstract class BSLinkset
// Called at taint-time!!
public abstract bool RemoveDependencies(BSPrimLinkable child);
// ================================================================
// Some physical setting happen to all members of the linkset
public virtual void SetPhysicalFriction(float friction)
{
ForEachMember((member) =>
{
if (member.PhysBody.HasPhysicalBody)
m_physicsScene.PE.SetFriction(member.PhysBody, friction);
return false; // 'false' says to continue looping
}
);
}
public virtual void SetPhysicalRestitution(float restitution)
{
ForEachMember((member) =>
{
if (member.PhysBody.HasPhysicalBody)
m_physicsScene.PE.SetRestitution(member.PhysBody, restitution);
return false; // 'false' says to continue looping
}
);
}
public virtual void SetPhysicalGravity(OMV.Vector3 gravity)
{
ForEachMember((member) =>
{
if (member.PhysBody.HasPhysicalBody)
m_physicsScene.PE.SetGravity(member.PhysBody, gravity);
return false; // 'false' says to continue looping
}
);
}
public virtual void ComputeLocalInertia()
{
ForEachMember((member) =>
{
if (member.PhysBody.HasPhysicalBody)
{
OMV.Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(member.PhysShape.physShapeInfo, member.Mass);
member.Inertia = inertia * BSParam.VehicleInertiaFactor;
m_physicsScene.PE.SetMassProps(member.PhysBody, member.Mass, member.Inertia);
m_physicsScene.PE.UpdateInertiaTensor(member.PhysBody);
}
return false; // 'false' says to continue looping
}
);
}
// ================================================================
protected virtual float ComputeLinksetMass()
{
@ -311,6 +385,5 @@ public abstract class BSLinkset
if (m_physicsScene.PhysicsLogging.Enabled)
m_physicsScene.DetailLog(msg, args);
}
}
}

View File

@ -353,6 +353,16 @@ public abstract class BSPhysObject : PhysicsActor
CollidingStep = BSScene.NotASimulationStep;
}
}
// Complex objects (like linksets) need to know if there is a collision on any part of
// their shape. 'IsColliding' has an existing definition of reporting a collision on
// only this specific prim or component of linksets.
// 'HasSomeCollision' is defined as reporting if there is a collision on any part of
// the complex body that this prim is the root of.
public virtual bool HasSomeCollision
{
get { return IsColliding; }
set { IsColliding = value; }
}
public override bool CollidingGround {
get { return (CollidingGroundStep == PhysScene.SimulationStep); }
set
@ -386,6 +396,7 @@ public abstract class BSPhysObject : PhysicsActor
// Return 'true' if a collision was processed and should be sent up.
// Return 'false' if this object is not enabled/subscribed/appropriate for or has already seen this collision.
// Called at taint time from within the Step() function
public delegate bool CollideCall(uint collidingWith, BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth);
public virtual bool Collide(uint collidingWith, BSPhysObject collidee,
OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
{

View File

@ -507,6 +507,7 @@ public class BSPrim : BSPhysObject
}
return ret;
}
public override int VehicleType {
get {
int ret = (int)Vehicle.TYPE_NONE;

View File

@ -200,20 +200,38 @@ public class BSPrimLinkable : BSPrimDisplaced
}
// Called after a simulation step to post a collision with this object.
// This returns 'true' if the collision has been queued and the SendCollisions call must
// be made at the end of the simulation step.
public override bool Collide(uint collidingWith, BSPhysObject collidee,
OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
{
// prims in the same linkset cannot collide with each other
BSPrimLinkable convCollidee = collidee as BSPrimLinkable;
if (convCollidee != null && (this.Linkset.LinksetID == convCollidee.Linkset.LinksetID))
bool ret = false;
// Ask the linkset if it wants to handle the collision
if (!Linkset.HandleCollide(collidingWith, collidee, contactPoint, contactNormal, pentrationDepth))
{
return false;
// The linkset didn't handle it so pass the collision through normal processing
ret = base.Collide(collidingWith, collidee, contactPoint, contactNormal, pentrationDepth);
}
return ret;
}
// TODO: handle collisions of other objects with with children of linkset.
// This is a problem for LinksetCompound since the children are packed into the root.
// A linkset reports any collision on any part of the linkset.
public long SomeCollisionSimulationStep = 0;
public override bool HasSomeCollision
{
get
{
return (SomeCollisionSimulationStep == PhysScene.SimulationStep) || base.IsColliding;
}
set
{
if (value)
SomeCollisionSimulationStep = PhysScene.SimulationStep;
else
SomeCollisionSimulationStep = 0;
return base.Collide(collidingWith, collidee, contactPoint, contactNormal, pentrationDepth);
base.HasSomeCollision = value;
}
}
}
}