aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs')
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs401
1 files changed, 362 insertions, 39 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs
index 008070b..6ae0c8a 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs
@@ -82,7 +82,9 @@ namespace OpenSim.Region.Physics.OdePlugin
82 // HOVER_UP_ONLY 82 // HOVER_UP_ONLY
83 // LIMIT_MOTOR_UP 83 // LIMIT_MOTOR_UP
84 // LIMIT_ROLL_ONLY 84 // LIMIT_ROLL_ONLY
85 85 private VehicleFlag m_Hoverflags = (VehicleFlag)0;
86 private Vector3 m_BlockingEndPoint = Vector3.Zero;
87 private Quaternion m_RollreferenceFrame = Quaternion.Identity;
86 // Linear properties 88 // Linear properties
87 private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time 89 private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time
88 private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL 90 private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL
@@ -91,6 +93,7 @@ namespace OpenSim.Region.Physics.OdePlugin
91 private float m_linearMotorDecayTimescale = 0; 93 private float m_linearMotorDecayTimescale = 0;
92 private float m_linearMotorTimescale = 0; 94 private float m_linearMotorTimescale = 0;
93 private Vector3 m_lastLinearVelocityVector = Vector3.Zero; 95 private Vector3 m_lastLinearVelocityVector = Vector3.Zero;
96 private d.Vector3 m_lastPositionVector = new d.Vector3();
94 // private bool m_LinearMotorSetLastFrame = false; 97 // private bool m_LinearMotorSetLastFrame = false;
95 // private Vector3 m_linearMotorOffset = Vector3.Zero; 98 // private Vector3 m_linearMotorOffset = Vector3.Zero;
96 99
@@ -255,6 +258,9 @@ namespace OpenSim.Region.Physics.OdePlugin
255 case Vehicle.LINEAR_MOTOR_OFFSET: 258 case Vehicle.LINEAR_MOTOR_OFFSET:
256 // m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); 259 // m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
257 break; 260 break;
261 case Vehicle.BLOCK_EXIT:
262 m_BlockingEndPoint = new Vector3(pValue.X, pValue.Y, pValue.Z);
263 break;
258 } 264 }
259 }//end ProcessVectorVehicleParam 265 }//end ProcessVectorVehicleParam
260 266
@@ -265,15 +271,189 @@ namespace OpenSim.Region.Physics.OdePlugin
265 case Vehicle.REFERENCE_FRAME: 271 case Vehicle.REFERENCE_FRAME:
266 // m_referenceFrame = pValue; 272 // m_referenceFrame = pValue;
267 break; 273 break;
274 case Vehicle.ROLL_FRAME:
275 m_RollreferenceFrame = pValue;
276 break;
268 } 277 }
269 }//end ProcessRotationVehicleParam 278 }//end ProcessRotationVehicleParam
270 279
280 internal void ProcessVehicleFlags(int pParam, bool remove)
281 {
282 if (remove)
283 {
284 if (pParam == -1)
285 {
286 m_flags = (VehicleFlag)0;
287 m_Hoverflags = (VehicleFlag)0;
288 return;
289 }
290 if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT)
291 {
292 if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != (VehicleFlag)0)
293 m_Hoverflags &= ~(VehicleFlag.HOVER_GLOBAL_HEIGHT);
294 }
295 if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
296 {
297 if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != (VehicleFlag)0)
298 m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY);
299 }
300 if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
301 {
302 if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != (VehicleFlag)0)
303 m_Hoverflags &= ~(VehicleFlag.HOVER_UP_ONLY);
304 }
305 if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
306 {
307 if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != (VehicleFlag)0)
308 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY);
309 }
310 if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
311 {
312 if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != (VehicleFlag)0)
313 m_flags &= ~(VehicleFlag.LIMIT_MOTOR_UP);
314 }
315 if ((pParam & (int)VehicleFlag.LIMIT_ROLL_ONLY) == (int)VehicleFlag.LIMIT_ROLL_ONLY)
316 {
317 if ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) != (VehicleFlag)0)
318 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
319 }
320 if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
321 {
322 if ((m_flags & VehicleFlag.MOUSELOOK_BANK) != (VehicleFlag)0)
323 m_flags &= ~(VehicleFlag.MOUSELOOK_BANK);
324 }
325 if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
326 {
327 if ((m_flags & VehicleFlag.MOUSELOOK_STEER) != (VehicleFlag)0)
328 m_flags &= ~(VehicleFlag.MOUSELOOK_STEER);
329 }
330 if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
331 {
332 if ((m_flags & VehicleFlag.NO_DEFLECTION_UP) != (VehicleFlag)0)
333 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP);
334 }
335 if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
336 {
337 if ((m_flags & VehicleFlag.CAMERA_DECOUPLED) != (VehicleFlag)0)
338 m_flags &= ~(VehicleFlag.CAMERA_DECOUPLED);
339 }
340 if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
341 {
342 if ((m_flags & VehicleFlag.NO_X) != (VehicleFlag)0)
343 m_flags &= ~(VehicleFlag.NO_X);
344 }
345 if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
346 {
347 if ((m_flags & VehicleFlag.NO_Y) != (VehicleFlag)0)
348 m_flags &= ~(VehicleFlag.NO_Y);
349 }
350 if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
351 {
352 if ((m_flags & VehicleFlag.NO_Z) != (VehicleFlag)0)
353 m_flags &= ~(VehicleFlag.NO_Z);
354 }
355 if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT)
356 {
357 if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != (VehicleFlag)0)
358 m_Hoverflags &= ~(VehicleFlag.LOCK_HOVER_HEIGHT);
359 }
360 if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
361 {
362 if ((m_flags & VehicleFlag.NO_DEFLECTION) != (VehicleFlag)0)
363 m_flags &= ~(VehicleFlag.NO_DEFLECTION);
364 }
365 if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
366 {
367 if ((m_flags & VehicleFlag.LOCK_ROTATION) != (VehicleFlag)0)
368 m_flags &= ~(VehicleFlag.LOCK_ROTATION);
369 }
370 }
371 else
372 {
373 if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT)
374 {
375 m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT | m_flags);
376 }
377 if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
378 {
379 m_Hoverflags |= (VehicleFlag.HOVER_TERRAIN_ONLY | m_flags);
380 }
381 if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
382 {
383 m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY | m_flags);
384 }
385 if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
386 {
387 m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY | m_flags);
388 }
389 if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
390 {
391 m_flags |= (VehicleFlag.LIMIT_MOTOR_UP | m_flags);
392 }
393 if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
394 {
395 m_flags |= (VehicleFlag.MOUSELOOK_BANK | m_flags);
396 }
397 if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
398 {
399 m_flags |= (VehicleFlag.MOUSELOOK_STEER | m_flags);
400 }
401 if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
402 {
403 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | m_flags);
404 }
405 if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
406 {
407 m_flags |= (VehicleFlag.CAMERA_DECOUPLED | m_flags);
408 }
409 if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
410 {
411 m_flags |= (VehicleFlag.NO_X);
412 }
413 if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
414 {
415 m_flags |= (VehicleFlag.NO_Y);
416 }
417 if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
418 {
419 m_flags |= (VehicleFlag.NO_Z);
420 }
421 if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT)
422 {
423 m_Hoverflags |= (VehicleFlag.LOCK_HOVER_HEIGHT);
424 }
425 if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
426 {
427 m_flags |= (VehicleFlag.NO_DEFLECTION);
428 }
429 if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
430 {
431 m_flags |= (VehicleFlag.LOCK_ROTATION);
432 }
433 }
434 }//end ProcessVehicleFlags
435
271 internal void ProcessTypeChange(Vehicle pType) 436 internal void ProcessTypeChange(Vehicle pType)
272 { 437 {
273 // Set Defaults For Type 438 // Set Defaults For Type
274 m_type = pType; 439 m_type = pType;
275 switch (pType) 440 switch (pType)
276 { 441 {
442 case Vehicle.TYPE_NONE:
443 m_linearFrictionTimescale = new Vector3(0, 0, 0);
444 m_angularFrictionTimescale = new Vector3(0, 0, 0);
445 m_linearMotorDirection = Vector3.Zero;
446 m_linearMotorTimescale = 0;
447 m_linearMotorDecayTimescale = 0;
448 m_angularMotorDirection = Vector3.Zero;
449 m_angularMotorTimescale = 0;
450 m_angularMotorDecayTimescale = 0;
451 m_VhoverHeight = 0;
452 m_VhoverTimescale = 0;
453 m_VehicleBuoyancy = 0;
454 m_flags = (VehicleFlag)0;
455 break;
456
277 case Vehicle.TYPE_SLED: 457 case Vehicle.TYPE_SLED:
278 m_linearFrictionTimescale = new Vector3(30, 1, 1000); 458 m_linearFrictionTimescale = new Vector3(30, 1, 1000);
279 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); 459 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
@@ -295,9 +475,9 @@ namespace OpenSim.Region.Physics.OdePlugin
295 // m_bankingMix = 1; 475 // m_bankingMix = 1;
296 // m_bankingTimescale = 10; 476 // m_bankingTimescale = 10;
297 // m_referenceFrame = Quaternion.Identity; 477 // m_referenceFrame = Quaternion.Identity;
298 m_flags &= 478 m_Hoverflags &=
299 ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | 479 ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
300 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); 480 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
301 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP); 481 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
302 break; 482 break;
303 case Vehicle.TYPE_CAR: 483 case Vehicle.TYPE_CAR:
@@ -323,9 +503,10 @@ namespace OpenSim.Region.Physics.OdePlugin
323 // m_bankingMix = 1; 503 // m_bankingMix = 1;
324 // m_bankingTimescale = 1; 504 // m_bankingTimescale = 1;
325 // m_referenceFrame = Quaternion.Identity; 505 // m_referenceFrame = Quaternion.Identity;
326 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); 506 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
327 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_UP_ONLY | 507 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY |
328 VehicleFlag.LIMIT_MOTOR_UP); 508 VehicleFlag.LIMIT_MOTOR_UP);
509 m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY);
329 break; 510 break;
330 case Vehicle.TYPE_BOAT: 511 case Vehicle.TYPE_BOAT:
331 m_linearFrictionTimescale = new Vector3(10, 3, 2); 512 m_linearFrictionTimescale = new Vector3(10, 3, 2);
@@ -350,10 +531,12 @@ namespace OpenSim.Region.Physics.OdePlugin
350 // m_bankingMix = 0.8f; 531 // m_bankingMix = 0.8f;
351 // m_bankingTimescale = 1; 532 // m_bankingTimescale = 1;
352 // m_referenceFrame = Quaternion.Identity; 533 // m_referenceFrame = Quaternion.Identity;
353 m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.LIMIT_ROLL_ONLY | 534 m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
354 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); 535 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
355 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | 536 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
537 m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
356 VehicleFlag.LIMIT_MOTOR_UP); 538 VehicleFlag.LIMIT_MOTOR_UP);
539 m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY);
357 break; 540 break;
358 case Vehicle.TYPE_AIRPLANE: 541 case Vehicle.TYPE_AIRPLANE:
359 m_linearFrictionTimescale = new Vector3(200, 10, 5); 542 m_linearFrictionTimescale = new Vector3(200, 10, 5);
@@ -378,8 +561,9 @@ namespace OpenSim.Region.Physics.OdePlugin
378 // m_bankingMix = 0.7f; 561 // m_bankingMix = 0.7f;
379 // m_bankingTimescale = 2; 562 // m_bankingTimescale = 2;
380 // m_referenceFrame = Quaternion.Identity; 563 // m_referenceFrame = Quaternion.Identity;
381 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | 564 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
382 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP); 565 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
566 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
383 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); 567 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
384 break; 568 break;
385 case Vehicle.TYPE_BALLOON: 569 case Vehicle.TYPE_BALLOON:
@@ -405,9 +589,11 @@ namespace OpenSim.Region.Physics.OdePlugin
405 // m_bankingMix = 0.7f; 589 // m_bankingMix = 0.7f;
406 // m_bankingTimescale = 5; 590 // m_bankingTimescale = 5;
407 // m_referenceFrame = Quaternion.Identity; 591 // m_referenceFrame = Quaternion.Identity;
408 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | 592 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
409 VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP); 593 VehicleFlag.HOVER_UP_ONLY);
410 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); 594 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
595 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
596 m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT);
411 break; 597 break;
412 598
413 } 599 }
@@ -431,6 +617,7 @@ namespace OpenSim.Region.Physics.OdePlugin
431 617
432 MoveLinear(pTimestep, pParentScene); 618 MoveLinear(pTimestep, pParentScene);
433 MoveAngular(pTimestep); 619 MoveAngular(pTimestep);
620 LimitRotation(pTimestep);
434 }// end Step 621 }// end Step
435 622
436 private void MoveLinear(float pTimestep, OdeScene _pParentScene) 623 private void MoveLinear(float pTimestep, OdeScene _pParentScene)
@@ -477,61 +664,152 @@ namespace OpenSim.Region.Physics.OdePlugin
477 // .Z velocity and gravity. Therefore only 0g will used script-requested 664 // .Z velocity and gravity. Therefore only 0g will used script-requested
478 // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only. 665 // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only.
479 Vector3 grav = Vector3.Zero; 666 Vector3 grav = Vector3.Zero;
480 if (m_VehicleBuoyancy < 1.0f) 667 // There is some gravity, make a gravity force vector
668 // that is applied after object velocity.
669 d.Mass objMass;
670 d.BodyGetMass(Body, out objMass);
671 // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
672 grav.Z = _pParentScene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy);
673 // Preserve the current Z velocity
674 d.Vector3 vel_now = d.BodyGetLinearVel(Body);
675 m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity
676
677 d.Vector3 pos = d.BodyGetPosition(Body);
678 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);
679 Vector3 posChange = new Vector3();
680 posChange.X = pos.X - m_lastPositionVector.X;
681 posChange.Y = pos.Y - m_lastPositionVector.Y;
682 posChange.Z = pos.Z - m_lastPositionVector.Z;
683 double Zchange = Math.Abs(posChange.Z);
684 if (m_BlockingEndPoint != Vector3.Zero)
685 {
686 if (pos.X >= (m_BlockingEndPoint.X - (float)1))
687 {
688 pos.X -= posChange.X + 1;
689 d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
690 }
691 if (pos.Y >= (m_BlockingEndPoint.Y - (float)1))
692 {
693 pos.Y -= posChange.Y + 1;
694 d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
695 }
696 if (pos.Z >= (m_BlockingEndPoint.Z - (float)1))
697 {
698 pos.Z -= posChange.Z + 1;
699 d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
700 }
701 if (pos.X <= 0)
702 {
703 pos.X += posChange.X + 1;
704 d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
705 }
706 if (pos.Y <= 0)
707 {
708 pos.Y += posChange.Y + 1;
709 d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
710 }
711 }
712 if (pos.Z < _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y))
481 { 713 {
482 // There is some gravity, make a gravity force vector 714 pos.Z = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + 2;
483 // that is applied after object velocity. 715 d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
484 d.Mass objMass; 716 }
485 d.BodyGetMass(Body, out objMass);
486 // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
487 grav.Z = _pParentScene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy);
488 // Preserve the current Z velocity
489 d.Vector3 vel_now = d.BodyGetLinearVel(Body);
490 m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity
491 } // else its 1.0, no gravity.
492 717
493 // Check if hovering 718 // Check if hovering
494 if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) 719 if ((m_Hoverflags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
495 { 720 {
496 // We should hover, get the target height 721 // We should hover, get the target height
497 d.Vector3 pos = d.BodyGetPosition(Body); 722 if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != 0)
498 if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) == VehicleFlag.HOVER_WATER_ONLY)
499 { 723 {
500 m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight; 724 m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight;
501 } 725 }
502 else if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) == VehicleFlag.HOVER_TERRAIN_ONLY) 726 if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
503 { 727 {
504 m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight; 728 m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
505 } 729 }
506 else if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == VehicleFlag.HOVER_GLOBAL_HEIGHT) 730 if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0)
507 { 731 {
508 m_VhoverTargetHeight = m_VhoverHeight; 732 m_VhoverTargetHeight = m_VhoverHeight;
509 } 733 }
510 734
511 if ((m_flags & VehicleFlag.HOVER_UP_ONLY) == VehicleFlag.HOVER_UP_ONLY) 735 if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != 0)
512 { 736 {
513 // If body is aready heigher, use its height as target height 737 // If body is aready heigher, use its height as target height
514 if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; 738 if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
515 } 739 }
740 if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
741 {
742 if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2)
743 {
744 d.BodySetPosition(Body, pos.X, pos.Y, m_VhoverTargetHeight);
745 }
746 }
747 else
748 {
749 float herr0 = pos.Z - m_VhoverTargetHeight;
750 // Replace Vertical speed with correction figure if significant
751 if (Math.Abs(herr0) > 0.01f)
752 {
753 m_dir.Z = -((herr0 * pTimestep * 50.0f) / m_VhoverTimescale);
754 //KF: m_VhoverEfficiency is not yet implemented
755 }
756 else
757 {
758 m_dir.Z = 0f;
759 }
760 }
516 761
517// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped 762// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped
518// m_VhoverTimescale = 0f; // time to acheive height 763// m_VhoverTimescale = 0f; // time to acheive height
519// pTimestep is time since last frame,in secs 764// pTimestep is time since last frame,in secs
520 float herr0 = pos.Z - m_VhoverTargetHeight; 765 }
521 // Replace Vertical speed with correction figure if significant 766
522 if (Math.Abs(herr0) > 0.01f) 767 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0)
768 {
769 //Start Experimental Values
770 if (Zchange > .3)
523 { 771 {
524 d.Mass objMass; 772 grav.Z = (float)(grav.Z * 3);
525 d.BodyGetMass(Body, out objMass);
526 m_dir.Z = - ((herr0 * pTimestep * 50.0f) / m_VhoverTimescale);
527 //KF: m_VhoverEfficiency is not yet implemented
528 } 773 }
529 else 774 if (Zchange > .15)
775 {
776 grav.Z = (float)(grav.Z * 2);
777 }
778 if (Zchange > .75)
779 {
780 grav.Z = (float)(grav.Z * 1.5);
781 }
782 if (Zchange > .05)
783 {
784 grav.Z = (float)(grav.Z * 1.25);
785 }
786 if (Zchange > .025)
787 {
788 grav.Z = (float)(grav.Z * 1.125);
789 }
790 float terraintemp = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y);
791 float postemp = (pos.Z - terraintemp);
792 if (postemp > 2.5f)
530 { 793 {
531 m_dir.Z = 0f; 794 grav.Z = (float)(grav.Z * 1.037125);
532 } 795 }
796 //End Experimental Values
797 }
798 if ((m_flags & (VehicleFlag.NO_X)) != 0)
799 {
800 m_dir.X = 0;
801 }
802 if ((m_flags & (VehicleFlag.NO_Y)) != 0)
803 {
804 m_dir.Y = 0;
805 }
806 if ((m_flags & (VehicleFlag.NO_Z)) != 0)
807 {
808 m_dir.Z = 0;
533 } 809 }
534 810
811 m_lastPositionVector = d.BodyGetPosition(Body);
812
535 // Apply velocity 813 // Apply velocity
536 d.BodySetLinearVel(Body, m_dir.X, m_dir.Y, m_dir.Z); 814 d.BodySetLinearVel(Body, m_dir.X, m_dir.Y, m_dir.Z);
537 // apply gravity force 815 // apply gravity force
@@ -629,6 +907,12 @@ namespace OpenSim.Region.Physics.OdePlugin
629 907
630 // Sum velocities 908 // Sum velocities
631 m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // + bank + deflection 909 m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // + bank + deflection
910
911 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
912 {
913 m_lastAngularVelocity.X = 0;
914 m_lastAngularVelocity.Y = 0;
915 }
632 916
633 if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) 917 if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
634 { 918 {
@@ -647,5 +931,44 @@ namespace OpenSim.Region.Physics.OdePlugin
647 d.BodySetAngularVel (Body, m_lastAngularVelocity.X, m_lastAngularVelocity.Y, m_lastAngularVelocity.Z); 931 d.BodySetAngularVel (Body, m_lastAngularVelocity.X, m_lastAngularVelocity.Y, m_lastAngularVelocity.Z);
648 932
649 } //end MoveAngular 933 } //end MoveAngular
934 internal void LimitRotation(float timestep)
935 {
936 d.Quaternion rot = d.BodyGetQuaternion(Body);
937 Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
938 d.Quaternion m_rot = new d.Quaternion();
939 bool changed = false;
940 m_rot.X = rotq.X;
941 m_rot.Y = rotq.Y;
942 m_rot.Z = rotq.Z;
943 m_rot.W = rotq.W;
944 if (m_RollreferenceFrame != Quaternion.Identity)
945 {
946 if (rotq.X >= m_RollreferenceFrame.X)
947 {
948 m_rot.X = rotq.X - (m_RollreferenceFrame.X / 2);
949 }
950 if (rotq.Y >= m_RollreferenceFrame.Y)
951 {
952 m_rot.Y = rotq.Y - (m_RollreferenceFrame.Y / 2);
953 }
954 if (rotq.X <= -m_RollreferenceFrame.X)
955 {
956 m_rot.X = rotq.X + (m_RollreferenceFrame.X / 2);
957 }
958 if (rotq.Y <= -m_RollreferenceFrame.Y)
959 {
960 m_rot.Y = rotq.Y + (m_RollreferenceFrame.Y / 2);
961 }
962 changed = true;
963 }
964 if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0)
965 {
966 m_rot.X = 0;
967 m_rot.Y = 0;
968 changed = true;
969 }
970 if (changed)
971 d.BodySetQuaternion(Body, ref m_rot);
972 }
650 } 973 }
651} 974}