diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 168 |
1 files changed, 116 insertions, 52 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 09e1f0c..f164afe 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -40,6 +40,7 @@ public class BSCharacter : PhysicsActor | |||
40 | private static readonly string LogHeader = "[BULLETS CHAR]"; | 40 | private static readonly string LogHeader = "[BULLETS CHAR]"; |
41 | 41 | ||
42 | private BSScene _scene; | 42 | private BSScene _scene; |
43 | public BSScene Scene { get { return _scene; } } | ||
43 | private String _avName; | 44 | private String _avName; |
44 | // private bool _stopped; | 45 | // private bool _stopped; |
45 | private Vector3 _size; | 46 | private Vector3 _size; |
@@ -73,6 +74,12 @@ public class BSCharacter : PhysicsActor | |||
73 | private bool _kinematic; | 74 | private bool _kinematic; |
74 | private float _buoyancy; | 75 | private float _buoyancy; |
75 | 76 | ||
77 | private BulletBody m_body; | ||
78 | public BulletBody Body { | ||
79 | get { return m_body; } | ||
80 | set { m_body = value; } | ||
81 | } | ||
82 | |||
76 | private int _subscribedEventsMs = 0; | 83 | private int _subscribedEventsMs = 0; |
77 | private int _nextCollisionOkTime = 0; | 84 | private int _nextCollisionOkTime = 0; |
78 | 85 | ||
@@ -95,7 +102,9 @@ public class BSCharacter : PhysicsActor | |||
95 | _orientation = Quaternion.Identity; | 102 | _orientation = Quaternion.Identity; |
96 | _velocity = Vector3.Zero; | 103 | _velocity = Vector3.Zero; |
97 | _buoyancy = ComputeBuoyancyFromFlying(isFlying); | 104 | _buoyancy = ComputeBuoyancyFromFlying(isFlying); |
98 | _scale = new Vector3(1f, 1f, 1f); | 105 | // The dimensions of the avatar capsule are kept in the scale. |
106 | // Physics creates a unit capsule which is scaled by the physics engine. | ||
107 | _scale = new Vector3(_scene.Params.avatarCapsuleRadius, _scene.Params.avatarCapsuleRadius, size.Z); | ||
99 | _density = _scene.Params.avatarDensity; | 108 | _density = _scene.Params.avatarDensity; |
100 | ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale | 109 | ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale |
101 | 110 | ||
@@ -113,9 +122,13 @@ public class BSCharacter : PhysicsActor | |||
113 | shapeData.Restitution = _scene.Params.avatarRestitution; | 122 | shapeData.Restitution = _scene.Params.avatarRestitution; |
114 | 123 | ||
115 | // do actual create at taint time | 124 | // do actual create at taint time |
116 | _scene.TaintedObject(delegate() | 125 | _scene.TaintedObject("BSCharacter.create", delegate() |
117 | { | 126 | { |
118 | BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData); | 127 | BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData); |
128 | |||
129 | m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); | ||
130 | // avatars get all collisions no matter what | ||
131 | BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); | ||
119 | }); | 132 | }); |
120 | 133 | ||
121 | return; | 134 | return; |
@@ -124,7 +137,8 @@ public class BSCharacter : PhysicsActor | |||
124 | // called when this character is being destroyed and the resources should be released | 137 | // called when this character is being destroyed and the resources should be released |
125 | public void Destroy() | 138 | public void Destroy() |
126 | { | 139 | { |
127 | _scene.TaintedObject(delegate() | 140 | // DetailLog("{0},Destroy", LocalID); |
141 | _scene.TaintedObject("BSCharacter.destroy", delegate() | ||
128 | { | 142 | { |
129 | BulletSimAPI.DestroyObject(_scene.WorldID, _localID); | 143 | BulletSimAPI.DestroyObject(_scene.WorldID, _localID); |
130 | }); | 144 | }); |
@@ -138,9 +152,28 @@ public class BSCharacter : PhysicsActor | |||
138 | public override bool Stopped { | 152 | public override bool Stopped { |
139 | get { return false; } | 153 | get { return false; } |
140 | } | 154 | } |
141 | public override Vector3 Size { | 155 | public override Vector3 Size { |
142 | get { return _size; } | 156 | get |
143 | set { _size = value; | 157 | { |
158 | // Avatar capsule size is kept in the scale parameter. | ||
159 | return new Vector3(_scale.X * 2, _scale.Y * 2, _scale.Z); | ||
160 | } | ||
161 | |||
162 | set { | ||
163 | // When an avatar's size is set, only the height is changed | ||
164 | // and that really only depends on the radius. | ||
165 | _size = value; | ||
166 | _scale.Z = (_size.Z * 1.15f) - (_scale.X + _scale.Y); | ||
167 | |||
168 | // TODO: something has to be done with the avatar's vertical position | ||
169 | |||
170 | ComputeAvatarVolumeAndMass(); | ||
171 | |||
172 | _scene.TaintedObject("BSCharacter.setSize", delegate() | ||
173 | { | ||
174 | BulletSimAPI.SetObjectScaleMass(_scene.WorldID, LocalID, _scale, _mass, true); | ||
175 | }); | ||
176 | |||
144 | } | 177 | } |
145 | } | 178 | } |
146 | public override PrimitiveBaseShape Shape { | 179 | public override PrimitiveBaseShape Shape { |
@@ -172,12 +205,37 @@ public class BSCharacter : PhysicsActor | |||
172 | } | 205 | } |
173 | set { | 206 | set { |
174 | _position = value; | 207 | _position = value; |
175 | _scene.TaintedObject(delegate() | 208 | PositionSanityCheck(); |
209 | |||
210 | _scene.TaintedObject("BSCharacter.setPosition", delegate() | ||
176 | { | 211 | { |
212 | DetailLog("{0},SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); | ||
177 | BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); | 213 | BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); |
178 | }); | 214 | }); |
179 | } | 215 | } |
180 | } | 216 | } |
217 | |||
218 | // Check that the current position is sane and, if not, modify the position to make it so. | ||
219 | // Check for being below terrain and being out of bounds. | ||
220 | // Returns 'true' of the position was made sane by some action. | ||
221 | private bool PositionSanityCheck() | ||
222 | { | ||
223 | bool ret = false; | ||
224 | |||
225 | // If below the ground, move the avatar up | ||
226 | float terrainHeight = Scene.GetTerrainHeightAtXYZ(_position); | ||
227 | if (_position.Z < terrainHeight) | ||
228 | { | ||
229 | DetailLog("{0},PositionAdjustUnderGround,call,pos={1},orient={2}", LocalID, _position, _orientation); | ||
230 | _position.Z = terrainHeight + 2.0f; | ||
231 | ret = true; | ||
232 | } | ||
233 | |||
234 | // TODO: check for out of bounds | ||
235 | |||
236 | return ret; | ||
237 | } | ||
238 | |||
181 | public override float Mass { | 239 | public override float Mass { |
182 | get { | 240 | get { |
183 | return _mass; | 241 | return _mass; |
@@ -188,9 +246,10 @@ public class BSCharacter : PhysicsActor | |||
188 | set { | 246 | set { |
189 | _force = value; | 247 | _force = value; |
190 | // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force); | 248 | // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force); |
191 | _scene.TaintedObject(delegate() | 249 | Scene.TaintedObject("BSCharacter.SetForce", delegate() |
192 | { | 250 | { |
193 | BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); | 251 | DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force); |
252 | BulletSimAPI.SetObjectForce(Scene.WorldID, LocalID, _force); | ||
194 | }); | 253 | }); |
195 | } | 254 | } |
196 | } | 255 | } |
@@ -214,8 +273,9 @@ public class BSCharacter : PhysicsActor | |||
214 | set { | 273 | set { |
215 | _velocity = value; | 274 | _velocity = value; |
216 | // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity); | 275 | // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity); |
217 | _scene.TaintedObject(delegate() | 276 | _scene.TaintedObject("BSCharacter.setVelocity", delegate() |
218 | { | 277 | { |
278 | DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity); | ||
219 | BulletSimAPI.SetObjectVelocity(_scene.WorldID, _localID, _velocity); | 279 | BulletSimAPI.SetObjectVelocity(_scene.WorldID, _localID, _velocity); |
220 | }); | 280 | }); |
221 | } | 281 | } |
@@ -239,7 +299,7 @@ public class BSCharacter : PhysicsActor | |||
239 | set { | 299 | set { |
240 | _orientation = value; | 300 | _orientation = value; |
241 | // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation); | 301 | // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation); |
242 | _scene.TaintedObject(delegate() | 302 | _scene.TaintedObject("BSCharacter.setOrientation", delegate() |
243 | { | 303 | { |
244 | // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); | 304 | // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); |
245 | BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); | 305 | BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); |
@@ -259,9 +319,12 @@ public class BSCharacter : PhysicsActor | |||
259 | public override bool Flying { | 319 | public override bool Flying { |
260 | get { return _flying; } | 320 | get { return _flying; } |
261 | set { | 321 | set { |
262 | _flying = value; | 322 | if (_flying != value) |
263 | // simulate flying by changing the effect of gravity | 323 | { |
264 | this.Buoyancy = ComputeBuoyancyFromFlying(_flying); | 324 | _flying = value; |
325 | // simulate flying by changing the effect of gravity | ||
326 | this.Buoyancy = ComputeBuoyancyFromFlying(_flying); | ||
327 | } | ||
265 | } | 328 | } |
266 | } | 329 | } |
267 | private float ComputeBuoyancyFromFlying(bool ifFlying) { | 330 | private float ComputeBuoyancyFromFlying(bool ifFlying) { |
@@ -303,8 +366,9 @@ public class BSCharacter : PhysicsActor | |||
303 | public override float Buoyancy { | 366 | public override float Buoyancy { |
304 | get { return _buoyancy; } | 367 | get { return _buoyancy; } |
305 | set { _buoyancy = value; | 368 | set { _buoyancy = value; |
306 | _scene.TaintedObject(delegate() | 369 | _scene.TaintedObject("BSCharacter.setBuoyancy", delegate() |
307 | { | 370 | { |
371 | DetailLog("{0},setBuoyancy,taint,buoy={1}", LocalID, _buoyancy); | ||
308 | BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy); | 372 | BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy); |
309 | }); | 373 | }); |
310 | } | 374 | } |
@@ -349,9 +413,10 @@ public class BSCharacter : PhysicsActor | |||
349 | _force.Y += force.Y; | 413 | _force.Y += force.Y; |
350 | _force.Z += force.Z; | 414 | _force.Z += force.Z; |
351 | // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force); | 415 | // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force); |
352 | _scene.TaintedObject(delegate() | 416 | _scene.TaintedObject("BSCharacter.AddForce", delegate() |
353 | { | 417 | { |
354 | BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); | 418 | DetailLog("{0},setAddForce,taint,addedForce={1}", LocalID, _force); |
419 | BulletSimAPI.AddObjectForce2(Body.Ptr, _force); | ||
355 | }); | 420 | }); |
356 | } | 421 | } |
357 | else | 422 | else |
@@ -369,11 +434,25 @@ public class BSCharacter : PhysicsActor | |||
369 | // Turn on collision events at a rate no faster than one every the given milliseconds | 434 | // Turn on collision events at a rate no faster than one every the given milliseconds |
370 | public override void SubscribeEvents(int ms) { | 435 | public override void SubscribeEvents(int ms) { |
371 | _subscribedEventsMs = ms; | 436 | _subscribedEventsMs = ms; |
372 | _nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs; // make first collision happen | 437 | if (ms > 0) |
438 | { | ||
439 | // make sure first collision happens | ||
440 | _nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs; | ||
441 | |||
442 | Scene.TaintedObject("BSCharacter.SubscribeEvents", delegate() | ||
443 | { | ||
444 | BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); | ||
445 | }); | ||
446 | } | ||
373 | } | 447 | } |
374 | // Stop collision events | 448 | // Stop collision events |
375 | public override void UnSubscribeEvents() { | 449 | public override void UnSubscribeEvents() { |
376 | _subscribedEventsMs = 0; | 450 | _subscribedEventsMs = 0; |
451 | // Avatars get all their collision events | ||
452 | // Scene.TaintedObject("BSCharacter.UnSubscribeEvents", delegate() | ||
453 | // { | ||
454 | // BulletSimAPI.RemoveFromCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); | ||
455 | // }); | ||
377 | } | 456 | } |
378 | // Return 'true' if someone has subscribed to events | 457 | // Return 'true' if someone has subscribed to events |
379 | public override bool SubscribedEvents() { | 458 | public override bool SubscribedEvents() { |
@@ -385,9 +464,15 @@ public class BSCharacter : PhysicsActor | |||
385 | { | 464 | { |
386 | _avatarVolume = (float)( | 465 | _avatarVolume = (float)( |
387 | Math.PI | 466 | Math.PI |
388 | * _scene.Params.avatarCapsuleRadius * _scale.X | 467 | * _scale.X |
389 | * _scene.Params.avatarCapsuleRadius * _scale.Y | 468 | * _scale.Y // the area of capsule cylinder |
390 | * _scene.Params.avatarCapsuleHeight * _scale.Z); | 469 | * _scale.Z // times height of capsule cylinder |
470 | + 1.33333333f | ||
471 | * Math.PI | ||
472 | * _scale.X | ||
473 | * Math.Min(_scale.X, _scale.Y) | ||
474 | * _scale.Y // plus the volume of the capsule end caps | ||
475 | ); | ||
391 | _mass = _density * _avatarVolume; | 476 | _mass = _density * _avatarVolume; |
392 | } | 477 | } |
393 | 478 | ||
@@ -395,43 +480,17 @@ public class BSCharacter : PhysicsActor | |||
395 | // the world that things have changed. | 480 | // the world that things have changed. |
396 | public void UpdateProperties(EntityProperties entprop) | 481 | public void UpdateProperties(EntityProperties entprop) |
397 | { | 482 | { |
398 | /* | ||
399 | bool changed = false; | ||
400 | // we assign to the local variables so the normal set action does not happen | ||
401 | if (_position != entprop.Position) { | ||
402 | _position = entprop.Position; | ||
403 | changed = true; | ||
404 | } | ||
405 | if (_orientation != entprop.Rotation) { | ||
406 | _orientation = entprop.Rotation; | ||
407 | changed = true; | ||
408 | } | ||
409 | if (_velocity != entprop.Velocity) { | ||
410 | _velocity = entprop.Velocity; | ||
411 | changed = true; | ||
412 | } | ||
413 | if (_acceleration != entprop.Acceleration) { | ||
414 | _acceleration = entprop.Acceleration; | ||
415 | changed = true; | ||
416 | } | ||
417 | if (_rotationalVelocity != entprop.RotationalVelocity) { | ||
418 | _rotationalVelocity = entprop.RotationalVelocity; | ||
419 | changed = true; | ||
420 | } | ||
421 | if (changed) { | ||
422 | // m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation); | ||
423 | // Avatar movement is not done by generating this event. There is code in the heartbeat | ||
424 | // loop that updates avatars. | ||
425 | // base.RequestPhysicsterseUpdate(); | ||
426 | } | ||
427 | */ | ||
428 | _position = entprop.Position; | 483 | _position = entprop.Position; |
429 | _orientation = entprop.Rotation; | 484 | _orientation = entprop.Rotation; |
430 | _velocity = entprop.Velocity; | 485 | _velocity = entprop.Velocity; |
431 | _acceleration = entprop.Acceleration; | 486 | _acceleration = entprop.Acceleration; |
432 | _rotationalVelocity = entprop.RotationalVelocity; | 487 | _rotationalVelocity = entprop.RotationalVelocity; |
433 | // Avatars don't report theirr changes the usual way. Changes are checked for in the heartbeat loop. | 488 | // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. |
434 | // base.RequestPhysicsterseUpdate(); | 489 | // base.RequestPhysicsterseUpdate(); |
490 | |||
491 | DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", | ||
492 | LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, | ||
493 | entprop.Acceleration, entprop.RotationalVelocity); | ||
435 | } | 494 | } |
436 | 495 | ||
437 | // Called by the scene when a collision with this object is reported | 496 | // Called by the scene when a collision with this object is reported |
@@ -480,5 +539,10 @@ public class BSCharacter : PhysicsActor | |||
480 | // End kludge | 539 | // End kludge |
481 | } | 540 | } |
482 | 541 | ||
542 | // Invoke the detailed logger and output something if it's enabled. | ||
543 | private void DetailLog(string msg, params Object[] args) | ||
544 | { | ||
545 | Scene.PhysicsLogging.Write(msg, args); | ||
546 | } | ||
483 | } | 547 | } |
484 | } | 548 | } |