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.cs166
1 files changed, 99 insertions, 67 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index e2f7af9..526dbad 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -34,13 +34,12 @@ using OpenSim.Region.Physics.Manager;
34 34
35namespace OpenSim.Region.Physics.BulletSPlugin 35namespace OpenSim.Region.Physics.BulletSPlugin
36{ 36{
37public class BSCharacter : PhysicsActor 37public class BSCharacter : BSPhysObject
38{ 38{
39 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 39 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
40 private static readonly string LogHeader = "[BULLETS CHAR]"; 40 private static readonly string LogHeader = "[BULLETS CHAR]";
41 41
42 private BSScene _scene; 42 public BSScene Scene { get; private set; }
43 public BSScene Scene { get { return _scene; } }
44 private String _avName; 43 private String _avName;
45 // private bool _stopped; 44 // private bool _stopped;
46 private Vector3 _size; 45 private Vector3 _size;
@@ -74,11 +73,9 @@ public class BSCharacter : PhysicsActor
74 private bool _kinematic; 73 private bool _kinematic;
75 private float _buoyancy; 74 private float _buoyancy;
76 75
77 private BulletBody m_body; 76 public override BulletBody BSBody { get; set; }
78 public BulletBody Body { 77 public override BulletShape BSShape { get; set; }
79 get { return m_body; } 78 public override BSLinkset Linkset { get; set; }
80 set { m_body = value; }
81 }
82 79
83 private int _subscribedEventsMs = 0; 80 private int _subscribedEventsMs = 0;
84 private int _nextCollisionOkTime = 0; 81 private int _nextCollisionOkTime = 0;
@@ -95,7 +92,8 @@ public class BSCharacter : PhysicsActor
95 { 92 {
96 _localID = localID; 93 _localID = localID;
97 _avName = avName; 94 _avName = avName;
98 _scene = parent_scene; 95 Scene = parent_scene;
96 _physicsActorType = (int)ActorTypes.Agent;
99 _position = pos; 97 _position = pos;
100 _size = size; 98 _size = size;
101 _flying = isFlying; 99 _flying = isFlying;
@@ -104,10 +102,12 @@ public class BSCharacter : PhysicsActor
104 _buoyancy = ComputeBuoyancyFromFlying(isFlying); 102 _buoyancy = ComputeBuoyancyFromFlying(isFlying);
105 // The dimensions of the avatar capsule are kept in the scale. 103 // The dimensions of the avatar capsule are kept in the scale.
106 // Physics creates a unit capsule which is scaled by the physics engine. 104 // Physics creates a unit capsule which is scaled by the physics engine.
107 _scale = new Vector3(_scene.Params.avatarCapsuleRadius, _scene.Params.avatarCapsuleRadius, size.Z); 105 _scale = new Vector3(Scene.Params.avatarCapsuleRadius, Scene.Params.avatarCapsuleRadius, size.Z);
108 _density = _scene.Params.avatarDensity; 106 _density = Scene.Params.avatarDensity;
109 ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale 107 ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale
110 108
109 Linkset = new BSLinkset(Scene, this);
110
111 ShapeData shapeData = new ShapeData(); 111 ShapeData shapeData = new ShapeData();
112 shapeData.ID = _localID; 112 shapeData.ID = _localID;
113 shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR; 113 shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR;
@@ -118,29 +118,31 @@ public class BSCharacter : PhysicsActor
118 shapeData.Mass = _mass; 118 shapeData.Mass = _mass;
119 shapeData.Buoyancy = _buoyancy; 119 shapeData.Buoyancy = _buoyancy;
120 shapeData.Static = ShapeData.numericFalse; 120 shapeData.Static = ShapeData.numericFalse;
121 shapeData.Friction = _scene.Params.avatarFriction; 121 shapeData.Friction = Scene.Params.avatarFriction;
122 shapeData.Restitution = _scene.Params.avatarRestitution; 122 shapeData.Restitution = Scene.Params.avatarRestitution;
123 123
124 // do actual create at taint time 124 // do actual create at taint time
125 _scene.TaintedObject("BSCharacter.create", delegate() 125 Scene.TaintedObject("BSCharacter.create", delegate()
126 { 126 {
127 BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData); 127 DetailLog("{0},BSCharacter.create", _localID);
128 BulletSimAPI.CreateObject(Scene.WorldID, shapeData);
128 129
129 m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); 130 // Set the buoyancy for flying. This will be refactored when all the settings happen in C#
130 // avatars get all collisions no matter what 131 BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy);
131 BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 132
133 BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(Scene.World.Ptr, LocalID));
132 }); 134 });
133 135
134 return; 136 return;
135 } 137 }
136 138
137 // called when this character is being destroyed and the resources should be released 139 // called when this character is being destroyed and the resources should be released
138 public void Destroy() 140 public override void Destroy()
139 { 141 {
140 // DetailLog("{0},BSCharacter.Destroy", LocalID); 142 DetailLog("{0},BSCharacter.Destroy", LocalID);
141 _scene.TaintedObject("BSCharacter.destroy", delegate() 143 Scene.TaintedObject("BSCharacter.destroy", delegate()
142 { 144 {
143 BulletSimAPI.DestroyObject(_scene.WorldID, _localID); 145 BulletSimAPI.DestroyObject(Scene.WorldID, _localID);
144 }); 146 });
145 } 147 }
146 148
@@ -169,9 +171,9 @@ public class BSCharacter : PhysicsActor
169 171
170 ComputeAvatarVolumeAndMass(); 172 ComputeAvatarVolumeAndMass();
171 173
172 _scene.TaintedObject("BSCharacter.setSize", delegate() 174 Scene.TaintedObject("BSCharacter.setSize", delegate()
173 { 175 {
174 BulletSimAPI.SetObjectScaleMass(_scene.WorldID, LocalID, _scale, _mass, true); 176 BulletSimAPI.SetObjectScaleMass(Scene.WorldID, LocalID, _scale, _mass, true);
175 }); 177 });
176 178
177 } 179 }
@@ -200,17 +202,17 @@ public class BSCharacter : PhysicsActor
200 202
201 public override Vector3 Position { 203 public override Vector3 Position {
202 get { 204 get {
203 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 205 // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID);
204 return _position; 206 return _position;
205 } 207 }
206 set { 208 set {
207 _position = value; 209 _position = value;
208 PositionSanityCheck(); 210 PositionSanityCheck();
209 211
210 _scene.TaintedObject("BSCharacter.setPosition", delegate() 212 Scene.TaintedObject("BSCharacter.setPosition", delegate()
211 { 213 {
212 DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); 214 DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
213 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 215 BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation);
214 }); 216 });
215 } 217 }
216 } 218 }
@@ -223,16 +225,35 @@ public class BSCharacter : PhysicsActor
223 bool ret = false; 225 bool ret = false;
224 226
225 // If below the ground, move the avatar up 227 // If below the ground, move the avatar up
226 float terrainHeight = Scene.GetTerrainHeightAtXYZ(_position); 228 float terrainHeight = Scene.TerrainManager.GetTerrainHeightAtXYZ(_position);
227 if (_position.Z < terrainHeight) 229 if (Position.Z < terrainHeight)
228 { 230 {
229 DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},orient={2}", LocalID, _position, _orientation); 231 DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight);
230 _position.Z = terrainHeight + 2.0f; 232 _position.Z = terrainHeight + 2.0f;
231 ret = true; 233 ret = true;
232 } 234 }
233 235
234 // TODO: check for out of bounds 236 // TODO: check for out of bounds
237 return ret;
238 }
235 239
240 // A version of the sanity check that also makes sure a new position value is
241 // pushed back to the physics engine. This routine would be used by anyone
242 // who is not already pushing the value.
243 private bool PositionSanityCheck2()
244 {
245 bool ret = false;
246 if (PositionSanityCheck())
247 {
248 // The new position value must be pushed into the physics engine but we can't
249 // just assign to "Position" because of potential call loops.
250 Scene.TaintedObject("BSCharacter.PositionSanityCheck", delegate()
251 {
252 DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation);
253 BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation);
254 });
255 ret = true;
256 }
236 return ret; 257 return ret;
237 } 258 }
238 259
@@ -241,6 +262,10 @@ public class BSCharacter : PhysicsActor
241 return _mass; 262 return _mass;
242 } 263 }
243 } 264 }
265
266 // used when we only want this prim's mass and not the linkset thing
267 public override float MassRaw { get {return _mass; } }
268
244 public override Vector3 Force { 269 public override Vector3 Force {
245 get { return _force; } 270 get { return _force; }
246 set { 271 set {
@@ -273,10 +298,10 @@ public class BSCharacter : PhysicsActor
273 set { 298 set {
274 _velocity = value; 299 _velocity = value;
275 // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity); 300 // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity);
276 _scene.TaintedObject("BSCharacter.setVelocity", delegate() 301 Scene.TaintedObject("BSCharacter.setVelocity", delegate()
277 { 302 {
278 DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity); 303 DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity);
279 BulletSimAPI.SetObjectVelocity(_scene.WorldID, _localID, _velocity); 304 BulletSimAPI.SetObjectVelocity(Scene.WorldID, _localID, _velocity);
280 }); 305 });
281 } 306 }
282 } 307 }
@@ -299,10 +324,10 @@ public class BSCharacter : PhysicsActor
299 set { 324 set {
300 _orientation = value; 325 _orientation = value;
301 // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation); 326 // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation);
302 _scene.TaintedObject("BSCharacter.setOrientation", delegate() 327 Scene.TaintedObject("BSCharacter.setOrientation", delegate()
303 { 328 {
304 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 329 // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID);
305 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 330 BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation);
306 }); 331 });
307 } 332 }
308 } 333 }
@@ -319,14 +344,13 @@ public class BSCharacter : PhysicsActor
319 public override bool Flying { 344 public override bool Flying {
320 get { return _flying; } 345 get { return _flying; }
321 set { 346 set {
322 if (_flying != value) 347 _flying = value;
323 { 348 // simulate flying by changing the effect of gravity
324 _flying = value; 349 this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
325 // simulate flying by changing the effect of gravity
326 this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
327 }
328 } 350 }
329 } 351 }
352 // Flying is implimented by changing the avatar's buoyancy.
353 // Would this be done better with a vehicle type?
330 private float ComputeBuoyancyFromFlying(bool ifFlying) { 354 private float ComputeBuoyancyFromFlying(bool ifFlying) {
331 return ifFlying ? 1f : 0f; 355 return ifFlying ? 1f : 0f;
332 } 356 }
@@ -340,11 +364,11 @@ public class BSCharacter : PhysicsActor
340 set { _throttleUpdates = value; } 364 set { _throttleUpdates = value; }
341 } 365 }
342 public override bool IsColliding { 366 public override bool IsColliding {
343 get { return (_collidingStep == _scene.SimulationStep); } 367 get { return (_collidingStep == Scene.SimulationStep); }
344 set { _isColliding = value; } 368 set { _isColliding = value; }
345 } 369 }
346 public override bool CollidingGround { 370 public override bool CollidingGround {
347 get { return (_collidingGroundStep == _scene.SimulationStep); } 371 get { return (_collidingGroundStep == Scene.SimulationStep); }
348 set { _collidingGround = value; } 372 set { _collidingGround = value; }
349 } 373 }
350 public override bool CollidingObj { 374 public override bool CollidingObj {
@@ -366,10 +390,10 @@ public class BSCharacter : PhysicsActor
366 public override float Buoyancy { 390 public override float Buoyancy {
367 get { return _buoyancy; } 391 get { return _buoyancy; }
368 set { _buoyancy = value; 392 set { _buoyancy = value;
369 _scene.TaintedObject("BSCharacter.setBuoyancy", delegate() 393 Scene.TaintedObject("BSCharacter.setBuoyancy", delegate()
370 { 394 {
371 DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 395 DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
372 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy); 396 BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy);
373 }); 397 });
374 } 398 }
375 } 399 }
@@ -413,10 +437,10 @@ public class BSCharacter : PhysicsActor
413 _force.Y += force.Y; 437 _force.Y += force.Y;
414 _force.Z += force.Z; 438 _force.Z += force.Z;
415 // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force); 439 // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force);
416 _scene.TaintedObject("BSCharacter.AddForce", delegate() 440 Scene.TaintedObject("BSCharacter.AddForce", delegate()
417 { 441 {
418 DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force); 442 DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force);
419 BulletSimAPI.AddObjectForce2(Body.Ptr, _force); 443 BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force);
420 }); 444 });
421 } 445 }
422 else 446 else
@@ -441,18 +465,23 @@ public class BSCharacter : PhysicsActor
441 465
442 Scene.TaintedObject("BSCharacter.SubscribeEvents", delegate() 466 Scene.TaintedObject("BSCharacter.SubscribeEvents", delegate()
443 { 467 {
444 BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 468 BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
445 }); 469 });
446 } 470 }
447 } 471 }
472
473 public override void ZeroMotion()
474 {
475 return;
476 }
477
448 // Stop collision events 478 // Stop collision events
449 public override void UnSubscribeEvents() { 479 public override void UnSubscribeEvents() {
450 _subscribedEventsMs = 0; 480 _subscribedEventsMs = 0;
451 // Avatars get all their collision events 481 Scene.TaintedObject("BSCharacter.UnSubscribeEvents", delegate()
452 // Scene.TaintedObject("BSCharacter.UnSubscribeEvents", delegate() 482 {
453 // { 483 BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
454 // BulletSimAPI.RemoveFromCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 484 });
455 // });
456 } 485 }
457 // Return 'true' if someone has subscribed to events 486 // Return 'true' if someone has subscribed to events
458 public override bool SubscribedEvents() { 487 public override bool SubscribedEvents() {
@@ -478,7 +507,7 @@ public class BSCharacter : PhysicsActor
478 507
479 // The physics engine says that properties have updated. Update same and inform 508 // The physics engine says that properties have updated. Update same and inform
480 // the world that things have changed. 509 // the world that things have changed.
481 public void UpdateProperties(EntityProperties entprop) 510 public override void UpdateProperties(EntityProperties entprop)
482 { 511 {
483 _position = entprop.Position; 512 _position = entprop.Position;
484 _orientation = entprop.Rotation; 513 _orientation = entprop.Rotation;
@@ -488,43 +517,46 @@ public class BSCharacter : PhysicsActor
488 // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. 517 // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
489 // base.RequestPhysicsterseUpdate(); 518 // base.RequestPhysicsterseUpdate();
490 519
491 /* 520 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
492 DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", 521 PositionSanityCheck2();
493 LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, 522
494 entprop.Acceleration, entprop.RotationalVelocity); 523 float heightHere = Scene.TerrainManager.GetTerrainHeightAtXYZ(_position); // only for debug
495 */ 524 DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5},terrain={6}",
525 LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity, heightHere);
496 } 526 }
497 527
498 // Called by the scene when a collision with this object is reported 528 // Called by the scene when a collision with this object is reported
499 // The collision, if it should be reported to the character, is placed in a collection 529 // The collision, if it should be reported to the character, is placed in a collection
500 // that will later be sent to the simulator when SendCollisions() is called. 530 // that will later be sent to the simulator when SendCollisions() is called.
501 CollisionEventUpdate collisionCollection = null; 531 CollisionEventUpdate collisionCollection = null;
502 public void Collide(uint collidingWith, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth) 532 public override bool Collide(uint collidingWith, BSPhysObject collidee, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
503 { 533 {
504 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); 534 bool ret = false;
505 535
506 // The following makes IsColliding() and IsCollidingGround() work 536 // The following makes IsColliding() and IsCollidingGround() work
507 _collidingStep = _scene.SimulationStep; 537 _collidingStep = Scene.SimulationStep;
508 if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID) 538 if (collidingWith <= Scene.TerrainManager.HighestTerrainID)
509 { 539 {
510 _collidingGroundStep = _scene.SimulationStep; 540 _collidingGroundStep = Scene.SimulationStep;
511 } 541 }
512 // DetailLog("{0},BSCharacter.Collison,call,with={1}", LocalID, collidingWith); 542 // DetailLog("{0},BSCharacter.Collison,call,with={1}", LocalID, collidingWith);
513 543
514 // throttle collisions to the rate specified in the subscription 544 // throttle collisions to the rate specified in the subscription
515 if (_subscribedEventsMs != 0) { 545 if (SubscribedEvents()) {
516 int nowTime = _scene.SimulationNowTime; 546 int nowTime = Scene.SimulationNowTime;
517 if (nowTime >= _nextCollisionOkTime) { 547 if (nowTime >= _nextCollisionOkTime) {
518 _nextCollisionOkTime = nowTime + _subscribedEventsMs; 548 _nextCollisionOkTime = nowTime + _subscribedEventsMs;
519 549
520 if (collisionCollection == null) 550 if (collisionCollection == null)
521 collisionCollection = new CollisionEventUpdate(); 551 collisionCollection = new CollisionEventUpdate();
522 collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); 552 collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
553 ret = true;
523 } 554 }
524 } 555 }
556 return ret;
525 } 557 }
526 558
527 public void SendCollisions() 559 public override void SendCollisions()
528 { 560 {
529 /* 561 /*
530 if (collisionCollection != null && collisionCollection.Count > 0) 562 if (collisionCollection != null && collisionCollection.Count > 0)