aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
diff options
context:
space:
mode:
authorRobert Adams2013-05-08 06:02:12 -0700
committerRobert Adams2013-05-08 06:02:12 -0700
commiteb0687f5af127ad6195b95965ce31346f2bc0a24 (patch)
tree8888b8d4c45874c646da0b475d09bd051b33e1cc /OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
parentAdd regression test for inventory item give, reject and subsequent trash fold... (diff)
downloadopensim-SC_OLD-eb0687f5af127ad6195b95965ce31346f2bc0a24.zip
opensim-SC_OLD-eb0687f5af127ad6195b95965ce31346f2bc0a24.tar.gz
opensim-SC_OLD-eb0687f5af127ad6195b95965ce31346f2bc0a24.tar.bz2
opensim-SC_OLD-eb0687f5af127ad6195b95965ce31346f2bc0a24.tar.xz
vh: update BulletSim (OpenSim/Region/Physics/BulletSPlugin
and DLL/SO) to ac6dcd35fb77f118fc6c3d72cb029591306c7e99 (Mon May 6 21:10:02 2013 -0400) on top of 0.7.5-postfixes.
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs385
1 files changed, 145 insertions, 240 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 103d8fc..542f732 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -45,11 +45,7 @@ public sealed class BSCharacter : BSPhysObject
45 private bool _selected; 45 private bool _selected;
46 private OMV.Vector3 _position; 46 private OMV.Vector3 _position;
47 private float _mass; 47 private float _mass;
48 private float _avatarDensity;
49 private float _avatarVolume; 48 private float _avatarVolume;
50 private OMV.Vector3 _force;
51 private OMV.Vector3 _velocity;
52 private OMV.Vector3 _torque;
53 private float _collisionScore; 49 private float _collisionScore;
54 private OMV.Vector3 _acceleration; 50 private OMV.Vector3 _acceleration;
55 private OMV.Quaternion _orientation; 51 private OMV.Quaternion _orientation;
@@ -58,25 +54,17 @@ public sealed class BSCharacter : BSPhysObject
58 private bool _flying; 54 private bool _flying;
59 private bool _setAlwaysRun; 55 private bool _setAlwaysRun;
60 private bool _throttleUpdates; 56 private bool _throttleUpdates;
61 private bool _isColliding;
62 private bool _collidingObj;
63 private bool _floatOnWater; 57 private bool _floatOnWater;
64 private OMV.Vector3 _rotationalVelocity; 58 private OMV.Vector3 _rotationalVelocity;
65 private bool _kinematic; 59 private bool _kinematic;
66 private float _buoyancy; 60 private float _buoyancy;
67 61
68 // The friction and velocity of the avatar is modified depending on whether walking or not. 62 private BSActorAvatarMove m_moveActor;
69 private float _currentFriction; // the friction currently being used (changed by setVelocity). 63 private const string AvatarMoveActorName = "BSCharacter.AvatarMove";
70
71 private BSVMotor _velocityMotor;
72 64
73 private OMV.Vector3 _PIDTarget; 65 private OMV.Vector3 _PIDTarget;
74 private bool _usePID; 66 private bool _usePID;
75 private float _PIDTau; 67 private float _PIDTau;
76 private bool _useHoverPID;
77 private float _PIDHoverHeight;
78 private PIDHoverType _PIDHoverType;
79 private float _PIDHoverTao;
80 68
81 public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying) 69 public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying)
82 : base(parent_scene, localID, avName, "BSCharacter") 70 : base(parent_scene, localID, avName, "BSCharacter")
@@ -86,10 +74,10 @@ public sealed class BSCharacter : BSPhysObject
86 74
87 _flying = isFlying; 75 _flying = isFlying;
88 _orientation = OMV.Quaternion.Identity; 76 _orientation = OMV.Quaternion.Identity;
89 _velocity = OMV.Vector3.Zero; 77 RawVelocity = OMV.Vector3.Zero;
90 _buoyancy = ComputeBuoyancyFromFlying(isFlying); 78 _buoyancy = ComputeBuoyancyFromFlying(isFlying);
91 _currentFriction = BSParam.AvatarStandingFriction; 79 Friction = BSParam.AvatarStandingFriction;
92 _avatarDensity = BSParam.AvatarDensity; 80 Density = BSParam.AvatarDensity / BSParam.DensityScaleFactor;
93 81
94 // Old versions of ScenePresence passed only the height. If width and/or depth are zero, 82 // Old versions of ScenePresence passed only the height. If width and/or depth are zero,
95 // replace with the default values. 83 // replace with the default values.
@@ -103,17 +91,22 @@ public sealed class BSCharacter : BSPhysObject
103 // set _avatarVolume and _mass based on capsule size, _density and Scale 91 // set _avatarVolume and _mass based on capsule size, _density and Scale
104 ComputeAvatarVolumeAndMass(); 92 ComputeAvatarVolumeAndMass();
105 93
106 SetupMovementMotor(); 94 // The avatar's movement is controlled by this motor that speeds up and slows down
95 // the avatar seeking to reach the motor's target speed.
96 // This motor runs as a prestep action for the avatar so it will keep the avatar
97 // standing as well as moving. Destruction of the avatar will destroy the pre-step action.
98 m_moveActor = new BSActorAvatarMove(PhysScene, this, AvatarMoveActorName);
99 PhysicalActors.Add(AvatarMoveActorName, m_moveActor);
107 100
108 DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", 101 DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}",
109 LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); 102 LocalID, _size, Scale, Density, _avatarVolume, RawMass);
110 103
111 // do actual creation in taint time 104 // do actual creation in taint time
112 PhysicsScene.TaintedObject("BSCharacter.create", delegate() 105 PhysScene.TaintedObject("BSCharacter.create", delegate()
113 { 106 {
114 DetailLog("{0},BSCharacter.create,taint", LocalID); 107 DetailLog("{0},BSCharacter.create,taint", LocalID);
115 // New body and shape into PhysBody and PhysShape 108 // New body and shape into PhysBody and PhysShape
116 PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this); 109 PhysScene.Shapes.GetBodyAndShape(true, PhysScene.World, this);
117 110
118 SetPhysicalProperties(); 111 SetPhysicalProperties();
119 }); 112 });
@@ -126,114 +119,63 @@ public sealed class BSCharacter : BSPhysObject
126 base.Destroy(); 119 base.Destroy();
127 120
128 DetailLog("{0},BSCharacter.Destroy", LocalID); 121 DetailLog("{0},BSCharacter.Destroy", LocalID);
129 PhysicsScene.TaintedObject("BSCharacter.destroy", delegate() 122 PhysScene.TaintedObject("BSCharacter.destroy", delegate()
130 { 123 {
131 PhysicsScene.Shapes.DereferenceBody(PhysBody, true, null); 124 PhysScene.Shapes.DereferenceBody(PhysBody, null /* bodyCallback */);
132 PhysBody.Clear(); 125 PhysBody.Clear();
133 PhysicsScene.Shapes.DereferenceShape(PhysShape, true, null); 126 PhysShape.Dereference(PhysScene);
134 PhysShape.Clear(); 127 PhysShape = new BSShapeNull();
135 }); 128 });
136 } 129 }
137 130
138 private void SetPhysicalProperties() 131 private void SetPhysicalProperties()
139 { 132 {
140 PhysicsScene.PE.RemoveObjectFromWorld(PhysicsScene.World, PhysBody); 133 PhysScene.PE.RemoveObjectFromWorld(PhysScene.World, PhysBody);
141 134
142 ZeroMotion(true); 135 ZeroMotion(true);
143 ForcePosition = _position; 136 ForcePosition = _position;
144 137
145 // Set the velocity and compute the proper friction 138 // Set the velocity
146 _velocityMotor.Reset(); 139 if (m_moveActor != null)
147 _velocityMotor.SetTarget(_velocity); 140 m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, false);
148 _velocityMotor.SetCurrent(_velocity); 141
149 ForceVelocity = _velocity; 142 ForceVelocity = RawVelocity;
150 143
151 // This will enable or disable the flying buoyancy of the avatar. 144 // This will enable or disable the flying buoyancy of the avatar.
152 // Needs to be reset especially when an avatar is recreated after crossing a region boundry. 145 // Needs to be reset especially when an avatar is recreated after crossing a region boundry.
153 Flying = _flying; 146 Flying = _flying;
154 147
155 PhysicsScene.PE.SetRestitution(PhysBody, BSParam.AvatarRestitution); 148 PhysScene.PE.SetRestitution(PhysBody, BSParam.AvatarRestitution);
156 PhysicsScene.PE.SetMargin(PhysShape, PhysicsScene.Params.collisionMargin); 149 PhysScene.PE.SetMargin(PhysShape.physShapeInfo, PhysScene.Params.collisionMargin);
157 PhysicsScene.PE.SetLocalScaling(PhysShape, Scale); 150 PhysScene.PE.SetLocalScaling(PhysShape.physShapeInfo, Scale);
158 PhysicsScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold); 151 PhysScene.PE.SetContactProcessingThreshold(PhysBody, BSParam.ContactProcessingThreshold);
159 if (BSParam.CcdMotionThreshold > 0f) 152 if (BSParam.CcdMotionThreshold > 0f)
160 { 153 {
161 PhysicsScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold); 154 PhysScene.PE.SetCcdMotionThreshold(PhysBody, BSParam.CcdMotionThreshold);
162 PhysicsScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius); 155 PhysScene.PE.SetCcdSweptSphereRadius(PhysBody, BSParam.CcdSweptSphereRadius);
163 } 156 }
164 157
165 UpdatePhysicalMassProperties(RawMass, false); 158 UpdatePhysicalMassProperties(RawMass, false);
166 159
167 // Make so capsule does not fall over 160 // Make so capsule does not fall over
168 PhysicsScene.PE.SetAngularFactorV(PhysBody, OMV.Vector3.Zero); 161 PhysScene.PE.SetAngularFactorV(PhysBody, OMV.Vector3.Zero);
169 162
170 PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_CHARACTER_OBJECT); 163 // The avatar mover sets some parameters.
164 PhysicalActors.Refresh();
171 165
172 PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody); 166 PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_CHARACTER_OBJECT);
167
168 PhysScene.PE.AddObjectToWorld(PhysScene.World, PhysBody);
173 169
174 // PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG); 170 // PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.ACTIVE_TAG);
175 PhysicsScene.PE.ForceActivationState(PhysBody, ActivationState.DISABLE_DEACTIVATION); 171 PhysScene.PE.ForceActivationState(PhysBody, ActivationState.DISABLE_DEACTIVATION);
176 PhysicsScene.PE.UpdateSingleAabb(PhysicsScene.World, PhysBody); 172 PhysScene.PE.UpdateSingleAabb(PhysScene.World, PhysBody);
177 173
178 // Do this after the object has been added to the world 174 // Do this after the object has been added to the world
179 PhysBody.collisionType = CollisionType.Avatar; 175 PhysBody.collisionType = CollisionType.Avatar;
180 PhysBody.ApplyCollisionMask(PhysicsScene); 176 PhysBody.ApplyCollisionMask(PhysScene);
181 } 177 }
182 178
183 // The avatar's movement is controlled by this motor that speeds up and slows down
184 // the avatar seeking to reach the motor's target speed.
185 // This motor runs as a prestep action for the avatar so it will keep the avatar
186 // standing as well as moving. Destruction of the avatar will destroy the pre-step action.
187 private void SetupMovementMotor()
188 {
189
190 // Someday, use a PID motor for asymmetric speed up and slow down
191 // _velocityMotor = new BSPIDVMotor("BSCharacter.Velocity", 3f, 5f, BSMotor.InfiniteVector, 1f);
192
193 // Infinite decay and timescale values so motor only changes current to target values.
194 _velocityMotor = new BSVMotor("BSCharacter.Velocity",
195 0.2f, // time scale
196 BSMotor.Infinite, // decay time scale
197 BSMotor.InfiniteVector, // friction timescale
198 1f // efficiency
199 );
200 // _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
201
202 RegisterPreStepAction("BSCharactor.Movement", LocalID, delegate(float timeStep)
203 {
204 // TODO: Decide if the step parameters should be changed depending on the avatar's
205 // state (flying, colliding, ...). There is code in ODE to do this.
206
207 OMV.Vector3 stepVelocity = _velocityMotor.Step(timeStep);
208
209 // If falling, we keep the world's downward vector no matter what the other axis specify.
210 if (!Flying && !IsColliding)
211 {
212 stepVelocity.Z = _velocity.Z;
213 // DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity);
214 }
215
216 // 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force.
217 OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass / PhysicsScene.LastTimeStep;
218
219 /*
220 // If moveForce is very small, zero things so we don't keep sending microscopic updates to the user
221 float moveForceMagnitudeSquared = moveForce.LengthSquared();
222 if (moveForceMagnitudeSquared < 0.0001)
223 {
224 DetailLog("{0},BSCharacter.MoveMotor,zeroMovement,stepVel={1},vel={2},mass={3},magSq={4},moveForce={5}",
225 LocalID, stepVelocity, _velocity, Mass, moveForceMagnitudeSquared, moveForce);
226 ForceVelocity = OMV.Vector3.Zero;
227 }
228 else
229 {
230 AddForce(moveForce, false, true);
231 }
232 */
233 // DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce);
234 AddForce(moveForce, false, true);
235 });
236 }
237 179
238 public override void RequestPhysicsterseUpdate() 180 public override void RequestPhysicsterseUpdate()
239 { 181 {
@@ -259,16 +201,16 @@ public sealed class BSCharacter : BSPhysObject
259 Scale = ComputeAvatarScale(_size); 201 Scale = ComputeAvatarScale(_size);
260 ComputeAvatarVolumeAndMass(); 202 ComputeAvatarVolumeAndMass();
261 DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}", 203 DetailLog("{0},BSCharacter.setSize,call,size={1},scale={2},density={3},volume={4},mass={5}",
262 LocalID, _size, Scale, _avatarDensity, _avatarVolume, RawMass); 204 LocalID, _size, Scale, Density, _avatarVolume, RawMass);
263 205
264 PhysicsScene.TaintedObject("BSCharacter.setSize", delegate() 206 PhysScene.TaintedObject("BSCharacter.setSize", delegate()
265 { 207 {
266 if (PhysBody.HasPhysicalBody && PhysShape.HasPhysicalShape) 208 if (PhysBody.HasPhysicalBody && PhysShape.physShapeInfo.HasPhysicalShape)
267 { 209 {
268 PhysicsScene.PE.SetLocalScaling(PhysShape, Scale); 210 PhysScene.PE.SetLocalScaling(PhysShape.physShapeInfo, Scale);
269 UpdatePhysicalMassProperties(RawMass, true); 211 UpdatePhysicalMassProperties(RawMass, true);
270 // Make sure this change appears as a property update event 212 // Make sure this change appears as a property update event
271 PhysicsScene.PE.PushUpdate(PhysBody); 213 PhysScene.PE.PushUpdate(PhysBody);
272 } 214 }
273 }); 215 });
274 216
@@ -279,11 +221,6 @@ public sealed class BSCharacter : BSPhysObject
279 { 221 {
280 set { BaseShape = value; } 222 set { BaseShape = value; }
281 } 223 }
282 // I want the physics engine to make an avatar capsule
283 public override BSPhysicsShapeType PreferredPhysicalShape
284 {
285 get {return BSPhysicsShapeType.SHAPE_CAPSULE; }
286 }
287 224
288 public override bool Grabbed { 225 public override bool Grabbed {
289 set { _grabbed = value; } 226 set { _grabbed = value; }
@@ -291,6 +228,10 @@ public sealed class BSCharacter : BSPhysObject
291 public override bool Selected { 228 public override bool Selected {
292 set { _selected = value; } 229 set { _selected = value; }
293 } 230 }
231 public override bool IsSelected
232 {
233 get { return _selected; }
234 }
294 public override void CrossingFailure() { return; } 235 public override void CrossingFailure() { return; }
295 public override void link(PhysicsActor obj) { return; } 236 public override void link(PhysicsActor obj) { return; }
296 public override void delink() { return; } 237 public override void delink() { return; }
@@ -301,29 +242,29 @@ public sealed class BSCharacter : BSPhysObject
301 // Called at taint time! 242 // Called at taint time!
302 public override void ZeroMotion(bool inTaintTime) 243 public override void ZeroMotion(bool inTaintTime)
303 { 244 {
304 _velocity = OMV.Vector3.Zero; 245 RawVelocity = OMV.Vector3.Zero;
305 _acceleration = OMV.Vector3.Zero; 246 _acceleration = OMV.Vector3.Zero;
306 _rotationalVelocity = OMV.Vector3.Zero; 247 _rotationalVelocity = OMV.Vector3.Zero;
307 248
308 // Zero some other properties directly into the physics engine 249 // Zero some other properties directly into the physics engine
309 PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate() 250 PhysScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate()
310 { 251 {
311 if (PhysBody.HasPhysicalBody) 252 if (PhysBody.HasPhysicalBody)
312 PhysicsScene.PE.ClearAllForces(PhysBody); 253 PhysScene.PE.ClearAllForces(PhysBody);
313 }); 254 });
314 } 255 }
315 public override void ZeroAngularMotion(bool inTaintTime) 256 public override void ZeroAngularMotion(bool inTaintTime)
316 { 257 {
317 _rotationalVelocity = OMV.Vector3.Zero; 258 _rotationalVelocity = OMV.Vector3.Zero;
318 259
319 PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate() 260 PhysScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate()
320 { 261 {
321 if (PhysBody.HasPhysicalBody) 262 if (PhysBody.HasPhysicalBody)
322 { 263 {
323 PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, OMV.Vector3.Zero); 264 PhysScene.PE.SetInterpolationAngularVelocity(PhysBody, OMV.Vector3.Zero);
324 PhysicsScene.PE.SetAngularVelocity(PhysBody, OMV.Vector3.Zero); 265 PhysScene.PE.SetAngularVelocity(PhysBody, OMV.Vector3.Zero);
325 // The next also get rid of applied linear force but the linear velocity is untouched. 266 // The next also get rid of applied linear force but the linear velocity is untouched.
326 PhysicsScene.PE.ClearForces(PhysBody); 267 PhysScene.PE.ClearForces(PhysBody);
327 } 268 }
328 }); 269 });
329 } 270 }
@@ -344,25 +285,26 @@ public sealed class BSCharacter : BSPhysObject
344 } 285 }
345 set { 286 set {
346 _position = value; 287 _position = value;
347 PositionSanityCheck();
348 288
349 PhysicsScene.TaintedObject("BSCharacter.setPosition", delegate() 289 PhysScene.TaintedObject("BSCharacter.setPosition", delegate()
350 { 290 {
351 DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); 291 DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
352 if (PhysBody.HasPhysicalBody) 292 PositionSanityCheck();
353 PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); 293 ForcePosition = _position;
354 }); 294 });
355 } 295 }
356 } 296 }
357 public override OMV.Vector3 ForcePosition { 297 public override OMV.Vector3 ForcePosition {
358 get { 298 get {
359 _position = PhysicsScene.PE.GetPosition(PhysBody); 299 _position = PhysScene.PE.GetPosition(PhysBody);
360 return _position; 300 return _position;
361 } 301 }
362 set { 302 set {
363 _position = value; 303 _position = value;
364 PositionSanityCheck(); 304 if (PhysBody.HasPhysicalBody)
365 PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); 305 {
306 PhysScene.PE.SetTranslation(PhysBody, _position, _orientation);
307 }
366 } 308 }
367 } 309 }
368 310
@@ -375,25 +317,27 @@ public sealed class BSCharacter : BSPhysObject
375 bool ret = false; 317 bool ret = false;
376 318
377 // TODO: check for out of bounds 319 // TODO: check for out of bounds
378 if (!PhysicsScene.TerrainManager.IsWithinKnownTerrain(_position)) 320 if (!PhysScene.TerrainManager.IsWithinKnownTerrain(RawPosition))
379 { 321 {
380 // The character is out of the known/simulated area. 322 // The character is out of the known/simulated area.
381 // Upper levels of code will handle the transition to other areas so, for 323 // Force the avatar position to be within known. ScenePresence will use the position
382 // the time, we just ignore the position. 324 // plus the velocity to decide if the avatar is moving out of the region.
383 return ret; 325 RawPosition = PhysScene.TerrainManager.ClampPositionIntoKnownTerrain(RawPosition);
326 DetailLog("{0},BSCharacter.PositionSanityCheck,notWithinKnownTerrain,clampedPos={1}", LocalID, RawPosition);
327 return true;
384 } 328 }
385 329
386 // If below the ground, move the avatar up 330 // If below the ground, move the avatar up
387 float terrainHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(_position); 331 float terrainHeight = PhysScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition);
388 if (Position.Z < terrainHeight) 332 if (Position.Z < terrainHeight)
389 { 333 {
390 DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight); 334 DetailLog("{0},BSCharacter.PositionSanityCheck,adjustForUnderGround,pos={1},terrain={2}", LocalID, _position, terrainHeight);
391 _position.Z = terrainHeight + 2.0f; 335 _position.Z = terrainHeight + BSParam.AvatarBelowGroundUpCorrectionMeters;
392 ret = true; 336 ret = true;
393 } 337 }
394 if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0) 338 if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0)
395 { 339 {
396 float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position); 340 float waterHeight = PhysScene.TerrainManager.GetWaterLevelAtXYZ(_position);
397 if (Position.Z < waterHeight) 341 if (Position.Z < waterHeight)
398 { 342 {
399 _position.Z = waterHeight; 343 _position.Z = waterHeight;
@@ -414,11 +358,10 @@ public sealed class BSCharacter : BSPhysObject
414 { 358 {
415 // The new position value must be pushed into the physics engine but we can't 359 // The new position value must be pushed into the physics engine but we can't
416 // just assign to "Position" because of potential call loops. 360 // just assign to "Position" because of potential call loops.
417 PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.PositionSanityCheck", delegate() 361 PhysScene.TaintedObject(inTaintTime, "BSCharacter.PositionSanityCheck", delegate()
418 { 362 {
419 DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation); 363 DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation);
420 if (PhysBody.HasPhysicalBody) 364 ForcePosition = _position;
421 PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation);
422 }); 365 });
423 ret = true; 366 ret = true;
424 } 367 }
@@ -428,25 +371,25 @@ public sealed class BSCharacter : BSPhysObject
428 public override float Mass { get { return _mass; } } 371 public override float Mass { get { return _mass; } }
429 372
430 // used when we only want this prim's mass and not the linkset thing 373 // used when we only want this prim's mass and not the linkset thing
431 public override float RawMass { 374 public override float RawMass {
432 get {return _mass; } 375 get {return _mass; }
433 } 376 }
434 public override void UpdatePhysicalMassProperties(float physMass, bool inWorld) 377 public override void UpdatePhysicalMassProperties(float physMass, bool inWorld)
435 { 378 {
436 OMV.Vector3 localInertia = PhysicsScene.PE.CalculateLocalInertia(PhysShape, physMass); 379 OMV.Vector3 localInertia = PhysScene.PE.CalculateLocalInertia(PhysShape.physShapeInfo, physMass);
437 PhysicsScene.PE.SetMassProps(PhysBody, physMass, localInertia); 380 PhysScene.PE.SetMassProps(PhysBody, physMass, localInertia);
438 } 381 }
439 382
440 public override OMV.Vector3 Force { 383 public override OMV.Vector3 Force {
441 get { return _force; } 384 get { return RawForce; }
442 set { 385 set {
443 _force = value; 386 RawForce = value;
444 // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force); 387 // m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force);
445 PhysicsScene.TaintedObject("BSCharacter.SetForce", delegate() 388 PhysScene.TaintedObject("BSCharacter.SetForce", delegate()
446 { 389 {
447 DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force); 390 DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, RawForce);
448 if (PhysBody.HasPhysicalBody) 391 if (PhysBody.HasPhysicalBody)
449 PhysicsScene.PE.SetObjectForce(PhysBody, _force); 392 PhysScene.PE.SetObjectForce(PhysBody, RawForce);
450 }); 393 });
451 } 394 }
452 } 395 }
@@ -469,77 +412,49 @@ public sealed class BSCharacter : BSPhysObject
469 { 412 {
470 get 413 get
471 { 414 {
472 return _velocityMotor.TargetValue; 415 return base.m_targetVelocity;
473 } 416 }
474 set 417 set
475 { 418 {
476 DetailLog("{0},BSCharacter.setTargetVelocity,call,vel={1}", LocalID, value); 419 DetailLog("{0},BSCharacter.setTargetVelocity,call,vel={1}", LocalID, value);
420 m_targetVelocity = value;
477 OMV.Vector3 targetVel = value; 421 OMV.Vector3 targetVel = value;
478 if (_setAlwaysRun) 422 if (_setAlwaysRun)
479 targetVel *= BSParam.AvatarAlwaysRunFactor; 423 targetVel *= new OMV.Vector3(BSParam.AvatarAlwaysRunFactor, BSParam.AvatarAlwaysRunFactor, 0f);
480 424
481 PhysicsScene.TaintedObject("BSCharacter.setTargetVelocity", delegate() 425 if (m_moveActor != null)
482 { 426 m_moveActor.SetVelocityAndTarget(RawVelocity, targetVel, false /* inTaintTime */);
483 _velocityMotor.Reset();
484 _velocityMotor.SetTarget(targetVel);
485 _velocityMotor.SetCurrent(_velocity);
486 _velocityMotor.Enabled = true;
487 });
488 } 427 }
489 } 428 }
490 // Directly setting velocity means this is what the user really wants now. 429 // Directly setting velocity means this is what the user really wants now.
491 public override OMV.Vector3 Velocity { 430 public override OMV.Vector3 Velocity {
492 get { return _velocity; } 431 get { return RawVelocity; }
493 set { 432 set {
494 _velocity = value; 433 RawVelocity = value;
495 // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity); 434 // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, RawVelocity);
496 PhysicsScene.TaintedObject("BSCharacter.setVelocity", delegate() 435 PhysScene.TaintedObject("BSCharacter.setVelocity", delegate()
497 { 436 {
498 _velocityMotor.Reset(); 437 if (m_moveActor != null)
499 _velocityMotor.SetCurrent(_velocity); 438 m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, true /* inTaintTime */);
500 _velocityMotor.SetTarget(_velocity); 439
501 // Even though the motor is initialized, it's not used and the velocity goes straight into the avatar. 440 DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, RawVelocity);
502 _velocityMotor.Enabled = false; 441 ForceVelocity = RawVelocity;
503
504 DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity);
505 ForceVelocity = _velocity;
506 }); 442 });
507 } 443 }
508 } 444 }
509 public override OMV.Vector3 ForceVelocity { 445 public override OMV.Vector3 ForceVelocity {
510 get { return _velocity; } 446 get { return RawVelocity; }
511 set { 447 set {
512 PhysicsScene.AssertInTaintTime("BSCharacter.ForceVelocity"); 448 PhysScene.AssertInTaintTime("BSCharacter.ForceVelocity");
513 449
514 _velocity = value; 450 RawVelocity = value;
515 // Depending on whether the avatar is moving or not, change the friction 451 PhysScene.PE.SetLinearVelocity(PhysBody, RawVelocity);
516 // to keep the avatar from slipping around 452 PhysScene.PE.Activate(PhysBody, true);
517 if (_velocity.Length() == 0)
518 {
519 if (_currentFriction != BSParam.AvatarStandingFriction)
520 {
521 _currentFriction = BSParam.AvatarStandingFriction;
522 if (PhysBody.HasPhysicalBody)
523 PhysicsScene.PE.SetFriction(PhysBody, _currentFriction);
524 }
525 }
526 else
527 {
528 if (_currentFriction != BSParam.AvatarFriction)
529 {
530 _currentFriction = BSParam.AvatarFriction;
531 if (PhysBody.HasPhysicalBody)
532 PhysicsScene.PE.SetFriction(PhysBody, _currentFriction);
533 }
534 }
535
536 PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity);
537 PhysicsScene.PE.Activate(PhysBody, true);
538 } 453 }
539 } 454 }
540 public override OMV.Vector3 Torque { 455 public override OMV.Vector3 Torque {
541 get { return _torque; } 456 get { return RawTorque; }
542 set { _torque = value; 457 set { RawTorque = value;
543 } 458 }
544 } 459 }
545 public override float CollisionScore { 460 public override float CollisionScore {
@@ -564,7 +479,7 @@ public sealed class BSCharacter : BSPhysObject
564 if (_orientation != value) 479 if (_orientation != value)
565 { 480 {
566 _orientation = value; 481 _orientation = value;
567 PhysicsScene.TaintedObject("BSCharacter.setOrientation", delegate() 482 PhysScene.TaintedObject("BSCharacter.setOrientation", delegate()
568 { 483 {
569 ForceOrientation = _orientation; 484 ForceOrientation = _orientation;
570 }); 485 });
@@ -576,7 +491,7 @@ public sealed class BSCharacter : BSPhysObject
576 { 491 {
577 get 492 get
578 { 493 {
579 _orientation = PhysicsScene.PE.GetOrientation(PhysBody); 494 _orientation = PhysScene.PE.GetOrientation(PhysBody);
580 return _orientation; 495 return _orientation;
581 } 496 }
582 set 497 set
@@ -585,7 +500,7 @@ public sealed class BSCharacter : BSPhysObject
585 if (PhysBody.HasPhysicalBody) 500 if (PhysBody.HasPhysicalBody)
586 { 501 {
587 // _position = PhysicsScene.PE.GetPosition(BSBody); 502 // _position = PhysicsScene.PE.GetPosition(BSBody);
588 PhysicsScene.PE.SetTranslation(PhysBody, _position, _orientation); 503 PhysScene.PE.SetTranslation(PhysBody, _position, _orientation);
589 } 504 }
590 } 505 }
591 } 506 }
@@ -605,6 +520,9 @@ public sealed class BSCharacter : BSPhysObject
605 public override bool IsStatic { 520 public override bool IsStatic {
606 get { return false; } 521 get { return false; }
607 } 522 }
523 public override bool IsPhysicallyActive {
524 get { return true; }
525 }
608 public override bool Flying { 526 public override bool Flying {
609 get { return _flying; } 527 get { return _flying; }
610 set { 528 set {
@@ -631,14 +549,14 @@ public sealed class BSCharacter : BSPhysObject
631 public override bool FloatOnWater { 549 public override bool FloatOnWater {
632 set { 550 set {
633 _floatOnWater = value; 551 _floatOnWater = value;
634 PhysicsScene.TaintedObject("BSCharacter.setFloatOnWater", delegate() 552 PhysScene.TaintedObject("BSCharacter.setFloatOnWater", delegate()
635 { 553 {
636 if (PhysBody.HasPhysicalBody) 554 if (PhysBody.HasPhysicalBody)
637 { 555 {
638 if (_floatOnWater) 556 if (_floatOnWater)
639 CurrentCollisionFlags = PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER); 557 CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER);
640 else 558 else
641 CurrentCollisionFlags = PhysicsScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER); 559 CurrentCollisionFlags = PhysScene.PE.RemoveFromCollisionFlags(PhysBody, CollisionFlags.BS_FLOATS_ON_WATER);
642 } 560 }
643 }); 561 });
644 } 562 }
@@ -659,7 +577,7 @@ public sealed class BSCharacter : BSPhysObject
659 public override float Buoyancy { 577 public override float Buoyancy {
660 get { return _buoyancy; } 578 get { return _buoyancy; }
661 set { _buoyancy = value; 579 set { _buoyancy = value;
662 PhysicsScene.TaintedObject("BSCharacter.setBuoyancy", delegate() 580 PhysScene.TaintedObject("BSCharacter.setBuoyancy", delegate()
663 { 581 {
664 DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 582 DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
665 ForceBuoyancy = _buoyancy; 583 ForceBuoyancy = _buoyancy;
@@ -668,15 +586,16 @@ public sealed class BSCharacter : BSPhysObject
668 } 586 }
669 public override float ForceBuoyancy { 587 public override float ForceBuoyancy {
670 get { return _buoyancy; } 588 get { return _buoyancy; }
671 set { 589 set {
672 PhysicsScene.AssertInTaintTime("BSCharacter.ForceBuoyancy"); 590 PhysScene.AssertInTaintTime("BSCharacter.ForceBuoyancy");
673 591
674 _buoyancy = value; 592 _buoyancy = value;
675 DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 593 DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
676 // Buoyancy is faked by changing the gravity applied to the object 594 // Buoyancy is faked by changing the gravity applied to the object
677 float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); 595 float grav = BSParam.Gravity * (1f - _buoyancy);
596 Gravity = new OMV.Vector3(0f, 0f, grav);
678 if (PhysBody.HasPhysicalBody) 597 if (PhysBody.HasPhysicalBody)
679 PhysicsScene.PE.SetGravity(PhysBody, new OMV.Vector3(0f, 0f, grav)); 598 PhysScene.PE.SetGravity(PhysBody, Gravity);
680 } 599 }
681 } 600 }
682 601
@@ -691,53 +610,25 @@ public sealed class BSCharacter : BSPhysObject
691 set { _PIDTau = value; } 610 set { _PIDTau = value; }
692 } 611 }
693 612
694 // Used for llSetHoverHeight and maybe vehicle height
695 // Hover Height will override MoveTo target's Z
696 public override bool PIDHoverActive {
697 set { _useHoverPID = value; }
698 }
699 public override float PIDHoverHeight {
700 set { _PIDHoverHeight = value; }
701 }
702 public override PIDHoverType PIDHoverType {
703 set { _PIDHoverType = value; }
704 }
705 public override float PIDHoverTau {
706 set { _PIDHoverTao = value; }
707 }
708
709 // For RotLookAt
710 public override OMV.Quaternion APIDTarget { set { return; } }
711 public override bool APIDActive { set { return; } }
712 public override float APIDStrength { set { return; } }
713 public override float APIDDamping { set { return; } }
714
715 public override void AddForce(OMV.Vector3 force, bool pushforce) 613 public override void AddForce(OMV.Vector3 force, bool pushforce)
716 { 614 {
717 // Since this force is being applied in only one step, make this a force per second. 615 // Since this force is being applied in only one step, make this a force per second.
718 OMV.Vector3 addForce = force / PhysicsScene.LastTimeStep; 616 OMV.Vector3 addForce = force / PhysScene.LastTimeStep;
719 AddForce(addForce, pushforce, false); 617 AddForce(addForce, pushforce, false);
720 } 618 }
721 private void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) { 619 private void AddForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) {
722 if (force.IsFinite()) 620 if (force.IsFinite())
723 { 621 {
724 float magnitude = force.Length(); 622 OMV.Vector3 addForce = Util.ClampV(force, BSParam.MaxAddForceMagnitude);
725 if (magnitude > BSParam.MaxAddForceMagnitude)
726 {
727 // Force has a limit
728 force = force / magnitude * BSParam.MaxAddForceMagnitude;
729 }
730
731 OMV.Vector3 addForce = force;
732 // DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce); 623 // DetailLog("{0},BSCharacter.addForce,call,force={1}", LocalID, addForce);
733 624
734 PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate() 625 PhysScene.TaintedObject(inTaintTime, "BSCharacter.AddForce", delegate()
735 { 626 {
736 // Bullet adds this central force to the total force for this tick 627 // Bullet adds this central force to the total force for this tick
737 // DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce); 628 // DetailLog("{0},BSCharacter.addForce,taint,force={1}", LocalID, addForce);
738 if (PhysBody.HasPhysicalBody) 629 if (PhysBody.HasPhysicalBody)
739 { 630 {
740 PhysicsScene.PE.ApplyCentralForce(PhysBody, addForce); 631 PhysScene.PE.ApplyCentralForce(PhysBody, addForce);
741 } 632 }
742 }); 633 });
743 } 634 }
@@ -748,7 +639,7 @@ public sealed class BSCharacter : BSPhysObject
748 } 639 }
749 } 640 }
750 641
751 public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { 642 public override void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) {
752 } 643 }
753 public override void SetMomentum(OMV.Vector3 momentum) { 644 public override void SetMomentum(OMV.Vector3 momentum) {
754 } 645 }
@@ -756,7 +647,7 @@ public sealed class BSCharacter : BSPhysObject
756 private OMV.Vector3 ComputeAvatarScale(OMV.Vector3 size) 647 private OMV.Vector3 ComputeAvatarScale(OMV.Vector3 size)
757 { 648 {
758 OMV.Vector3 newScale; 649 OMV.Vector3 newScale;
759 650
760 // Bullet's capsule total height is the "passed height + radius * 2"; 651 // Bullet's capsule total height is the "passed height + radius * 2";
761 // The base capsule is 1 diameter and 2 height (passed radius=0.5, passed height = 1) 652 // The base capsule is 1 diameter and 2 height (passed radius=0.5, passed height = 1)
762 // The number we pass in for 'scaling' is the multiplier to get that base 653 // The number we pass in for 'scaling' is the multiplier to get that base
@@ -794,34 +685,48 @@ public sealed class BSCharacter : BSPhysObject
794 * Math.Min(Size.X, Size.Y) / 2 685 * Math.Min(Size.X, Size.Y) / 2
795 * Size.Y / 2f // plus the volume of the capsule end caps 686 * Size.Y / 2f // plus the volume of the capsule end caps
796 ); 687 );
797 _mass = _avatarDensity * _avatarVolume; 688 _mass = Density * BSParam.DensityScaleFactor * _avatarVolume;
798 } 689 }
799 690
800 // The physics engine says that properties have updated. Update same and inform 691 // The physics engine says that properties have updated. Update same and inform
801 // the world that things have changed. 692 // the world that things have changed.
802 public override void UpdateProperties(EntityProperties entprop) 693 public override void UpdateProperties(EntityProperties entprop)
803 { 694 {
804 _position = entprop.Position; 695 // Don't change position if standing on a stationary object.
696 if (!IsStationary)
697 _position = entprop.Position;
698
805 _orientation = entprop.Rotation; 699 _orientation = entprop.Rotation;
806 _velocity = entprop.Velocity; 700
701 // Smooth velocity. OpenSimulator is VERY sensitive to changes in velocity of the avatar
702 // and will send agent updates to the clients if velocity changes by more than
703 // 0.001m/s. Bullet introduces a lot of jitter in the velocity which causes many
704 // extra updates.
705 if (!entprop.Velocity.ApproxEquals(RawVelocity, 0.1f))
706 RawVelocity = entprop.Velocity;
707
807 _acceleration = entprop.Acceleration; 708 _acceleration = entprop.Acceleration;
808 _rotationalVelocity = entprop.RotationalVelocity; 709 _rotationalVelocity = entprop.RotationalVelocity;
809 710
810 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds. 711 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
811 PositionSanityCheck(true); 712 if (PositionSanityCheck(true))
713 {
714 DetailLog("{0},BSCharacter.UpdateProperties,updatePosForSanity,pos={1}", LocalID, _position);
715 entprop.Position = _position;
716 }
812 717
813 // remember the current and last set values 718 // remember the current and last set values
814 LastEntityProperties = CurrentEntityProperties; 719 LastEntityProperties = CurrentEntityProperties;
815 CurrentEntityProperties = entprop; 720 CurrentEntityProperties = entprop;
816 721
817 // Tell the linkset about value changes 722 // Tell the linkset about value changes
818 Linkset.UpdateProperties(this, true); 723 // Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
819 724
820 // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. 725 // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
821 // base.RequestPhysicsterseUpdate(); 726 // base.RequestPhysicsterseUpdate();
822 727
823 DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", 728 DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
824 LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); 729 LocalID, _position, _orientation, RawVelocity, _acceleration, _rotationalVelocity);
825 } 730 }
826} 731}
827} 732}