aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs511
1 files changed, 181 insertions, 330 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 5a9f135..65b38d6 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -54,17 +54,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
54{ 54{
55 public class BSDynamics 55 public class BSDynamics
56 { 56 {
57 private int frcount = 0; // Used to limit dynamics debug output to 57 private BSScene PhysicsScene { get; set; }
58 // every 100th frame 58 // the prim this dynamic controller belongs to
59 59 private BSPrim Prim { get; set; }
60 private BSPrim m_prim; // the prim this dynamic controller belongs to
61 60
62 // Vehicle properties 61 // Vehicle properties
63 private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind 62 public Vehicle Type { get; set; }
64 public Vehicle Type 63
65 {
66 get { return m_type; }
67 }
68 // private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier 64 // private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier
69 private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings: 65 private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings:
70 // HOVER_TERRAIN_ONLY 66 // HOVER_TERRAIN_ONLY
@@ -74,13 +70,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
74 // HOVER_UP_ONLY 70 // HOVER_UP_ONLY
75 // LIMIT_MOTOR_UP 71 // LIMIT_MOTOR_UP
76 // LIMIT_ROLL_ONLY 72 // LIMIT_ROLL_ONLY
77 private VehicleFlag m_Hoverflags = (VehicleFlag)0;
78 private Vector3 m_BlockingEndPoint = Vector3.Zero; 73 private Vector3 m_BlockingEndPoint = Vector3.Zero;
79 private Quaternion m_RollreferenceFrame = Quaternion.Identity; 74 private Quaternion m_RollreferenceFrame = Quaternion.Identity;
80 // Linear properties 75 // Linear properties
81 private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time 76 private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time
82 private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL 77 private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL
83 private Vector3 m_dir = Vector3.Zero; // velocity applied to body 78 private Vector3 m_newVelocity = Vector3.Zero; // velocity computed to be applied to body
84 private Vector3 m_linearFrictionTimescale = Vector3.Zero; 79 private Vector3 m_linearFrictionTimescale = Vector3.Zero;
85 private float m_linearMotorDecayTimescale = 0; 80 private float m_linearMotorDecayTimescale = 0;
86 private float m_linearMotorTimescale = 0; 81 private float m_linearMotorTimescale = 0;
@@ -124,15 +119,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin
124 private float m_verticalAttractionEfficiency = 1.0f; // damped 119 private float m_verticalAttractionEfficiency = 1.0f; // damped
125 private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. 120 private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor.
126 121
127 public BSDynamics(BSPrim myPrim) 122 public BSDynamics(BSScene myScene, BSPrim myPrim)
128 { 123 {
129 m_prim = myPrim; 124 PhysicsScene = myScene;
130 m_type = Vehicle.TYPE_NONE; 125 Prim = myPrim;
126 Type = Vehicle.TYPE_NONE;
131 } 127 }
132 128
133 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue, float timestep) 129 // Return 'true' if this vehicle is doing vehicle things
130 public bool IsActive
134 { 131 {
135 DetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); 132 get { return Type != Vehicle.TYPE_NONE; }
133 }
134
135 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
136 {
137 VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue);
136 switch (pParam) 138 switch (pParam)
137 { 139 {
138 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: 140 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
@@ -229,9 +231,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
229 } 231 }
230 }//end ProcessFloatVehicleParam 232 }//end ProcessFloatVehicleParam
231 233
232 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue, float timestep) 234 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue)
233 { 235 {
234 DetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); 236 VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue);
235 switch (pParam) 237 switch (pParam)
236 { 238 {
237 case Vehicle.ANGULAR_FRICTION_TIMESCALE: 239 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
@@ -266,7 +268,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
266 268
267 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) 269 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
268 { 270 {
269 DetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); 271 VDetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue);
270 switch (pParam) 272 switch (pParam)
271 { 273 {
272 case Vehicle.REFERENCE_FRAME: 274 case Vehicle.REFERENCE_FRAME:
@@ -280,166 +282,29 @@ namespace OpenSim.Region.Physics.BulletSPlugin
280 282
281 internal void ProcessVehicleFlags(int pParam, bool remove) 283 internal void ProcessVehicleFlags(int pParam, bool remove)
282 { 284 {
283 DetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", m_prim.LocalID, pParam, remove); 285 VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", Prim.LocalID, pParam, remove);
286 VehicleFlag parm = (VehicleFlag)pParam;
284 if (remove) 287 if (remove)
285 { 288 {
286 if (pParam == -1) 289 if (pParam == -1)
287 { 290 {
288 m_flags = (VehicleFlag)0; 291 m_flags = (VehicleFlag)0;
289 m_Hoverflags = (VehicleFlag)0;
290 return;
291 }
292 if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT)
293 {
294 if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != (VehicleFlag)0)
295 m_Hoverflags &= ~(VehicleFlag.HOVER_GLOBAL_HEIGHT);
296 }
297 if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
298 {
299 if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != (VehicleFlag)0)
300 m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY);
301 }
302 if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
303 {
304 if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != (VehicleFlag)0)
305 m_Hoverflags &= ~(VehicleFlag.HOVER_UP_ONLY);
306 }
307 if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
308 {
309 if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != (VehicleFlag)0)
310 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY);
311 }
312 if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
313 {
314 if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != (VehicleFlag)0)
315 m_flags &= ~(VehicleFlag.LIMIT_MOTOR_UP);
316 }
317 if ((pParam & (int)VehicleFlag.LIMIT_ROLL_ONLY) == (int)VehicleFlag.LIMIT_ROLL_ONLY)
318 {
319 if ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) != (VehicleFlag)0)
320 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
321 }
322 if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
323 {
324 if ((m_flags & VehicleFlag.MOUSELOOK_BANK) != (VehicleFlag)0)
325 m_flags &= ~(VehicleFlag.MOUSELOOK_BANK);
326 }
327 if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
328 {
329 if ((m_flags & VehicleFlag.MOUSELOOK_STEER) != (VehicleFlag)0)
330 m_flags &= ~(VehicleFlag.MOUSELOOK_STEER);
331 }
332 if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
333 {
334 if ((m_flags & VehicleFlag.NO_DEFLECTION_UP) != (VehicleFlag)0)
335 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP);
336 }
337 if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
338 {
339 if ((m_flags & VehicleFlag.CAMERA_DECOUPLED) != (VehicleFlag)0)
340 m_flags &= ~(VehicleFlag.CAMERA_DECOUPLED);
341 }
342 if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
343 {
344 if ((m_flags & VehicleFlag.NO_X) != (VehicleFlag)0)
345 m_flags &= ~(VehicleFlag.NO_X);
346 }
347 if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
348 {
349 if ((m_flags & VehicleFlag.NO_Y) != (VehicleFlag)0)
350 m_flags &= ~(VehicleFlag.NO_Y);
351 }
352 if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
353 {
354 if ((m_flags & VehicleFlag.NO_Z) != (VehicleFlag)0)
355 m_flags &= ~(VehicleFlag.NO_Z);
356 } 292 }
357 if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT) 293 else
358 {
359 if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != (VehicleFlag)0)
360 m_Hoverflags &= ~(VehicleFlag.LOCK_HOVER_HEIGHT);
361 }
362 if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
363 {
364 if ((m_flags & VehicleFlag.NO_DEFLECTION) != (VehicleFlag)0)
365 m_flags &= ~(VehicleFlag.NO_DEFLECTION);
366 }
367 if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
368 { 294 {
369 if ((m_flags & VehicleFlag.LOCK_ROTATION) != (VehicleFlag)0) 295 m_flags &= ~parm;
370 m_flags &= ~(VehicleFlag.LOCK_ROTATION);
371 } 296 }
372 } 297 }
373 else 298 else {
374 { 299 m_flags |= parm;
375 if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT)
376 {
377 m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT | m_flags);
378 }
379 if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
380 {
381 m_Hoverflags |= (VehicleFlag.HOVER_TERRAIN_ONLY | m_flags);
382 }
383 if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
384 {
385 m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY | m_flags);
386 }
387 if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
388 {
389 m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY | m_flags);
390 }
391 if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
392 {
393 m_flags |= (VehicleFlag.LIMIT_MOTOR_UP | m_flags);
394 }
395 if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
396 {
397 m_flags |= (VehicleFlag.MOUSELOOK_BANK | m_flags);
398 }
399 if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
400 {
401 m_flags |= (VehicleFlag.MOUSELOOK_STEER | m_flags);
402 }
403 if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
404 {
405 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | m_flags);
406 }
407 if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
408 {
409 m_flags |= (VehicleFlag.CAMERA_DECOUPLED | m_flags);
410 }
411 if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
412 {
413 m_flags |= (VehicleFlag.NO_X);
414 }
415 if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
416 {
417 m_flags |= (VehicleFlag.NO_Y);
418 }
419 if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
420 {
421 m_flags |= (VehicleFlag.NO_Z);
422 }
423 if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT)
424 {
425 m_Hoverflags |= (VehicleFlag.LOCK_HOVER_HEIGHT);
426 }
427 if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
428 {
429 m_flags |= (VehicleFlag.NO_DEFLECTION);
430 }
431 if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
432 {
433 m_flags |= (VehicleFlag.LOCK_ROTATION);
434 }
435 } 300 }
436 }//end ProcessVehicleFlags 301 }//end ProcessVehicleFlags
437 302
438 internal void ProcessTypeChange(Vehicle pType) 303 internal void ProcessTypeChange(Vehicle pType)
439 { 304 {
440 DetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType); 305 VDetailLog("{0},ProcessTypeChange,type={1}", Prim.LocalID, pType);
441 // Set Defaults For Type 306 // Set Defaults For Type
442 m_type = pType; 307 Type = pType;
443 switch (pType) 308 switch (pType)
444 { 309 {
445 case Vehicle.TYPE_NONE: 310 case Vehicle.TYPE_NONE:
@@ -478,10 +343,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
478 // m_bankingMix = 1; 343 // m_bankingMix = 1;
479 // m_bankingTimescale = 10; 344 // m_bankingTimescale = 10;
480 // m_referenceFrame = Quaternion.Identity; 345 // m_referenceFrame = Quaternion.Identity;
481 m_Hoverflags &= 346 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
347 m_flags &=
482 ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | 348 ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
483 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); 349 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
484 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
485 break; 350 break;
486 case Vehicle.TYPE_CAR: 351 case Vehicle.TYPE_CAR:
487 m_linearFrictionTimescale = new Vector3(100, 2, 1000); 352 m_linearFrictionTimescale = new Vector3(100, 2, 1000);
@@ -506,10 +371,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
506 // m_bankingMix = 1; 371 // m_bankingMix = 1;
507 // m_bankingTimescale = 1; 372 // m_bankingTimescale = 1;
508 // m_referenceFrame = Quaternion.Identity; 373 // m_referenceFrame = Quaternion.Identity;
509 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
510 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | 374 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY |
511 VehicleFlag.LIMIT_MOTOR_UP); 375 VehicleFlag.LIMIT_MOTOR_UP);
512 m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY); 376 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
377 m_flags |= (VehicleFlag.HOVER_UP_ONLY);
513 break; 378 break;
514 case Vehicle.TYPE_BOAT: 379 case Vehicle.TYPE_BOAT:
515 m_linearFrictionTimescale = new Vector3(10, 3, 2); 380 m_linearFrictionTimescale = new Vector3(10, 3, 2);
@@ -534,12 +399,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
534 // m_bankingMix = 0.8f; 399 // m_bankingMix = 0.8f;
535 // m_bankingTimescale = 1; 400 // m_bankingTimescale = 1;
536 // m_referenceFrame = Quaternion.Identity; 401 // m_referenceFrame = Quaternion.Identity;
537 m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | 402 m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
538 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); 403 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
539 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY); 404 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
540 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | 405 m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
541 VehicleFlag.LIMIT_MOTOR_UP); 406 VehicleFlag.LIMIT_MOTOR_UP);
542 m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY); 407 m_flags |= (VehicleFlag.HOVER_WATER_ONLY);
543 break; 408 break;
544 case Vehicle.TYPE_AIRPLANE: 409 case Vehicle.TYPE_AIRPLANE:
545 m_linearFrictionTimescale = new Vector3(200, 10, 5); 410 m_linearFrictionTimescale = new Vector3(200, 10, 5);
@@ -564,7 +429,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
564 // m_bankingMix = 0.7f; 429 // m_bankingMix = 0.7f;
565 // m_bankingTimescale = 2; 430 // m_bankingTimescale = 2;
566 // m_referenceFrame = Quaternion.Identity; 431 // m_referenceFrame = Quaternion.Identity;
567 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | 432 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
568 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); 433 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
569 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP); 434 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
570 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); 435 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
@@ -592,50 +457,63 @@ namespace OpenSim.Region.Physics.BulletSPlugin
592 // m_bankingMix = 0.7f; 457 // m_bankingMix = 0.7f;
593 // m_bankingTimescale = 5; 458 // m_bankingTimescale = 5;
594 // m_referenceFrame = Quaternion.Identity; 459 // m_referenceFrame = Quaternion.Identity;
595 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | 460 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
596 VehicleFlag.HOVER_UP_ONLY); 461 VehicleFlag.HOVER_UP_ONLY);
597 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP); 462 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
598 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); 463 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
599 m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT); 464 m_flags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT);
600 break; 465 break;
601 } 466 }
602 }//end SetDefaultsForType 467 }//end SetDefaultsForType
603 468
604 internal void Step(float pTimestep) 469 // Some of the properties of this prim may have changed.
470 // Do any updating needed for a vehicle
471 public void Refresh()
605 { 472 {
606 if (m_type == Vehicle.TYPE_NONE) return; 473 if (Type == Vehicle.TYPE_NONE) return;
474
475 // Set the prim's inertia to zero. The vehicle code handles that and this
476 // removes the torque action introduced by Bullet.
477 Vector3 inertia = Vector3.Zero;
478 BulletSimAPI.SetMassProps2(Prim.BSBody.ptr, Prim.MassRaw, inertia);
479 BulletSimAPI.UpdateInertiaTensor2(Prim.BSBody.ptr);
480 }
607 481
608 frcount++; // used to limit debug comment output 482 // One step of the vehicle properties for the next 'pTimestep' seconds.
609 if (frcount > 100) 483 internal void Step(float pTimestep)
610 frcount = 0; 484 {
485 if (!IsActive) return;
611 486
612 MoveLinear(pTimestep); 487 MoveLinear(pTimestep);
613 MoveAngular(pTimestep); 488 MoveAngular(pTimestep);
614 LimitRotation(pTimestep); 489 LimitRotation(pTimestep);
615 490
616 DetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", 491 // remember the position so next step we can limit absolute movement effects
617 m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity); 492 m_lastPositionVector = Prim.Position;
493
494 VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
495 Prim.LocalID, Prim.Position, Prim.Force, Prim.Velocity, Prim.RotationalVelocity);
618 }// end Step 496 }// end Step
619 497
498 // Apply the effect of the linear motor.
499 // Also does hover and float.
620 private void MoveLinear(float pTimestep) 500 private void MoveLinear(float pTimestep)
621 { 501 {
622 // requested m_linearMotorDirection is significant 502 // m_linearMotorDirection is the direction we are moving relative to the vehicle coordinates
623 // if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) 503 // m_lastLinearVelocityVector is the speed we are moving in that direction
624 if (m_linearMotorDirection.LengthSquared() > 0.0001f) 504 if (m_linearMotorDirection.LengthSquared() > 0.001f)
625 { 505 {
626 Vector3 origDir = m_linearMotorDirection; 506 Vector3 origDir = m_linearMotorDirection;
627 Vector3 origVel = m_lastLinearVelocityVector; 507 Vector3 origVel = m_lastLinearVelocityVector;
628 508
629 // add drive to body 509 // add drive to body
630 // Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep); 510 // Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale / pTimestep);
631 Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale); 511 Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/(m_linearMotorTimescale / pTimestep);
632 // lastLinearVelocityVector is the current body velocity vector? 512 // lastLinearVelocityVector is the current body velocity vector
633 // RA: Not sure what the *10 is for. A correction for pTimestep? 513 // RA: Not sure what the *10 is for. A correction for pTimestep?
634 // m_lastLinearVelocityVector += (addAmount*10); 514 // m_lastLinearVelocityVector += (addAmount*10);
635 m_lastLinearVelocityVector += addAmount; 515 m_lastLinearVelocityVector += addAmount;
636 516
637 // This will work temporarily, but we really need to compare speed on an axis
638 // KF: Limit body velocity to applied velocity?
639 // Limit the velocity vector to less than the last set linear motor direction 517 // Limit the velocity vector to less than the last set linear motor direction
640 if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X)) 518 if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X))
641 m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X; 519 m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X;
@@ -644,124 +522,87 @@ namespace OpenSim.Region.Physics.BulletSPlugin
644 if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z)) 522 if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z))
645 m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z; 523 m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z;
646 524
525 /*
647 // decay applied velocity 526 // decay applied velocity
648 Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep))); 527 Vector3 decayfraction = Vector3.One/(m_linearMotorDecayTimescale / pTimestep);
528 // (RA: do not know where the 0.5f comes from)
649 m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f; 529 m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f;
650
651 /*
652 Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/m_linearMotorTimescale;
653 m_lastLinearVelocityVector += addAmount;
654
655 float decayfraction = (1.0f - 1.0f / m_linearMotorDecayTimescale);
656 m_linearMotorDirection *= decayfraction;
657
658 */ 530 */
531 float keepfraction = 1.0f - (1.0f / (m_linearMotorDecayTimescale / pTimestep));
532 m_linearMotorDirection *= keepfraction;
659 533
660 DetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}", 534 VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},notDecay={4},dir={5},vel={6}",
661 m_prim.LocalID, origDir, origVel, addAmount, decayfraction, m_linearMotorDirection, m_lastLinearVelocityVector); 535 Prim.LocalID, origDir, origVel, addAmount, keepfraction, m_linearMotorDirection, m_lastLinearVelocityVector);
662 } 536 }
663 else 537 else
664 { 538 {
665 // if what remains of applied is small, zero it. 539 // if what remains of direction is very small, zero it.
666 // if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f))
667 // m_lastLinearVelocityVector = Vector3.Zero;
668 m_linearMotorDirection = Vector3.Zero; 540 m_linearMotorDirection = Vector3.Zero;
669 m_lastLinearVelocityVector = Vector3.Zero; 541 m_lastLinearVelocityVector = Vector3.Zero;
542 VDetailLog("{0},MoveLinear,zeroed", Prim.LocalID);
670 } 543 }
671 544
672 // convert requested object velocity to world-referenced vector 545 // convert requested object velocity to object relative vector
673 Quaternion rotq = m_prim.Orientation; 546 Quaternion rotq = Prim.Orientation;
674 m_dir = m_lastLinearVelocityVector * rotq; 547 m_newVelocity = m_lastLinearVelocityVector * rotq;
675 548
676 // Add the various forces into m_dir which will be our new direction vector (velocity) 549 // Add the various forces into m_dir which will be our new direction vector (velocity)
677 550
678 // add Gravity and Buoyancy 551 // add Gravity and Buoyancy
679 // KF: So far I have found no good method to combine a script-requested
680 // .Z velocity and gravity. Therefore only 0g will used script-requested
681 // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only.
682 Vector3 grav = Vector3.Zero;
683 // There is some gravity, make a gravity force vector that is applied after object velocity. 552 // There is some gravity, make a gravity force vector that is applied after object velocity.
684 // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; 553 // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
685 grav.Z = m_prim.Scene.DefaultGravity.Z * m_prim.Mass * (1f - m_VehicleBuoyancy); 554 Vector3 grav = Prim.PhysicsScene.DefaultGravity * (Prim.Mass * (1f - m_VehicleBuoyancy));
555
556 /*
557 * RA: Not sure why one would do this
686 // Preserve the current Z velocity 558 // Preserve the current Z velocity
687 Vector3 vel_now = m_prim.Velocity; 559 Vector3 vel_now = m_prim.Velocity;
688 m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity 560 m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity
561 */
689 562
690 Vector3 pos = m_prim.Position; 563 Vector3 pos = Prim.Position;
691 Vector3 posChange = pos;
692// Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f); 564// Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f);
693 double Zchange = Math.Abs(posChange.Z);
694 if (m_BlockingEndPoint != Vector3.Zero)
695 {
696 bool changed = false;
697 if (pos.X >= (m_BlockingEndPoint.X - (float)1))
698 {
699 pos.X -= posChange.X + 1;
700 changed = true;
701 }
702 if (pos.Y >= (m_BlockingEndPoint.Y - (float)1))
703 {
704 pos.Y -= posChange.Y + 1;
705 changed = true;
706 }
707 if (pos.Z >= (m_BlockingEndPoint.Z - (float)1))
708 {
709 pos.Z -= posChange.Z + 1;
710 changed = true;
711 }
712 if (pos.X <= 0)
713 {
714 pos.X += posChange.X + 1;
715 changed = true;
716 }
717 if (pos.Y <= 0)
718 {
719 pos.Y += posChange.Y + 1;
720 changed = true;
721 }
722 if (changed)
723 {
724 m_prim.Position = pos;
725 DetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
726 m_prim.LocalID, m_BlockingEndPoint, posChange, pos);
727 }
728 }
729 565
730 // If below the terrain, move us above the ground a little. 566 // If below the terrain, move us above the ground a little.
731 if (pos.Z < m_prim.Scene.GetTerrainHeightAtXYZ(pos)) 567 float terrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos);
568 // Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset.
569 // Need to add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass.
570 // Vector3 rotatedSize = m_prim.Size * m_prim.Orientation;
571 // if (rotatedSize.Z < terrainHeight)
572 if (pos.Z < terrainHeight)
732 { 573 {
733 pos.Z = m_prim.Scene.GetTerrainHeightAtXYZ(pos) + 2; 574 pos.Z = terrainHeight + 2;
734 m_prim.Position = pos; 575 Prim.Position = pos;
735 DetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos); 576 VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, terrainHeight, pos);
736 } 577 }
737 578
738 // Check if hovering 579 // Check if hovering
739 if ((m_Hoverflags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) 580 if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
740 { 581 {
741 // We should hover, get the target height 582 // We should hover, get the target height
742 if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != 0) 583 if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
743 { 584 {
744 m_VhoverTargetHeight = m_prim.Scene.GetWaterLevel() + m_VhoverHeight; 585 m_VhoverTargetHeight = Prim.PhysicsScene.GetWaterLevelAtXYZ(pos) + m_VhoverHeight;
745 } 586 }
746 if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) 587 if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
747 { 588 {
748 m_VhoverTargetHeight = m_prim.Scene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight; 589 m_VhoverTargetHeight = terrainHeight + m_VhoverHeight;
749 } 590 }
750 if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) 591 if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0)
751 { 592 {
752 m_VhoverTargetHeight = m_VhoverHeight; 593 m_VhoverTargetHeight = m_VhoverHeight;
753 } 594 }
754 595
755 if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != 0) 596 if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0)
756 { 597 {
757 // If body is aready heigher, use its height as target height 598 // If body is aready heigher, use its height as target height
758 if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; 599 if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
759 } 600 }
760 if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) 601 if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
761 { 602 {
762 if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2) 603 if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2)
763 { 604 {
764 m_prim.Position = pos; 605 Prim.Position = pos;
765 } 606 }
766 } 607 }
767 else 608 else
@@ -770,85 +611,96 @@ namespace OpenSim.Region.Physics.BulletSPlugin
770 // Replace Vertical speed with correction figure if significant 611 // Replace Vertical speed with correction figure if significant
771 if (Math.Abs(herr0) > 0.01f) 612 if (Math.Abs(herr0) > 0.01f)
772 { 613 {
773 m_dir.Z = -((herr0 * pTimestep * 50.0f) / m_VhoverTimescale); 614 m_newVelocity.Z = -((herr0 * pTimestep * 50.0f) / m_VhoverTimescale);
774 //KF: m_VhoverEfficiency is not yet implemented 615 //KF: m_VhoverEfficiency is not yet implemented
775 } 616 }
776 else 617 else
777 { 618 {
778 m_dir.Z = 0f; 619 m_newVelocity.Z = 0f;
779 } 620 }
780 } 621 }
781 622
782 DetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight); 623 VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", Prim.LocalID, pos, m_newVelocity, m_VhoverHeight, m_VhoverTargetHeight);
624 }
783 625
784// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped 626 Vector3 posChange = pos - m_lastPositionVector;
785// m_VhoverTimescale = 0f; // time to acheive height 627 if (m_BlockingEndPoint != Vector3.Zero)
786// pTimestep is time since last frame,in secs 628 {
629 bool changed = false;
630 if (pos.X >= (m_BlockingEndPoint.X - (float)1))
631 {
632 pos.X -= posChange.X + 1;
633 changed = true;
634 }
635 if (pos.Y >= (m_BlockingEndPoint.Y - (float)1))
636 {
637 pos.Y -= posChange.Y + 1;
638 changed = true;
639 }
640 if (pos.Z >= (m_BlockingEndPoint.Z - (float)1))
641 {
642 pos.Z -= posChange.Z + 1;
643 changed = true;
644 }
645 if (pos.X <= 0)
646 {
647 pos.X += posChange.X + 1;
648 changed = true;
649 }
650 if (pos.Y <= 0)
651 {
652 pos.Y += posChange.Y + 1;
653 changed = true;
654 }
655 if (changed)
656 {
657 Prim.Position = pos;
658 VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
659 Prim.LocalID, m_BlockingEndPoint, posChange, pos);
660 }
787 } 661 }
788 662
663 float Zchange = Math.Abs(posChange.Z);
789 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) 664 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0)
790 { 665 {
791 //Start Experimental Values
792 if (Zchange > .3) 666 if (Zchange > .3)
793 {
794 grav.Z = (float)(grav.Z * 3); 667 grav.Z = (float)(grav.Z * 3);
795 }
796 if (Zchange > .15) 668 if (Zchange > .15)
797 {
798 grav.Z = (float)(grav.Z * 2); 669 grav.Z = (float)(grav.Z * 2);
799 }
800 if (Zchange > .75) 670 if (Zchange > .75)
801 {
802 grav.Z = (float)(grav.Z * 1.5); 671 grav.Z = (float)(grav.Z * 1.5);
803 }
804 if (Zchange > .05) 672 if (Zchange > .05)
805 {
806 grav.Z = (float)(grav.Z * 1.25); 673 grav.Z = (float)(grav.Z * 1.25);
807 }
808 if (Zchange > .025) 674 if (Zchange > .025)
809 {
810 grav.Z = (float)(grav.Z * 1.125); 675 grav.Z = (float)(grav.Z * 1.125);
811 } 676 float postemp = (pos.Z - terrainHeight);
812 float terraintemp = m_prim.Scene.GetTerrainHeightAtXYZ(pos);
813 float postemp = (pos.Z - terraintemp);
814 if (postemp > 2.5f) 677 if (postemp > 2.5f)
815 {
816 grav.Z = (float)(grav.Z * 1.037125); 678 grav.Z = (float)(grav.Z * 1.037125);
817 } 679 VDetailLog("{0},MoveLinear,limitMotorUp,grav={1}", Prim.LocalID, grav);
818 DetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav);
819 //End Experimental Values
820 } 680 }
821 if ((m_flags & (VehicleFlag.NO_X)) != 0) 681 if ((m_flags & (VehicleFlag.NO_X)) != 0)
822 { 682 m_newVelocity.X = 0;
823 m_dir.X = 0;
824 }
825 if ((m_flags & (VehicleFlag.NO_Y)) != 0) 683 if ((m_flags & (VehicleFlag.NO_Y)) != 0)
826 { 684 m_newVelocity.Y = 0;
827 m_dir.Y = 0;
828 }
829 if ((m_flags & (VehicleFlag.NO_Z)) != 0) 685 if ((m_flags & (VehicleFlag.NO_Z)) != 0)
830 { 686 m_newVelocity.Z = 0;
831 m_dir.Z = 0;
832 }
833
834 m_lastPositionVector = m_prim.Position;
835 687
836 // Apply velocity 688 // Apply velocity
837 m_prim.Velocity = m_dir; 689 Prim.Velocity = m_newVelocity;
838 // apply gravity force 690 // apply gravity force
839 // Why is this set here? The physics engine already does gravity. 691 // Why is this set here? The physics engine already does gravity.
840 // m_prim.AddForce(grav, false); 692 // m_prim.AddForce(grav, false);
841 // m_prim.Force = grav;
842 693
843 // Apply friction 694 // Apply friction
844 Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); 695 Vector3 keepFraction = Vector3.One - (Vector3.One / (m_linearFrictionTimescale / pTimestep));
845 m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount; 696 m_lastLinearVelocityVector *= keepFraction;
846 697
847 DetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}", 698 VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},grav={4},1Mdecay={5}",
848 m_prim.LocalID, m_lastPositionVector, m_dir, grav, decayamount); 699 Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity, grav, keepFraction);
849 700
850 } // end MoveLinear() 701 } // end MoveLinear()
851 702
703 // Apply the effect of the angular motor.
852 private void MoveAngular(float pTimestep) 704 private void MoveAngular(float pTimestep)
853 { 705 {
854 // m_angularMotorDirection // angular velocity requested by LSL motor 706 // m_angularMotorDirection // angular velocity requested by LSL motor
@@ -860,7 +712,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
860 // m_lastAngularVelocity // what was last applied to body 712 // m_lastAngularVelocity // what was last applied to body
861 713
862 // Get what the body is doing, this includes 'external' influences 714 // Get what the body is doing, this includes 'external' influences
863 Vector3 angularVelocity = m_prim.RotationalVelocity; 715 Vector3 angularVelocity = Prim.RotationalVelocity;
864 716
865 if (m_angularMotorApply > 0) 717 if (m_angularMotorApply > 0)
866 { 718 {
@@ -870,32 +722,35 @@ namespace OpenSim.Region.Physics.BulletSPlugin
870 // There are m_angularMotorApply steps. 722 // There are m_angularMotorApply steps.
871 Vector3 origAngularVelocity = m_angularMotorVelocity; 723 Vector3 origAngularVelocity = m_angularMotorVelocity;
872 // ramp up to new value 724 // ramp up to new value
873 // current velocity += error / (time to get there / step interval) 725 // current velocity += error / ( time to get there / step interval)
874 // requested speed - last motor speed 726 // requested speed - last motor speed
875 m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep); 727 m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep);
876 m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep); 728 m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep);
877 m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep); 729 m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep);
878 730
879 DetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}", 731 VDetailLog("{0},MoveAngular,angularMotorApply,apply={1},angTScale={2},timeStep={3},origvel={4},dir={5},vel={6}",
880 m_prim.LocalID,m_angularMotorApply,origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity); 732 Prim.LocalID, m_angularMotorApply, m_angularMotorTimescale, pTimestep, origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity);
881 733
882 m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected 734 // This is done so that if script request rate is less than phys frame rate the expected
883 // velocity may still be acheived. 735 // velocity may still be acheived.
736 m_angularMotorApply--;
884 } 737 }
885 else 738 else
886 { 739 {
887 // No motor recently applied, keep the body velocity 740 // No motor recently applied, keep the body velocity
888 // and decay the velocity 741 // and decay the velocity
889 m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep); 742 m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep);
743 if (m_angularMotorVelocity.LengthSquared() < 0.00001)
744 m_angularMotorVelocity = Vector3.Zero;
890 } // end motor section 745 } // end motor section
891 746
892 // Vertical attractor section 747 // Vertical attractor section
893 Vector3 vertattr = Vector3.Zero; 748 Vector3 vertattr = Vector3.Zero;
894 if (m_verticalAttractionTimescale < 300) 749 if (m_verticalAttractionTimescale < 300)
895 { 750 {
896 float VAservo = 0.2f / (m_verticalAttractionTimescale * pTimestep); 751 float VAservo = 0.2f / (m_verticalAttractionTimescale / pTimestep);
897 // get present body rotation 752 // get present body rotation
898 Quaternion rotq = m_prim.Orientation; 753 Quaternion rotq = Prim.Orientation;
899 // make a vector pointing up 754 // make a vector pointing up
900 Vector3 verterr = Vector3.Zero; 755 Vector3 verterr = Vector3.Zero;
901 verterr.Z = 1.0f; 756 verterr.Z = 1.0f;
@@ -924,8 +779,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
924 vertattr.X += bounce * angularVelocity.X; 779 vertattr.X += bounce * angularVelocity.X;
925 vertattr.Y += bounce * angularVelocity.Y; 780 vertattr.Y += bounce * angularVelocity.Y;
926 781
927 DetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}", 782 VDetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}",
928 m_prim.LocalID, verterr, bounce, vertattr); 783 Prim.LocalID, verterr, bounce, vertattr);
929 784
930 } // else vertical attractor is off 785 } // else vertical attractor is off
931 786
@@ -937,18 +792,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin
937 792
938 // Sum velocities 793 // Sum velocities
939 m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // + bank + deflection 794 m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // + bank + deflection
940 795
941 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) 796 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
942 { 797 {
943 m_lastAngularVelocity.X = 0; 798 m_lastAngularVelocity.X = 0;
944 m_lastAngularVelocity.Y = 0; 799 m_lastAngularVelocity.Y = 0;
945 DetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity); 800 VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity);
946 } 801 }
947 802
948 if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) 803 if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
949 { 804 {
950 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. 805 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
951 DetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity); 806 VDetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity);
952 } 807 }
953 808
954 // apply friction 809 // apply friction
@@ -956,14 +811,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin
956 m_lastAngularVelocity -= m_lastAngularVelocity * decayamount; 811 m_lastAngularVelocity -= m_lastAngularVelocity * decayamount;
957 812
958 // Apply to the body 813 // Apply to the body
959 m_prim.RotationalVelocity = m_lastAngularVelocity; 814 Prim.RotationalVelocity = m_lastAngularVelocity;
960 815
961 DetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", m_prim.LocalID, decayamount, m_lastAngularVelocity); 816 VDetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", Prim.LocalID, decayamount, m_lastAngularVelocity);
962 } //end MoveAngular 817 } //end MoveAngular
963 818
964 internal void LimitRotation(float timestep) 819 internal void LimitRotation(float timestep)
965 { 820 {
966 Quaternion rotq = m_prim.Orientation; 821 Quaternion rotq = Prim.Orientation;
967 Quaternion m_rot = rotq; 822 Quaternion m_rot = rotq;
968 bool changed = false; 823 bool changed = false;
969 if (m_RollreferenceFrame != Quaternion.Identity) 824 if (m_RollreferenceFrame != Quaternion.Identity)
@@ -996,23 +851,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin
996 m_rot.Y = 0; 851 m_rot.Y = 0;
997 changed = true; 852 changed = true;
998 } 853 }
999 if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0) 854 if (changed)
1000 { 855 {
1001 m_rot.X = 0; 856 Prim.Orientation = m_rot;
1002 m_rot.Y = 0; 857 VDetailLog("{0},LimitRotation,done,orig={1},new={2}", Prim.LocalID, rotq, m_rot);
1003 changed = true;
1004 } 858 }
1005 if (changed)
1006 m_prim.Orientation = m_rot;
1007 859
1008 DetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot);
1009 } 860 }
1010 861
1011 // Invoke the detailed logger and output something if it's enabled. 862 // Invoke the detailed logger and output something if it's enabled.
1012 private void DetailLog(string msg, params Object[] args) 863 private void VDetailLog(string msg, params Object[] args)
1013 { 864 {
1014 if (m_prim.Scene.VehicleLoggingEnabled) 865 if (Prim.PhysicsScene.VehicleLoggingEnabled)
1015 m_prim.Scene.PhysicsLogging.Write(msg, args); 866 Prim.PhysicsScene.PhysicsLogging.Write(msg, args);
1016 } 867 }
1017 } 868 }
1018} 869}