aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs182
1 files changed, 133 insertions, 49 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 2e6b2da..7c2f856 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -41,8 +41,6 @@ public class BSCharacter : BSPhysObject
41 41
42 // private bool _stopped; 42 // private bool _stopped;
43 private OMV.Vector3 _size; 43 private OMV.Vector3 _size;
44 private OMV.Vector3 _scale;
45 private PrimitiveBaseShape _pbs;
46 private bool _grabbed; 44 private bool _grabbed;
47 private bool _selected; 45 private bool _selected;
48 private OMV.Vector3 _position; 46 private OMV.Vector3 _position;
@@ -67,6 +65,10 @@ public class BSCharacter : BSPhysObject
67 private bool _kinematic; 65 private bool _kinematic;
68 private float _buoyancy; 66 private float _buoyancy;
69 67
68 // The friction and velocity of the avatar is modified depending on whether walking or not.
69 private OMV.Vector3 _appliedVelocity; // the last velocity applied to the avatar
70 private float _currentFriction; // the friction currently being used (changed by setVelocity).
71
70 private OMV.Vector3 _PIDTarget; 72 private OMV.Vector3 _PIDTarget;
71 private bool _usePID; 73 private bool _usePID;
72 private float _PIDTau; 74 private float _PIDTau;
@@ -84,13 +86,15 @@ public class BSCharacter : BSPhysObject
84 _flying = isFlying; 86 _flying = isFlying;
85 _orientation = OMV.Quaternion.Identity; 87 _orientation = OMV.Quaternion.Identity;
86 _velocity = OMV.Vector3.Zero; 88 _velocity = OMV.Vector3.Zero;
89 _appliedVelocity = OMV.Vector3.Zero;
87 _buoyancy = ComputeBuoyancyFromFlying(isFlying); 90 _buoyancy = ComputeBuoyancyFromFlying(isFlying);
91 _currentFriction = PhysicsScene.Params.avatarStandingFriction;
88 92
89 // The dimensions of the avatar capsule are kept in the scale. 93 // The dimensions of the avatar capsule are kept in the scale.
90 // Physics creates a unit capsule which is scaled by the physics engine. 94 // Physics creates a unit capsule which is scaled by the physics engine.
91 ComputeAvatarScale(_size); 95 ComputeAvatarScale(_size);
92 _avatarDensity = PhysicsScene.Params.avatarDensity; 96 _avatarDensity = PhysicsScene.Params.avatarDensity;
93 // set _avatarVolume and _mass based on capsule size, _density and _scale 97 // set _avatarVolume and _mass based on capsule size, _density and Scale
94 ComputeAvatarVolumeAndMass(); 98 ComputeAvatarVolumeAndMass();
95 99
96 ShapeData shapeData = new ShapeData(); 100 ShapeData shapeData = new ShapeData();
@@ -99,24 +103,24 @@ public class BSCharacter : BSPhysObject
99 shapeData.Position = _position; 103 shapeData.Position = _position;
100 shapeData.Rotation = _orientation; 104 shapeData.Rotation = _orientation;
101 shapeData.Velocity = _velocity; 105 shapeData.Velocity = _velocity;
102 shapeData.Scale = _scale; 106 shapeData.Scale = Scale;
103 shapeData.Mass = _mass; 107 shapeData.Mass = _mass;
104 shapeData.Buoyancy = _buoyancy; 108 shapeData.Buoyancy = _buoyancy;
105 shapeData.Static = ShapeData.numericFalse; 109 shapeData.Static = ShapeData.numericFalse;
106 shapeData.Friction = PhysicsScene.Params.avatarFriction; 110 shapeData.Friction = PhysicsScene.Params.avatarStandingFriction;
107 shapeData.Restitution = PhysicsScene.Params.avatarRestitution; 111 shapeData.Restitution = PhysicsScene.Params.avatarRestitution;
108 112
109 // do actual create at taint time 113 // do actual create at taint time
110 PhysicsScene.TaintedObject("BSCharacter.create", delegate() 114 PhysicsScene.TaintedObject("BSCharacter.create", delegate()
111 { 115 {
112 DetailLog("{0},BSCharacter.create,taint", LocalID); 116 DetailLog("{0},BSCharacter.create,taint", LocalID);
113 BulletSimAPI.CreateObject(PhysicsScene.WorldID, shapeData); 117 PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this, shapeData, null, null, null);
118
119 SetPhysicalProperties();
114 120
115 // Set the buoyancy for flying. This will be refactored when all the settings happen in C#. 121 // Set the buoyancy for flying. This will be refactored when all the settings happen in C#.
116 // If not set at creation, the avatar will stop flying when created after crossing a region boundry. 122 // If not set at creation, the avatar will stop flying when created after crossing a region boundry.
117 BulletSimAPI.SetObjectBuoyancy(PhysicsScene.WorldID, LocalID, _buoyancy); 123 ForceBuoyancy = _buoyancy;
118
119 BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(PhysicsScene.World.ptr, LocalID));
120 124
121 // This works here because CreateObject has already put the character into the physical world. 125 // This works here because CreateObject has already put the character into the physical world.
122 BulletSimAPI.SetCollisionFilterMask2(BSBody.ptr, 126 BulletSimAPI.SetCollisionFilterMask2(BSBody.ptr,
@@ -131,10 +135,40 @@ public class BSCharacter : BSPhysObject
131 DetailLog("{0},BSCharacter.Destroy", LocalID); 135 DetailLog("{0},BSCharacter.Destroy", LocalID);
132 PhysicsScene.TaintedObject("BSCharacter.destroy", delegate() 136 PhysicsScene.TaintedObject("BSCharacter.destroy", delegate()
133 { 137 {
134 BulletSimAPI.DestroyObject(PhysicsScene.WorldID, LocalID); 138 PhysicsScene.Shapes.DereferenceBody(BSBody, true, null);
139 PhysicsScene.Shapes.DereferenceShape(BSShape, true, null);
135 }); 140 });
136 } 141 }
137 142
143 private void SetPhysicalProperties()
144 {
145 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, BSBody.ptr);
146
147 ZeroMotion();
148
149 OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSBody.ptr, MassRaw);
150 BulletSimAPI.SetMassProps2(BSBody.ptr, MassRaw, localInertia);
151
152 // Set the velocity and compute the proper friction
153 ForceVelocity = _velocity;
154
155 BulletSimAPI.SetFriction2(BSBody.ptr, _currentFriction);
156 BulletSimAPI.SetRestitution2(BSBody.ptr, PhysicsScene.Params.avatarRestitution);
157
158 BulletSimAPI.SetLocalScaling2(BSShape.ptr, Scale);
159 BulletSimAPI.SetContactProcessingThreshold2(BSBody.ptr, PhysicsScene.Params.contactProcessingThreshold);
160
161 if (PhysicsScene.Params.ccdMotionThreshold > 0f)
162 {
163 BulletSimAPI.SetCcdMotionThreshold2(BSBody.ptr, PhysicsScene.Params.ccdMotionThreshold);
164 BulletSimAPI.SetCcdSweepSphereRadius2(BSBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius);
165 }
166
167 BulletSimAPI.SetActivationState2(BSBody.ptr, (int)ActivationState.DISABLE_DEACTIVATION);
168
169 BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, BSBody.ptr);
170 }
171
138 public override void RequestPhysicsterseUpdate() 172 public override void RequestPhysicsterseUpdate()
139 { 173 {
140 base.RequestPhysicsterseUpdate(); 174 base.RequestPhysicsterseUpdate();
@@ -147,7 +181,7 @@ public class BSCharacter : BSPhysObject
147 get 181 get
148 { 182 {
149 // Avatar capsule size is kept in the scale parameter. 183 // Avatar capsule size is kept in the scale parameter.
150 return new OMV.Vector3(_scale.X * 2, _scale.Y * 2, _scale.Z); 184 return new OMV.Vector3(Scale.X * 2, Scale.Y * 2, Scale.Z);
151 } 185 }
152 186
153 set { 187 set {
@@ -162,22 +196,25 @@ public class BSCharacter : BSPhysObject
162 196
163 PhysicsScene.TaintedObject("BSCharacter.setSize", delegate() 197 PhysicsScene.TaintedObject("BSCharacter.setSize", delegate()
164 { 198 {
165 BulletSimAPI.SetObjectScaleMass(PhysicsScene.WorldID, LocalID, _scale, _mass, true); 199 BulletSimAPI.SetLocalScaling2(BSBody.ptr, Scale);
200 OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSBody.ptr, MassRaw);
201 BulletSimAPI.SetMassProps2(BSBody.ptr, MassRaw, localInertia);
166 }); 202 });
167 203
168 } 204 }
169 } 205 }
170 public override PrimitiveBaseShape Shape { 206 public override OMV.Vector3 Scale { get; set; }
171 set { _pbs = value; 207 private PrimitiveBaseShape _pbs;
172 } 208 public override PrimitiveBaseShape Shape
209 {
210 set { _pbs = value;}
173 } 211 }
212
174 public override bool Grabbed { 213 public override bool Grabbed {
175 set { _grabbed = value; 214 set { _grabbed = value; }
176 }
177 } 215 }
178 public override bool Selected { 216 public override bool Selected {
179 set { _selected = value; 217 set { _selected = value; }
180 }
181 } 218 }
182 public override void CrossingFailure() { return; } 219 public override void CrossingFailure() { return; }
183 public override void link(PhysicsActor obj) { return; } 220 public override void link(PhysicsActor obj) { return; }
@@ -204,7 +241,7 @@ public class BSCharacter : BSPhysObject
204 241
205 public override OMV.Vector3 Position { 242 public override OMV.Vector3 Position {
206 get { 243 get {
207 // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID); 244 // _position = BulletSimAPI.GetObjectPosition2(Scene.World.ptr, LocalID);
208 return _position; 245 return _position;
209 } 246 }
210 set { 247 set {
@@ -214,7 +251,7 @@ public class BSCharacter : BSPhysObject
214 PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate() 251 PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate()
215 { 252 {
216 DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); 253 DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
217 BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, LocalID, _position, _orientation); 254 BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation);
218 }); 255 });
219 } 256 }
220 } 257 }
@@ -273,7 +310,7 @@ public class BSCharacter : BSPhysObject
273 BSScene.TaintCallback sanityOperation = delegate() 310 BSScene.TaintCallback sanityOperation = delegate()
274 { 311 {
275 DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); 312 DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation);
276 BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, LocalID, _position, _orientation); 313 BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation);
277 }; 314 };
278 if (inTaintTime) 315 if (inTaintTime)
279 sanityOperation(); 316 sanityOperation();
@@ -284,11 +321,7 @@ public class BSCharacter : BSPhysObject
284 return ret; 321 return ret;
285 } 322 }
286 323
287 public override float Mass { 324 public override float Mass { get { return _mass; } }
288 get {
289 return _mass;
290 }
291 }
292 325
293 // used when we only want this prim's mass and not the linkset thing 326 // used when we only want this prim's mass and not the linkset thing
294 public override float MassRaw { get {return _mass; } } 327 public override float MassRaw { get {return _mass; } }
@@ -301,15 +334,13 @@ public class BSCharacter : BSPhysObject
301 PhysicsScene.TaintedObject("BSCharacter.SetForce", delegate() 334 PhysicsScene.TaintedObject("BSCharacter.SetForce", delegate()
302 { 335 {
303 DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force); 336 DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force);
304 BulletSimAPI.SetObjectForce(PhysicsScene.WorldID, LocalID, _force); 337 BulletSimAPI.SetObjectForce2(BSBody.ptr, _force);
305 }); 338 });
306 } 339 }
307 } 340 }
308 341
309 public override int VehicleType { 342 // Avatars don't do vehicles
310 get { return 0; } 343 public override int VehicleType { get { return 0; } set { return; } }
311 set { return; }
312 }
313 public override void VehicleFloatParam(int param, float value) { } 344 public override void VehicleFloatParam(int param, float value) { }
314 public override void VehicleVectorParam(int param, OMV.Vector3 value) {} 345 public override void VehicleVectorParam(int param, OMV.Vector3 value) {}
315 public override void VehicleRotationParam(int param, OMV.Quaternion rotation) { } 346 public override void VehicleRotationParam(int param, OMV.Quaternion rotation) { }
@@ -328,15 +359,35 @@ public class BSCharacter : BSPhysObject
328 PhysicsScene.TaintedObject("BSCharacter.setVelocity", delegate() 359 PhysicsScene.TaintedObject("BSCharacter.setVelocity", delegate()
329 { 360 {
330 DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity); 361 DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity);
331 BulletSimAPI.SetObjectVelocity(PhysicsScene.WorldID, LocalID, _velocity); 362 ForceVelocity = _velocity;
332 }); 363 });
333 } 364 }
334 } 365 }
335 public override OMV.Vector3 ForceVelocity { 366 public override OMV.Vector3 ForceVelocity {
336 get { return _velocity; } 367 get { return _velocity; }
337 set { 368 set {
369 // Depending on whether the avatar is moving or not, change the friction
370 // to keep the avatar from slipping around
371 if (_velocity.Length() == 0)
372 {
373 if (_currentFriction != PhysicsScene.Params.avatarStandingFriction)
374 {
375 _currentFriction = PhysicsScene.Params.avatarStandingFriction;
376 BulletSimAPI.SetFriction2(BSBody.ptr, _currentFriction);
377 }
378 }
379 else
380 {
381 if (_currentFriction == 999f)
382 {
383 _currentFriction = PhysicsScene.Params.avatarFriction;
384 BulletSimAPI.SetFriction2(BSBody.ptr, _currentFriction);
385 }
386 }
338 _velocity = value; 387 _velocity = value;
339 BulletSimAPI.SetObjectVelocity(PhysicsScene.WorldID, LocalID, _velocity); 388 _appliedVelocity = value;
389 BulletSimAPI.SetLinearVelocity2(BSBody.ptr, _velocity);
390 BulletSimAPI.Activate2(BSBody.ptr, true);
340 } 391 }
341 } 392 }
342 public override OMV.Vector3 Torque { 393 public override OMV.Vector3 Torque {
@@ -360,8 +411,8 @@ public class BSCharacter : BSPhysObject
360 // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation); 411 // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation);
361 PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate() 412 PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate()
362 { 413 {
363 // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID); 414 // _position = BulletSimAPI.GetPosition2(BSBody.ptr);
364 BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, LocalID, _position, _orientation); 415 BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation);
365 }); 416 });
366 } 417 }
367 } 418 }
@@ -389,12 +440,18 @@ public class BSCharacter : BSPhysObject
389 set { _isPhysical = value; 440 set { _isPhysical = value;
390 } 441 }
391 } 442 }
443 public override bool IsSolid {
444 get { return true; }
445 }
446 public override bool IsStatic {
447 get { return false; }
448 }
392 public override bool Flying { 449 public override bool Flying {
393 get { return _flying; } 450 get { return _flying; }
394 set { 451 set {
395 _flying = value; 452 _flying = value;
396 // simulate flying by changing the effect of gravity 453 // simulate flying by changing the effect of gravity
397 this.Buoyancy = ComputeBuoyancyFromFlying(_flying); 454 Buoyancy = ComputeBuoyancyFromFlying(_flying);
398 } 455 }
399 } 456 }
400 // Flying is implimented by changing the avatar's buoyancy. 457 // Flying is implimented by changing the avatar's buoyancy.
@@ -454,10 +511,19 @@ public class BSCharacter : BSPhysObject
454 PhysicsScene.TaintedObject("BSCharacter.setBuoyancy", delegate() 511 PhysicsScene.TaintedObject("BSCharacter.setBuoyancy", delegate()
455 { 512 {
456 DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 513 DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
457 BulletSimAPI.SetObjectBuoyancy(PhysicsScene.WorldID, LocalID, _buoyancy); 514 ForceBuoyancy = _buoyancy;
458 }); 515 });
459 } 516 }
460 } 517 }
518 public override float ForceBuoyancy {
519 get { return _buoyancy; }
520 set { _buoyancy = value;
521 DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
522 // Buoyancy is faked by changing the gravity applied to the object
523 float grav = PhysicsScene.Params.gravity * (1f - _buoyancy);
524 BulletSimAPI.SetGravity2(BSBody.ptr, new OMV.Vector3(0f, 0f, grav));
525 }
526 }
461 527
462 // Used for MoveTo 528 // Used for MoveTo
463 public override OMV.Vector3 PIDTarget { 529 public override OMV.Vector3 PIDTarget {
@@ -518,27 +584,29 @@ public class BSCharacter : BSPhysObject
518 584
519 private void ComputeAvatarScale(OMV.Vector3 size) 585 private void ComputeAvatarScale(OMV.Vector3 size)
520 { 586 {
521 _scale.X = PhysicsScene.Params.avatarCapsuleRadius; 587 OMV.Vector3 newScale = OMV.Vector3.Zero;
522 _scale.Y = PhysicsScene.Params.avatarCapsuleRadius; 588 newScale.X = PhysicsScene.Params.avatarCapsuleRadius;
589 newScale.Y = PhysicsScene.Params.avatarCapsuleRadius;
523 590
524 // The 1.15 came from ODE but it seems to cause the avatar to float off the ground 591 // The 1.15 came from ODE but it seems to cause the avatar to float off the ground
525 // _scale.Z = (_size.Z * 1.15f) - (_scale.X + _scale.Y); 592 // Scale.Z = (_size.Z * 1.15f) - (Scale.X + Scale.Y);
526 _scale.Z = (_size.Z) - (_scale.X + _scale.Y); 593 newScale.Z = (_size.Z) - (Scale.X + Scale.Y);
594 Scale = newScale;
527 } 595 }
528 596
529 // set _avatarVolume and _mass based on capsule size, _density and _scale 597 // set _avatarVolume and _mass based on capsule size, _density and Scale
530 private void ComputeAvatarVolumeAndMass() 598 private void ComputeAvatarVolumeAndMass()
531 { 599 {
532 _avatarVolume = (float)( 600 _avatarVolume = (float)(
533 Math.PI 601 Math.PI
534 * _scale.X 602 * Scale.X
535 * _scale.Y // the area of capsule cylinder 603 * Scale.Y // the area of capsule cylinder
536 * _scale.Z // times height of capsule cylinder 604 * Scale.Z // times height of capsule cylinder
537 + 1.33333333f 605 + 1.33333333f
538 * Math.PI 606 * Math.PI
539 * _scale.X 607 * Scale.X
540 * Math.Min(_scale.X, _scale.Y) 608 * Math.Min(Scale.X, Scale.Y)
541 * _scale.Y // plus the volume of the capsule end caps 609 * Scale.Y // plus the volume of the capsule end caps
542 ); 610 );
543 _mass = _avatarDensity * _avatarVolume; 611 _mass = _avatarDensity * _avatarVolume;
544 } 612 }
@@ -555,6 +623,22 @@ public class BSCharacter : BSPhysObject
555 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. 623 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
556 PositionSanityCheck2(true); 624 PositionSanityCheck2(true);
557 625
626 // remember the current and last set values
627 LastEntityProperties = CurrentEntityProperties;
628 CurrentEntityProperties = entprop;
629
630 if (entprop.Velocity != LastEntityProperties.Velocity)
631 {
632 // Changes in the velocity are suppressed in avatars.
633 // That's just the way they are defined.
634 OMV.Vector3 avVel = new OMV.Vector3(_appliedVelocity.X, _appliedVelocity.Y, entprop.Velocity.Z);
635 _velocity = avVel;
636 BulletSimAPI.SetLinearVelocity2(BSBody.ptr, avVel);
637 }
638
639 // Tell the linkset about this
640 Linkset.UpdateProperties(this);
641
558 // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. 642 // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
559 // base.RequestPhysicsterseUpdate(); 643 // base.RequestPhysicsterseUpdate();
560 644