diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 229 |
1 files changed, 162 insertions, 67 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 2a52e01..623ac8f 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,14 +86,18 @@ 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; | ||
92 | _avatarDensity = PhysicsScene.Params.avatarDensity; | ||
88 | 93 | ||
89 | // The dimensions of the avatar capsule are kept in the scale. | 94 | // The dimensions of the avatar capsule are kept in the scale. |
90 | // Physics creates a unit capsule which is scaled by the physics engine. | 95 | // Physics creates a unit capsule which is scaled by the physics engine. |
91 | ComputeAvatarScale(_size); | 96 | ComputeAvatarScale(_size); |
92 | _avatarDensity = PhysicsScene.Params.avatarDensity; | 97 | // set _avatarVolume and _mass based on capsule size, _density and Scale |
93 | // set _avatarVolume and _mass based on capsule size, _density and _scale | ||
94 | ComputeAvatarVolumeAndMass(); | 98 | ComputeAvatarVolumeAndMass(); |
99 | DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", | ||
100 | LocalID, _size, Scale, _avatarDensity, _avatarVolume, MassRaw); | ||
95 | 101 | ||
96 | ShapeData shapeData = new ShapeData(); | 102 | ShapeData shapeData = new ShapeData(); |
97 | shapeData.ID = LocalID; | 103 | shapeData.ID = LocalID; |
@@ -99,28 +105,22 @@ public class BSCharacter : BSPhysObject | |||
99 | shapeData.Position = _position; | 105 | shapeData.Position = _position; |
100 | shapeData.Rotation = _orientation; | 106 | shapeData.Rotation = _orientation; |
101 | shapeData.Velocity = _velocity; | 107 | shapeData.Velocity = _velocity; |
102 | shapeData.Scale = _scale; | 108 | shapeData.Size = Scale; |
109 | shapeData.Scale = Scale; | ||
103 | shapeData.Mass = _mass; | 110 | shapeData.Mass = _mass; |
104 | shapeData.Buoyancy = _buoyancy; | 111 | shapeData.Buoyancy = _buoyancy; |
105 | shapeData.Static = ShapeData.numericFalse; | 112 | shapeData.Static = ShapeData.numericFalse; |
106 | shapeData.Friction = PhysicsScene.Params.avatarFriction; | 113 | shapeData.Friction = PhysicsScene.Params.avatarStandingFriction; |
107 | shapeData.Restitution = PhysicsScene.Params.avatarRestitution; | 114 | shapeData.Restitution = PhysicsScene.Params.avatarRestitution; |
108 | 115 | ||
109 | // do actual create at taint time | 116 | // do actual create at taint time |
110 | PhysicsScene.TaintedObject("BSCharacter.create", delegate() | 117 | PhysicsScene.TaintedObject("BSCharacter.create", delegate() |
111 | { | 118 | { |
112 | DetailLog("{0},BSCharacter.create,taint", LocalID); | 119 | DetailLog("{0},BSCharacter.create,taint", LocalID); |
113 | BulletSimAPI.CreateObject(PhysicsScene.WorldID, shapeData); | 120 | // New body and shape into BSBody and BSShape |
114 | 121 | PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this, shapeData, null, null, null); | |
115 | // 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. | ||
117 | BulletSimAPI.SetObjectBuoyancy(PhysicsScene.WorldID, LocalID, _buoyancy); | ||
118 | 122 | ||
119 | BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(PhysicsScene.World.ptr, LocalID)); | 123 | SetPhysicalProperties(); |
120 | |||
121 | // This works here because CreateObject has already put the character into the physical world. | ||
122 | BulletSimAPI.SetCollisionFilterMask2(BSBody.ptr, | ||
123 | (uint)CollisionFilterGroups.AvatarFilter, (uint)CollisionFilterGroups.AvatarMask); | ||
124 | }); | 124 | }); |
125 | return; | 125 | return; |
126 | } | 126 | } |
@@ -131,53 +131,85 @@ public class BSCharacter : BSPhysObject | |||
131 | DetailLog("{0},BSCharacter.Destroy", LocalID); | 131 | DetailLog("{0},BSCharacter.Destroy", LocalID); |
132 | PhysicsScene.TaintedObject("BSCharacter.destroy", delegate() | 132 | PhysicsScene.TaintedObject("BSCharacter.destroy", delegate() |
133 | { | 133 | { |
134 | BulletSimAPI.DestroyObject(PhysicsScene.WorldID, LocalID); | 134 | PhysicsScene.Shapes.DereferenceBody(BSBody, true, null); |
135 | PhysicsScene.Shapes.DereferenceShape(BSShape, true, null); | ||
135 | }); | 136 | }); |
136 | } | 137 | } |
137 | 138 | ||
139 | private void SetPhysicalProperties() | ||
140 | { | ||
141 | BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, BSBody.ptr); | ||
142 | |||
143 | ZeroMotion(); | ||
144 | ForcePosition = _position; | ||
145 | // Set the velocity and compute the proper friction | ||
146 | ForceVelocity = _velocity; | ||
147 | BulletSimAPI.SetRestitution2(BSBody.ptr, PhysicsScene.Params.avatarRestitution); | ||
148 | BulletSimAPI.SetLocalScaling2(BSShape.ptr, Scale); | ||
149 | BulletSimAPI.SetContactProcessingThreshold2(BSBody.ptr, PhysicsScene.Params.contactProcessingThreshold); | ||
150 | if (PhysicsScene.Params.ccdMotionThreshold > 0f) | ||
151 | { | ||
152 | BulletSimAPI.SetCcdMotionThreshold2(BSBody.ptr, PhysicsScene.Params.ccdMotionThreshold); | ||
153 | BulletSimAPI.SetCcdSweepSphereRadius2(BSBody.ptr, PhysicsScene.Params.ccdSweptSphereRadius); | ||
154 | } | ||
155 | |||
156 | OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, MassRaw); | ||
157 | BulletSimAPI.SetMassProps2(BSBody.ptr, MassRaw, localInertia); | ||
158 | |||
159 | BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.CF_CHARACTER_OBJECT); | ||
160 | |||
161 | BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, BSBody.ptr); | ||
162 | |||
163 | BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ACTIVE_TAG); | ||
164 | BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, BSBody.ptr); | ||
165 | |||
166 | // Do this after the object has been added to the world | ||
167 | BulletSimAPI.SetCollisionFilterMask2(BSBody.ptr, | ||
168 | (uint)CollisionFilterGroups.AvatarFilter, | ||
169 | (uint)CollisionFilterGroups.AvatarMask); | ||
170 | } | ||
171 | |||
138 | public override void RequestPhysicsterseUpdate() | 172 | public override void RequestPhysicsterseUpdate() |
139 | { | 173 | { |
140 | base.RequestPhysicsterseUpdate(); | 174 | base.RequestPhysicsterseUpdate(); |
141 | } | 175 | } |
142 | // No one calls this method so I don't know what it could possibly mean | 176 | // No one calls this method so I don't know what it could possibly mean |
143 | public override bool Stopped { | 177 | public override bool Stopped { get { return false; } } |
144 | get { return false; } | ||
145 | } | ||
146 | public override OMV.Vector3 Size { | 178 | public override OMV.Vector3 Size { |
147 | get | 179 | get |
148 | { | 180 | { |
149 | // Avatar capsule size is kept in the scale parameter. | 181 | // Avatar capsule size is kept in the scale parameter. |
150 | return new OMV.Vector3(_scale.X * 2, _scale.Y * 2, _scale.Z); | 182 | return _size; |
151 | } | 183 | } |
152 | 184 | ||
153 | set { | 185 | set { |
154 | // When an avatar's size is set, only the height is changed | 186 | // When an avatar's size is set, only the height is changed. |
155 | // and that really only depends on the radius. | ||
156 | _size = value; | 187 | _size = value; |
157 | ComputeAvatarScale(_size); | 188 | ComputeAvatarScale(_size); |
158 | |||
159 | // TODO: something has to be done with the avatar's vertical position | ||
160 | |||
161 | ComputeAvatarVolumeAndMass(); | 189 | ComputeAvatarVolumeAndMass(); |
190 | DetailLog("{0},BSCharacter.setSize,call,scale={1},density={2},volume={3},mass={4}", | ||
191 | LocalID, Scale, _avatarDensity, _avatarVolume, MassRaw); | ||
162 | 192 | ||
163 | PhysicsScene.TaintedObject("BSCharacter.setSize", delegate() | 193 | PhysicsScene.TaintedObject("BSCharacter.setSize", delegate() |
164 | { | 194 | { |
165 | BulletSimAPI.SetObjectScaleMass(PhysicsScene.WorldID, LocalID, _scale, _mass, true); | 195 | BulletSimAPI.SetLocalScaling2(BSShape.ptr, Scale); |
196 | OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(BSShape.ptr, MassRaw); | ||
197 | BulletSimAPI.SetMassProps2(BSBody.ptr, MassRaw, localInertia); | ||
166 | }); | 198 | }); |
167 | 199 | ||
168 | } | 200 | } |
169 | } | 201 | } |
170 | public override PrimitiveBaseShape Shape { | 202 | public override OMV.Vector3 Scale { get; set; } |
171 | set { _pbs = value; | 203 | public override PrimitiveBaseShape Shape |
172 | } | 204 | { |
205 | set { BaseShape = value; } | ||
173 | } | 206 | } |
207 | |||
174 | public override bool Grabbed { | 208 | public override bool Grabbed { |
175 | set { _grabbed = value; | 209 | set { _grabbed = value; } |
176 | } | ||
177 | } | 210 | } |
178 | public override bool Selected { | 211 | public override bool Selected { |
179 | set { _selected = value; | 212 | set { _selected = value; } |
180 | } | ||
181 | } | 213 | } |
182 | public override void CrossingFailure() { return; } | 214 | public override void CrossingFailure() { return; } |
183 | public override void link(PhysicsActor obj) { return; } | 215 | public override void link(PhysicsActor obj) { return; } |
@@ -204,7 +236,7 @@ public class BSCharacter : BSPhysObject | |||
204 | 236 | ||
205 | public override OMV.Vector3 Position { | 237 | public override OMV.Vector3 Position { |
206 | get { | 238 | get { |
207 | // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID); | 239 | // _position = BulletSimAPI.GetObjectPosition2(Scene.World.ptr, LocalID); |
208 | return _position; | 240 | return _position; |
209 | } | 241 | } |
210 | set { | 242 | set { |
@@ -214,7 +246,7 @@ public class BSCharacter : BSPhysObject | |||
214 | PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate() | 246 | PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate() |
215 | { | 247 | { |
216 | DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); | 248 | DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); |
217 | BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, LocalID, _position, _orientation); | 249 | BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); |
218 | }); | 250 | }); |
219 | } | 251 | } |
220 | } | 252 | } |
@@ -263,7 +295,7 @@ public class BSCharacter : BSPhysObject | |||
263 | // A version of the sanity check that also makes sure a new position value is | 295 | // A version of the sanity check that also makes sure a new position value is |
264 | // pushed back to the physics engine. This routine would be used by anyone | 296 | // pushed back to the physics engine. This routine would be used by anyone |
265 | // who is not already pushing the value. | 297 | // who is not already pushing the value. |
266 | private bool PositionSanityCheck2(bool atTaintTime) | 298 | private bool PositionSanityCheck(bool inTaintTime) |
267 | { | 299 | { |
268 | bool ret = false; | 300 | bool ret = false; |
269 | if (PositionSanityCheck()) | 301 | if (PositionSanityCheck()) |
@@ -273,9 +305,9 @@ public class BSCharacter : BSPhysObject | |||
273 | BSScene.TaintCallback sanityOperation = delegate() | 305 | BSScene.TaintCallback sanityOperation = delegate() |
274 | { | 306 | { |
275 | DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); | 307 | DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); |
276 | BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, LocalID, _position, _orientation); | 308 | BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); |
277 | }; | 309 | }; |
278 | if (atTaintTime) | 310 | if (inTaintTime) |
279 | sanityOperation(); | 311 | sanityOperation(); |
280 | else | 312 | else |
281 | PhysicsScene.TaintedObject("BSCharacter.PositionSanityCheck", sanityOperation); | 313 | PhysicsScene.TaintedObject("BSCharacter.PositionSanityCheck", sanityOperation); |
@@ -284,11 +316,7 @@ public class BSCharacter : BSPhysObject | |||
284 | return ret; | 316 | return ret; |
285 | } | 317 | } |
286 | 318 | ||
287 | public override float Mass { | 319 | public override float Mass { get { return _mass; } } |
288 | get { | ||
289 | return _mass; | ||
290 | } | ||
291 | } | ||
292 | 320 | ||
293 | // used when we only want this prim's mass and not the linkset thing | 321 | // used when we only want this prim's mass and not the linkset thing |
294 | public override float MassRaw { get {return _mass; } } | 322 | public override float MassRaw { get {return _mass; } } |
@@ -301,15 +329,13 @@ public class BSCharacter : BSPhysObject | |||
301 | PhysicsScene.TaintedObject("BSCharacter.SetForce", delegate() | 329 | PhysicsScene.TaintedObject("BSCharacter.SetForce", delegate() |
302 | { | 330 | { |
303 | DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force); | 331 | DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force); |
304 | BulletSimAPI.SetObjectForce(PhysicsScene.WorldID, LocalID, _force); | 332 | BulletSimAPI.SetObjectForce2(BSBody.ptr, _force); |
305 | }); | 333 | }); |
306 | } | 334 | } |
307 | } | 335 | } |
308 | 336 | ||
309 | public override int VehicleType { | 337 | // Avatars don't do vehicles |
310 | get { return 0; } | 338 | public override int VehicleType { get { return 0; } set { return; } } |
311 | set { return; } | ||
312 | } | ||
313 | public override void VehicleFloatParam(int param, float value) { } | 339 | public override void VehicleFloatParam(int param, float value) { } |
314 | public override void VehicleVectorParam(int param, OMV.Vector3 value) {} | 340 | public override void VehicleVectorParam(int param, OMV.Vector3 value) {} |
315 | public override void VehicleRotationParam(int param, OMV.Quaternion rotation) { } | 341 | public override void VehicleRotationParam(int param, OMV.Quaternion rotation) { } |
@@ -328,10 +354,39 @@ public class BSCharacter : BSPhysObject | |||
328 | PhysicsScene.TaintedObject("BSCharacter.setVelocity", delegate() | 354 | PhysicsScene.TaintedObject("BSCharacter.setVelocity", delegate() |
329 | { | 355 | { |
330 | DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity); | 356 | DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity); |
331 | BulletSimAPI.SetObjectVelocity(PhysicsScene.WorldID, LocalID, _velocity); | 357 | ForceVelocity = _velocity; |
332 | }); | 358 | }); |
333 | } | 359 | } |
334 | } | 360 | } |
361 | public override OMV.Vector3 ForceVelocity { | ||
362 | get { return _velocity; } | ||
363 | set { | ||
364 | // Depending on whether the avatar is moving or not, change the friction | ||
365 | // to keep the avatar from slipping around | ||
366 | if (_velocity.Length() == 0) | ||
367 | { | ||
368 | if (_currentFriction != PhysicsScene.Params.avatarStandingFriction) | ||
369 | { | ||
370 | _currentFriction = PhysicsScene.Params.avatarStandingFriction; | ||
371 | BulletSimAPI.SetFriction2(BSBody.ptr, _currentFriction); | ||
372 | } | ||
373 | } | ||
374 | else | ||
375 | { | ||
376 | if (_currentFriction != PhysicsScene.Params.avatarFriction) | ||
377 | { | ||
378 | _currentFriction = PhysicsScene.Params.avatarFriction; | ||
379 | BulletSimAPI.SetFriction2(BSBody.ptr, _currentFriction); | ||
380 | } | ||
381 | } | ||
382 | _velocity = value; | ||
383 | // Remember the set velocity so we can suppress the reduction by friction, ... | ||
384 | _appliedVelocity = value; | ||
385 | |||
386 | BulletSimAPI.SetLinearVelocity2(BSBody.ptr, _velocity); | ||
387 | BulletSimAPI.Activate2(BSBody.ptr, true); | ||
388 | } | ||
389 | } | ||
335 | public override OMV.Vector3 Torque { | 390 | public override OMV.Vector3 Torque { |
336 | get { return _torque; } | 391 | get { return _torque; } |
337 | set { _torque = value; | 392 | set { _torque = value; |
@@ -353,8 +408,8 @@ public class BSCharacter : BSPhysObject | |||
353 | // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation); | 408 | // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation); |
354 | PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate() | 409 | PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate() |
355 | { | 410 | { |
356 | // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID); | 411 | // _position = BulletSimAPI.GetPosition2(BSBody.ptr); |
357 | BulletSimAPI.SetObjectTranslation(PhysicsScene.WorldID, LocalID, _position, _orientation); | 412 | BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); |
358 | }); | 413 | }); |
359 | } | 414 | } |
360 | } | 415 | } |
@@ -382,12 +437,18 @@ public class BSCharacter : BSPhysObject | |||
382 | set { _isPhysical = value; | 437 | set { _isPhysical = value; |
383 | } | 438 | } |
384 | } | 439 | } |
440 | public override bool IsSolid { | ||
441 | get { return true; } | ||
442 | } | ||
443 | public override bool IsStatic { | ||
444 | get { return false; } | ||
445 | } | ||
385 | public override bool Flying { | 446 | public override bool Flying { |
386 | get { return _flying; } | 447 | get { return _flying; } |
387 | set { | 448 | set { |
388 | _flying = value; | 449 | _flying = value; |
389 | // simulate flying by changing the effect of gravity | 450 | // simulate flying by changing the effect of gravity |
390 | this.Buoyancy = ComputeBuoyancyFromFlying(_flying); | 451 | Buoyancy = ComputeBuoyancyFromFlying(_flying); |
391 | } | 452 | } |
392 | } | 453 | } |
393 | // Flying is implimented by changing the avatar's buoyancy. | 454 | // Flying is implimented by changing the avatar's buoyancy. |
@@ -432,6 +493,10 @@ public class BSCharacter : BSPhysObject | |||
432 | get { return _rotationalVelocity; } | 493 | get { return _rotationalVelocity; } |
433 | set { _rotationalVelocity = value; } | 494 | set { _rotationalVelocity = value; } |
434 | } | 495 | } |
496 | public override OMV.Vector3 ForceRotationalVelocity { | ||
497 | get { return _rotationalVelocity; } | ||
498 | set { _rotationalVelocity = value; } | ||
499 | } | ||
435 | public override bool Kinematic { | 500 | public override bool Kinematic { |
436 | get { return _kinematic; } | 501 | get { return _kinematic; } |
437 | set { _kinematic = value; } | 502 | set { _kinematic = value; } |
@@ -443,10 +508,19 @@ public class BSCharacter : BSPhysObject | |||
443 | PhysicsScene.TaintedObject("BSCharacter.setBuoyancy", delegate() | 508 | PhysicsScene.TaintedObject("BSCharacter.setBuoyancy", delegate() |
444 | { | 509 | { |
445 | DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy); | 510 | DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy); |
446 | BulletSimAPI.SetObjectBuoyancy(PhysicsScene.WorldID, LocalID, _buoyancy); | 511 | ForceBuoyancy = _buoyancy; |
447 | }); | 512 | }); |
448 | } | 513 | } |
449 | } | 514 | } |
515 | public override float ForceBuoyancy { | ||
516 | get { return _buoyancy; } | ||
517 | set { _buoyancy = value; | ||
518 | DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); | ||
519 | // Buoyancy is faked by changing the gravity applied to the object | ||
520 | float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); | ||
521 | BulletSimAPI.SetGravity2(BSBody.ptr, new OMV.Vector3(0f, 0f, grav)); | ||
522 | } | ||
523 | } | ||
450 | 524 | ||
451 | // Used for MoveTo | 525 | // Used for MoveTo |
452 | public override OMV.Vector3 PIDTarget { | 526 | public override OMV.Vector3 PIDTarget { |
@@ -507,27 +581,32 @@ public class BSCharacter : BSPhysObject | |||
507 | 581 | ||
508 | private void ComputeAvatarScale(OMV.Vector3 size) | 582 | private void ComputeAvatarScale(OMV.Vector3 size) |
509 | { | 583 | { |
510 | _scale.X = PhysicsScene.Params.avatarCapsuleRadius; | 584 | // The 'size' given by the simulator is the mid-point of the avatar |
511 | _scale.Y = PhysicsScene.Params.avatarCapsuleRadius; | 585 | // and X and Y are unspecified. |
586 | |||
587 | OMV.Vector3 newScale = OMV.Vector3.Zero; | ||
588 | newScale.X = PhysicsScene.Params.avatarCapsuleRadius; | ||
589 | newScale.Y = PhysicsScene.Params.avatarCapsuleRadius; | ||
512 | 590 | ||
513 | // The 1.15 came from ODE but it seems to cause the avatar to float off the ground | 591 | // From the total height, remote the capsule half spheres that are at each end |
514 | // _scale.Z = (_size.Z * 1.15f) - (_scale.X + _scale.Y); | 592 | newScale.Z = (size.Z * 2f) - Math.Min(newScale.X, newScale.Y); |
515 | _scale.Z = (_size.Z) - (_scale.X + _scale.Y); | 593 | // newScale.Z = (size.Z * 2f); |
594 | Scale = newScale; | ||
516 | } | 595 | } |
517 | 596 | ||
518 | // set _avatarVolume and _mass based on capsule size, _density and _scale | 597 | // set _avatarVolume and _mass based on capsule size, _density and Scale |
519 | private void ComputeAvatarVolumeAndMass() | 598 | private void ComputeAvatarVolumeAndMass() |
520 | { | 599 | { |
521 | _avatarVolume = (float)( | 600 | _avatarVolume = (float)( |
522 | Math.PI | 601 | Math.PI |
523 | * _scale.X | 602 | * Scale.X |
524 | * _scale.Y // the area of capsule cylinder | 603 | * Scale.Y // the area of capsule cylinder |
525 | * _scale.Z // times height of capsule cylinder | 604 | * Scale.Z // times height of capsule cylinder |
526 | + 1.33333333f | 605 | + 1.33333333f |
527 | * Math.PI | 606 | * Math.PI |
528 | * _scale.X | 607 | * Scale.X |
529 | * Math.Min(_scale.X, _scale.Y) | 608 | * Math.Min(Scale.X, Scale.Y) |
530 | * _scale.Y // plus the volume of the capsule end caps | 609 | * Scale.Y // plus the volume of the capsule end caps |
531 | ); | 610 | ); |
532 | _mass = _avatarDensity * _avatarVolume; | 611 | _mass = _avatarDensity * _avatarVolume; |
533 | } | 612 | } |
@@ -542,7 +621,23 @@ public class BSCharacter : BSPhysObject | |||
542 | _acceleration = entprop.Acceleration; | 621 | _acceleration = entprop.Acceleration; |
543 | _rotationalVelocity = entprop.RotationalVelocity; | 622 | _rotationalVelocity = entprop.RotationalVelocity; |
544 | // 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. |
545 | PositionSanityCheck2(true); | 624 | PositionSanityCheck(true); |
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); | ||
546 | 641 | ||
547 | // 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. |
548 | // base.RequestPhysicsterseUpdate(); | 643 | // base.RequestPhysicsterseUpdate(); |