Merge branch 'master' into careminster

Conflicts:
	OpenSim/Data/MySQL/MySQLSimulationData.cs
	OpenSim/Data/MySQL/Resources/RegionStore.migrations
	OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
	OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
	OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs
	OpenSim/Region/CoreModules/World/LightShare/LightShareModule.cs
	OpenSim/Region/Framework/Scenes/Scene.cs
	OpenSim/Region/Framework/Scenes/ScenePresence.cs
	OpenSim/Region/Framework/Scenes/Tests/ScenePresenceCapabilityTests.cs
	OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
	OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
This commit is contained in:
Melanie
2013-10-04 20:03:12 +01:00
85 changed files with 2998 additions and 873 deletions

View File

@@ -596,6 +596,60 @@ public override bool SetBreakingImpulseThreshold(BulletConstraint constrain, flo
return BSAPICPP.SetBreakingImpulseThreshold2(constrainu.ptr, threshold);
}
public override bool HingeSetLimits(BulletConstraint constrain, float low, float high, float softness, float bias, float relaxation)
{
BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
return BSAPICPP.HingeSetLimits2(constrainu.ptr, low, high, softness, bias, relaxation);
}
public override bool SpringEnable(BulletConstraint constrain, int index, float numericTrueFalse)
{
BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
return BSAPICPP.ConstraintSpringEnable2(constrainu.ptr, index, numericTrueFalse);
}
public override bool SpringSetEquilibriumPoint(BulletConstraint constrain, int index, float equilibriumPoint)
{
BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
return BSAPICPP.ConstraintSpringSetEquilibriumPoint2(constrainu.ptr, index, equilibriumPoint);
}
public override bool SpringSetStiffness(BulletConstraint constrain, int index, float stiffnesss)
{
BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
return BSAPICPP.ConstraintSpringSetStiffness2(constrainu.ptr, index, stiffnesss);
}
public override bool SpringSetDamping(BulletConstraint constrain, int index, float damping)
{
BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
return BSAPICPP.ConstraintSpringSetDamping2(constrainu.ptr, index, damping);
}
public override bool SliderSetLimits(BulletConstraint constrain, int lowerUpper, int linAng, float val)
{
BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
return BSAPICPP.SliderSetLimits2(constrainu.ptr, lowerUpper, linAng, val);
}
public override bool SliderSet(BulletConstraint constrain, int softRestDamp, int dirLimOrtho, int linAng, float val)
{
BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
return BSAPICPP.SliderSet2(constrainu.ptr, softRestDamp, dirLimOrtho, linAng, val);
}
public override bool SliderMotorEnable(BulletConstraint constrain, int linAng, float numericTrueFalse)
{
BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
return BSAPICPP.SliderMotorEnable2(constrainu.ptr, linAng, numericTrueFalse);
}
public override bool SliderMotor(BulletConstraint constrain, int forceVel, int linAng, float val)
{
BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
return BSAPICPP.SliderMotor2(constrainu.ptr, forceVel, linAng, val);
}
public override bool CalculateTransforms(BulletConstraint constrain)
{
BulletConstraintUnman constrainu = constrain as BulletConstraintUnman;
@@ -671,6 +725,13 @@ public override bool RemoveObjectFromWorld(BulletWorld world, BulletBody obj)
return BSAPICPP.RemoveObjectFromWorld2(worldu.ptr, bodyu.ptr);
}
public override bool ClearCollisionProxyCache(BulletWorld world, BulletBody obj)
{
BulletWorldUnman worldu = world as BulletWorldUnman;
BulletBodyUnman bodyu = obj as BulletBodyUnman;
return BSAPICPP.ClearCollisionProxyCache2(worldu.ptr, bodyu.ptr);
}
public override bool AddConstraintToWorld(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects)
{
BulletWorldUnman worldu = world as BulletWorldUnman;
@@ -1600,6 +1661,33 @@ public static extern bool TranslationalLimitMotor2(IntPtr constrain, float enabl
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SetBreakingImpulseThreshold2(IntPtr constrain, float threshold);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool HingeSetLimits2(IntPtr constrain, float low, float high, float softness, float bias, float relaxation);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool ConstraintSpringEnable2(IntPtr constrain, int index, float numericTrueFalse);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool ConstraintSpringSetEquilibriumPoint2(IntPtr constrain, int index, float equilibriumPoint);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool ConstraintSpringSetStiffness2(IntPtr constrain, int index, float stiffness);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool ConstraintSpringSetDamping2(IntPtr constrain, int index, float damping);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SliderSetLimits2(IntPtr constrain, int lowerUpper, int linAng, float val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SliderSet2(IntPtr constrain, int softRestDamp, int dirLimOrtho, int linAng, float val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SliderMotorEnable2(IntPtr constrain, int linAng, float numericTrueFalse);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool SliderMotor2(IntPtr constrain, int forceVel, int linAng, float val);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool CalculateTransforms2(IntPtr constrain);
@@ -1631,6 +1719,9 @@ public static extern bool AddObjectToWorld2(IntPtr world, IntPtr obj);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool RemoveObjectFromWorld2(IntPtr world, IntPtr obj);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool ClearCollisionProxyCache2(IntPtr world, IntPtr obj);
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern bool AddConstraintToWorld2(IntPtr world, IntPtr constrain, bool disableCollisionsBetweenLinkedObjects);

View File

@@ -169,6 +169,19 @@ private sealed class BulletConstraintXNA : BulletConstraint
return true;
}
public override bool ClearCollisionProxyCache(BulletWorld pWorld, BulletBody pBody)
{
DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
RigidBody body = ((BulletBodyXNA)pBody).rigidBody;
CollisionObject collisionObject = ((BulletBodyXNA)pBody).body;
if (body != null && collisionObject != null && collisionObject.GetBroadphaseHandle() != null)
{
world.RemoveCollisionObject(collisionObject);
world.AddCollisionObject(collisionObject);
}
return true;
}
public override bool AddConstraintToWorld(BulletWorld pWorld, BulletConstraint pConstraint, bool pDisableCollisionsBetweenLinkedObjects)
{
DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
@@ -752,6 +765,214 @@ private sealed class BulletConstraintXNA : BulletConstraint
constraint.SetBreakingImpulseThreshold(threshold);
return true;
}
public override bool HingeSetLimits(BulletConstraint pConstraint, float low, float high, float softness, float bias, float relaxation)
{
HingeConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as HingeConstraint;
if (softness == HINGE_NOT_SPECIFIED)
constraint.SetLimit(low, high);
else
constraint.SetLimit(low, high, softness, bias, relaxation);
return true;
}
public override bool SpringEnable(BulletConstraint pConstraint, int index, float numericTrueFalse)
{
Generic6DofSpringConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofSpringConstraint;
constraint.EnableSpring(index, (numericTrueFalse == 0f ? false : true));
return true;
}
public override bool SpringSetEquilibriumPoint(BulletConstraint pConstraint, int index, float equilibriumPoint)
{
Generic6DofSpringConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofSpringConstraint;
if (index == SPRING_NOT_SPECIFIED)
{
constraint.SetEquilibriumPoint();
}
else
{
if (equilibriumPoint == SPRING_NOT_SPECIFIED)
constraint.SetEquilibriumPoint(index);
else
constraint.SetEquilibriumPoint(index, equilibriumPoint);
}
return true;
}
public override bool SpringSetStiffness(BulletConstraint pConstraint, int index, float stiffness)
{
Generic6DofSpringConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofSpringConstraint;
constraint.SetStiffness(index, stiffness);
return true;
}
public override bool SpringSetDamping(BulletConstraint pConstraint, int index, float damping)
{
Generic6DofSpringConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as Generic6DofSpringConstraint;
constraint.SetDamping(index, damping);
return true;
}
public override bool SliderSetLimits(BulletConstraint pConstraint, int lowerUpper, int linAng, float val)
{
SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint;
switch (lowerUpper)
{
case SLIDER_LOWER_LIMIT:
switch (linAng)
{
case SLIDER_LINEAR:
constraint.SetLowerLinLimit(val);
break;
case SLIDER_ANGULAR:
constraint.SetLowerAngLimit(val);
break;
}
break;
case SLIDER_UPPER_LIMIT:
switch (linAng)
{
case SLIDER_LINEAR:
constraint.SetUpperLinLimit(val);
break;
case SLIDER_ANGULAR:
constraint.SetUpperAngLimit(val);
break;
}
break;
}
return true;
}
public override bool SliderSet(BulletConstraint pConstraint, int softRestDamp, int dirLimOrtho, int linAng, float val)
{
SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint;
switch (softRestDamp)
{
case SLIDER_SET_SOFTNESS:
switch (dirLimOrtho)
{
case SLIDER_SET_DIRECTION:
switch (linAng)
{
case SLIDER_LINEAR: constraint.SetSoftnessDirLin(val); break;
case SLIDER_ANGULAR: constraint.SetSoftnessDirAng(val); break;
}
break;
case SLIDER_SET_LIMIT:
switch (linAng)
{
case SLIDER_LINEAR: constraint.SetSoftnessLimLin(val); break;
case SLIDER_ANGULAR: constraint.SetSoftnessLimAng(val); break;
}
break;
case SLIDER_SET_ORTHO:
switch (linAng)
{
case SLIDER_LINEAR: constraint.SetSoftnessOrthoLin(val); break;
case SLIDER_ANGULAR: constraint.SetSoftnessOrthoAng(val); break;
}
break;
}
break;
case SLIDER_SET_RESTITUTION:
switch (dirLimOrtho)
{
case SLIDER_SET_DIRECTION:
switch (linAng)
{
case SLIDER_LINEAR: constraint.SetRestitutionDirLin(val); break;
case SLIDER_ANGULAR: constraint.SetRestitutionDirAng(val); break;
}
break;
case SLIDER_SET_LIMIT:
switch (linAng)
{
case SLIDER_LINEAR: constraint.SetRestitutionLimLin(val); break;
case SLIDER_ANGULAR: constraint.SetRestitutionLimAng(val); break;
}
break;
case SLIDER_SET_ORTHO:
switch (linAng)
{
case SLIDER_LINEAR: constraint.SetRestitutionOrthoLin(val); break;
case SLIDER_ANGULAR: constraint.SetRestitutionOrthoAng(val); break;
}
break;
}
break;
case SLIDER_SET_DAMPING:
switch (dirLimOrtho)
{
case SLIDER_SET_DIRECTION:
switch (linAng)
{
case SLIDER_LINEAR: constraint.SetDampingDirLin(val); break;
case SLIDER_ANGULAR: constraint.SetDampingDirAng(val); break;
}
break;
case SLIDER_SET_LIMIT:
switch (linAng)
{
case SLIDER_LINEAR: constraint.SetDampingLimLin(val); break;
case SLIDER_ANGULAR: constraint.SetDampingLimAng(val); break;
}
break;
case SLIDER_SET_ORTHO:
switch (linAng)
{
case SLIDER_LINEAR: constraint.SetDampingOrthoLin(val); break;
case SLIDER_ANGULAR: constraint.SetDampingOrthoAng(val); break;
}
break;
}
break;
}
return true;
}
public override bool SliderMotorEnable(BulletConstraint pConstraint, int linAng, float numericTrueFalse)
{
SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint;
switch (linAng)
{
case SLIDER_LINEAR:
constraint.SetPoweredLinMotor(numericTrueFalse == 0.0 ? false : true);
break;
case SLIDER_ANGULAR:
constraint.SetPoweredAngMotor(numericTrueFalse == 0.0 ? false : true);
break;
}
return true;
}
public override bool SliderMotor(BulletConstraint pConstraint, int forceVel, int linAng, float val)
{
SliderConstraint constraint = (pConstraint as BulletConstraintXNA).constrain as SliderConstraint;
switch (forceVel)
{
case SLIDER_MOTOR_VELOCITY:
switch (linAng)
{
case SLIDER_LINEAR:
constraint.SetTargetLinMotorVelocity(val);
break;
case SLIDER_ANGULAR:
constraint.SetTargetAngMotorVelocity(val);
break;
}
break;
case SLIDER_MAX_MOTOR_FORCE:
switch (linAng)
{
case SLIDER_LINEAR:
constraint.SetMaxLinMotorForce(val);
break;
case SLIDER_ANGULAR:
constraint.SetMaxAngMotorForce(val);
break;
}
break;
}
return true;
}
//BulletSimAPI.SetAngularDamping(Prim.PhysBody.ptr, angularDamping);
public override void SetAngularDamping(BulletBody pBody, float angularDamping)
{

View File

@@ -105,7 +105,7 @@ public class BSActorAvatarMove : BSActor
// into the movement motor.
public void SetVelocityAndTarget(OMV.Vector3 vel, OMV.Vector3 targ, bool inTaintTime)
{
m_physicsScene.TaintedObject(inTaintTime, "BSActorAvatarMove.setVelocityAndTarget", delegate()
m_physicsScene.TaintedObject(inTaintTime, m_controllingPrim.LocalID, "BSActorAvatarMove.setVelocityAndTarget", delegate()
{
if (m_velocityMotor != null)
{
@@ -128,6 +128,7 @@ public class BSActorAvatarMove : BSActor
BSMotor.Infinite, // decay time scale
1f // efficiency
);
m_velocityMotor.ErrorZeroThreshold = BSParam.AvatarStopZeroThreshold;
// _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
SetVelocityAndTarget(m_controllingPrim.RawVelocity, m_controllingPrim.TargetVelocity, true /* inTaintTime */);
@@ -278,6 +279,7 @@ public class BSActorAvatarMove : BSActor
if (m_controllingPrim.IsStationary)
{
entprop.Position = m_controllingPrim.RawPosition;
entprop.Velocity = OMV.Vector3.Zero;
m_physicsScene.PE.SetTranslation(m_controllingPrim.PhysBody, entprop.Position, entprop.Rotation);
}

View File

@@ -43,7 +43,9 @@ public enum ConstraintType : int
SLIDER_CONSTRAINT_TYPE,
CONTACT_CONSTRAINT_TYPE,
D6_SPRING_CONSTRAINT_TYPE,
MAX_CONSTRAINT_TYPE
MAX_CONSTRAINT_TYPE, // last type defined by Bullet
//
FIXED_CONSTRAINT_TYPE = 1234 // BulletSim constraint that is fixed and unmoving
}
// ===============================================================================
@@ -290,7 +292,7 @@ public enum ConstraintParamAxis : int
AXIS_ANGULAR_X,
AXIS_ANGULAR_Y,
AXIS_ANGULAR_Z,
AXIS_LINEAR_ALL = 20, // these last three added by BulletSim so we don't have to do zillions of calls
AXIS_LINEAR_ALL = 20, // added by BulletSim so we don't have to do zillions of calls
AXIS_ANGULAR_ALL,
AXIS_ALL
};
@@ -441,6 +443,38 @@ public abstract bool TranslationalLimitMotor(BulletConstraint constrain, float e
public abstract bool SetBreakingImpulseThreshold(BulletConstraint constrain, float threshold);
public const int HINGE_NOT_SPECIFIED = -1;
public abstract bool HingeSetLimits(BulletConstraint constrain, float low, float high, float softness, float bias, float relaxation);
public abstract bool SpringEnable(BulletConstraint constrain, int index, float numericTrueFalse);
public const int SPRING_NOT_SPECIFIED = -1;
public abstract bool SpringSetEquilibriumPoint(BulletConstraint constrain, int index, float equilibriumPoint);
public abstract bool SpringSetStiffness(BulletConstraint constrain, int index, float stiffnesss);
public abstract bool SpringSetDamping(BulletConstraint constrain, int index, float damping);
public const int SLIDER_LOWER_LIMIT = 0;
public const int SLIDER_UPPER_LIMIT = 1;
public const int SLIDER_LINEAR = 2;
public const int SLIDER_ANGULAR = 3;
public abstract bool SliderSetLimits(BulletConstraint constrain, int lowerUpper, int linAng, float val);
public const int SLIDER_SET_SOFTNESS = 4;
public const int SLIDER_SET_RESTITUTION = 5;
public const int SLIDER_SET_DAMPING = 6;
public const int SLIDER_SET_DIRECTION = 7;
public const int SLIDER_SET_LIMIT = 8;
public const int SLIDER_SET_ORTHO = 9;
public abstract bool SliderSet(BulletConstraint constrain, int softRestDamp, int dirLimOrtho, int linAng, float val);
public abstract bool SliderMotorEnable(BulletConstraint constrain, int linAng, float numericTrueFalse);
public const int SLIDER_MOTOR_VELOCITY = 10;
public const int SLIDER_MAX_MOTOR_FORCE = 11;
public abstract bool SliderMotor(BulletConstraint constrain, int forceVel, int linAng, float val);
public abstract bool CalculateTransforms(BulletConstraint constrain);
public abstract bool SetConstraintParam(BulletConstraint constrain, ConstraintParams paramIndex, float value, ConstraintParamAxis axis);
@@ -464,6 +498,8 @@ public abstract bool AddObjectToWorld(BulletWorld world, BulletBody obj);
public abstract bool RemoveObjectFromWorld(BulletWorld world, BulletBody obj);
public abstract bool ClearCollisionProxyCache(BulletWorld world, BulletBody obj);
public abstract bool AddConstraintToWorld(BulletWorld world, BulletConstraint constrain, bool disableCollisionsBetweenLinkedObjects);
public abstract bool RemoveConstraintFromWorld(BulletWorld world, BulletConstraint constrain);

View File

@@ -93,7 +93,7 @@ public sealed class BSCharacter : BSPhysObject
LocalID, _size, Scale, Density, _avatarVolume, RawMass, pos);
// do actual creation in taint time
PhysScene.TaintedObject("BSCharacter.create", delegate()
PhysScene.TaintedObject(LocalID, "BSCharacter.create", delegate()
{
DetailLog("{0},BSCharacter.create,taint", LocalID);
// New body and shape into PhysBody and PhysShape
@@ -121,7 +121,7 @@ public sealed class BSCharacter : BSPhysObject
base.Destroy();
DetailLog("{0},BSCharacter.Destroy", LocalID);
PhysScene.TaintedObject("BSCharacter.destroy", delegate()
PhysScene.TaintedObject(LocalID, "BSCharacter.destroy", delegate()
{
PhysScene.Shapes.DereferenceBody(PhysBody, null /* bodyCallback */);
PhysBody.Clear();
@@ -209,7 +209,7 @@ public sealed class BSCharacter : BSPhysObject
DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}",
LocalID, _size, Scale, Density, _avatarVolume, RawMass);
PhysScene.TaintedObject("BSCharacter.setSize", delegate()
PhysScene.TaintedObject(LocalID, "BSCharacter.setSize", delegate()
{
if (PhysBody.HasPhysicalBody && PhysShape.physShapeInfo.HasPhysicalShape)
{
@@ -257,7 +257,7 @@ public sealed class BSCharacter : BSPhysObject
_rotationalVelocity = OMV.Vector3.Zero;
// Zero some other properties directly into the physics engine
PhysScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate()
PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.ZeroMotion", delegate()
{
if (PhysBody.HasPhysicalBody)
PhysScene.PE.ClearAllForces(PhysBody);
@@ -267,7 +267,7 @@ public sealed class BSCharacter : BSPhysObject
{
_rotationalVelocity = OMV.Vector3.Zero;
PhysScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate()
PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.ZeroMotion", delegate()
{
if (PhysBody.HasPhysicalBody)
{
@@ -291,7 +291,7 @@ public sealed class BSCharacter : BSPhysObject
set {
RawPosition = value;
PhysScene.TaintedObject("BSCharacter.setPosition", delegate()
PhysScene.TaintedObject(LocalID, "BSCharacter.setPosition", delegate()
{
DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation);
PositionSanityCheck();
@@ -363,7 +363,7 @@ public sealed class BSCharacter : BSPhysObject
{
// The new position value must be pushed into the physics engine but we can't
// just assign to "Position" because of potential call loops.
PhysScene.TaintedObject(inTaintTime, "BSCharacter.PositionSanityCheck", delegate()
PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.PositionSanityCheck", delegate()
{
DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation);
ForcePosition = RawPosition;
@@ -390,7 +390,7 @@ public sealed class BSCharacter : BSPhysObject
set {
RawForce = value;
// m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force);
PhysScene.TaintedObject("BSCharacter.SetForce", delegate()
PhysScene.TaintedObject(LocalID, "BSCharacter.SetForce", delegate()
{
DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, RawForce);
if (PhysBody.HasPhysicalBody)
@@ -438,7 +438,7 @@ public sealed class BSCharacter : BSPhysObject
set {
RawVelocity = value;
// m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, RawVelocity);
PhysScene.TaintedObject("BSCharacter.setVelocity", delegate()
PhysScene.TaintedObject(LocalID, "BSCharacter.setVelocity", delegate()
{
if (m_moveActor != null)
m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, true /* inTaintTime */);
@@ -480,7 +480,7 @@ public sealed class BSCharacter : BSPhysObject
if (RawOrientation != value)
{
RawOrientation = value;
PhysScene.TaintedObject("BSCharacter.setOrientation", delegate()
PhysScene.TaintedObject(LocalID, "BSCharacter.setOrientation", delegate()
{
// Bullet assumes we know what we are doing when forcing orientation
// so it lets us go against all the rules and just compensates for them later.
@@ -560,7 +560,7 @@ public sealed class BSCharacter : BSPhysObject
public override bool FloatOnWater {
set {
_floatOnWater = value;
PhysScene.TaintedObject("BSCharacter.setFloatOnWater", delegate()
PhysScene.TaintedObject(LocalID, "BSCharacter.setFloatOnWater", delegate()
{
if (PhysBody.HasPhysicalBody)
{
@@ -588,7 +588,7 @@ public sealed class BSCharacter : BSPhysObject
public override float Buoyancy {
get { return _buoyancy; }
set { _buoyancy = value;
PhysScene.TaintedObject("BSCharacter.setBuoyancy", delegate()
PhysScene.TaintedObject(LocalID, "BSCharacter.setBuoyancy", delegate()
{
DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
ForceBuoyancy = _buoyancy;
@@ -633,7 +633,7 @@ public sealed class BSCharacter : BSPhysObject
OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
// DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce);
PhysScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate()
PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.AddForce", delegate()
{
// Bullet adds this central force to the total force for this tick
// DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce);
@@ -676,18 +676,20 @@ public sealed class BSCharacter : BSPhysObject
float heightAdjust = BSParam.AvatarHeightMidFudge;
if (BSParam.AvatarHeightLowFudge != 0f || BSParam.AvatarHeightHighFudge != 0f)
{
// An avatar is between 1.61 and 2.12 meters. Midpoint is 1.87m.
// The "times 4" relies on the fact that the difference from the midpoint to the extremes is exactly 0.25
float midHeightOffset = size.Z - 1.87f;
const float AVATAR_LOW = 1.1f;
const float AVATAR_MID = 1.775f; // 1.87f
const float AVATAR_HI = 2.45f;
// An avatar is between 1.1 and 2.45 meters. Midpoint is 1.775m.
float midHeightOffset = size.Z - AVATAR_MID;
if (midHeightOffset < 0f)
{
// Small avatar. Add the adjustment based on the distance from midheight
heightAdjust += -1f * midHeightOffset * 4f * BSParam.AvatarHeightLowFudge;
heightAdjust += ((-1f * midHeightOffset) / (AVATAR_MID - AVATAR_LOW)) * BSParam.AvatarHeightLowFudge;
}
else
{
// Large avatar. Add the adjustment based on the distance from midheight
heightAdjust += midHeightOffset * 4f * BSParam.AvatarHeightHighFudge;
heightAdjust += ((midHeightOffset) / (AVATAR_HI - AVATAR_MID)) * BSParam.AvatarHeightHighFudge;
}
}
// The total scale height is the central cylindar plus the caps on the two ends.
@@ -698,6 +700,9 @@ public sealed class BSCharacter : BSPhysObject
if (newScale.Z < 0)
newScale.Z = 0.1f;
DetailLog("{0},BSCharacter.ComputerAvatarScale,size={1},lowF={2},midF={3},hiF={4},adj={5},newScale={6}",
LocalID, size, BSParam.AvatarHeightLowFudge, BSParam.AvatarHeightMidFudge, BSParam.AvatarHeightHighFudge, heightAdjust, newScale);
return newScale;
}

View File

@@ -64,7 +64,7 @@ public abstract class BSConstraint : IDisposable
{
bool success = PhysicsScene.PE.DestroyConstraint(m_world, m_constraint);
m_world.physicsScene.DetailLog("{0},BSConstraint.Dispose,taint,id1={1},body1={2},id2={3},body2={4},success={5}",
BSScene.DetailLogZero,
m_body1.ID,
m_body1.ID, m_body1.AddrString,
m_body2.ID, m_body2.AddrString,
success);
@@ -77,7 +77,10 @@ public abstract class BSConstraint : IDisposable
{
bool ret = false;
if (m_enabled)
{
m_world.physicsScene.DetailLog("{0},BSConstraint.SetLinearLimits,taint,low={1},high={2}", m_body1.ID, low, high);
ret = PhysicsScene.PE.SetLinearLimits(m_constraint, low, high);
}
return ret;
}
@@ -86,6 +89,7 @@ public abstract class BSConstraint : IDisposable
bool ret = false;
if (m_enabled)
{
m_world.physicsScene.DetailLog("{0},BSConstraint.SetAngularLimits,taint,low={1},high={2}", m_body1.ID, low, high);
ret = PhysicsScene.PE.SetAngularLimits(m_constraint, low, high);
}
return ret;

View File

@@ -32,12 +32,19 @@ using OpenMetaverse;
namespace OpenSim.Region.Physics.BulletSPlugin
{
public sealed class BSConstraint6Dof : BSConstraint
public class BSConstraint6Dof : BSConstraint
{
private static string LogHeader = "[BULLETSIM 6DOF CONSTRAINT]";
public override ConstraintType Type { get { return ConstraintType.D6_CONSTRAINT_TYPE; } }
public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2) :base(world)
{
m_body1 = obj1;
m_body2 = obj2;
m_enabled = false;
}
// Create a btGeneric6DofConstraint
public BSConstraint6Dof(BulletWorld world, BulletBody obj1, BulletBody obj2,
Vector3 frame1, Quaternion frame1rot,
@@ -52,9 +59,11 @@ public sealed class BSConstraint6Dof : BSConstraint
frame2, frame2rot,
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
m_enabled = true;
world.physicsScene.DetailLog("{0},BS6DofConstraint,createFrame,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
BSScene.DetailLogZero, world.worldID,
PhysicsScene.DetailLog("{0},BS6DofConstraint,create,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
m_body1.ID, world.worldID,
obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString);
PhysicsScene.DetailLog("{0},BS6DofConstraint,create, f1Loc={1},f1Rot={2},f2Loc={3},f2Rot={4},usefA={5},disCol={6}",
m_body1.ID, frame1, frame1rot, frame2, frame2rot, useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
}
// 6 Dof constraint based on a midpoint between the two constrained bodies
@@ -79,9 +88,11 @@ public sealed class BSConstraint6Dof : BSConstraint
m_constraint = PhysicsScene.PE.Create6DofConstraintToPoint(m_world, m_body1, m_body2,
joinPoint,
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
PhysicsScene.DetailLog("{0},BS6DofConstraint,createMidPoint,wID={1}, csrt={2}, rID={3}, rBody={4}, cID={5}, cBody={6}",
BSScene.DetailLogZero, world.worldID, m_constraint.AddrString,
m_body1.ID, world.worldID, m_constraint.AddrString,
obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString);
if (!m_constraint.HasPhysicalConstraint)
{
world.physicsScene.Logger.ErrorFormat("{0} Failed creation of 6Dof constraint. rootID={1}, childID={2}",
@@ -106,8 +117,10 @@ public sealed class BSConstraint6Dof : BSConstraint
frameInBloc, frameInBrot,
useLinearReferenceFrameB, disableCollisionsBetweenLinkedBodies);
m_enabled = true;
world.physicsScene.DetailLog("{0},BS6DofConstraint,createFixed,wID={1},rID={2},rBody={3}",
BSScene.DetailLogZero, world.worldID, obj1.ID, obj1.AddrString);
PhysicsScene.DetailLog("{0},BS6DofConstraint,createFixed,wID={1},rID={2},rBody={3}",
m_body1.ID, world.worldID, obj1.ID, obj1.AddrString);
PhysicsScene.DetailLog("{0},BS6DofConstraint,createFixed, fBLoc={1},fBRot={2},usefA={3},disCol={4}",
m_body1.ID, frameInBloc, frameInBrot, useLinearReferenceFrameB, disableCollisionsBetweenLinkedBodies);
}
public bool SetFrames(Vector3 frameA, Quaternion frameArot, Vector3 frameB, Quaternion frameBrot)

View File

@@ -0,0 +1,54 @@
/*
* 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 OpenMetaverse;
namespace OpenSim.Region.Physics.BulletSPlugin
{
public sealed class BSConstraintConeTwist : BSConstraint
{
public override ConstraintType Type { get { return ConstraintType.CONETWIST_CONSTRAINT_TYPE; } }
public BSConstraintConeTwist(BulletWorld world, BulletBody obj1, BulletBody obj2,
Vector3 frameInAloc, Quaternion frameInArot,
Vector3 frameInBloc, Quaternion frameInBrot,
bool disableCollisionsBetweenLinkedBodies)
: base(world)
{
m_body1 = obj1;
m_body2 = obj2;
m_constraint = PhysicsScene.PE.CreateConeTwistConstraint(world, obj1, obj2,
frameInAloc, frameInArot, frameInBloc, frameInBrot,
disableCollisionsBetweenLinkedBodies);
m_enabled = true;
}
}
}

View File

@@ -0,0 +1,55 @@
/*
* 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 OpenMetaverse;
namespace OpenSim.Region.Physics.BulletSPlugin
{
public sealed class BSConstraintSlider : BSConstraint
{
public override ConstraintType Type { get { return ConstraintType.SLIDER_CONSTRAINT_TYPE; } }
public BSConstraintSlider(BulletWorld world, BulletBody obj1, BulletBody obj2,
Vector3 frameInAloc, Quaternion frameInArot,
Vector3 frameInBloc, Quaternion frameInBrot,
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
: base(world)
{
m_body1 = obj1;
m_body2 = obj2;
m_constraint = PhysicsScene.PE.CreateSliderConstraint(world, obj1, obj2,
frameInAloc, frameInArot, frameInBloc, frameInBrot,
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
m_enabled = true;
}
}
}

View File

@@ -0,0 +1,103 @@
/*
* 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 OpenMetaverse;
namespace OpenSim.Region.Physics.BulletSPlugin
{
public sealed class BSConstraintSpring : BSConstraint6Dof
{
public override ConstraintType Type { get { return ConstraintType.D6_SPRING_CONSTRAINT_TYPE; } }
public BSConstraintSpring(BulletWorld world, BulletBody obj1, BulletBody obj2,
Vector3 frame1Loc, Quaternion frame1Rot,
Vector3 frame2Loc, Quaternion frame2Rot,
bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies)
:base(world, obj1, obj2)
{
m_constraint = PhysicsScene.PE.Create6DofSpringConstraint(world, obj1, obj2,
frame1Loc, frame1Rot, frame2Loc, frame2Rot,
useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
m_enabled = true;
PhysicsScene.DetailLog("{0},BSConstraintSpring,create,wID={1}, rID={2}, rBody={3}, cID={4}, cBody={5}",
obj1.ID, world.worldID, obj1.ID, obj1.AddrString, obj2.ID, obj2.AddrString);
PhysicsScene.DetailLog("{0},BSConstraintSpring,create, f1Loc={1},f1Rot={2},f2Loc={3},f2Rot={4},usefA={5},disCol={6}",
m_body1.ID, frame1Loc, frame1Rot, frame2Loc, frame2Rot, useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies);
}
public bool SetAxisEnable(int pIndex, bool pAxisEnable)
{
PhysicsScene.DetailLog("{0},BSConstraintSpring.SetEnable,obj1ID={1},obj2ID={2},indx={3},enable={4}",
m_body1.ID, m_body1.ID, m_body2.ID, pIndex, pAxisEnable);
PhysicsScene.PE.SpringEnable(m_constraint, pIndex, BSParam.NumericBool(pAxisEnable));
return true;
}
public bool SetStiffness(int pIndex, float pStiffness)
{
PhysicsScene.DetailLog("{0},BSConstraintSpring.SetStiffness,obj1ID={1},obj2ID={2},indx={3},stiff={4}",
m_body1.ID, m_body1.ID, m_body2.ID, pIndex, pStiffness);
PhysicsScene.PE.SpringSetStiffness(m_constraint, pIndex, pStiffness);
return true;
}
public bool SetDamping(int pIndex, float pDamping)
{
PhysicsScene.DetailLog("{0},BSConstraintSpring.SetDamping,obj1ID={1},obj2ID={2},indx={3},damp={4}",
m_body1.ID, m_body1.ID, m_body2.ID, pIndex, pDamping);
PhysicsScene.PE.SpringSetDamping(m_constraint, pIndex, pDamping);
return true;
}
public bool SetEquilibriumPoint(int pIndex, float pEqPoint)
{
PhysicsScene.DetailLog("{0},BSConstraintSpring.SetEquilibriumPoint,obj1ID={1},obj2ID={2},indx={3},eqPoint={4}",
m_body1.ID, m_body1.ID, m_body2.ID, pIndex, pEqPoint);
PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, pIndex, pEqPoint);
return true;
}
public bool SetEquilibriumPoint(Vector3 linearEq, Vector3 angularEq)
{
PhysicsScene.DetailLog("{0},BSConstraintSpring.SetEquilibriumPoint,obj1ID={1},obj2ID={2},linearEq={3},angularEq={4}",
m_body1.ID, m_body1.ID, m_body2.ID, linearEq, angularEq);
PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, 0, linearEq.X);
PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, 1, linearEq.Y);
PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, 2, linearEq.Z);
PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, 3, angularEq.X);
PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, 4, angularEq.Y);
PhysicsScene.PE.SpringSetEquilibriumPoint(m_constraint, 5, angularEq.Z);
return true;
}
}
}

View File

@@ -77,6 +77,10 @@ public abstract class BSLinkset
{
member = pMember;
}
public virtual void ResetLink() { }
public virtual void SetLinkParameters(BSConstraint constrain) { }
// Returns 'true' if physical property updates from the child should be reported to the simulator
public virtual bool ShouldUpdateChildProperties() { return false; }
}
public LinksetImplementation LinksetImpl { get; protected set; }
@@ -148,7 +152,7 @@ public abstract class BSLinkset
// Returns a new linkset for the child which is a linkset of one (just the
// orphened child).
// Called at runtime.
public BSLinkset RemoveMeFromLinkset(BSPrimLinkable child)
public BSLinkset RemoveMeFromLinkset(BSPrimLinkable child, bool inTaintTime)
{
lock (m_linksetActivityLock)
{
@@ -157,7 +161,7 @@ public abstract class BSLinkset
// Cannot remove the root from a linkset.
return this;
}
RemoveChildFromLinkset(child);
RemoveChildFromLinkset(child, inTaintTime);
LinksetMass = ComputeLinksetMass();
}
@@ -205,6 +209,17 @@ public abstract class BSLinkset
return ret;
}
public bool TryGetLinkInfo(BSPrimLinkable child, out BSLinkInfo foundInfo)
{
bool ret = false;
BSLinkInfo found = null;
lock (m_linksetActivityLock)
{
ret = m_children.TryGetValue(child, out found);
}
foundInfo = found;
return ret;
}
// 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.
public delegate bool ForEachLinkInfoAction(BSLinkInfo obj);
@@ -222,6 +237,21 @@ public abstract class BSLinkset
return ret;
}
// Check the type of the link and return 'true' if the link is flexible and the
// updates from the child should be sent to the simulator so things change.
public virtual bool ShouldReportPropertyUpdates(BSPrimLinkable child)
{
bool ret = false;
BSLinkInfo linkInfo;
if (m_children.TryGetValue(child, out linkInfo))
{
ret = linkInfo.ShouldUpdateChildProperties();
}
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.
@@ -255,7 +285,7 @@ public abstract class BSLinkset
// 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.
protected abstract void RemoveChildFromLinkset(BSPrimLinkable child);
protected abstract void RemoveChildFromLinkset(BSPrimLinkable child, bool inTaintTime);
// When physical properties are changed the linkset needs to recalculate
// its internal properties.
@@ -430,6 +460,13 @@ public abstract class BSLinkset
return com;
}
#region Extension
public virtual object Extension(string pFunct, params object[] pParams)
{
return null;
}
#endregion // Extension
// Invoke the detailed logger and output something if it's enabled.
protected void DetailLog(string msg, params Object[] args)
{

View File

@@ -90,10 +90,9 @@ public sealed class BSLinksetCompound : BSLinkset
// its internal properties.
public override void Refresh(BSPrimLinkable requestor)
{
base.Refresh(requestor);
// Something changed so do the rebuilding thing
// ScheduleRebuild();
ScheduleRebuild(requestor);
base.Refresh(requestor);
}
// Schedule a refresh to happen after all the other taint processing.
@@ -127,7 +126,7 @@ public sealed class BSLinksetCompound : BSLinkset
if (IsRoot(child))
{
// The root is going dynamic. Rebuild the linkset so parts and mass get computed properly.
ScheduleRebuild(LinksetRoot);
Refresh(LinksetRoot);
}
return ret;
}
@@ -144,7 +143,7 @@ public sealed class BSLinksetCompound : BSLinkset
if (IsRoot(child))
{
// Schedule a rebuild to verify that the root shape is set to the real shape.
ScheduleRebuild(LinksetRoot);
Refresh(LinksetRoot);
}
return ret;
}
@@ -227,7 +226,7 @@ public sealed class BSLinksetCompound : BSLinkset
// there will already be a rebuild scheduled.
DetailLog("{0},BSLinksetCompound.UpdateProperties,couldNotUpdateChild.schedulingRebuild,whichUpdated={1}",
updated.LocalID, whichUpdated);
ScheduleRebuild(updated);
Refresh(updated);
}
}
}
@@ -242,10 +241,10 @@ public sealed class BSLinksetCompound : BSLinkset
{
bool ret = false;
DetailLog("{0},BSLinksetCompound.RemoveBodyDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}",
DetailLog("{0},BSLinksetCompound.RemoveDependencies,refreshIfChild,rID={1},rBody={2},isRoot={3}",
child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody, IsRoot(child));
ScheduleRebuild(child);
Refresh(child);
return ret;
}
@@ -263,14 +262,14 @@ public sealed class BSLinksetCompound : BSLinkset
DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
// Rebuild the compound shape with the new child shape included
ScheduleRebuild(child);
Refresh(child);
}
return;
}
// Remove the specified child from the linkset.
// Safe to call even if the child is not really in the linkset.
protected override void RemoveChildFromLinkset(BSPrimLinkable child)
protected override void RemoveChildFromLinkset(BSPrimLinkable child, bool inTaintTime)
{
child.ClearDisplacement();
@@ -282,17 +281,17 @@ public sealed class BSLinksetCompound : BSLinkset
child.LocalID, child.PhysBody.AddrString);
// Cause the child's body to be rebuilt and thus restored to normal operation
child.ForceBodyShapeRebuild(false);
child.ForceBodyShapeRebuild(inTaintTime);
if (!HasAnyChildren)
{
// The linkset is now empty. The root needs rebuilding.
LinksetRoot.ForceBodyShapeRebuild(false);
LinksetRoot.ForceBodyShapeRebuild(inTaintTime);
}
else
{
// Rebuild the compound shape with the child removed
ScheduleRebuild(LinksetRoot);
Refresh(LinksetRoot);
}
}
return;
@@ -318,10 +317,10 @@ public sealed class BSLinksetCompound : BSLinkset
// being destructed and going non-physical.
LinksetRoot.ForceBodyShapeRebuild(true);
// There is no reason to build all this physical stuff for a non-physical linkset.
if (!LinksetRoot.IsPhysicallyActive)
// There is no reason to build all this physical stuff for a non-physical or empty linkset.
if (!LinksetRoot.IsPhysicallyActive || !HasAnyChildren)
{
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,notPhysical", LinksetRoot.LocalID);
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,notPhysicalOrNoChildren", LinksetRoot.LocalID);
return; // Note the 'finally' clause at the botton which will get executed.
}

View File

@@ -1,4 +1,4 @@
/*
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@@ -28,6 +28,8 @@ using System;
using System.Collections.Generic;
using System.Text;
using OpenSim.Region.OptionalModules.Scripting;
using OMV = OpenMetaverse;
namespace OpenSim.Region.Physics.BulletSPlugin
@@ -51,18 +53,32 @@ public sealed class BSLinksetConstraints : BSLinkset
public float cfm;
public float erp;
public float solverIterations;
//
public OMV.Vector3 frameInAloc;
public OMV.Quaternion frameInArot;
public OMV.Vector3 frameInBloc;
public OMV.Quaternion frameInBrot;
public bool useLinearReferenceFrameA;
// Spring
public bool[] springAxisEnable;
public float[] springDamping;
public float[] springStiffness;
public OMV.Vector3 springLinearEquilibriumPoint;
public OMV.Vector3 springAngularEquilibriumPoint;
public BSLinkInfoConstraint(BSPrimLinkable pMember)
: base(pMember)
{
constraint = null;
ResetToFixedConstraint();
ResetLink();
member.PhysScene.DetailLog("{0},BSLinkInfoConstraint.creation", member.LocalID);
}
// Set all the parameters for this constraint to a fixed, non-movable constraint.
public void ResetToFixedConstraint()
public override void ResetLink()
{
constraintType = ConstraintType.D6_CONSTRAINT_TYPE;
// constraintType = ConstraintType.D6_CONSTRAINT_TYPE;
constraintType = ConstraintType.FIXED_CONSTRAINT_TYPE;
linearLimitLow = OMV.Vector3.Zero;
linearLimitHigh = OMV.Vector3.Zero;
angularLimitLow = OMV.Vector3.Zero;
@@ -74,17 +90,37 @@ public sealed class BSLinksetConstraints : BSLinkset
cfm = BSParam.LinkConstraintCFM;
erp = BSParam.LinkConstraintERP;
solverIterations = BSParam.LinkConstraintSolverIterations;
frameInAloc = OMV.Vector3.Zero;
frameInArot = OMV.Quaternion.Identity;
frameInBloc = OMV.Vector3.Zero;
frameInBrot = OMV.Quaternion.Identity;
useLinearReferenceFrameA = true;
springAxisEnable = new bool[6];
springDamping = new float[6];
springStiffness = new float[6];
for (int ii = 0; ii < springAxisEnable.Length; ii++)
{
springAxisEnable[ii] = false;
springDamping[ii] = BSAPITemplate.SPRING_NOT_SPECIFIED;
springStiffness[ii] = BSAPITemplate.SPRING_NOT_SPECIFIED;
}
springLinearEquilibriumPoint = OMV.Vector3.Zero;
springAngularEquilibriumPoint = OMV.Vector3.Zero;
member.PhysScene.DetailLog("{0},BSLinkInfoConstraint.ResetLink", member.LocalID);
}
// Given a constraint, apply the current constraint parameters to same.
public void SetConstraintParameters(BSConstraint constrain)
public override void SetLinkParameters(BSConstraint constrain)
{
member.PhysScene.DetailLog("{0},BSLinkInfoConstraint.SetLinkParameters,type={1}", member.LocalID, constraintType);
switch (constraintType)
{
case ConstraintType.FIXED_CONSTRAINT_TYPE:
case ConstraintType.D6_CONSTRAINT_TYPE:
BSConstraint6Dof constrain6dof = constrain as BSConstraint6Dof;
if (constrain6dof != null)
{
// NOTE: D6_SPRING_CONSTRAINT_TYPE should be updated if you change any of this code.
// zero linear and angular limits makes the objects unable to move in relation to each other
constrain6dof.SetLinearLimits(linearLimitLow, linearLimitHigh);
constrain6dof.SetAngularLimits(angularLimitLow, angularLimitHigh);
@@ -99,10 +135,55 @@ public sealed class BSLinksetConstraints : BSLinkset
}
}
break;
case ConstraintType.D6_SPRING_CONSTRAINT_TYPE:
BSConstraintSpring constrainSpring = constrain as BSConstraintSpring;
if (constrainSpring != null)
{
// zero linear and angular limits makes the objects unable to move in relation to each other
constrainSpring.SetLinearLimits(linearLimitLow, linearLimitHigh);
constrainSpring.SetAngularLimits(angularLimitLow, angularLimitHigh);
// tweek the constraint to increase stability
constrainSpring.UseFrameOffset(useFrameOffset);
constrainSpring.TranslationalLimitMotor(enableTransMotor, transMotorMaxVel, transMotorMaxForce);
constrainSpring.SetCFMAndERP(cfm, erp);
if (solverIterations != 0f)
{
constrainSpring.SetSolverIterations(solverIterations);
}
for (int ii = 0; ii < springAxisEnable.Length; ii++)
{
constrainSpring.SetAxisEnable(ii, springAxisEnable[ii]);
if (springDamping[ii] != BSAPITemplate.SPRING_NOT_SPECIFIED)
constrainSpring.SetDamping(ii, springDamping[ii]);
if (springStiffness[ii] != BSAPITemplate.SPRING_NOT_SPECIFIED)
constrainSpring.SetStiffness(ii, springStiffness[ii]);
}
constrainSpring.CalculateTransforms();
if (springLinearEquilibriumPoint != OMV.Vector3.Zero)
constrainSpring.SetEquilibriumPoint(springLinearEquilibriumPoint, springAngularEquilibriumPoint);
else
constrainSpring.SetEquilibriumPoint(BSAPITemplate.SPRING_NOT_SPECIFIED, BSAPITemplate.SPRING_NOT_SPECIFIED);
}
break;
default:
break;
}
}
// Return 'true' if the property updates from the physics engine should be reported
// to the simulator.
// If the constraint is fixed, we don't need to report as the simulator and viewer will
// report the right things.
public override bool ShouldUpdateChildProperties()
{
bool ret = true;
if (constraintType == ConstraintType.FIXED_CONSTRAINT_TYPE)
ret = false;
return ret;
}
}
public BSLinksetConstraints(BSScene scene, BSPrimLinkable parent) : base(scene, parent)
@@ -110,12 +191,15 @@ public sealed class BSLinksetConstraints : BSLinkset
LinksetImpl = LinksetImplementation.Constraint;
}
private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINT]";
// When physical properties are changed the linkset needs to recalculate
// 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(BSPrimLinkable requestor)
{
ScheduleRebuild(requestor);
base.Refresh(requestor);
}
@@ -132,10 +216,16 @@ public sealed class BSLinksetConstraints : BSLinkset
{
// Queue to happen after all the other taint processing
m_physicsScene.PostTaintObject("BSLinksetContraints.Refresh", requestor.LocalID, delegate()
{
if (HasAnyChildren)
{
if (HasAnyChildren)
RecomputeLinksetConstraints();
});
// Constraints that have not been changed are not rebuild but make sure
// the constraint of the requestor is rebuilt.
PhysicallyUnlinkAChildFromRoot(LinksetRoot, requestor);
// Rebuild the linkset and all its constraints.
RecomputeLinksetConstraints();
}
});
}
}
@@ -152,7 +242,7 @@ public sealed class BSLinksetConstraints : BSLinkset
if (IsRoot(child))
{
// The root is going dynamic. Rebuild the linkset so parts and mass get computed properly.
ScheduleRebuild(LinksetRoot);
Refresh(LinksetRoot);
}
return ret;
}
@@ -171,7 +261,7 @@ public sealed class BSLinksetConstraints : BSLinkset
if (IsRoot(child))
{
// Schedule a rebuild to verify that the root shape is set to the real shape.
ScheduleRebuild(LinksetRoot);
Refresh(LinksetRoot);
}
return ret;
}
@@ -199,7 +289,7 @@ public sealed class BSLinksetConstraints : BSLinkset
// Just undo all the constraints for this linkset. Rebuild at the end of the step.
ret = PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot);
// Cause the constraints, et al to be rebuilt before the next simulation step.
ScheduleRebuild(LinksetRoot);
Refresh(LinksetRoot);
}
return ret;
}
@@ -217,14 +307,14 @@ public sealed class BSLinksetConstraints : BSLinkset
DetailLog("{0},BSLinksetConstraints.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID);
// Cause constraints and assorted properties to be recomputed before the next simulation step.
ScheduleRebuild(LinksetRoot);
Refresh(LinksetRoot);
}
return;
}
// Remove the specified child from the linkset.
// Safe to call even if the child is not really in my linkset.
protected override void RemoveChildFromLinkset(BSPrimLinkable child)
protected override void RemoveChildFromLinkset(BSPrimLinkable child, bool inTaintTime)
{
if (m_children.Remove(child))
{
@@ -236,12 +326,12 @@ public sealed class BSLinksetConstraints : BSLinkset
rootx.LocalID, rootx.PhysBody.AddrString,
childx.LocalID, childx.PhysBody.AddrString);
m_physicsScene.TaintedObject("BSLinksetConstraints.RemoveChildFromLinkset", delegate()
m_physicsScene.TaintedObject(inTaintTime, childx.LocalID, "BSLinksetConstraints.RemoveChildFromLinkset", delegate()
{
PhysicallyUnlinkAChildFromRoot(rootx, childx);
});
// See that the linkset parameters are recomputed at the end of the taint time.
ScheduleRebuild(LinksetRoot);
Refresh(LinksetRoot);
}
else
{
@@ -262,8 +352,8 @@ public sealed class BSLinksetConstraints : BSLinkset
// Create a static constraint between the two passed objects
private BSConstraint BuildConstraint(BSPrimLinkable rootPrim, BSLinkInfo li)
{
BSLinkInfoConstraint liConstraint = li as BSLinkInfoConstraint;
if (liConstraint == null)
BSLinkInfoConstraint linkInfo = li as BSLinkInfoConstraint;
if (linkInfo == null)
return null;
// Zero motion for children so they don't interpolate
@@ -271,27 +361,26 @@ public sealed class BSLinksetConstraints : BSLinkset
BSConstraint constrain = null;
switch (liConstraint.constraintType)
switch (linkInfo.constraintType)
{
case ConstraintType.FIXED_CONSTRAINT_TYPE:
case ConstraintType.D6_CONSTRAINT_TYPE:
// Relative position normalized to the root prim
// Essentually a vector pointing from center of rootPrim to center of li.member
OMV.Vector3 childRelativePosition = liConstraint.member.Position - rootPrim.Position;
OMV.Vector3 childRelativePosition = linkInfo.member.Position - rootPrim.Position;
// real world coordinate of midpoint between the two objects
OMV.Vector3 midPoint = rootPrim.Position + (childRelativePosition / 2);
DetailLog("{0},BSLinksetConstraint.BuildConstraint,taint,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6},midLoc={7}",
rootPrim.LocalID,
rootPrim.LocalID, rootPrim.PhysBody.AddrString,
liConstraint.member.LocalID, liConstraint.member.PhysBody.AddrString,
rootPrim.Position, liConstraint.member.Position, midPoint);
DetailLog("{0},BSLinksetConstraint.BuildConstraint,6Dof,rBody={1},cBody={2},rLoc={3},cLoc={4},midLoc={5}",
rootPrim.LocalID, rootPrim.PhysBody, linkInfo.member.PhysBody,
rootPrim.Position, linkInfo.member.Position, midPoint);
// create a constraint that allows no freedom of movement between the two objects
// http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
constrain = new BSConstraint6Dof(
m_physicsScene.World, rootPrim.PhysBody, liConstraint.member.PhysBody, midPoint, true, true );
m_physicsScene.World, rootPrim.PhysBody, linkInfo.member.PhysBody, midPoint, true, true );
/* NOTE: below is an attempt to build constraint with full frame computation, etc.
* Using the midpoint is easier since it lets the Bullet code manipulate the transforms
@@ -319,12 +408,24 @@ public sealed class BSLinksetConstraints : BSLinkset
// ==================================================================================
*/
break;
case ConstraintType.D6_SPRING_CONSTRAINT_TYPE:
constrain = new BSConstraintSpring(m_physicsScene.World, rootPrim.PhysBody, linkInfo.member.PhysBody,
linkInfo.frameInAloc, linkInfo.frameInArot, linkInfo.frameInBloc, linkInfo.frameInBrot,
linkInfo.useLinearReferenceFrameA,
true /*disableCollisionsBetweenLinkedBodies*/);
DetailLog("{0},BSLinksetConstraint.BuildConstraint,spring,root={1},rBody={2},child={3},cBody={4},rLoc={5},cLoc={6}",
rootPrim.LocalID,
rootPrim.LocalID, rootPrim.PhysBody.AddrString,
linkInfo.member.LocalID, linkInfo.member.PhysBody.AddrString,
rootPrim.Position, linkInfo.member.Position);
break;
default:
break;
}
liConstraint.SetConstraintParameters(constrain);
linkInfo.SetLinkParameters(constrain);
m_physicsScene.Constraints.AddConstraint(constrain);
@@ -343,13 +444,22 @@ public sealed class BSLinksetConstraints : BSLinkset
rootPrim.LocalID, rootPrim.PhysBody.AddrString,
childPrim.LocalID, childPrim.PhysBody.AddrString);
// Find the constraint for this link and get rid of it from the overall collection and from my list
if (m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody))
// If asked to unlink root from root, just remove all the constraints
if (rootPrim == childPrim || childPrim == LinksetRoot)
{
// Make the child refresh its location
m_physicsScene.PE.PushUpdate(childPrim.PhysBody);
PhysicallyUnlinkAllChildrenFromRoot(LinksetRoot);
ret = true;
}
else
{
// Find the constraint for this link and get rid of it from the overall collection and from my list
if (m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.PhysBody, childPrim.PhysBody))
{
// Make the child refresh its location
m_physicsScene.PE.PushUpdate(childPrim.PhysBody);
ret = true;
}
}
return ret;
}
@@ -382,9 +492,9 @@ public sealed class BSLinksetConstraints : BSLinkset
Rebuilding = true;
// There is no reason to build all this physical stuff for a non-physical linkset.
if (!LinksetRoot.IsPhysicallyActive)
if (!LinksetRoot.IsPhysicallyActive || !HasAnyChildren)
{
DetailLog("{0},BSLinksetConstraint.RecomputeLinksetCompound,notPhysical", LinksetRoot.LocalID);
DetailLog("{0},BSLinksetConstraint.RecomputeLinksetCompound,notPhysicalOrNoChildren", LinksetRoot.LocalID);
return; // Note the 'finally' clause at the botton which will get executed.
}
@@ -401,6 +511,7 @@ public sealed class BSLinksetConstraints : BSLinkset
// If constraint doesn't exist yet, create it.
constrain = BuildConstraint(LinksetRoot, li);
}
li.SetLinkParameters(constrain);
constrain.RecomputeConstraintVariables(linksetMass);
// PhysicsScene.PE.DumpConstraint(PhysicsScene.World, constrain.Constraint); // DEBUG DEBUG
@@ -412,5 +523,324 @@ public sealed class BSLinksetConstraints : BSLinkset
Rebuilding = false;
}
}
#region Extension
public override object Extension(string pFunct, params object[] pParams)
{
object ret = null;
switch (pFunct)
{
// pParams = [ BSPhysObject root, BSPhysObject child, integer linkType ]
case ExtendedPhysics.PhysFunctChangeLinkType:
if (pParams.Length > 2)
{
int requestedType = (int)pParams[2];
DetailLog("{0},BSLinksetConstraint.ChangeLinkType,requestedType={1}", LinksetRoot.LocalID, requestedType);
if (requestedType == (int)ConstraintType.FIXED_CONSTRAINT_TYPE
|| requestedType == (int)ConstraintType.D6_CONSTRAINT_TYPE
|| requestedType == (int)ConstraintType.D6_SPRING_CONSTRAINT_TYPE
|| requestedType == (int)ConstraintType.HINGE_CONSTRAINT_TYPE
|| requestedType == (int)ConstraintType.CONETWIST_CONSTRAINT_TYPE
|| requestedType == (int)ConstraintType.SLIDER_CONSTRAINT_TYPE)
{
BSPrimLinkable child = pParams[1] as BSPrimLinkable;
if (child != null)
{
DetailLog("{0},BSLinksetConstraint.ChangeLinkType,rootID={1},childID={2},type={3}",
LinksetRoot.LocalID, LinksetRoot.LocalID, child.LocalID, requestedType);
m_physicsScene.TaintedObject(child.LocalID, "BSLinksetConstraint.PhysFunctChangeLinkType", delegate()
{
// Pick up all the constraints currently created.
RemoveDependencies(child);
BSLinkInfo linkInfo = null;
if (TryGetLinkInfo(child, out linkInfo))
{
BSLinkInfoConstraint linkInfoC = linkInfo as BSLinkInfoConstraint;
if (linkInfoC != null)
{
linkInfoC.constraintType = (ConstraintType)requestedType;
ret = (object)true;
DetailLog("{0},BSLinksetConstraint.ChangeLinkType,link={1},type={2}",
linkInfo.member.LocalID, linkInfo.member.LocalID, linkInfoC.constraintType);
}
else
{
DetailLog("{0},BSLinksetConstraint.ChangeLinkType,linkInfoNotConstraint,childID={1}", LinksetRoot.LocalID, child.LocalID);
}
}
else
{
DetailLog("{0},BSLinksetConstraint.ChangeLinkType,noLinkInfoForChild,childID={1}", LinksetRoot.LocalID, child.LocalID);
}
// Cause the whole linkset to be rebuilt in post-taint time.
Refresh(child);
});
}
else
{
DetailLog("{0},BSLinksetConstraint.SetLinkType,childNotBSPrimLinkable", LinksetRoot.LocalID);
}
}
else
{
DetailLog("{0},BSLinksetConstraint.SetLinkType,illegalRequestedType,reqested={1},spring={2}",
LinksetRoot.LocalID, requestedType, ((int)ConstraintType.D6_SPRING_CONSTRAINT_TYPE));
}
}
break;
// pParams = [ BSPhysObject root, BSPhysObject child ]
case ExtendedPhysics.PhysFunctGetLinkType:
if (pParams.Length > 0)
{
BSPrimLinkable child = pParams[1] as BSPrimLinkable;
if (child != null)
{
BSLinkInfo linkInfo = null;
if (TryGetLinkInfo(child, out linkInfo))
{
BSLinkInfoConstraint linkInfoC = linkInfo as BSLinkInfoConstraint;
if (linkInfoC != null)
{
ret = (object)(int)linkInfoC.constraintType;
DetailLog("{0},BSLinksetConstraint.GetLinkType,link={1},type={2}",
linkInfo.member.LocalID, linkInfo.member.LocalID, linkInfoC.constraintType);
}
}
}
}
break;
// pParams = [ BSPhysObject root, BSPhysObject child, int op, object opParams, int op, object opParams, ... ]
case ExtendedPhysics.PhysFunctChangeLinkParams:
// There should be two parameters: the childActor and a list of parameters to set
if (pParams.Length > 2)
{
BSPrimLinkable child = pParams[1] as BSPrimLinkable;
BSLinkInfo baseLinkInfo = null;
if (TryGetLinkInfo(child, out baseLinkInfo))
{
BSLinkInfoConstraint linkInfo = baseLinkInfo as BSLinkInfoConstraint;
if (linkInfo != null)
{
int valueInt;
float valueFloat;
bool valueBool;
OMV.Vector3 valueVector;
OMV.Vector3 valueVector2;
OMV.Quaternion valueQuaternion;
int axisLow, axisHigh;
int opIndex = 2;
while (opIndex < pParams.Length)
{
int thisOp = 0;
string errMsg = "";
try
{
thisOp = (int)pParams[opIndex];
DetailLog("{0},BSLinksetConstraint.ChangeLinkParams2,op={1},val={2}",
linkInfo.member.LocalID, thisOp, pParams[opIndex + 1]);
switch (thisOp)
{
case ExtendedPhysics.PHYS_PARAM_LINK_TYPE:
valueInt = (int)pParams[opIndex + 1];
ConstraintType valueType = (ConstraintType)valueInt;
if (valueType == ConstraintType.FIXED_CONSTRAINT_TYPE
|| valueType == ConstraintType.D6_CONSTRAINT_TYPE
|| valueType == ConstraintType.D6_SPRING_CONSTRAINT_TYPE
|| valueType == ConstraintType.HINGE_CONSTRAINT_TYPE
|| valueType == ConstraintType.CONETWIST_CONSTRAINT_TYPE
|| valueType == ConstraintType.SLIDER_CONSTRAINT_TYPE)
{
linkInfo.constraintType = valueType;
}
opIndex += 2;
break;
case ExtendedPhysics.PHYS_PARAM_FRAMEINA_LOC:
errMsg = "PHYS_PARAM_FRAMEINA_LOC takes one parameter of type vector";
valueVector = (OMV.Vector3)pParams[opIndex + 1];
linkInfo.frameInAloc = valueVector;
opIndex += 2;
break;
case ExtendedPhysics.PHYS_PARAM_FRAMEINA_ROT:
errMsg = "PHYS_PARAM_FRAMEINA_ROT takes one parameter of type rotation";
valueQuaternion = (OMV.Quaternion)pParams[opIndex + 1];
linkInfo.frameInArot = valueQuaternion;
opIndex += 2;
break;
case ExtendedPhysics.PHYS_PARAM_FRAMEINB_LOC:
errMsg = "PHYS_PARAM_FRAMEINB_LOC takes one parameter of type vector";
valueVector = (OMV.Vector3)pParams[opIndex + 1];
linkInfo.frameInBloc = valueVector;
opIndex += 2;
break;
case ExtendedPhysics.PHYS_PARAM_FRAMEINB_ROT:
errMsg = "PHYS_PARAM_FRAMEINB_ROT takes one parameter of type rotation";
valueQuaternion = (OMV.Quaternion)pParams[opIndex + 1];
linkInfo.frameInBrot = valueQuaternion;
opIndex += 2;
break;
case ExtendedPhysics.PHYS_PARAM_LINEAR_LIMIT_LOW:
errMsg = "PHYS_PARAM_LINEAR_LIMIT_LOW takes one parameter of type vector";
valueVector = (OMV.Vector3)pParams[opIndex + 1];
linkInfo.linearLimitLow = valueVector;
opIndex += 2;
break;
case ExtendedPhysics.PHYS_PARAM_LINEAR_LIMIT_HIGH:
errMsg = "PHYS_PARAM_LINEAR_LIMIT_HIGH takes one parameter of type vector";
valueVector = (OMV.Vector3)pParams[opIndex + 1];
linkInfo.linearLimitHigh = valueVector;
opIndex += 2;
break;
case ExtendedPhysics.PHYS_PARAM_ANGULAR_LIMIT_LOW:
errMsg = "PHYS_PARAM_ANGULAR_LIMIT_LOW takes one parameter of type vector";
valueVector = (OMV.Vector3)pParams[opIndex + 1];
linkInfo.angularLimitLow = valueVector;
opIndex += 2;
break;
case ExtendedPhysics.PHYS_PARAM_ANGULAR_LIMIT_HIGH:
errMsg = "PHYS_PARAM_ANGULAR_LIMIT_HIGH takes one parameter of type vector";
valueVector = (OMV.Vector3)pParams[opIndex + 1];
linkInfo.angularLimitHigh = valueVector;
opIndex += 2;
break;
case ExtendedPhysics.PHYS_PARAM_USE_FRAME_OFFSET:
errMsg = "PHYS_PARAM_USE_FRAME_OFFSET takes one parameter of type integer (bool)";
valueBool = ((int)pParams[opIndex + 1]) != 0;
linkInfo.useFrameOffset = valueBool;
opIndex += 2;
break;
case ExtendedPhysics.PHYS_PARAM_ENABLE_TRANSMOTOR:
errMsg = "PHYS_PARAM_ENABLE_TRANSMOTOR takes one parameter of type integer (bool)";
valueBool = ((int)pParams[opIndex + 1]) != 0;
linkInfo.enableTransMotor = valueBool;
opIndex += 2;
break;
case ExtendedPhysics.PHYS_PARAM_TRANSMOTOR_MAXVEL:
errMsg = "PHYS_PARAM_TRANSMOTOR_MAXVEL takes one parameter of type float";
valueFloat = (float)pParams[opIndex + 1];
linkInfo.transMotorMaxVel = valueFloat;
opIndex += 2;
break;
case ExtendedPhysics.PHYS_PARAM_TRANSMOTOR_MAXFORCE:
errMsg = "PHYS_PARAM_TRANSMOTOR_MAXFORCE takes one parameter of type float";
valueFloat = (float)pParams[opIndex + 1];
linkInfo.transMotorMaxForce = valueFloat;
opIndex += 2;
break;
case ExtendedPhysics.PHYS_PARAM_CFM:
errMsg = "PHYS_PARAM_CFM takes one parameter of type float";
valueFloat = (float)pParams[opIndex + 1];
linkInfo.cfm = valueFloat;
opIndex += 2;
break;
case ExtendedPhysics.PHYS_PARAM_ERP:
errMsg = "PHYS_PARAM_ERP takes one parameter of type float";
valueFloat = (float)pParams[opIndex + 1];
linkInfo.erp = valueFloat;
opIndex += 2;
break;
case ExtendedPhysics.PHYS_PARAM_SOLVER_ITERATIONS:
errMsg = "PHYS_PARAM_SOLVER_ITERATIONS takes one parameter of type float";
valueFloat = (float)pParams[opIndex + 1];
linkInfo.solverIterations = valueFloat;
opIndex += 2;
break;
case ExtendedPhysics.PHYS_PARAM_SPRING_AXIS_ENABLE:
errMsg = "PHYS_PARAM_SPRING_AXIS_ENABLE takes two parameters of types integer and integer (bool)";
valueInt = (int)pParams[opIndex + 1];
valueBool = ((int)pParams[opIndex + 2]) != 0;
GetAxisRange(valueInt, out axisLow, out axisHigh);
for (int ii = axisLow; ii <= axisHigh; ii++)
linkInfo.springAxisEnable[ii] = valueBool;
opIndex += 3;
break;
case ExtendedPhysics.PHYS_PARAM_SPRING_DAMPING:
errMsg = "PHYS_PARAM_SPRING_DAMPING takes two parameters of types integer and float";
valueInt = (int)pParams[opIndex + 1];
valueFloat = (float)pParams[opIndex + 2];
GetAxisRange(valueInt, out axisLow, out axisHigh);
for (int ii = axisLow; ii <= axisHigh; ii++)
linkInfo.springDamping[ii] = valueFloat;
opIndex += 3;
break;
case ExtendedPhysics.PHYS_PARAM_SPRING_STIFFNESS:
errMsg = "PHYS_PARAM_SPRING_STIFFNESS takes two parameters of types integer and float";
valueInt = (int)pParams[opIndex + 1];
valueFloat = (float)pParams[opIndex + 2];
GetAxisRange(valueInt, out axisLow, out axisHigh);
for (int ii = axisLow; ii <= axisHigh; ii++)
linkInfo.springStiffness[ii] = valueFloat;
opIndex += 3;
break;
case ExtendedPhysics.PHYS_PARAM_SPRING_EQUILIBRIUM_POINT:
errMsg = "PHYS_PARAM_SPRING_EQUILIBRIUM_POINT takes two parameters of type vector";
valueVector = (OMV.Vector3)pParams[opIndex + 1];
valueVector2 = (OMV.Vector3)pParams[opIndex + 2];
linkInfo.springLinearEquilibriumPoint = valueVector;
linkInfo.springAngularEquilibriumPoint = valueVector2;
opIndex += 3;
break;
case ExtendedPhysics.PHYS_PARAM_USE_LINEAR_FRAMEA:
errMsg = "PHYS_PARAM_USE_LINEAR_FRAMEA takes one parameter of type integer (bool)";
valueBool = ((int)pParams[opIndex + 1]) != 0;
linkInfo.useLinearReferenceFrameA = valueBool;
opIndex += 2;
break;
default:
break;
}
}
catch (InvalidCastException e)
{
m_physicsScene.Logger.WarnFormat("{0} value of wrong type in physSetLinksetParams: {1}, err={2}",
LogHeader, errMsg, e);
}
catch (Exception e)
{
m_physicsScene.Logger.WarnFormat("{0} bad parameters in physSetLinksetParams: {1}", LogHeader, e);
}
}
}
// Something changed so a rebuild is in order
Refresh(child);
}
}
break;
default:
ret = base.Extension(pFunct, pParams);
break;
}
return ret;
}
// Bullet constraints keep some limit parameters for each linear and angular axis.
// Setting same is easier if there is an easy way to see all or types.
// This routine returns the array limits for the set of axis.
private void GetAxisRange(int rangeSpec, out int low, out int high)
{
switch (rangeSpec)
{
case ExtendedPhysics.PHYS_AXIS_LINEAR_ALL:
low = 0;
high = 2;
break;
case ExtendedPhysics.PHYS_AXIS_ANGULAR_ALL:
low = 3;
high = 5;
break;
case ExtendedPhysics.PHYS_AXIS_ALL:
low = 0;
high = 5;
break;
default:
low = high = rangeSpec;
break;
}
return;
}
#endregion // Extension
}
}

View File

@@ -134,6 +134,7 @@ public static class BSParam
public static float AvatarHeightMidFudge { get; private set; }
public static float AvatarHeightHighFudge { get; private set; }
public static float AvatarContactProcessingThreshold { get; private set; }
public static float AvatarStopZeroThreshold { get; private set; }
public static int AvatarJumpFrames { get; private set; }
public static float AvatarBelowGroundUpCorrectionMeters { get; private set; }
public static float AvatarStepHeight { get; private set; }
@@ -570,11 +571,13 @@ public static class BSParam
new ParameterDefn<float>("AvatarHeightLowFudge", "A fudge factor to make small avatars stand on the ground",
-0.2f ),
new ParameterDefn<float>("AvatarHeightMidFudge", "A fudge distance to adjust average sized avatars to be standing on ground",
0.2f ),
0.1f ),
new ParameterDefn<float>("AvatarHeightHighFudge", "A fudge factor to make tall avatars stand on the ground",
0.2f ),
0.1f ),
new ParameterDefn<float>("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
0.1f ),
new ParameterDefn<float>("AvatarStopZeroThreshold", "Movement velocity below which avatar is assumed to be stopped",
0.1f ),
new ParameterDefn<float>("AvatarBelowGroundUpCorrectionMeters", "Meters to move avatar up if it seems to be below ground",
1.0f ),
new ParameterDefn<int>("AvatarJumpFrames", "Number of frames to allow jump forces. Changes jump height.",
@@ -683,21 +686,21 @@ public static class BSParam
0f ),
new ParameterDefn<float>("BHullMaxVerticesPerHull", "Bullet impl: max number of vertices per created hull",
100f ),
200f ),
new ParameterDefn<float>("BHullMinClusters", "Bullet impl: minimum number of hulls to create per mesh",
2f ),
10f ),
new ParameterDefn<float>("BHullCompacityWeight", "Bullet impl: weight factor for how compact to make hulls",
0.1f ),
20f ),
new ParameterDefn<float>("BHullVolumeWeight", "Bullet impl: weight factor for volume in created hull",
0f ),
0.1f ),
new ParameterDefn<float>("BHullConcavity", "Bullet impl: weight factor for how convex a created hull can be",
100f ),
10f ),
new ParameterDefn<bool>("BHullAddExtraDistPoints", "Bullet impl: whether to add extra vertices for long distance vectors",
false ),
true ),
new ParameterDefn<bool>("BHullAddNeighboursDistPoints", "Bullet impl: whether to add extra vertices between neighbor hulls",
false ),
true ),
new ParameterDefn<bool>("BHullAddFacesPoints", "Bullet impl: whether to add extra vertices to break up hull faces",
false ),
true ),
new ParameterDefn<bool>("BHullShouldAdjustCollisionMargin", "Bullet impl: whether to shrink resulting hulls to account for collision margin",
false ),
@@ -826,7 +829,7 @@ public static class BSParam
private static void ResetConstraintSolverTainted(BSScene pPhysScene, float v)
{
BSScene physScene = pPhysScene;
physScene.TaintedObject("BSParam.ResetConstraintSolver", delegate()
physScene.TaintedObject(BSScene.DetailLogZero, "BSParam.ResetConstraintSolver", delegate()
{
physScene.PE.ResetConstraintSolver(physScene.World);
});

View File

@@ -121,7 +121,7 @@ public abstract class BSPhysObject : PhysicsActor
public virtual void Destroy()
{
PhysicalActors.Enable(false);
PhysScene.TaintedObject("BSPhysObject.Destroy", delegate()
PhysScene.TaintedObject(LocalID, "BSPhysObject.Destroy", delegate()
{
PhysicalActors.Dispose();
});
@@ -300,8 +300,19 @@ public abstract class BSPhysObject : PhysicsActor
// Called in taint-time!!
public void ActivateIfPhysical(bool forceIt)
{
if (IsPhysical && PhysBody.HasPhysicalBody)
PhysScene.PE.Activate(PhysBody, forceIt);
if (PhysBody.HasPhysicalBody)
{
if (IsPhysical)
{
// Physical objects might need activating
PhysScene.PE.Activate(PhysBody, forceIt);
}
else
{
// Clear the collision cache since we've changed some properties.
PhysScene.PE.ClearCollisionProxyCache(PhysScene.World, PhysBody);
}
}
}
// 'actors' act on the physical object to change or constrain its motion. These can range from
@@ -509,7 +520,7 @@ public abstract class BSPhysObject : PhysicsActor
// make sure first collision happens
NextCollisionOkTime = Util.EnvironmentTickCountSubtract(SubscribedEventsMs);
PhysScene.TaintedObject(TypeName+".SubscribeEvents", delegate()
PhysScene.TaintedObject(LocalID, TypeName+".SubscribeEvents", delegate()
{
if (PhysBody.HasPhysicalBody)
CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
@@ -524,7 +535,7 @@ public abstract class BSPhysObject : PhysicsActor
public override void UnSubscribeEvents() {
// DetailLog("{0},{1}.UnSubscribeEvents,unsubscribing", LocalID, TypeName);
SubscribedEventsMs = 0;
PhysScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate()
PhysScene.TaintedObject(LocalID, TypeName+".UnSubscribeEvents", delegate()
{
// Make sure there is a body there because sometimes destruction happens in an un-ideal order.
if (PhysBody.HasPhysicalBody)

View File

@@ -41,7 +41,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
[Serializable]
public class BSPrim : BSPhysObject
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string LogHeader = "[BULLETS PRIM]";
// _size is what the user passed. Scale is what we pass to the physics engine with the mesh.
@@ -102,7 +102,7 @@ public class BSPrim : BSPhysObject
// DetailLog("{0},BSPrim.constructor,call", LocalID);
// do the actual object creation at taint time
PhysScene.TaintedObject("BSPrim.create", delegate()
PhysScene.TaintedObject(LocalID, "BSPrim.create", delegate()
{
// Make sure the object is being created with some sanity.
ExtremeSanityCheck(true /* inTaintTime */);
@@ -126,7 +126,7 @@ public class BSPrim : BSPhysObject
// Undo any vehicle properties
this.VehicleType = (int)Vehicle.TYPE_NONE;
PhysScene.TaintedObject("BSPrim.Destroy", delegate()
PhysScene.TaintedObject(LocalID, "BSPrim.Destroy", delegate()
{
DetailLog("{0},BSPrim.Destroy,taint,", LocalID);
// If there are physical body and shape, release my use of same.
@@ -161,7 +161,7 @@ public class BSPrim : BSPhysObject
}
public override bool ForceBodyShapeRebuild(bool inTaintTime)
{
PhysScene.TaintedObject(inTaintTime, "BSPrim.ForceBodyShapeRebuild", delegate()
PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ForceBodyShapeRebuild", delegate()
{
_mass = CalculateMass(); // changing the shape changes the mass
CreateGeomAndObject(true);
@@ -178,7 +178,7 @@ public class BSPrim : BSPhysObject
if (value != _isSelected)
{
_isSelected = value;
PhysScene.TaintedObject("BSPrim.setSelected", delegate()
PhysScene.TaintedObject(LocalID, "BSPrim.setSelected", delegate()
{
DetailLog("{0},BSPrim.selected,taint,selected={1}", LocalID, _isSelected);
SetObjectDynamic(false);
@@ -224,7 +224,7 @@ public class BSPrim : BSPhysObject
_rotationalVelocity = OMV.Vector3.Zero;
// Zero some other properties in the physics engine
PhysScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ZeroMotion", delegate()
{
if (PhysBody.HasPhysicalBody)
PhysScene.PE.ClearAllForces(PhysBody);
@@ -234,7 +234,7 @@ public class BSPrim : BSPhysObject
{
_rotationalVelocity = OMV.Vector3.Zero;
// Zero some other properties in the physics engine
PhysScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ZeroMotion", delegate()
{
// DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity);
if (PhysBody.HasPhysicalBody)
@@ -262,7 +262,7 @@ public class BSPrim : BSPhysObject
});
// Update parameters so the new actor's Refresh() action is called at the right time.
PhysScene.TaintedObject("BSPrim.LockAngularMotion", delegate()
PhysScene.TaintedObject(LocalID, "BSPrim.LockAngularMotion", delegate()
{
UpdatePhysicalParameters();
});
@@ -287,7 +287,7 @@ public class BSPrim : BSPhysObject
RawPosition = value;
PositionSanityCheck(false);
PhysScene.TaintedObject("BSPrim.setPosition", delegate()
PhysScene.TaintedObject(LocalID, "BSPrim.setPosition", delegate()
{
DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, RawPosition, RawOrientation);
ForcePosition = RawPosition;
@@ -531,7 +531,7 @@ public class BSPrim : BSPhysObject
set {
Vehicle type = (Vehicle)value;
PhysScene.TaintedObject("setVehicleType", delegate()
PhysScene.TaintedObject(LocalID, "setVehicleType", delegate()
{
// Some vehicle scripts change vehicle type on the fly as an easy way to
// change all the parameters. Like a plane changing to CAR when on the
@@ -561,7 +561,7 @@ public class BSPrim : BSPhysObject
}
public override void VehicleFloatParam(int param, float value)
{
PhysScene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
PhysScene.TaintedObject(LocalID, "BSPrim.VehicleFloatParam", delegate()
{
BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */);
if (vehicleActor != null)
@@ -573,7 +573,7 @@ public class BSPrim : BSPhysObject
}
public override void VehicleVectorParam(int param, OMV.Vector3 value)
{
PhysScene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
PhysScene.TaintedObject(LocalID, "BSPrim.VehicleVectorParam", delegate()
{
BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */);
if (vehicleActor != null)
@@ -585,7 +585,7 @@ public class BSPrim : BSPhysObject
}
public override void VehicleRotationParam(int param, OMV.Quaternion rotation)
{
PhysScene.TaintedObject("BSPrim.VehicleRotationParam", delegate()
PhysScene.TaintedObject(LocalID, "BSPrim.VehicleRotationParam", delegate()
{
BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */);
if (vehicleActor != null)
@@ -597,7 +597,7 @@ public class BSPrim : BSPhysObject
}
public override void VehicleFlags(int param, bool remove)
{
PhysScene.TaintedObject("BSPrim.VehicleFlags", delegate()
PhysScene.TaintedObject(LocalID, "BSPrim.VehicleFlags", delegate()
{
BSDynamics vehicleActor = GetVehicleActor(true /* createIfNone */);
if (vehicleActor != null)
@@ -613,7 +613,7 @@ public class BSPrim : BSPhysObject
if (_isVolumeDetect != newValue)
{
_isVolumeDetect = newValue;
PhysScene.TaintedObject("BSPrim.SetVolumeDetect", delegate()
PhysScene.TaintedObject(LocalID, "BSPrim.SetVolumeDetect", delegate()
{
// DetailLog("{0},setVolumeDetect,taint,volDetect={1}", LocalID, _isVolumeDetect);
SetObjectDynamic(true);
@@ -628,7 +628,7 @@ public class BSPrim : BSPhysObject
public override void SetMaterial(int material)
{
base.SetMaterial(material);
PhysScene.TaintedObject("BSPrim.SetMaterial", delegate()
PhysScene.TaintedObject(LocalID, "BSPrim.SetMaterial", delegate()
{
UpdatePhysicalParameters();
});
@@ -641,7 +641,7 @@ public class BSPrim : BSPhysObject
if (base.Friction != value)
{
base.Friction = value;
PhysScene.TaintedObject("BSPrim.setFriction", delegate()
PhysScene.TaintedObject(LocalID, "BSPrim.setFriction", delegate()
{
UpdatePhysicalParameters();
});
@@ -656,7 +656,7 @@ public class BSPrim : BSPhysObject
if (base.Restitution != value)
{
base.Restitution = value;
PhysScene.TaintedObject("BSPrim.setRestitution", delegate()
PhysScene.TaintedObject(LocalID, "BSPrim.setRestitution", delegate()
{
UpdatePhysicalParameters();
});
@@ -673,7 +673,7 @@ public class BSPrim : BSPhysObject
if (base.Density != value)
{
base.Density = value;
PhysScene.TaintedObject("BSPrim.setDensity", delegate()
PhysScene.TaintedObject(LocalID, "BSPrim.setDensity", delegate()
{
UpdatePhysicalParameters();
});
@@ -688,7 +688,7 @@ public class BSPrim : BSPhysObject
if (base.GravModifier != value)
{
base.GravModifier = value;
PhysScene.TaintedObject("BSPrim.setGravityModifier", delegate()
PhysScene.TaintedObject(LocalID, "BSPrim.setGravityModifier", delegate()
{
UpdatePhysicalParameters();
});
@@ -699,7 +699,7 @@ public class BSPrim : BSPhysObject
get { return RawVelocity; }
set {
RawVelocity = value;
PhysScene.TaintedObject("BSPrim.setVelocity", delegate()
PhysScene.TaintedObject(LocalID, "BSPrim.setVelocity", delegate()
{
// DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, RawVelocity);
ForceVelocity = RawVelocity;
@@ -745,7 +745,7 @@ public class BSPrim : BSPhysObject
return;
RawOrientation = value;
PhysScene.TaintedObject("BSPrim.setOrientation", delegate()
PhysScene.TaintedObject(LocalID, "BSPrim.setOrientation", delegate()
{
ForceOrientation = RawOrientation;
});
@@ -776,7 +776,7 @@ public class BSPrim : BSPhysObject
if (_isPhysical != value)
{
_isPhysical = value;
PhysScene.TaintedObject("BSPrim.setIsPhysical", delegate()
PhysScene.TaintedObject(LocalID, "BSPrim.setIsPhysical", delegate()
{
DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical);
SetObjectDynamic(true);
@@ -1020,7 +1020,7 @@ public class BSPrim : BSPhysObject
public override bool FloatOnWater {
set {
_floatOnWater = value;
PhysScene.TaintedObject("BSPrim.setFloatOnWater", delegate()
PhysScene.TaintedObject(LocalID, "BSPrim.setFloatOnWater", delegate()
{
if (_floatOnWater)
CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER);
@@ -1037,7 +1037,7 @@ public class BSPrim : BSPhysObject
_rotationalVelocity = value;
Util.ClampV(_rotationalVelocity, BSParam.MaxAngularVelocity);
// m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
PhysScene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
PhysScene.TaintedObject(LocalID, "BSPrim.setRotationalVelocity", delegate()
{
ForceRotationalVelocity = _rotationalVelocity;
});
@@ -1068,7 +1068,7 @@ public class BSPrim : BSPhysObject
get { return _buoyancy; }
set {
_buoyancy = value;
PhysScene.TaintedObject("BSPrim.setBuoyancy", delegate()
PhysScene.TaintedObject(LocalID, "BSPrim.setBuoyancy", delegate()
{
ForceBuoyancy = _buoyancy;
});
@@ -1142,7 +1142,7 @@ public class BSPrim : BSPhysObject
// DetailLog("{0},BSPrim.addForce,call,force={1}", LocalID, addForce);
OMV.Vector3 addForce = force;
PhysScene.TaintedObject(inTaintTime, "BSPrim.AddForce", delegate()
PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.AddForce", delegate()
{
// Bullet adds this central force to the total force for this tick.
// Deep down in Bullet:
@@ -1172,7 +1172,7 @@ public class BSPrim : BSPhysObject
OMV.Vector3 addImpulse = Util.ClampV(impulse, BSParam.MaxAddForceMagnitude);
// DetailLog("{0},BSPrim.addForceImpulse,call,impulse={1}", LocalID, impulse);
PhysScene.TaintedObject(inTaintTime, "BSPrim.AddImpulse", delegate()
PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.AddImpulse", delegate()
{
// Bullet adds this impulse immediately to the velocity
DetailLog("{0},BSPrim.addForceImpulse,taint,impulseforce={1}", LocalID, addImpulse);
@@ -1197,7 +1197,7 @@ public class BSPrim : BSPhysObject
if (force.IsFinite())
{
OMV.Vector3 angForce = force;
PhysScene.TaintedObject(inTaintTime, "BSPrim.AddAngularForce", delegate()
PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.AddAngularForce", delegate()
{
if (PhysBody.HasPhysicalBody)
{
@@ -1221,7 +1221,7 @@ public class BSPrim : BSPhysObject
public void ApplyTorqueImpulse(OMV.Vector3 impulse, bool inTaintTime)
{
OMV.Vector3 applyImpulse = impulse;
PhysScene.TaintedObject(inTaintTime, "BSPrim.ApplyTorqueImpulse", delegate()
PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ApplyTorqueImpulse", delegate()
{
if (PhysBody.HasPhysicalBody)
{
@@ -1552,39 +1552,10 @@ public class BSPrim : BSPhysObject
#region Extension
public override object Extension(string pFunct, params object[] pParams)
{
DetailLog("{0} BSPrim.Extension,op={1}", LocalID, pFunct);
object ret = null;
switch (pFunct)
{
case BSScene.PhysFunctGetLinksetType:
{
BSPrimLinkable myHandle = this as BSPrimLinkable;
if (myHandle != null)
{
ret = (object)myHandle.LinksetType;
}
m_log.DebugFormat("{0} Extension.physGetLinksetType, type={1}", LogHeader, ret);
break;
}
case BSScene.PhysFunctSetLinksetType:
{
if (pParams.Length > 0)
{
BSLinkset.LinksetImplementation linksetType = (BSLinkset.LinksetImplementation)pParams[0];
BSPrimLinkable myHandle = this as BSPrimLinkable;
if (myHandle != null && myHandle.Linkset.IsRoot(myHandle))
{
PhysScene.TaintedObject("BSPrim.PhysFunctSetLinksetType", delegate()
{
// Cause the linkset type to change
m_log.DebugFormat("{0} Extension.physSetLinksetType, oldType={1}, newType={2}",
LogHeader, myHandle.Linkset.LinksetImpl, linksetType);
myHandle.ConvertLinkset(linksetType);
});
}
ret = (object)(int)linksetType;
}
break;
}
default:
ret = base.Extension(pFunct, pParams);
break;

View File

@@ -30,6 +30,7 @@ using System.Linq;
using System.Text;
using OpenSim.Framework;
using OpenSim.Region.OptionalModules.Scripting;
using OMV = OpenMetaverse;
@@ -41,6 +42,8 @@ public class BSPrimLinkable : BSPrimDisplaced
// operations necessary for keeping the linkset created and, additionally, this
// calls the linkset implementation for its creation and management.
private static readonly string LogHeader = "[BULLETS PRIMLINKABLE]";
// This adds the overrides for link() and delink() so the prim is linkable.
public BSLinkset Linkset { get; set; }
@@ -58,15 +61,12 @@ public class BSPrimLinkable : BSPrimDisplaced
Linkset = BSLinkset.Factory(PhysScene, this);
PhysScene.TaintedObject("BSPrimLinksetCompound.Refresh", delegate()
{
Linkset.Refresh(this);
});
Linkset.Refresh(this);
}
public override void Destroy()
{
Linkset = Linkset.RemoveMeFromLinkset(this);
Linkset = Linkset.RemoveMeFromLinkset(this, false /* inTaintTime */);
base.Destroy();
}
@@ -80,7 +80,7 @@ public class BSPrimLinkable : BSPrimDisplaced
Linkset = parent.Linkset.AddMeToLinkset(this);
DetailLog("{0},BSPrimLinkset.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}",
DetailLog("{0},BSPrimLinkable.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}",
LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
}
return;
@@ -94,9 +94,9 @@ public class BSPrimLinkable : BSPrimDisplaced
BSPhysObject parentBefore = Linkset.LinksetRoot; // DEBUG
int childrenBefore = Linkset.NumberOfChildren; // DEBUG
Linkset = Linkset.RemoveMeFromLinkset(this);
Linkset = Linkset.RemoveMeFromLinkset(this, false /* inTaintTime*/);
DetailLog("{0},BSPrimLinkset.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",
DetailLog("{0},BSPrimLinkable.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",
LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
return;
}
@@ -108,7 +108,7 @@ public class BSPrimLinkable : BSPrimDisplaced
set
{
base.Position = value;
PhysScene.TaintedObject("BSPrimLinkset.setPosition", delegate()
PhysScene.TaintedObject(LocalID, "BSPrimLinkable.setPosition", delegate()
{
Linkset.UpdateProperties(UpdatedProperties.Position, this);
});
@@ -122,7 +122,7 @@ public class BSPrimLinkable : BSPrimDisplaced
set
{
base.Orientation = value;
PhysScene.TaintedObject("BSPrimLinkset.setOrientation", delegate()
PhysScene.TaintedObject(LocalID, "BSPrimLinkable.setOrientation", delegate()
{
Linkset.UpdateProperties(UpdatedProperties.Orientation, this);
});
@@ -180,7 +180,7 @@ public class BSPrimLinkable : BSPrimDisplaced
// Do any filtering/modification needed for linksets.
public override void UpdateProperties(EntityProperties entprop)
{
if (Linkset.IsRoot(this))
if (Linkset.IsRoot(this) || Linkset.ShouldReportPropertyUpdates(this))
{
// Properties are only updated for the roots of a linkset.
// TODO: this will have to change when linksets are articulated.
@@ -240,6 +240,8 @@ public class BSPrimLinkable : BSPrimDisplaced
bool ret = false;
if (LinksetType != newType)
{
DetailLog("{0},BSPrimLinkable.ConvertLinkset,oldT={1},newT={2}", LocalID, LinksetType, newType);
// Set the implementation type first so the call to BSLinkset.Factory gets the new type.
this.LinksetType = newType;
@@ -263,7 +265,10 @@ public class BSPrimLinkable : BSPrimDisplaced
// Remove the children from the old linkset and add to the new (will be a new instance from the factory)
foreach (BSPrimLinkable child in children)
{
oldLinkset.RemoveMeFromLinkset(child);
oldLinkset.RemoveMeFromLinkset(child, true /*inTaintTime*/);
}
foreach (BSPrimLinkable child in children)
{
newLinkset.AddMeToLinkset(child);
child.Linkset = newLinkset;
}
@@ -274,5 +279,70 @@ public class BSPrimLinkable : BSPrimDisplaced
}
return ret;
}
#region Extension
public override object Extension(string pFunct, params object[] pParams)
{
DetailLog("{0} BSPrimLinkable.Extension,op={1},nParam={2}", LocalID, pFunct, pParams.Length);
object ret = null;
switch (pFunct)
{
// physGetLinksetType();
// pParams = [ BSPhysObject root, null ]
case ExtendedPhysics.PhysFunctGetLinksetType:
{
ret = (object)LinksetType;
DetailLog("{0},BSPrimLinkable.Extension.physGetLinksetType,type={1}", LocalID, ret);
break;
}
// physSetLinksetType(type);
// pParams = [ BSPhysObject root, null, integer type ]
case ExtendedPhysics.PhysFunctSetLinksetType:
{
if (pParams.Length > 2)
{
BSLinkset.LinksetImplementation linksetType = (BSLinkset.LinksetImplementation)pParams[2];
if (Linkset.IsRoot(this))
{
PhysScene.TaintedObject(LocalID, "BSPrim.PhysFunctSetLinksetType", delegate()
{
// Cause the linkset type to change
DetailLog("{0},BSPrimLinkable.Extension.physSetLinksetType, oldType={1},newType={2}",
LocalID, Linkset.LinksetImpl, linksetType);
ConvertLinkset(linksetType);
});
}
ret = (object)(int)linksetType;
}
break;
}
// physChangeLinkType(linknum, typeCode);
// pParams = [ BSPhysObject root, BSPhysObject child, integer linkType ]
case ExtendedPhysics.PhysFunctChangeLinkType:
{
ret = Linkset.Extension(pFunct, pParams);
break;
}
// physGetLinkType(linknum);
// pParams = [ BSPhysObject root, BSPhysObject child ]
case ExtendedPhysics.PhysFunctGetLinkType:
{
ret = Linkset.Extension(pFunct, pParams);
break;
}
// physChangeLinkParams(linknum, [code, value, code, value, ...]);
// pParams = [ BSPhysObject root, BSPhysObject child, object[] [ string op, object opParam, string op, object opParam, ... ] ]
case ExtendedPhysics.PhysFunctChangeLinkParams:
{
ret = Linkset.Extension(pFunct, pParams);
break;
}
default:
ret = base.Extension(pFunct, pParams);
break;
}
return ret;
}
#endregion // Extension
}
}

View File

@@ -157,12 +157,20 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
public delegate void TaintCallback();
private struct TaintCallbackEntry
{
public String originator;
public String ident;
public TaintCallback callback;
public TaintCallbackEntry(string i, TaintCallback c)
public TaintCallbackEntry(string pIdent, TaintCallback pCallBack)
{
ident = i;
callback = c;
originator = BSScene.DetailLogZero;
ident = pIdent;
callback = pCallBack;
}
public TaintCallbackEntry(string pOrigin, string pIdent, TaintCallback pCallBack)
{
originator = pOrigin;
ident = pIdent;
callback = pCallBack;
}
}
private Object _taintLock = new Object(); // lock for using the next object
@@ -867,18 +875,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
public override bool IsThreaded { get { return false; } }
#region Extensions
// =============================================================
// Per scene functions. See below.
// Per avatar functions. See BSCharacter.
// Per prim functions. See BSPrim.
public const string PhysFunctGetLinksetType = "BulletSim.GetLinksetType";
public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType";
// =============================================================
public override object Extension(string pFunct, params object[] pParams)
{
DetailLog("{0} BSScene.Extension,op={1}", DetailLogZero, pFunct);
return base.Extension(pFunct, pParams);
}
#endregion // Extensions
@@ -897,26 +896,37 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
// Calls to the PhysicsActors can't directly call into the physics engine
// because it might be busy. We delay changes to a known time.
// We rely on C#'s closure to save and restore the context for the delegate.
public void TaintedObject(String ident, TaintCallback callback)
public void TaintedObject(string pOriginator, string pIdent, TaintCallback pCallback)
{
TaintedObject(false /*inTaintTime*/, pOriginator, pIdent, pCallback);
}
public void TaintedObject(uint pOriginator, String pIdent, TaintCallback pCallback)
{
TaintedObject(false /*inTaintTime*/, m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback);
}
public void TaintedObject(bool inTaintTime, String pIdent, TaintCallback pCallback)
{
TaintedObject(inTaintTime, BSScene.DetailLogZero, pIdent, pCallback);
}
public void TaintedObject(bool inTaintTime, uint pOriginator, String pIdent, TaintCallback pCallback)
{
TaintedObject(inTaintTime, m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback);
}
// Sometimes a potentially tainted operation can be used in and out of taint time.
// This routine executes the command immediately if in taint-time otherwise it is queued.
public void TaintedObject(bool inTaintTime, string pOriginator, string pIdent, TaintCallback pCallback)
{
if (!m_initialized) return;
lock (_taintLock)
{
_taintOperations.Add(new TaintCallbackEntry(ident, callback));
}
return;
}
// Sometimes a potentially tainted operation can be used in and out of taint time.
// This routine executes the command immediately if in taint-time otherwise it is queued.
public void TaintedObject(bool inTaintTime, string ident, TaintCallback callback)
{
if (inTaintTime)
callback();
pCallback();
else
TaintedObject(ident, callback);
{
lock (_taintLock)
{
_taintOperations.Add(new TaintCallbackEntry(pOriginator, pIdent, pCallback));
}
}
}
private void TriggerPreStepEvent(float timeStep)
@@ -960,7 +970,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
{
try
{
DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", DetailLogZero, tcbe.ident); // DEBUG DEBUG DEBUG
DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", tcbe.originator, tcbe.ident); // DEBUG DEBUG DEBUG
tcbe.callback();
}
catch (Exception e)
@@ -977,10 +987,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
// will replace any previous operation by the same object.
public void PostTaintObject(String ident, uint ID, TaintCallback callback)
{
string uniqueIdent = ident + "-" + ID.ToString();
string IDAsString = ID.ToString();
string uniqueIdent = ident + "-" + IDAsString;
lock (_taintLock)
{
_postTaintOperations[uniqueIdent] = new TaintCallbackEntry(uniqueIdent, callback);
_postTaintOperations[uniqueIdent] = new TaintCallbackEntry(IDAsString, uniqueIdent, callback);
}
return;
@@ -1090,7 +1101,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
string xval = val;
List<uint> xlIDs = lIDs;
string xparm = parm;
TaintedObject("BSScene.UpdateParameterSet", delegate() {
TaintedObject(DetailLogZero, "BSScene.UpdateParameterSet", delegate() {
BSParam.ParameterDefnBase thisParam;
if (BSParam.TryGetParameter(xparm, out thisParam))
{