diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 92 |
1 files changed, 69 insertions, 23 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index fc18960..9c3f160 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -61,18 +61,31 @@ public sealed class BSCharacter : BSPhysObject | |||
61 | private const string AvatarMoveActorName = "BSCharacter.AvatarMove"; | 61 | private const string AvatarMoveActorName = "BSCharacter.AvatarMove"; |
62 | 62 | ||
63 | private OMV.Vector3 _PIDTarget; | 63 | private OMV.Vector3 _PIDTarget; |
64 | private bool _usePID; | ||
65 | private float _PIDTau; | 64 | private float _PIDTau; |
66 | 65 | ||
67 | public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying) | 66 | // public override OMV.Vector3 RawVelocity |
67 | // { get { return base.RawVelocity; } | ||
68 | // set { | ||
69 | // if (value != base.RawVelocity) | ||
70 | // Util.PrintCallStack(); | ||
71 | // Console.WriteLine("Set rawvel to {0}", value); | ||
72 | // base.RawVelocity = value; } | ||
73 | // } | ||
74 | |||
75 | // Avatars are always complete (in the physics engine sense) | ||
76 | public override bool IsIncomplete { get { return false; } } | ||
77 | |||
78 | public BSCharacter( | ||
79 | uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 vel, OMV.Vector3 size, bool isFlying) | ||
80 | |||
68 | : base(parent_scene, localID, avName, "BSCharacter") | 81 | : base(parent_scene, localID, avName, "BSCharacter") |
69 | { | 82 | { |
70 | _physicsActorType = (int)ActorTypes.Agent; | 83 | _physicsActorType = (int)ActorTypes.Agent; |
71 | RawPosition = pos; | 84 | RawPosition = pos; |
72 | 85 | ||
73 | _flying = isFlying; | 86 | _flying = isFlying; |
74 | RawOrientation = OMV.Quaternion.Identity; | 87 | RawOrientation = OMV.Quaternion.Identity; |
75 | RawVelocity = OMV.Vector3.Zero; | 88 | RawVelocity = vel; |
76 | _buoyancy = ComputeBuoyancyFromFlying(isFlying); | 89 | _buoyancy = ComputeBuoyancyFromFlying(isFlying); |
77 | Friction = BSParam.AvatarStandingFriction; | 90 | Friction = BSParam.AvatarStandingFriction; |
78 | Density = BSParam.AvatarDensity; | 91 | Density = BSParam.AvatarDensity; |
@@ -89,13 +102,15 @@ public sealed class BSCharacter : BSPhysObject | |||
89 | // set _avatarVolume and _mass based on capsule size, _density and Scale | 102 | // set _avatarVolume and _mass based on capsule size, _density and Scale |
90 | ComputeAvatarVolumeAndMass(); | 103 | ComputeAvatarVolumeAndMass(); |
91 | 104 | ||
92 | DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5},pos={6}", | 105 | DetailLog( |
93 | LocalID, _size, Scale, Density, _avatarVolume, RawMass, pos); | 106 | "{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5},pos={6},vel={7}", |
107 | LocalID, _size, Scale, Density, _avatarVolume, RawMass, pos, vel); | ||
94 | 108 | ||
95 | // do actual creation in taint time | 109 | // do actual creation in taint time |
96 | PhysScene.TaintedObject(LocalID, "BSCharacter.create", delegate() | 110 | PhysScene.TaintedObject(LocalID, "BSCharacter.create", delegate() |
97 | { | 111 | { |
98 | DetailLog("{0},BSCharacter.create,taint", LocalID); | 112 | DetailLog("{0},BSCharacter.create,taint", LocalID); |
113 | |||
99 | // New body and shape into PhysBody and PhysShape | 114 | // New body and shape into PhysBody and PhysShape |
100 | PhysScene.Shapes.GetBodyAndShape(true, PhysScene.World, this); | 115 | PhysScene.Shapes.GetBodyAndShape(true, PhysScene.World, this); |
101 | 116 | ||
@@ -134,7 +149,6 @@ public sealed class BSCharacter : BSPhysObject | |||
134 | { | 149 | { |
135 | PhysScene.PE.RemoveObjectFromWorld(PhysScene.World, PhysBody); | 150 | PhysScene.PE.RemoveObjectFromWorld(PhysScene.World, PhysBody); |
136 | 151 | ||
137 | ZeroMotion(true); | ||
138 | ForcePosition = RawPosition; | 152 | ForcePosition = RawPosition; |
139 | 153 | ||
140 | // Set the velocity | 154 | // Set the velocity |
@@ -142,6 +156,7 @@ public sealed class BSCharacter : BSPhysObject | |||
142 | m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, false); | 156 | m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, false); |
143 | 157 | ||
144 | ForceVelocity = RawVelocity; | 158 | ForceVelocity = RawVelocity; |
159 | TargetVelocity = RawVelocity; | ||
145 | 160 | ||
146 | // This will enable or disable the flying buoyancy of the avatar. | 161 | // This will enable or disable the flying buoyancy of the avatar. |
147 | // Needs to be reset especially when an avatar is recreated after crossing a region boundry. | 162 | // Needs to be reset especially when an avatar is recreated after crossing a region boundry. |
@@ -174,15 +189,19 @@ public sealed class BSCharacter : BSPhysObject | |||
174 | PhysScene.PE.UpdateSingleAabb(PhysScene.World, PhysBody); | 189 | PhysScene.PE.UpdateSingleAabb(PhysScene.World, PhysBody); |
175 | 190 | ||
176 | // Do this after the object has been added to the world | 191 | // Do this after the object has been added to the world |
177 | PhysBody.collisionType = CollisionType.Avatar; | 192 | if (BSParam.AvatarToAvatarCollisionsByDefault) |
193 | PhysBody.collisionType = CollisionType.Avatar; | ||
194 | else | ||
195 | PhysBody.collisionType = CollisionType.PhantomToOthersAvatar; | ||
196 | |||
178 | PhysBody.ApplyCollisionMask(PhysScene); | 197 | PhysBody.ApplyCollisionMask(PhysScene); |
179 | } | 198 | } |
180 | 199 | ||
181 | |||
182 | public override void RequestPhysicsterseUpdate() | 200 | public override void RequestPhysicsterseUpdate() |
183 | { | 201 | { |
184 | base.RequestPhysicsterseUpdate(); | 202 | base.RequestPhysicsterseUpdate(); |
185 | } | 203 | } |
204 | |||
186 | // No one calls this method so I don't know what it could possibly mean | 205 | // No one calls this method so I don't know what it could possibly mean |
187 | public override bool Stopped { get { return false; } } | 206 | public override bool Stopped { get { return false; } } |
188 | 207 | ||
@@ -263,6 +282,7 @@ public sealed class BSCharacter : BSPhysObject | |||
263 | PhysScene.PE.ClearAllForces(PhysBody); | 282 | PhysScene.PE.ClearAllForces(PhysBody); |
264 | }); | 283 | }); |
265 | } | 284 | } |
285 | |||
266 | public override void ZeroAngularMotion(bool inTaintTime) | 286 | public override void ZeroAngularMotion(bool inTaintTime) |
267 | { | 287 | { |
268 | _rotationalVelocity = OMV.Vector3.Zero; | 288 | _rotationalVelocity = OMV.Vector3.Zero; |
@@ -426,7 +446,7 @@ public sealed class BSCharacter : BSPhysObject | |||
426 | m_targetVelocity = value; | 446 | m_targetVelocity = value; |
427 | OMV.Vector3 targetVel = value; | 447 | OMV.Vector3 targetVel = value; |
428 | if (_setAlwaysRun && !_flying) | 448 | if (_setAlwaysRun && !_flying) |
429 | targetVel *= new OMV.Vector3(BSParam.AvatarAlwaysRunFactor, BSParam.AvatarAlwaysRunFactor, 0f); | 449 | targetVel *= new OMV.Vector3(BSParam.AvatarAlwaysRunFactor, BSParam.AvatarAlwaysRunFactor, 1f); |
430 | 450 | ||
431 | if (m_moveActor != null) | 451 | if (m_moveActor != null) |
432 | m_moveActor.SetVelocityAndTarget(RawVelocity, targetVel, false /* inTaintTime */); | 452 | m_moveActor.SetVelocityAndTarget(RawVelocity, targetVel, false /* inTaintTime */); |
@@ -437,32 +457,40 @@ public sealed class BSCharacter : BSPhysObject | |||
437 | get { return RawVelocity; } | 457 | get { return RawVelocity; } |
438 | set { | 458 | set { |
439 | RawVelocity = value; | 459 | RawVelocity = value; |
440 | // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, RawVelocity); | 460 | OMV.Vector3 vel = RawVelocity; |
461 | |||
462 | DetailLog("{0}: set Velocity = {1}", LocalID, value); | ||
463 | |||
441 | PhysScene.TaintedObject(LocalID, "BSCharacter.setVelocity", delegate() | 464 | PhysScene.TaintedObject(LocalID, "BSCharacter.setVelocity", delegate() |
442 | { | 465 | { |
443 | if (m_moveActor != null) | 466 | if (m_moveActor != null) |
444 | m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, true /* inTaintTime */); | 467 | m_moveActor.SetVelocityAndTarget(vel, vel, true /* inTaintTime */); |
445 | 468 | ||
446 | DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, RawVelocity); | 469 | DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, vel); |
447 | ForceVelocity = RawVelocity; | 470 | ForceVelocity = vel; |
448 | }); | 471 | }); |
449 | } | 472 | } |
450 | } | 473 | } |
474 | |||
451 | public override OMV.Vector3 ForceVelocity { | 475 | public override OMV.Vector3 ForceVelocity { |
452 | get { return RawVelocity; } | 476 | get { return RawVelocity; } |
453 | set { | 477 | set { |
454 | PhysScene.AssertInTaintTime("BSCharacter.ForceVelocity"); | 478 | PhysScene.AssertInTaintTime("BSCharacter.ForceVelocity"); |
479 | // Util.PrintCallStack(); | ||
480 | DetailLog("{0}: set ForceVelocity = {1}", LocalID, value); | ||
455 | 481 | ||
456 | RawVelocity = value; | 482 | RawVelocity = value; |
457 | PhysScene.PE.SetLinearVelocity(PhysBody, RawVelocity); | 483 | PhysScene.PE.SetLinearVelocity(PhysBody, RawVelocity); |
458 | PhysScene.PE.Activate(PhysBody, true); | 484 | PhysScene.PE.Activate(PhysBody, true); |
459 | } | 485 | } |
460 | } | 486 | } |
487 | |||
461 | public override OMV.Vector3 Torque { | 488 | public override OMV.Vector3 Torque { |
462 | get { return RawTorque; } | 489 | get { return RawTorque; } |
463 | set { RawTorque = value; | 490 | set { RawTorque = value; |
464 | } | 491 | } |
465 | } | 492 | } |
493 | |||
466 | public override float CollisionScore { | 494 | public override float CollisionScore { |
467 | get { return _collisionScore; } | 495 | get { return _collisionScore; } |
468 | set { _collisionScore = value; | 496 | set { _collisionScore = value; |
@@ -614,9 +642,9 @@ public sealed class BSCharacter : BSPhysObject | |||
614 | public override OMV.Vector3 PIDTarget { | 642 | public override OMV.Vector3 PIDTarget { |
615 | set { _PIDTarget = value; } | 643 | set { _PIDTarget = value; } |
616 | } | 644 | } |
617 | public override bool PIDActive { | 645 | |
618 | set { _usePID = value; } | 646 | public override bool PIDActive { get; set; } |
619 | } | 647 | |
620 | public override float PIDTau { | 648 | public override float PIDTau { |
621 | set { _PIDTau = value; } | 649 | set { _PIDTau = value; } |
622 | } | 650 | } |
@@ -657,7 +685,7 @@ public sealed class BSCharacter : BSPhysObject | |||
657 | 685 | ||
658 | private OMV.Vector3 ComputeAvatarScale(OMV.Vector3 size) | 686 | private OMV.Vector3 ComputeAvatarScale(OMV.Vector3 size) |
659 | { | 687 | { |
660 | OMV.Vector3 newScale; | 688 | OMV.Vector3 newScale = size; |
661 | 689 | ||
662 | // Bullet's capsule total height is the "passed height + radius * 2"; | 690 | // Bullet's capsule total height is the "passed height + radius * 2"; |
663 | // The base capsule is 1 unit in diameter and 2 units in height (passed radius=0.5, passed height = 1) | 691 | // The base capsule is 1 unit in diameter and 2 units in height (passed radius=0.5, passed height = 1) |
@@ -670,8 +698,6 @@ public sealed class BSCharacter : BSPhysObject | |||
670 | // for a asymmetrical capsule, other parts of the code presume it is cylindrical. | 698 | // for a asymmetrical capsule, other parts of the code presume it is cylindrical. |
671 | 699 | ||
672 | // Scale is multiplier of radius with one of "0.5" | 700 | // Scale is multiplier of radius with one of "0.5" |
673 | newScale.X = size.X / 2f; | ||
674 | newScale.Y = size.Y / 2f; | ||
675 | 701 | ||
676 | float heightAdjust = BSParam.AvatarHeightMidFudge; | 702 | float heightAdjust = BSParam.AvatarHeightMidFudge; |
677 | if (BSParam.AvatarHeightLowFudge != 0f || BSParam.AvatarHeightHighFudge != 0f) | 703 | if (BSParam.AvatarHeightLowFudge != 0f || BSParam.AvatarHeightHighFudge != 0f) |
@@ -692,8 +718,17 @@ public sealed class BSCharacter : BSPhysObject | |||
692 | heightAdjust += ((midHeightOffset) / (AVATAR_HI - AVATAR_MID)) * BSParam.AvatarHeightHighFudge; | 718 | heightAdjust += ((midHeightOffset) / (AVATAR_HI - AVATAR_MID)) * BSParam.AvatarHeightHighFudge; |
693 | } | 719 | } |
694 | } | 720 | } |
695 | // The total scale height is the central cylindar plus the caps on the two ends. | 721 | if (BSParam.AvatarShape == BSShapeCollection.AvatarShapeCapsule) |
696 | newScale.Z = (size.Z + (Math.Min(size.X, size.Y) * 2) + heightAdjust) / 2f; | 722 | { |
723 | newScale.X = size.X / 2f; | ||
724 | newScale.Y = size.Y / 2f; | ||
725 | // The total scale height is the central cylindar plus the caps on the two ends. | ||
726 | newScale.Z = (size.Z + (Math.Min(size.X, size.Y) * 2) + heightAdjust) / 2f; | ||
727 | } | ||
728 | else | ||
729 | { | ||
730 | newScale.Z = size.Z + heightAdjust; | ||
731 | } | ||
697 | // m_log.DebugFormat("{0} ComputeAvatarScale: size={1},adj={2},scale={3}", LogHeader, size, heightAdjust, newScale); | 732 | // m_log.DebugFormat("{0} ComputeAvatarScale: size={1},adj={2},scale={3}", LogHeader, size, heightAdjust, newScale); |
698 | 733 | ||
699 | // If smaller than the endcaps, just fake like we're almost that small | 734 | // If smaller than the endcaps, just fake like we're almost that small |
@@ -737,7 +772,18 @@ public sealed class BSCharacter : BSPhysObject | |||
737 | // and will send agent updates to the clients if velocity changes by more than | 772 | // and will send agent updates to the clients if velocity changes by more than |
738 | // 0.001m/s. Bullet introduces a lot of jitter in the velocity which causes many | 773 | // 0.001m/s. Bullet introduces a lot of jitter in the velocity which causes many |
739 | // extra updates. | 774 | // extra updates. |
740 | if (!entprop.Velocity.ApproxEquals(RawVelocity, 0.1f)) | 775 | // |
776 | // XXX: Contrary to the above comment, setting an update threshold here above 0.4 actually introduces jitter to | ||
777 | // avatar movement rather than removes it. The larger the threshold, the bigger the jitter. | ||
778 | // This is most noticeable in level flight and can be seen with | ||
779 | // the "show updates" option in a viewer. With an update threshold, the RawVelocity cycles between a lower | ||
780 | // bound and an upper bound, where the difference between the two is enough to trigger a large delta v update | ||
781 | // and subsequently trigger an update in ScenePresence.SendTerseUpdateToAllClients(). The cause of this cycle (feedback?) | ||
782 | // has not yet been identified. | ||
783 | // | ||
784 | // If there is a threshold below 0.4 or no threshold check at all (as in ODE), then RawVelocity stays constant and extra | ||
785 | // updates are not triggered in ScenePresence.SendTerseUpdateToAllClients(). | ||
786 | // if (!entprop.Velocity.ApproxEquals(RawVelocity, 0.1f)) | ||
741 | RawVelocity = entprop.Velocity; | 787 | RawVelocity = entprop.Velocity; |
742 | 788 | ||
743 | _acceleration = entprop.Acceleration; | 789 | _acceleration = entprop.Acceleration; |