diff options
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs | 13 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 9 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 12 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 78 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 145 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 193 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 17 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 10 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | 46 | ||||
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 7 |
10 files changed, 396 insertions, 134 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 2aeb4cc..7035e38 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs | |||
@@ -204,9 +204,12 @@ namespace OpenMetaverse | |||
204 | { | 204 | { |
205 | UDPPacketBuffer buf; | 205 | UDPPacketBuffer buf; |
206 | 206 | ||
207 | if (UsePools) | 207 | // FIXME: Disabled for now as this causes issues with reused packet objects interfering with each other |
208 | buf = Pool.GetObject(); | 208 | // on Windows with m_asyncPacketHandling = true, though this has not been seen on Linux. |
209 | else | 209 | // Possibly some unexpected issue with fetching UDP data concurrently with multiple threads. Requires more investigation. |
210 | // if (UsePools) | ||
211 | // buf = Pool.GetObject(); | ||
212 | // else | ||
210 | buf = new UDPPacketBuffer(); | 213 | buf = new UDPPacketBuffer(); |
211 | 214 | ||
212 | if (IsRunningInbound) | 215 | if (IsRunningInbound) |
@@ -287,8 +290,8 @@ namespace OpenMetaverse | |||
287 | catch (ObjectDisposedException) { } | 290 | catch (ObjectDisposedException) { } |
288 | finally | 291 | finally |
289 | { | 292 | { |
290 | if (UsePools) | 293 | // if (UsePools) |
291 | Pool.ReturnObject(buffer); | 294 | // Pool.ReturnObject(buffer); |
292 | 295 | ||
293 | // Synchronous mode waits until the packet callback completes | 296 | // Synchronous mode waits until the packet callback completes |
294 | // before starting the receive to fetch another packet | 297 | // before starting the receive to fetch another packet |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 2051a53..1fc8d3d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -101,6 +101,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
101 | /// </summary> | 101 | /// </summary> |
102 | public partial class SceneObjectGroup : EntityBase, ISceneObject | 102 | public partial class SceneObjectGroup : EntityBase, ISceneObject |
103 | { | 103 | { |
104 | // Axis selection bitmask used by SetAxisRotation() | ||
105 | // Just happen to be the same bits used by llSetStatus() and defined in ScriptBaseClass. | ||
106 | public enum axisSelect : int | ||
107 | { | ||
108 | STATUS_ROTATE_X = 0x002, | ||
109 | STATUS_ROTATE_Y = 0x004, | ||
110 | STATUS_ROTATE_Z = 0x008, | ||
111 | } | ||
112 | |||
104 | // private PrimCountTaintedDelegate handlerPrimCountTainted = null; | 113 | // private PrimCountTaintedDelegate handlerPrimCountTainted = null; |
105 | 114 | ||
106 | /// <summary> | 115 | /// <summary> |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index c746690..143a339 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -2431,11 +2431,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
2431 | public int GetAxisRotation(int axis) | 2431 | public int GetAxisRotation(int axis) |
2432 | { | 2432 | { |
2433 | //Cannot use ScriptBaseClass constants as no referance to it currently. | 2433 | //Cannot use ScriptBaseClass constants as no referance to it currently. |
2434 | if (axis == 2)//STATUS_ROTATE_X | 2434 | if (axis == (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_X) |
2435 | return STATUS_ROTATE_X; | 2435 | return STATUS_ROTATE_X; |
2436 | if (axis == 4)//STATUS_ROTATE_Y | 2436 | if (axis == (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Y) |
2437 | return STATUS_ROTATE_Y; | 2437 | return STATUS_ROTATE_Y; |
2438 | if (axis == 8)//STATUS_ROTATE_Z | 2438 | if (axis == (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Z) |
2439 | return STATUS_ROTATE_Z; | 2439 | return STATUS_ROTATE_Z; |
2440 | 2440 | ||
2441 | return 0; | 2441 | return 0; |
@@ -3316,13 +3316,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
3316 | ParentGroup.SetAxisRotation(axis, rotate); | 3316 | ParentGroup.SetAxisRotation(axis, rotate); |
3317 | 3317 | ||
3318 | //Cannot use ScriptBaseClass constants as no referance to it currently. | 3318 | //Cannot use ScriptBaseClass constants as no referance to it currently. |
3319 | if (axis == 2)//STATUS_ROTATE_X | 3319 | if ((axis & (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_X) != 0) |
3320 | STATUS_ROTATE_X = rotate; | 3320 | STATUS_ROTATE_X = rotate; |
3321 | 3321 | ||
3322 | if (axis == 4)//STATUS_ROTATE_Y | 3322 | if ((axis & (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Y) != 0) |
3323 | STATUS_ROTATE_Y = rotate; | 3323 | STATUS_ROTATE_Y = rotate; |
3324 | 3324 | ||
3325 | if (axis == 8)//STATUS_ROTATE_Z | 3325 | if ((axis & (int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Z) != 0) |
3326 | STATUS_ROTATE_Z = rotate; | 3326 | STATUS_ROTATE_Z = rotate; |
3327 | } | 3327 | } |
3328 | 3328 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 4dd6264..57c5898 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -69,6 +69,8 @@ public sealed class BSCharacter : BSPhysObject | |||
69 | private OMV.Vector3 _appliedVelocity; // the last velocity applied to the avatar | 69 | private OMV.Vector3 _appliedVelocity; // the last velocity applied to the avatar |
70 | private float _currentFriction; // the friction currently being used (changed by setVelocity). | 70 | private float _currentFriction; // the friction currently being used (changed by setVelocity). |
71 | 71 | ||
72 | private BSVMotor _velocityMotor; | ||
73 | |||
72 | private OMV.Vector3 _PIDTarget; | 74 | private OMV.Vector3 _PIDTarget; |
73 | private bool _usePID; | 75 | private bool _usePID; |
74 | private float _PIDTau; | 76 | private float _PIDTau; |
@@ -89,6 +91,18 @@ public sealed class BSCharacter : BSPhysObject | |||
89 | if (_size.X == 0f) _size.X = PhysicsScene.Params.avatarCapsuleDepth; | 91 | if (_size.X == 0f) _size.X = PhysicsScene.Params.avatarCapsuleDepth; |
90 | if (_size.Y == 0f) _size.Y = PhysicsScene.Params.avatarCapsuleWidth; | 92 | if (_size.Y == 0f) _size.Y = PhysicsScene.Params.avatarCapsuleWidth; |
91 | 93 | ||
94 | // A motor to control the acceleration and deceleration of the avatar movement. | ||
95 | // _velocityMotor = new BSVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); | ||
96 | // _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f); | ||
97 | // Infinite decay and timescale values so motor only changes current to target values. | ||
98 | _velocityMotor = new BSVMotor("BSCharacter.Velocity", | ||
99 | 0.2f, // time scale | ||
100 | BSMotor.Infinite, // decay time scale | ||
101 | BSMotor.InfiniteVector, // friction timescale | ||
102 | 1f // efficiency | ||
103 | ); | ||
104 | _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages. | ||
105 | |||
92 | _flying = isFlying; | 106 | _flying = isFlying; |
93 | _orientation = OMV.Quaternion.Identity; | 107 | _orientation = OMV.Quaternion.Identity; |
94 | _velocity = OMV.Vector3.Zero; | 108 | _velocity = OMV.Vector3.Zero; |
@@ -138,6 +152,10 @@ public sealed class BSCharacter : BSPhysObject | |||
138 | ForcePosition = _position; | 152 | ForcePosition = _position; |
139 | // Set the velocity and compute the proper friction | 153 | // Set the velocity and compute the proper friction |
140 | ForceVelocity = _velocity; | 154 | ForceVelocity = _velocity; |
155 | // Setting the current and target in the motor will cause it to start computing any deceleration. | ||
156 | _velocityMotor.Reset(); | ||
157 | _velocityMotor.SetCurrent(_velocity); | ||
158 | _velocityMotor.SetTarget(_velocity); | ||
141 | 159 | ||
142 | // This will enable or disable the flying buoyancy of the avatar. | 160 | // This will enable or disable the flying buoyancy of the avatar. |
143 | // Needs to be reset especially when an avatar is recreated after crossing a region boundry. | 161 | // Needs to be reset especially when an avatar is recreated after crossing a region boundry. |
@@ -239,6 +257,7 @@ public sealed class BSCharacter : BSPhysObject | |||
239 | public override void ZeroMotion(bool inTaintTime) | 257 | public override void ZeroMotion(bool inTaintTime) |
240 | { | 258 | { |
241 | _velocity = OMV.Vector3.Zero; | 259 | _velocity = OMV.Vector3.Zero; |
260 | _velocityMotor.Zero(); | ||
242 | _acceleration = OMV.Vector3.Zero; | 261 | _acceleration = OMV.Vector3.Zero; |
243 | _rotationalVelocity = OMV.Vector3.Zero; | 262 | _rotationalVelocity = OMV.Vector3.Zero; |
244 | 263 | ||
@@ -400,10 +419,38 @@ public sealed class BSCharacter : BSPhysObject | |||
400 | 419 | ||
401 | public override OMV.Vector3 GeometricCenter { get { return OMV.Vector3.Zero; } } | 420 | public override OMV.Vector3 GeometricCenter { get { return OMV.Vector3.Zero; } } |
402 | public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } } | 421 | public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } } |
422 | |||
423 | // Sets the target in the motor. This starts the changing of the avatar's velocity. | ||
424 | public override OMV.Vector3 TargetVelocity | ||
425 | { | ||
426 | get | ||
427 | { | ||
428 | return _velocityMotor.TargetValue; | ||
429 | } | ||
430 | set | ||
431 | { | ||
432 | DetailLog("{0},BSCharacter.setTargetVelocity,call,vel={1}", LocalID, value); | ||
433 | OMV.Vector3 targetVel = value; | ||
434 | PhysicsScene.TaintedObject("BSCharacter.setTargetVelocity", delegate() | ||
435 | { | ||
436 | float timeStep = 0.089f; // DEBUG DEBUG FIX FIX FIX | ||
437 | _velocityMotor.Reset(); | ||
438 | _velocityMotor.SetTarget(targetVel); | ||
439 | _velocityMotor.SetCurrent(_velocity); | ||
440 | // Compute a velocity value and make sure it gets pushed into the avatar. | ||
441 | // This makes sure the avatar will start from a stop. | ||
442 | ForceVelocity = _velocityMotor.Step(timeStep); | ||
443 | }); | ||
444 | } | ||
445 | } | ||
446 | // Directly setting velocity means this is what the user really wants now. | ||
403 | public override OMV.Vector3 Velocity { | 447 | public override OMV.Vector3 Velocity { |
404 | get { return _velocity; } | 448 | get { return _velocity; } |
405 | set { | 449 | set { |
406 | _velocity = value; | 450 | _velocity = value; |
451 | _velocityMotor.Reset(); | ||
452 | _velocityMotor.SetCurrent(_velocity); | ||
453 | _velocityMotor.SetTarget(_velocity); | ||
407 | // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity); | 454 | // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity); |
408 | PhysicsScene.TaintedObject("BSCharacter.setVelocity", delegate() | 455 | PhysicsScene.TaintedObject("BSCharacter.setVelocity", delegate() |
409 | { | 456 | { |
@@ -415,6 +462,8 @@ public sealed class BSCharacter : BSPhysObject | |||
415 | public override OMV.Vector3 ForceVelocity { | 462 | public override OMV.Vector3 ForceVelocity { |
416 | get { return _velocity; } | 463 | get { return _velocity; } |
417 | set { | 464 | set { |
465 | PhysicsScene.AssertInTaintTime("BSCharacter.ForceVelocity"); | ||
466 | |||
418 | // Depending on whether the avatar is moving or not, change the friction | 467 | // Depending on whether the avatar is moving or not, change the friction |
419 | // to keep the avatar from slipping around | 468 | // to keep the avatar from slipping around |
420 | if (_velocity.Length() == 0) | 469 | if (_velocity.Length() == 0) |
@@ -511,6 +560,13 @@ public sealed class BSCharacter : BSPhysObject | |||
511 | get { return _flying; } | 560 | get { return _flying; } |
512 | set { | 561 | set { |
513 | _flying = value; | 562 | _flying = value; |
563 | |||
564 | // Velocity movement is different when flying: flying velocity degrades over time. | ||
565 | if (_flying) | ||
566 | _velocityMotor.TargetValueDecayTimeScale = 1f; | ||
567 | else | ||
568 | _velocityMotor.TargetValueDecayTimeScale = BSMotor.Infinite; | ||
569 | |||
514 | // simulate flying by changing the effect of gravity | 570 | // simulate flying by changing the effect of gravity |
515 | Buoyancy = ComputeBuoyancyFromFlying(_flying); | 571 | Buoyancy = ComputeBuoyancyFromFlying(_flying); |
516 | } | 572 | } |
@@ -581,7 +637,10 @@ public sealed class BSCharacter : BSPhysObject | |||
581 | } | 637 | } |
582 | public override float ForceBuoyancy { | 638 | public override float ForceBuoyancy { |
583 | get { return _buoyancy; } | 639 | get { return _buoyancy; } |
584 | set { _buoyancy = value; | 640 | set { |
641 | PhysicsScene.AssertInTaintTime("BSCharacter.ForceBuoyancy"); | ||
642 | |||
643 | _buoyancy = value; | ||
585 | DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); | 644 | DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); |
586 | // Buoyancy is faked by changing the gravity applied to the object | 645 | // Buoyancy is faked by changing the gravity applied to the object |
587 | float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); | 646 | float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); |
@@ -698,6 +757,22 @@ public sealed class BSCharacter : BSPhysObject | |||
698 | LastEntityProperties = CurrentEntityProperties; | 757 | LastEntityProperties = CurrentEntityProperties; |
699 | CurrentEntityProperties = entprop; | 758 | CurrentEntityProperties = entprop; |
700 | 759 | ||
760 | // Avatars don't respond to world friction, etc. They only go the speed I tell them too. | ||
761 | // Special kludge here for falling. Even though the target velocity might not have a | ||
762 | // Z component, the avatar could be falling (walked off a ledge, stopped flying, ...) | ||
763 | // and that velocity component must be retained. | ||
764 | float timeStep = 0.089f; // DEBUG DEBUG FIX FIX FIX | ||
765 | OMV.Vector3 stepVelocity = _velocityMotor.Step(timeStep); | ||
766 | // Remove next line so avatars don't fly up forever. DEBUG DEBUG this is only temporary. | ||
767 | // stepVelocity.Z += entprop.Velocity.Z; | ||
768 | _velocity = stepVelocity; | ||
769 | BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); | ||
770 | /* | ||
771 | OMV.Vector3 stepVelocity = _velocityMotor.Step(timeStep); | ||
772 | OMV.Vector3 avVel = new OMV.Vector3(stepVelocity.X, stepVelocity.Y, entprop.Velocity.Z); | ||
773 | _velocity = avVel; | ||
774 | BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, avVel); | ||
775 | |||
701 | if (entprop.Velocity != LastEntityProperties.Velocity) | 776 | if (entprop.Velocity != LastEntityProperties.Velocity) |
702 | { | 777 | { |
703 | // Changes in the velocity are suppressed in avatars. | 778 | // Changes in the velocity are suppressed in avatars. |
@@ -706,6 +781,7 @@ public sealed class BSCharacter : BSPhysObject | |||
706 | _velocity = avVel; | 781 | _velocity = avVel; |
707 | BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, avVel); | 782 | BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, avVel); |
708 | } | 783 | } |
784 | */ | ||
709 | 785 | ||
710 | // Tell the linkset about value changes | 786 | // Tell the linkset about value changes |
711 | Linkset.UpdateProperties(this, true); | 787 | Linkset.UpdateProperties(this, true); |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 5887249..a5acd86 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | |||
@@ -91,6 +91,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
91 | private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body | 91 | private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body |
92 | 92 | ||
93 | //Deflection properties | 93 | //Deflection properties |
94 | private BSVMotor m_angularDeflectionMotor = new BSVMotor("AngularDeflection"); | ||
94 | private float m_angularDeflectionEfficiency = 0; | 95 | private float m_angularDeflectionEfficiency = 0; |
95 | private float m_angularDeflectionTimescale = 0; | 96 | private float m_angularDeflectionTimescale = 0; |
96 | private float m_linearDeflectionEfficiency = 0; | 97 | private float m_linearDeflectionEfficiency = 0; |
@@ -102,6 +103,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
102 | private float m_bankingTimescale = 0; | 103 | private float m_bankingTimescale = 0; |
103 | 104 | ||
104 | //Hover and Buoyancy properties | 105 | //Hover and Buoyancy properties |
106 | private BSVMotor m_hoverMotor = new BSVMotor("Hover"); | ||
105 | private float m_VhoverHeight = 0f; | 107 | private float m_VhoverHeight = 0f; |
106 | private float m_VhoverEfficiency = 0f; | 108 | private float m_VhoverEfficiency = 0f; |
107 | private float m_VhoverTimescale = 0f; | 109 | private float m_VhoverTimescale = 0f; |
@@ -118,6 +120,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
118 | // Timescale > cutoff means no vert attractor. | 120 | // Timescale > cutoff means no vert attractor. |
119 | private float m_verticalAttractionTimescale = 510f; | 121 | private float m_verticalAttractionTimescale = 510f; |
120 | 122 | ||
123 | // Just some recomputed constants: | ||
124 | static readonly float PIOverFour = ((float)Math.PI) / 4f; | ||
125 | static readonly float PIOverTwo = ((float)Math.PI) / 2f; | ||
126 | |||
121 | public BSDynamics(BSScene myScene, BSPrim myPrim) | 127 | public BSDynamics(BSScene myScene, BSPrim myPrim) |
122 | { | 128 | { |
123 | PhysicsScene = myScene; | 129 | PhysicsScene = myScene; |
@@ -563,9 +569,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
563 | // Vehicles report collision events so we know when it's on the ground | 569 | // Vehicles report collision events so we know when it's on the ground |
564 | BulletSimAPI.AddToCollisionFlags2(Prim.PhysBody.ptr, CollisionFlags.BS_VEHICLE_COLLISIONS); | 570 | BulletSimAPI.AddToCollisionFlags2(Prim.PhysBody.ptr, CollisionFlags.BS_VEHICLE_COLLISIONS); |
565 | 571 | ||
566 | // DEBUG DEBUG DEBUG: use uniform inertia to smooth movement added by Bullet | ||
567 | // Vector3 localInertia = new Vector3(1f, 1f, 1f); | ||
568 | // Vector3 localInertia = new Vector3(m_vehicleMass, m_vehicleMass, m_vehicleMass); | ||
569 | Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(Prim.PhysShape.ptr, m_vehicleMass); | 572 | Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(Prim.PhysShape.ptr, m_vehicleMass); |
570 | BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); | 573 | BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); |
571 | BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr); | 574 | BulletSimAPI.UpdateInertiaTensor2(Prim.PhysBody.ptr); |
@@ -599,21 +602,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
599 | 602 | ||
600 | #region Known vehicle value functions | 603 | #region Known vehicle value functions |
601 | // Vehicle physical parameters that we buffer from constant getting and setting. | 604 | // Vehicle physical parameters that we buffer from constant getting and setting. |
602 | // The "m_known*" variables are initialized to 'null', fetched only if referenced | 605 | // The "m_known*" values are unknown until they are fetched and the m_knownHas flag is set. |
603 | // and stored back into the physics engine only if updated. | 606 | // Changing is remembered and the parameter is stored back into the physics engine only if updated. |
604 | // This does two things: 1) saves continuious calls into unmanaged code, and | 607 | // This does two things: 1) saves continuious calls into unmanaged code, and |
605 | // 2) signals when a physics property update must happen back to the simulator | 608 | // 2) signals when a physics property update must happen back to the simulator |
606 | // to update values modified for the vehicle. | 609 | // to update values modified for the vehicle. |
607 | private int m_knownChanged; | 610 | private int m_knownChanged; |
608 | private float? m_knownTerrainHeight; | 611 | private int m_knownHas; |
609 | private float? m_knownWaterLevel; | 612 | private float m_knownTerrainHeight; |
610 | private Vector3? m_knownPosition; | 613 | private float m_knownWaterLevel; |
611 | private Vector3? m_knownVelocity; | 614 | private Vector3 m_knownPosition; |
615 | private Vector3 m_knownVelocity; | ||
612 | private Vector3 m_knownForce; | 616 | private Vector3 m_knownForce; |
613 | private Quaternion? m_knownOrientation; | 617 | private Quaternion m_knownOrientation; |
614 | private Vector3? m_knownRotationalVelocity; | 618 | private Vector3 m_knownRotationalVelocity; |
615 | private Vector3 m_knownRotationalForce; | 619 | private Vector3 m_knownRotationalForce; |
616 | private float? m_knownForwardSpeed; | 620 | private Vector3 m_knownForwardVelocity; // vehicle relative forward speed |
617 | 621 | ||
618 | private const int m_knownChangedPosition = 1 << 0; | 622 | private const int m_knownChangedPosition = 1 << 0; |
619 | private const int m_knownChangedVelocity = 1 << 1; | 623 | private const int m_knownChangedVelocity = 1 << 1; |
@@ -621,18 +625,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
621 | private const int m_knownChangedOrientation = 1 << 3; | 625 | private const int m_knownChangedOrientation = 1 << 3; |
622 | private const int m_knownChangedRotationalVelocity = 1 << 4; | 626 | private const int m_knownChangedRotationalVelocity = 1 << 4; |
623 | private const int m_knownChangedRotationalForce = 1 << 5; | 627 | private const int m_knownChangedRotationalForce = 1 << 5; |
628 | private const int m_knownChangedTerrainHeight = 1 << 6; | ||
629 | private const int m_knownChangedWaterLevel = 1 << 7; | ||
630 | private const int m_knownChangedForwardVelocity = 1 << 8; | ||
624 | 631 | ||
625 | private void ForgetKnownVehicleProperties() | 632 | private void ForgetKnownVehicleProperties() |
626 | { | 633 | { |
627 | m_knownTerrainHeight = null; | 634 | m_knownHas = 0; |
628 | m_knownWaterLevel = null; | ||
629 | m_knownPosition = null; | ||
630 | m_knownVelocity = null; | ||
631 | m_knownForce = Vector3.Zero; | ||
632 | m_knownOrientation = null; | ||
633 | m_knownRotationalVelocity = null; | ||
634 | m_knownRotationalForce = Vector3.Zero; | ||
635 | m_knownForwardSpeed = null; | ||
636 | m_knownChanged = 0; | 635 | m_knownChanged = 0; |
637 | } | 636 | } |
638 | private void PushKnownChanged() | 637 | private void PushKnownChanged() |
@@ -671,17 +670,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
671 | // is used ot fetch the height only once for each vehicle simulation step. | 670 | // is used ot fetch the height only once for each vehicle simulation step. |
672 | private float GetTerrainHeight(Vector3 pos) | 671 | private float GetTerrainHeight(Vector3 pos) |
673 | { | 672 | { |
674 | if (m_knownTerrainHeight == null) | 673 | if ((m_knownHas & m_knownChangedTerrainHeight) == 0) |
674 | { | ||
675 | m_knownTerrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); | 675 | m_knownTerrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); |
676 | return (float)m_knownTerrainHeight; | 676 | m_knownHas |= m_knownChangedTerrainHeight; |
677 | } | ||
678 | return m_knownTerrainHeight; | ||
677 | } | 679 | } |
678 | 680 | ||
679 | // Since the computation of water level can be a little involved, this routine | 681 | // Since the computation of water level can be a little involved, this routine |
680 | // is used ot fetch the level only once for each vehicle simulation step. | 682 | // is used ot fetch the level only once for each vehicle simulation step. |
681 | private float GetWaterLevel(Vector3 pos) | 683 | private float GetWaterLevel(Vector3 pos) |
682 | { | 684 | { |
683 | if (m_knownWaterLevel == null) | 685 | if ((m_knownHas & m_knownChangedWaterLevel) == 0) |
686 | { | ||
684 | m_knownWaterLevel = Prim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos); | 687 | m_knownWaterLevel = Prim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos); |
688 | m_knownHas |= m_knownChangedWaterLevel; | ||
689 | } | ||
685 | return (float)m_knownWaterLevel; | 690 | return (float)m_knownWaterLevel; |
686 | } | 691 | } |
687 | 692 | ||
@@ -689,8 +694,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
689 | { | 694 | { |
690 | get | 695 | get |
691 | { | 696 | { |
692 | if (m_knownPosition == null) | 697 | if ((m_knownHas & m_knownChangedPosition) == 0) |
698 | { | ||
693 | m_knownPosition = Prim.ForcePosition; | 699 | m_knownPosition = Prim.ForcePosition; |
700 | m_knownHas |= m_knownChangedPosition; | ||
701 | } | ||
694 | return (Vector3)m_knownPosition; | 702 | return (Vector3)m_knownPosition; |
695 | } | 703 | } |
696 | set | 704 | set |
@@ -704,8 +712,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
704 | { | 712 | { |
705 | get | 713 | get |
706 | { | 714 | { |
707 | if (m_knownOrientation == null) | 715 | if ((m_knownHas & m_knownChangedOrientation) == 0) |
716 | { | ||
708 | m_knownOrientation = Prim.ForceOrientation; | 717 | m_knownOrientation = Prim.ForceOrientation; |
718 | m_knownHas |= m_knownChangedOrientation; | ||
719 | } | ||
709 | return (Quaternion)m_knownOrientation; | 720 | return (Quaternion)m_knownOrientation; |
710 | } | 721 | } |
711 | set | 722 | set |
@@ -719,8 +730,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
719 | { | 730 | { |
720 | get | 731 | get |
721 | { | 732 | { |
722 | if (m_knownVelocity == null) | 733 | if ((m_knownHas & m_knownChangedVelocity) == 0) |
734 | { | ||
723 | m_knownVelocity = Prim.ForceVelocity; | 735 | m_knownVelocity = Prim.ForceVelocity; |
736 | m_knownHas |= m_knownChangedVelocity; | ||
737 | } | ||
724 | return (Vector3)m_knownVelocity; | 738 | return (Vector3)m_knownVelocity; |
725 | } | 739 | } |
726 | set | 740 | set |
@@ -740,8 +754,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
740 | { | 754 | { |
741 | get | 755 | get |
742 | { | 756 | { |
743 | if (m_knownRotationalVelocity == null) | 757 | if ((m_knownHas & m_knownChangedRotationalVelocity) == 0) |
758 | { | ||
744 | m_knownRotationalVelocity = Prim.ForceRotationalVelocity; | 759 | m_knownRotationalVelocity = Prim.ForceRotationalVelocity; |
760 | m_knownHas |= m_knownChangedRotationalVelocity; | ||
761 | } | ||
745 | return (Vector3)m_knownRotationalVelocity; | 762 | return (Vector3)m_knownRotationalVelocity; |
746 | } | 763 | } |
747 | set | 764 | set |
@@ -755,13 +772,24 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
755 | m_knownRotationalForce += aForce; | 772 | m_knownRotationalForce += aForce; |
756 | m_knownChanged |= m_knownChangedRotationalForce; | 773 | m_knownChanged |= m_knownChangedRotationalForce; |
757 | } | 774 | } |
775 | // Vehicle relative forward velocity | ||
776 | private Vector3 VehicleForwardVelocity | ||
777 | { | ||
778 | get | ||
779 | { | ||
780 | if ((m_knownHas & m_knownChangedForwardVelocity) == 0) | ||
781 | { | ||
782 | m_knownForwardVelocity = VehicleVelocity * Quaternion.Inverse(Quaternion.Normalize(VehicleOrientation)); | ||
783 | m_knownHas |= m_knownChangedForwardVelocity; | ||
784 | } | ||
785 | return (Vector3)m_knownForwardVelocity; | ||
786 | } | ||
787 | } | ||
758 | private float VehicleForwardSpeed | 788 | private float VehicleForwardSpeed |
759 | { | 789 | { |
760 | get | 790 | get |
761 | { | 791 | { |
762 | if (m_knownForwardSpeed == null) | 792 | return VehicleForwardVelocity.X; |
763 | m_knownForwardSpeed = (VehicleVelocity * Quaternion.Inverse(VehicleOrientation)).X; | ||
764 | return (float)m_knownForwardSpeed; | ||
765 | } | 793 | } |
766 | } | 794 | } |
767 | 795 | ||
@@ -832,13 +860,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
832 | // ================================================================== | 860 | // ================================================================== |
833 | // Clamp high or low velocities | 861 | // Clamp high or low velocities |
834 | float newVelocityLengthSq = newVelocity.LengthSquared(); | 862 | float newVelocityLengthSq = newVelocity.LengthSquared(); |
835 | // if (newVelocityLengthSq > 1e6f) | ||
836 | if (newVelocityLengthSq > 1000f) | 863 | if (newVelocityLengthSq > 1000f) |
837 | { | 864 | { |
838 | newVelocity /= newVelocity.Length(); | 865 | newVelocity /= newVelocity.Length(); |
839 | newVelocity *= 1000f; | 866 | newVelocity *= 1000f; |
840 | } | 867 | } |
841 | // else if (newVelocityLengthSq < 1e-6f) | ||
842 | else if (newVelocityLengthSq < 0.001f) | 868 | else if (newVelocityLengthSq < 0.001f) |
843 | newVelocity = Vector3.Zero; | 869 | newVelocity = Vector3.Zero; |
844 | 870 | ||
@@ -1003,7 +1029,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1003 | // Not colliding if the vehicle is off the ground | 1029 | // Not colliding if the vehicle is off the ground |
1004 | if (!Prim.IsColliding) | 1030 | if (!Prim.IsColliding) |
1005 | { | 1031 | { |
1006 | // downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep); | ||
1007 | // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); | 1032 | // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); |
1008 | ret = new Vector3(0, 0, -distanceAboveGround); | 1033 | ret = new Vector3(0, 0, -distanceAboveGround); |
1009 | } | 1034 | } |
@@ -1026,7 +1051,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1026 | // set directly on the vehicle. | 1051 | // set directly on the vehicle. |
1027 | private void MoveAngular(float pTimestep) | 1052 | private void MoveAngular(float pTimestep) |
1028 | { | 1053 | { |
1029 | // The user wants how many radians per second angular change? | 1054 | // The user wants this many radians per second angular change? |
1030 | Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); | 1055 | Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); |
1031 | 1056 | ||
1032 | // ================================================================== | 1057 | // ================================================================== |
@@ -1135,31 +1160,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1135 | // zero and one. | 1160 | // zero and one. |
1136 | // The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees. | 1161 | // The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees. |
1137 | 1162 | ||
1163 | // Y error means needed rotation around X axis and visa versa. | ||
1164 | // Since the error goes from zero to one, the asin is the corresponding angle. | ||
1165 | ret.X = (float)Math.Asin(verticalError.Y); | ||
1166 | // (Tilt forward (positive X) needs to tilt back (rotate negative) around Y axis.) | ||
1167 | ret.Y = -(float)Math.Asin(verticalError.X); | ||
1168 | |||
1138 | // If verticalError.Z is negative, the vehicle is upside down. Add additional push. | 1169 | // If verticalError.Z is negative, the vehicle is upside down. Add additional push. |
1139 | if (verticalError.Z < 0f) | 1170 | if (verticalError.Z < 0f) |
1140 | { | 1171 | { |
1141 | verticalError.X = 2f - verticalError.X; | 1172 | ret.X += PIOverFour; |
1142 | verticalError.Y = 2f - verticalError.Y; | 1173 | ret.Y += PIOverFour; |
1143 | } | 1174 | } |
1144 | 1175 | ||
1145 | // Y error means needed rotation around X axis and visa versa. | 1176 | // 'ret' is now the necessary velocity to correct tilt in one second. |
1146 | ret.X = verticalError.Y; | 1177 | // Correction happens over a number of seconds. |
1147 | ret.Y = - verticalError.X; | ||
1148 | ret.Z = 0f; | ||
1149 | |||
1150 | // Scale the correction force by how far we're off from vertical. | ||
1151 | // Z error of one says little error. As Z gets smaller, the vehicle is leaning farther over. | ||
1152 | float clampedSqrZError = ClampInRange(0.01f, verticalError.Z * verticalError.Z, 1f); | ||
1153 | float vertForce = 1f / clampedSqrZError; | ||
1154 | |||
1155 | ret *= vertForce; | ||
1156 | |||
1157 | // Correction happens over a number of seconds. | ||
1158 | Vector3 unscaledContrib = ret; | 1178 | Vector3 unscaledContrib = ret; |
1159 | ret /= m_verticalAttractionTimescale; | 1179 | ret /= m_verticalAttractionTimescale; |
1160 | 1180 | ||
1161 | VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},vertForce={3},eff={4},vertAttr={5}", | 1181 | VDetailLog("{0}, MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},eff={3},ts={4},vertAttr={5}", |
1162 | Prim.LocalID, verticalError, unscaledContrib, vertForce, m_verticalAttractionEfficiency, ret); | 1182 | Prim.LocalID, verticalError, unscaledContrib, m_verticalAttractionEfficiency, m_verticalAttractionTimescale, ret); |
1163 | } | 1183 | } |
1164 | return ret; | 1184 | return ret; |
1165 | } | 1185 | } |
@@ -1172,7 +1192,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1172 | public Vector3 ComputeAngularDeflection() | 1192 | public Vector3 ComputeAngularDeflection() |
1173 | { | 1193 | { |
1174 | Vector3 ret = Vector3.Zero; | 1194 | Vector3 ret = Vector3.Zero; |
1175 | return ret; // DEBUG DEBUG DEBUG debug one force at a time | 1195 | return ret; // DEBUG DEBUG DEBUG |
1196 | // Disable angular deflection for the moment. | ||
1197 | // Since angularMotorUp and angularDeflection are computed independently, they will calculate | ||
1198 | // approximately the same X or Y correction. When added together (when contributions are combined) | ||
1199 | // this creates an over-correction and then wabbling as the target is overshot. | ||
1200 | // TODO: rethink how the different correction computations inter-relate. | ||
1176 | 1201 | ||
1177 | if (m_angularDeflectionEfficiency != 0) | 1202 | if (m_angularDeflectionEfficiency != 0) |
1178 | { | 1203 | { |
@@ -1184,15 +1209,24 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1184 | Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation; | 1209 | Vector3 pointingDirection = Vector3.UnitX * VehicleOrientation; |
1185 | pointingDirection.Normalize(); | 1210 | pointingDirection.Normalize(); |
1186 | 1211 | ||
1187 | // The difference between what is and what should be | 1212 | // The difference between what is and what should be. |
1188 | Vector3 deflectionError = movingDirection - pointingDirection; | 1213 | Vector3 deflectionError = movingDirection - pointingDirection; |
1189 | 1214 | ||
1215 | // Don't try to correct very large errors (not our job) | ||
1216 | if (Math.Abs(deflectionError.X) > PIOverFour) deflectionError.X = 0f; | ||
1217 | if (Math.Abs(deflectionError.Y) > PIOverFour) deflectionError.Y = 0f; | ||
1218 | if (Math.Abs(deflectionError.Z) > PIOverFour) deflectionError.Z = 0f; | ||
1219 | |||
1220 | // ret = m_angularDeflectionCorrectionMotor(1f, deflectionError); | ||
1221 | |||
1190 | // Scale the correction by recovery timescale and efficiency | 1222 | // Scale the correction by recovery timescale and efficiency |
1191 | ret = (-deflectionError * VehicleForwardSpeed) * m_angularDeflectionEfficiency; | 1223 | ret = (-deflectionError) * m_angularDeflectionEfficiency; |
1192 | ret /= m_angularDeflectionTimescale; | 1224 | ret /= m_angularDeflectionTimescale; |
1193 | 1225 | ||
1194 | VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}", | 1226 | VDetailLog("{0}, MoveAngular,Deflection,movingDir={1},pointingDir={2},deflectError={3},ret={4}", |
1195 | Prim.LocalID, movingDirection, pointingDirection, deflectionError, ret); | 1227 | Prim.LocalID, movingDirection, pointingDirection, deflectionError, ret); |
1228 | VDetailLog("{0}, MoveAngular,Deflection,fwdSpd={1},defEff={2},defTS={3}", | ||
1229 | Prim.LocalID, VehicleForwardSpeed, m_angularDeflectionEfficiency, m_angularDeflectionTimescale); | ||
1196 | } | 1230 | } |
1197 | return ret; | 1231 | return ret; |
1198 | } | 1232 | } |
@@ -1308,6 +1342,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1308 | private float ClampInRange(float low, float val, float high) | 1342 | private float ClampInRange(float low, float val, float high) |
1309 | { | 1343 | { |
1310 | return Math.Max(low, Math.Min(val, high)); | 1344 | return Math.Max(low, Math.Min(val, high)); |
1345 | // return Utils.Clamp(val, low, high); | ||
1311 | } | 1346 | } |
1312 | 1347 | ||
1313 | // Invoke the detailed logger and output something if it's enabled. | 1348 | // Invoke the detailed logger and output something if it's enabled. |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index e0faf4e..34a87c6 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | |||
@@ -29,13 +29,14 @@ using System; | |||
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Text; | 30 | using System.Text; |
31 | using OpenMetaverse; | 31 | using OpenMetaverse; |
32 | using OpenSim.Framework; | ||
32 | 33 | ||
33 | namespace OpenSim.Region.Physics.BulletSPlugin | 34 | namespace OpenSim.Region.Physics.BulletSPlugin |
34 | { | 35 | { |
35 | public abstract class BSMotor | 36 | public abstract class BSMotor |
36 | { | 37 | { |
37 | // Timescales and other things can be turned off by setting them to 'infinite'. | 38 | // Timescales and other things can be turned off by setting them to 'infinite'. |
38 | public const float Infinite = 12345f; | 39 | public const float Infinite = 12345.6f; |
39 | public readonly static Vector3 InfiniteVector = new Vector3(BSMotor.Infinite, BSMotor.Infinite, BSMotor.Infinite); | 40 | public readonly static Vector3 InfiniteVector = new Vector3(BSMotor.Infinite, BSMotor.Infinite, BSMotor.Infinite); |
40 | 41 | ||
41 | public BSMotor(string useName) | 42 | public BSMotor(string useName) |
@@ -45,6 +46,7 @@ public abstract class BSMotor | |||
45 | } | 46 | } |
46 | public virtual void Reset() { } | 47 | public virtual void Reset() { } |
47 | public virtual void Zero() { } | 48 | public virtual void Zero() { } |
49 | public virtual void GenerateTestOutput(float timeStep) { } | ||
48 | 50 | ||
49 | // A name passed at motor creation for easily identifyable debugging messages. | 51 | // A name passed at motor creation for easily identifyable debugging messages. |
50 | public string UseName { get; private set; } | 52 | public string UseName { get; private set; } |
@@ -62,12 +64,16 @@ public abstract class BSMotor | |||
62 | } | 64 | } |
63 | } | 65 | } |
64 | } | 66 | } |
65 | // Can all the incremental stepping be replaced with motor classes? | ||
66 | 67 | ||
67 | // Motor which moves CurrentValue to TargetValue over TimeScale seconds. | 68 | // Motor which moves CurrentValue to TargetValue over TimeScale seconds. |
68 | // The TargetValue decays in TargetValueDecayTimeScale and | 69 | // The TargetValue decays in TargetValueDecayTimeScale and |
69 | // the CurrentValue will be held back by FrictionTimeScale. | 70 | // the CurrentValue will be held back by FrictionTimeScale. |
70 | // TimeScale and TargetDelayTimeScale may be 'infinite' which means go decay. | 71 | // This motor will "zero itself" over time in that the targetValue will |
72 | // decay to zero and the currentValue will follow it to that zero. | ||
73 | // The overall effect is for the returned correction value to go from large | ||
74 | // values (the total difference between current and target minus friction) | ||
75 | // to small and eventually zero values. | ||
76 | // TimeScale and TargetDelayTimeScale may be 'infinite' which means no decay. | ||
71 | 77 | ||
72 | // For instance, if something is moving at speed X and the desired speed is Y, | 78 | // For instance, if something is moving at speed X and the desired speed is Y, |
73 | // CurrentValue is X and TargetValue is Y. As the motor is stepped, new | 79 | // CurrentValue is X and TargetValue is Y. As the motor is stepped, new |
@@ -81,13 +87,16 @@ public class BSVMotor : BSMotor | |||
81 | // public Vector3 FrameOfReference { get; set; } | 87 | // public Vector3 FrameOfReference { get; set; } |
82 | // public Vector3 Offset { get; set; } | 88 | // public Vector3 Offset { get; set; } |
83 | 89 | ||
84 | public float TimeScale { get; set; } | 90 | public virtual float TimeScale { get; set; } |
85 | public float TargetValueDecayTimeScale { get; set; } | 91 | public virtual float TargetValueDecayTimeScale { get; set; } |
86 | public Vector3 FrictionTimescale { get; set; } | 92 | public virtual Vector3 FrictionTimescale { get; set; } |
87 | public float Efficiency { get; set; } | 93 | public virtual float Efficiency { get; set; } |
94 | |||
95 | public virtual float ErrorZeroThreshold { get; set; } | ||
88 | 96 | ||
89 | public Vector3 TargetValue { get; private set; } | 97 | public virtual Vector3 TargetValue { get; protected set; } |
90 | public Vector3 CurrentValue { get; private set; } | 98 | public virtual Vector3 CurrentValue { get; protected set; } |
99 | public virtual Vector3 LastError { get; protected set; } | ||
91 | 100 | ||
92 | public BSVMotor(string useName) | 101 | public BSVMotor(string useName) |
93 | : base(useName) | 102 | : base(useName) |
@@ -96,6 +105,7 @@ public class BSVMotor : BSMotor | |||
96 | Efficiency = 1f; | 105 | Efficiency = 1f; |
97 | FrictionTimescale = BSMotor.InfiniteVector; | 106 | FrictionTimescale = BSMotor.InfiniteVector; |
98 | CurrentValue = TargetValue = Vector3.Zero; | 107 | CurrentValue = TargetValue = Vector3.Zero; |
108 | ErrorZeroThreshold = 0.01f; | ||
99 | } | 109 | } |
100 | public BSVMotor(string useName, float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency) | 110 | public BSVMotor(string useName, float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency) |
101 | : this(useName) | 111 | : this(useName) |
@@ -114,25 +124,25 @@ public class BSVMotor : BSMotor | |||
114 | { | 124 | { |
115 | TargetValue = target; | 125 | TargetValue = target; |
116 | } | 126 | } |
117 | 127 | public override void Zero() | |
118 | // A form of stepping that does not take the time quantum into account. | ||
119 | // The caller must do the right thing later. | ||
120 | public Vector3 Step() | ||
121 | { | 128 | { |
122 | return Step(1f); | 129 | base.Zero(); |
130 | CurrentValue = TargetValue = Vector3.Zero; | ||
123 | } | 131 | } |
124 | 132 | ||
125 | public Vector3 Step(float timeStep) | 133 | // Compute the next step and return the new current value |
134 | public virtual Vector3 Step(float timeStep) | ||
126 | { | 135 | { |
127 | Vector3 returnCurrent = Vector3.Zero; | 136 | Vector3 origTarget = TargetValue; // DEBUG |
128 | if (!CurrentValue.ApproxEquals(TargetValue, 0.01f)) | 137 | Vector3 origCurrVal = CurrentValue; // DEBUG |
138 | |||
139 | Vector3 correction = Vector3.Zero; | ||
140 | Vector3 error = TargetValue - CurrentValue; | ||
141 | if (!error.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) | ||
129 | { | 142 | { |
130 | Vector3 origTarget = TargetValue; // DEBUG | 143 | correction = Step(timeStep, error); |
131 | Vector3 origCurrVal = CurrentValue; // DEBUG | ||
132 | 144 | ||
133 | // Addition = (desiredVector - currentAppliedVector) / secondsItShouldTakeToComplete | 145 | CurrentValue += correction; |
134 | Vector3 addAmount = (TargetValue - CurrentValue)/TimeScale * timeStep; | ||
135 | CurrentValue += addAmount; | ||
136 | 146 | ||
137 | // The desired value reduces to zero which also reduces the difference with current. | 147 | // The desired value reduces to zero which also reduces the difference with current. |
138 | // If the decay time is infinite, don't decay at all. | 148 | // If the decay time is infinite, don't decay at all. |
@@ -143,40 +153,80 @@ public class BSVMotor : BSMotor | |||
143 | TargetValue *= (1f - decayFactor); | 153 | TargetValue *= (1f - decayFactor); |
144 | } | 154 | } |
145 | 155 | ||
156 | // The amount we can correct the error is reduced by the friction | ||
146 | Vector3 frictionFactor = Vector3.Zero; | 157 | Vector3 frictionFactor = Vector3.Zero; |
147 | if (FrictionTimescale != BSMotor.InfiniteVector) | 158 | if (FrictionTimescale != BSMotor.InfiniteVector) |
148 | { | 159 | { |
149 | // frictionFactor = (Vector3.One / FrictionTimescale) * timeStep; | 160 | // frictionFactor = (Vector3.One / FrictionTimescale) * timeStep; |
150 | // Individual friction components can be 'infinite' so compute each separately. | 161 | // Individual friction components can be 'infinite' so compute each separately. |
151 | frictionFactor.X = FrictionTimescale.X == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.X) * timeStep; | 162 | frictionFactor.X = (FrictionTimescale.X == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.X); |
152 | frictionFactor.Y = FrictionTimescale.Y == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.Y) * timeStep; | 163 | frictionFactor.Y = (FrictionTimescale.Y == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.Y); |
153 | frictionFactor.Z = FrictionTimescale.Z == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.Z) * timeStep; | 164 | frictionFactor.Z = (FrictionTimescale.Z == BSMotor.Infinite) ? 0f : (1f / FrictionTimescale.Z); |
165 | frictionFactor *= timeStep; | ||
154 | CurrentValue *= (Vector3.One - frictionFactor); | 166 | CurrentValue *= (Vector3.One - frictionFactor); |
155 | } | 167 | } |
156 | 168 | ||
157 | returnCurrent = CurrentValue; | 169 | MDetailLog("{0}, BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},err={5},corr={6}", |
158 | |||
159 | MDetailLog("{0}, BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},timeScale={5},addAmnt={6},targetDecay={7},decayFact={8},fricTS={9},frictFact={10}", | ||
160 | BSScene.DetailLogZero, UseName, origCurrVal, origTarget, | 170 | BSScene.DetailLogZero, UseName, origCurrVal, origTarget, |
161 | timeStep, TimeScale, addAmount, | 171 | timeStep, error, correction); |
162 | TargetValueDecayTimeScale, decayFactor, | 172 | MDetailLog("{0}, BSVMotor.Step,nonZero,{1},tgtDecayTS={2},decayFact={3},frictTS={4},frictFact={5},tgt={6},curr={7}", |
163 | FrictionTimescale, frictionFactor); | 173 | BSScene.DetailLogZero, UseName, |
164 | MDetailLog("{0}, BSVMotor.Step,nonZero,{1},curr={2},target={3},add={4},decay={5},frict={6},ret={7}", | 174 | TargetValueDecayTimeScale, decayFactor, FrictionTimescale, frictionFactor, |
165 | BSScene.DetailLogZero, UseName, CurrentValue, TargetValue, | 175 | TargetValue, CurrentValue); |
166 | addAmount, decayFactor, frictionFactor, returnCurrent); | ||
167 | } | 176 | } |
168 | else | 177 | else |
169 | { | 178 | { |
170 | // Difference between what we have and target is small. Motor is done. | 179 | // Difference between what we have and target is small. Motor is done. |
171 | CurrentValue = Vector3.Zero; | 180 | CurrentValue = TargetValue; |
172 | TargetValue = Vector3.Zero; | 181 | MDetailLog("{0}, BSVMotor.Step,zero,{1},origTgt={2},origCurr={3},ret={2}", |
182 | BSScene.DetailLogZero, UseName, origCurrVal, origTarget, CurrentValue); | ||
183 | } | ||
184 | |||
185 | return CurrentValue; | ||
186 | } | ||
187 | public virtual Vector3 Step(float timeStep, Vector3 error) | ||
188 | { | ||
189 | LastError = error; | ||
190 | Vector3 returnCorrection = Vector3.Zero; | ||
191 | if (!error.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) | ||
192 | { | ||
193 | // correction = error / secondsItShouldTakeToCorrect | ||
194 | Vector3 correctionAmount; | ||
195 | if (TimeScale == 0f || TimeScale == BSMotor.Infinite) | ||
196 | correctionAmount = error * timeStep; | ||
197 | else | ||
198 | correctionAmount = error / TimeScale * timeStep; | ||
173 | 199 | ||
174 | MDetailLog("{0}, BSVMotor.Step,zero,{1},curr={2},target={3},ret={4}", | 200 | returnCorrection = correctionAmount; |
175 | BSScene.DetailLogZero, UseName, TargetValue, CurrentValue, returnCurrent); | 201 | MDetailLog("{0}, BSVMotor.Step,nonZero,{1},timeStep={2},timeScale={3},err={4},corr={5}", |
202 | BSScene.DetailLogZero, UseName, timeStep, TimeScale, error, correctionAmount); | ||
203 | } | ||
204 | return returnCorrection; | ||
205 | } | ||
176 | 206 | ||
207 | // The user sets all the parameters and calls this which outputs values until error is zero. | ||
208 | public override void GenerateTestOutput(float timeStep) | ||
209 | { | ||
210 | // maximum number of outputs to generate. | ||
211 | int maxOutput = 50; | ||
212 | MDetailLog("{0},BSVMotor.Test,{1},===================================== BEGIN Test Output", BSScene.DetailLogZero, UseName); | ||
213 | MDetailLog("{0},BSVMotor.Test,{1},timeScale={2},targDlyTS={3},frictTS={4},eff={5},curr={6},tgt={7}", | ||
214 | BSScene.DetailLogZero, UseName, | ||
215 | TimeScale, TargetValueDecayTimeScale, FrictionTimescale, Efficiency, | ||
216 | CurrentValue, TargetValue); | ||
217 | |||
218 | LastError = BSMotor.InfiniteVector; | ||
219 | while (maxOutput-- > 0 && !LastError.ApproxEquals(Vector3.Zero, ErrorZeroThreshold)) | ||
220 | { | ||
221 | Vector3 lastStep = Step(timeStep); | ||
222 | MDetailLog("{0},BSVMotor.Test,{1},cur={2},tgt={3},lastError={4},lastStep={5}", | ||
223 | BSScene.DetailLogZero, UseName, CurrentValue, TargetValue, LastError, lastStep); | ||
177 | } | 224 | } |
178 | return returnCurrent; | 225 | MDetailLog("{0},BSVMotor.Test,{1},===================================== END Test Output", BSScene.DetailLogZero, UseName); |
226 | |||
227 | |||
179 | } | 228 | } |
229 | |||
180 | public override string ToString() | 230 | public override string ToString() |
181 | { | 231 | { |
182 | return String.Format("<{0},curr={1},targ={2},decayTS={3},frictTS={4}>", | 232 | return String.Format("<{0},curr={1},targ={2},decayTS={3},frictTS={4}>", |
@@ -204,17 +254,74 @@ public class BSFMotor : BSMotor | |||
204 | public void SetTarget(float target) | 254 | public void SetTarget(float target) |
205 | { | 255 | { |
206 | } | 256 | } |
207 | public float Step(float timeStep) | 257 | public virtual float Step(float timeStep) |
208 | { | 258 | { |
209 | return 0f; | 259 | return 0f; |
210 | } | 260 | } |
211 | } | 261 | } |
212 | public class BSPIDMotor : BSMotor | 262 | |
263 | // Proportional, Integral, Derivitive Motor | ||
264 | // Good description at http://www.answers.com/topic/pid-controller . Includes processes for choosing p, i and d factors. | ||
265 | public class BSPIDVMotor : BSVMotor | ||
213 | { | 266 | { |
214 | // TODO: write and use this one | 267 | // Larger makes more overshoot, smaller means converge quicker. Range of 0.1 to 10. |
215 | public BSPIDMotor(string useName) | 268 | public Vector3 proportionFactor { get; set; } |
269 | public Vector3 integralFactor { get; set; } | ||
270 | public Vector3 derivFactor { get; set; } | ||
271 | // Arbritrary factor range. | ||
272 | // EfficiencyHigh means move quickly to the correct number. EfficiencyLow means might over correct. | ||
273 | public float EfficiencyHigh = 0.4f; | ||
274 | public float EfficiencyLow = 4.0f; | ||
275 | |||
276 | Vector3 IntegralFactor { get; set; } | ||
277 | |||
278 | public BSPIDVMotor(string useName) | ||
216 | : base(useName) | 279 | : base(useName) |
217 | { | 280 | { |
281 | proportionFactor = new Vector3(1.00f, 1.00f, 1.00f); | ||
282 | integralFactor = new Vector3(1.00f, 1.00f, 1.00f); | ||
283 | derivFactor = new Vector3(1.00f, 1.00f, 1.00f); | ||
284 | IntegralFactor = Vector3.Zero; | ||
285 | LastError = Vector3.Zero; | ||
286 | } | ||
287 | |||
288 | public override void Zero() | ||
289 | { | ||
290 | base.Zero(); | ||
291 | } | ||
292 | |||
293 | public override float Efficiency | ||
294 | { | ||
295 | get { return base.Efficiency; } | ||
296 | set | ||
297 | { | ||
298 | base.Efficiency = Util.Clamp(value, 0f, 1f); | ||
299 | // Compute factors based on efficiency. | ||
300 | // If efficiency is high (1f), use a factor value that moves the error value to zero with little overshoot. | ||
301 | // If efficiency is low (0f), use a factor value that overcorrects. | ||
302 | // TODO: might want to vary contribution of different factor depending on efficiency. | ||
303 | float factor = ((1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow) / 3f; | ||
304 | // float factor = (1f - this.Efficiency) * EfficiencyHigh + EfficiencyLow; | ||
305 | proportionFactor = new Vector3(factor, factor, factor); | ||
306 | integralFactor = new Vector3(factor, factor, factor); | ||
307 | derivFactor = new Vector3(factor, factor, factor); | ||
308 | } | ||
309 | } | ||
310 | |||
311 | // Ignore Current and Target Values and just advance the PID computation on this error. | ||
312 | public override Vector3 Step(float timeStep, Vector3 error) | ||
313 | { | ||
314 | // Add up the error so we can integrate over the accumulated errors | ||
315 | IntegralFactor += error * timeStep; | ||
316 | |||
317 | // A simple derivitive is the rate of change from the last error. | ||
318 | Vector3 derivFactor = (error - LastError) * timeStep; | ||
319 | LastError = error; | ||
320 | |||
321 | // Correction = -(proportionOfPresentError + accumulationOfPastError + rateOfChangeOfError) | ||
322 | Vector3 ret = -(error * proportionFactor + IntegralFactor * integralFactor + derivFactor * derivFactor); | ||
323 | |||
324 | return ret; | ||
218 | } | 325 | } |
219 | } | 326 | } |
220 | } | 327 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 758d92b..68a0db6 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -100,10 +100,15 @@ public sealed class BSPrim : BSPhysObject | |||
100 | BaseShape = pbs; | 100 | BaseShape = pbs; |
101 | _isPhysical = pisPhysical; | 101 | _isPhysical = pisPhysical; |
102 | _isVolumeDetect = false; | 102 | _isVolumeDetect = false; |
103 | _friction = PhysicsScene.Params.defaultFriction; // TODO: compute based on object material | 103 | |
104 | _density = PhysicsScene.Params.defaultDensity; // TODO: compute based on object material | 104 | // Someday set default attributes based on the material but, for now, we don't know the prim material yet. |
105 | // MaterialAttributes primMat = BSMaterials.GetAttributes(Material, pisPhysical); | ||
106 | _density = PhysicsScene.Params.defaultDensity; | ||
107 | _friction = PhysicsScene.Params.defaultFriction; | ||
105 | _restitution = PhysicsScene.Params.defaultRestitution; | 108 | _restitution = PhysicsScene.Params.defaultRestitution; |
109 | |||
106 | _vehicle = new BSDynamics(PhysicsScene, this); // add vehicleness | 110 | _vehicle = new BSDynamics(PhysicsScene, this); // add vehicleness |
111 | |||
107 | _mass = CalculateMass(); | 112 | _mass = CalculateMass(); |
108 | 113 | ||
109 | // No body or shape yet | 114 | // No body or shape yet |
@@ -527,16 +532,18 @@ public sealed class BSPrim : BSPhysObject | |||
527 | PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate() | 532 | PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate() |
528 | { | 533 | { |
529 | // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); | 534 | // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); |
530 | if (PhysBody.HasPhysicalBody) | 535 | ForceVelocity = _velocity; |
531 | BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); | ||
532 | }); | 536 | }); |
533 | } | 537 | } |
534 | } | 538 | } |
535 | public override OMV.Vector3 ForceVelocity { | 539 | public override OMV.Vector3 ForceVelocity { |
536 | get { return _velocity; } | 540 | get { return _velocity; } |
537 | set { | 541 | set { |
542 | PhysicsScene.AssertInTaintTime("BSPrim.ForceVelocity"); | ||
543 | |||
538 | _velocity = value; | 544 | _velocity = value; |
539 | BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); | 545 | if (PhysBody.HasPhysicalBody) |
546 | BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, _velocity); | ||
540 | } | 547 | } |
541 | } | 548 | } |
542 | public override OMV.Vector3 Torque { | 549 | public override OMV.Vector3 Torque { |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 069cb0d..2ca4912 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -96,6 +96,16 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
96 | public long SimulationStep { get { return m_simulationStep; } } | 96 | public long SimulationStep { get { return m_simulationStep; } } |
97 | private int m_taintsToProcessPerStep; | 97 | private int m_taintsToProcessPerStep; |
98 | 98 | ||
99 | // Avatar parameters | ||
100 | public float ParamAvatarFriction { get; private set; } | ||
101 | public float ParamAvatarStandingFriction { get; private set; } | ||
102 | public float ParamAvatarDensity { get; private set; } | ||
103 | public float ParamAvatarRestitution { get; private set; } | ||
104 | public float ParamAvatarCapsuleWidth { get; private set; } | ||
105 | public float ParamAvatarCapsuleDepth { get; private set; } | ||
106 | public float ParamAvatarCapsuleHeight { get; private set; } | ||
107 | public float ParamAvatarContactProcessingThreshold { get; private set; } | ||
108 | |||
99 | public delegate void PreStepAction(float timeStep); | 109 | public delegate void PreStepAction(float timeStep); |
100 | public event PreStepAction BeforeStep; | 110 | public event PreStepAction BeforeStep; |
101 | 111 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 0d9a156..c084ab4 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | |||
@@ -1,15 +1,16 @@ | |||
1 | CURRENT PRIORITIES | 1 | CURRENT PRIORITIES |
2 | ================================================= | 2 | ================================================= |
3 | Eliminate all crashes (DONEish) | 3 | Smooth avatar movement with motor |
4 | Editing/deleting physical linkset (DONE) | 4 | Should motor update be all at taint-time? |
5 | Border crossing of physical linkset (DONE) | ||
6 | Enable vehicle border crossings (at least as poorly as ODE) | 5 | Enable vehicle border crossings (at least as poorly as ODE) |
6 | Terrain skirts | ||
7 | Avatar created in previous region and not new region when crossing border | 7 | Avatar created in previous region and not new region when crossing border |
8 | Vehicle recreated in new sim at small Z value (offset from root value?) (DONE) | 8 | Vehicle recreated in new sim at small Z value (offset from root value?) (DONE) |
9 | Calibrate turning radius | 9 | Vehicle movement on terrain smoothness |
10 | Vehicle script tuning/debugging | ||
11 | Avanti speed script | ||
12 | Weapon shooter script | ||
10 | limitMotorUp calibration (more down?) | 13 | limitMotorUp calibration (more down?) |
11 | study PID motors (include 'efficiency' implementation | ||
12 | Add to avatar movement | ||
13 | 14 | ||
14 | CRASHES | 15 | CRASHES |
15 | ================================================= | 16 | ================================================= |
@@ -25,7 +26,6 @@ CRASHES | |||
25 | VEHICLES TODO LIST: | 26 | VEHICLES TODO LIST: |
26 | ================================================= | 27 | ================================================= |
27 | Border crossing with linked vehicle causes crash | 28 | Border crossing with linked vehicle causes crash |
28 | Neb vehicle taking > 25ms of physics time!! | ||
29 | Vehicles (Move smoothly) | 29 | Vehicles (Move smoothly) |
30 | Add vehicle collisions so IsColliding is properly reported. | 30 | Add vehicle collisions so IsColliding is properly reported. |
31 | Needed for banking, limitMotorUp, movementLimiting, ... | 31 | Needed for banking, limitMotorUp, movementLimiting, ... |
@@ -34,28 +34,25 @@ Cannot edit/move a vehicle being ridden: it jumps back to the origional position | |||
34 | Neb car jiggling left and right | 34 | Neb car jiggling left and right |
35 | Happens on terrain and any other mesh object. Flat cubes are much smoother. | 35 | Happens on terrain and any other mesh object. Flat cubes are much smoother. |
36 | This has been reduced but not eliminated. | 36 | This has been reduced but not eliminated. |
37 | Light cycle falling over when driving | ||
38 | Implement referenceFrame for all the motion routines. | 37 | Implement referenceFrame for all the motion routines. |
39 | Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE. | 38 | Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE. |
40 | Verify that angular motion specified around Z moves in the vehicle coordinates. | 39 | Verify that angular motion specified around Z moves in the vehicle coordinates. |
41 | Verify llGetVel() is returning a smooth and good value for vehicle movement. | 40 | Verify llGetVel() is returning a smooth and good value for vehicle movement. |
42 | llGetVel() should return the root's velocity if requested in a child prim. | 41 | llGetVel() should return the root's velocity if requested in a child prim. |
43 | Implement function efficiency for lineaar and angular motion. | 42 | Implement function efficiency for lineaar and angular motion. |
44 | Should vehicle angular/linear movement friction happen after all the components | ||
45 | or does it only apply to the basic movement? | ||
46 | After getting off a vehicle, the root prim is phantom (can be walked through) | 43 | After getting off a vehicle, the root prim is phantom (can be walked through) |
47 | Need to force a position update for the root prim after compound shape destruction | 44 | Need to force a position update for the root prim after compound shape destruction |
48 | Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint) | 45 | Linkset explosion after three "rides" on Nebadon lite vehicle (LinksetConstraint) |
49 | For limitMotorUp, use raycast down to find if vehicle is in the air. | 46 | For limitMotorUp, use raycast down to find if vehicle is in the air. |
50 | Remove vehicle angular velocity zeroing in BSPrim.UpdateProperties(). | 47 | Remove vehicle angular velocity zeroing in BSPrim.UpdateProperties(). |
51 | A kludge that isn't fixing the real problem of Bullet adding extra motion. | 48 | A kludge that isn't fixing the real problem of Bullet adding extra motion. |
49 | Incorporate inter-relationship of angular corrections. For instance, angularDeflection | ||
50 | and angularMotorUp will compute same X or Y correction. When added together | ||
51 | creates over-correction and over-shoot and wabbling. | ||
52 | 52 | ||
53 | BULLETSIM TODO LIST: | 53 | BULLETSIM TODO LIST: |
54 | ================================================= | 54 | ================================================= |
55 | Revisit CollisionMargin. Builders notice the 0.04 spacing between prims. | 55 | Revisit CollisionMargin. Builders notice the 0.04 spacing between prims. |
56 | Avatar height off after unsitting (floats off ground) | ||
57 | Editting appearance then moving restores. | ||
58 | Must not be initializing height when recreating capsule after unsit. | ||
59 | Duplicating a physical prim causes old prim to jump away | 56 | Duplicating a physical prim causes old prim to jump away |
60 | Dup a phys prim and the original become unselected and thus interacts w/ selected prim. | 57 | Dup a phys prim and the original become unselected and thus interacts w/ selected prim. |
61 | Scenes with hundred of thousands of static objects take a lot of physics CPU time. | 58 | Scenes with hundred of thousands of static objects take a lot of physics CPU time. |
@@ -82,6 +79,9 @@ Add osGetPhysicsEngineName() so scripters can tell whether BulletSim or ODE | |||
82 | Also osGetPhysicsEngineVerion() maybe. | 79 | Also osGetPhysicsEngineVerion() maybe. |
83 | Linkset.Position and Linkset.Orientation requre rewrite to properly return | 80 | Linkset.Position and Linkset.Orientation requre rewrite to properly return |
84 | child position. LinksetConstraint acts like it's at taint time!! | 81 | child position. LinksetConstraint acts like it's at taint time!! |
82 | Implement LockAngularMotion -- implements llSetStatus(ROTATE_AXIS_*, T/F) | ||
83 | Should the different PID factors have non-equal contributions for different | ||
84 | values of Efficiency? | ||
85 | 85 | ||
86 | LINKSETS | 86 | LINKSETS |
87 | ====================================================== | 87 | ====================================================== |
@@ -99,17 +99,16 @@ Disable activity of passive linkset children. | |||
99 | Since the linkset is a compound object, the old prims are left lying | 99 | Since the linkset is a compound object, the old prims are left lying |
100 | around and need to be phantomized so they don't collide, ... | 100 | around and need to be phantomized so they don't collide, ... |
101 | Speed up creation of large physical linksets | 101 | Speed up creation of large physical linksets |
102 | For instance, sitting in Neb's car (130 prims) takes several seconds to become physical | 102 | For instance, sitting in Neb's car (130 prims) takes several seconds to become physical. |
103 | REALLY bad for very large physical linksets (freezes the sim for many seconds). | ||
103 | Eliminate collisions between objects in a linkset. (LinksetConstraint) | 104 | Eliminate collisions between objects in a linkset. (LinksetConstraint) |
104 | Have UserPointer point to struct with localID and linksetID? | 105 | Have UserPointer point to struct with localID and linksetID? |
105 | Objects in original linkset still collide with each other? | 106 | Objects in original linkset still collide with each other? |
106 | 107 | ||
107 | MORE | 108 | MORE |
108 | ====================================================== | 109 | ====================================================== |
109 | Find/remove avatar collision with ID=0. | ||
110 | Test avatar walking up stairs. How does compare with SL. | 110 | Test avatar walking up stairs. How does compare with SL. |
111 | Radius of the capsule affects ability to climb edges. | 111 | Radius of the capsule affects ability to climb edges. |
112 | Tune terrain/object friction to be closer to SL. | ||
113 | Debounce avatar contact so legs don't keep folding up when standing. | 112 | Debounce avatar contact so legs don't keep folding up when standing. |
114 | Implement LSL physics controls. Like STATUS_ROTATE_X. | 113 | Implement LSL physics controls. Like STATUS_ROTATE_X. |
115 | Add border extensions to terrain to help region crossings and objects leaving region. | 114 | Add border extensions to terrain to help region crossings and objects leaving region. |
@@ -140,6 +139,8 @@ Consider moving prim/character body and shape destruction in destroy() | |||
140 | to postTimeTime rather than protecting all the potential sets that | 139 | to postTimeTime rather than protecting all the potential sets that |
141 | might have been queued up. | 140 | might have been queued up. |
142 | Remove unused fields from ShapeData (not used in API2) | 141 | Remove unused fields from ShapeData (not used in API2) |
142 | Remove unused fields from pinned memory shared parameter block | ||
143 | Create parameter variables in BSScene to replace same. | ||
143 | Breakout code for mesh/hull/compound/native into separate BSShape* classes | 144 | Breakout code for mesh/hull/compound/native into separate BSShape* classes |
144 | Standardize access to building and reference code. | 145 | Standardize access to building and reference code. |
145 | The skeleton classes are in the sources but are not complete or linked in. | 146 | The skeleton classes are in the sources but are not complete or linked in. |
@@ -202,3 +203,16 @@ Single prim vehicles don't seem to properly vehiclize. | |||
202 | Add material type linkage and input all the material property definitions. | 203 | Add material type linkage and input all the material property definitions. |
203 | Skeleton classes and table are in the sources but are not filled or used. | 204 | Skeleton classes and table are in the sources but are not filled or used. |
204 | (Resolution: | 205 | (Resolution: |
206 | Neb vehicle taking > 25ms of physics time!! | ||
207 | (Resolution: compound linksets were being rebuild WAY too often) | ||
208 | Avatar height off after unsitting (floats off ground) | ||
209 | Editting appearance then moving restores. | ||
210 | Must not be initializing height when recreating capsule after unsit. | ||
211 | (Resolution: confusion of scale vs size for native objects removed) | ||
212 | Light cycle falling over when driving (Resolution: implemented angularMotorUp) | ||
213 | Should vehicle angular/linear movement friction happen after all the components | ||
214 | or does it only apply to the basic movement? | ||
215 | (Resolution: friction added before returning newly computed motor value. | ||
216 | What is expected by some vehicles (turning up friction to moderate speed)) | ||
217 | Tune terrain/object friction to be closer to SL. | ||
218 | (Resolution: added material type with friction and resolution) | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 3a9d0ff..30bacc6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -1483,19 +1483,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1483 | return 0; | 1483 | return 0; |
1484 | 1484 | ||
1485 | case ScriptBaseClass.STATUS_ROTATE_X: | 1485 | case ScriptBaseClass.STATUS_ROTATE_X: |
1486 | if (m_host.GetAxisRotation(2) == 2) | 1486 | // if (m_host.GetAxisRotation(2) != 0) |
1487 | if (m_host.GetAxisRotation((int)SceneObjectGroup.axisSelect.STATUS_ROTATE_X) != 0) | ||
1487 | return 1; | 1488 | return 1; |
1488 | else | 1489 | else |
1489 | return 0; | 1490 | return 0; |
1490 | 1491 | ||
1491 | case ScriptBaseClass.STATUS_ROTATE_Y: | 1492 | case ScriptBaseClass.STATUS_ROTATE_Y: |
1492 | if (m_host.GetAxisRotation(4) == 4) | 1493 | if (m_host.GetAxisRotation((int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Y) != 0) |
1493 | return 1; | 1494 | return 1; |
1494 | else | 1495 | else |
1495 | return 0; | 1496 | return 0; |
1496 | 1497 | ||
1497 | case ScriptBaseClass.STATUS_ROTATE_Z: | 1498 | case ScriptBaseClass.STATUS_ROTATE_Z: |
1498 | if (m_host.GetAxisRotation(8) == 8) | 1499 | if (m_host.GetAxisRotation((int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Z) != 0) |
1499 | return 1; | 1500 | return 1; |
1500 | else | 1501 | else |
1501 | return 0; | 1502 | return 0; |