diff options
author | Robert Adams | 2012-10-12 16:03:03 -0700 |
---|---|---|
committer | Robert Adams | 2012-10-19 10:51:58 -0700 |
commit | fd7a097849b8a405bdd62cfe6d4ee2bbf0a3961c (patch) | |
tree | 93606a507aa16538a73e10956735a66f4306fe18 /OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |
parent | minor: Increase attachment name field from 36 to 50 chars in "attachments sho... (diff) | |
download | opensim-SC-fd7a097849b8a405bdd62cfe6d4ee2bbf0a3961c.zip opensim-SC-fd7a097849b8a405bdd62cfe6d4ee2bbf0a3961c.tar.gz opensim-SC-fd7a097849b8a405bdd62cfe6d4ee2bbf0a3961c.tar.bz2 opensim-SC-fd7a097849b8a405bdd62cfe6d4ee2bbf0a3961c.tar.xz |
BulletSim: Update BSCharacter to use API2 interface.
Add capsule shape to BSShapeCollection().
Remember last updated values so inter frame diffs can be computed.
Parameterize avatarStandingFriction and reduce to 10 from 999.
The latter high value made avatars very hard to push.
Set CCD parameters for prims and characters of specified.
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 182 |
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 | ||