42 using System.Collections.Generic;
43 using System.Reflection;
44 using System.Runtime.InteropServices;
47 using OpenSim.Framework;
48 using OpenSim.Region.PhysicsModules.SharedBase;
51 namespace OpenSim.
Region.PhysicsModule.ODE
57 get {
return m_type; }
62 get {
return m_body; }
65 private int frcount = 0;
69 private IntPtr m_body = IntPtr.Zero;
75 private Vehicle m_type = Vehicle.TYPE_NONE;
86 private Vector3 m_BlockingEndPoint = Vector3.Zero;
87 private Quaternion m_RollreferenceFrame = Quaternion.Identity;
89 private Vector3 m_linearMotorDirection = Vector3.Zero;
90 private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero;
91 private Vector3 m_dir = Vector3.Zero;
92 private Vector3 m_linearFrictionTimescale = Vector3.Zero;
93 private float m_linearMotorDecayTimescale = 0;
94 private float m_linearMotorTimescale = 0;
95 private Vector3 m_lastLinearVelocityVector = Vector3.Zero;
101 private Vector3 m_angularMotorDirection = Vector3.Zero;
102 private int m_angularMotorApply = 0;
103 private Vector3 m_angularMotorVelocity = Vector3.Zero;
104 private float m_angularMotorTimescale = 0;
105 private float m_angularMotorDecayTimescale = 0;
106 private Vector3 m_angularFrictionTimescale = Vector3.Zero;
107 private Vector3 m_lastAngularVelocity = Vector3.Zero;
122 private float m_VhoverHeight = 0f;
124 private float m_VhoverTimescale = 0f;
125 private float m_VhoverTargetHeight = -1.0f;
126 private float m_VehicleBuoyancy = 0f;
132 private float m_verticalAttractionEfficiency = 1.0f;
133 private float m_verticalAttractionTimescale = 500f;
135 internal void ProcessFloatVehicleParam(
Vehicle pParam,
float pValue)
139 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
140 if (pValue < 0.01f) pValue = 0.01f;
143 case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
144 if (pValue < 0.01f) pValue = 0.01f;
147 case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
148 if (pValue < 0.01f) pValue = 0.01f;
149 m_angularMotorDecayTimescale = pValue;
151 case Vehicle.ANGULAR_MOTOR_TIMESCALE:
152 if (pValue < 0.01f) pValue = 0.01f;
153 m_angularMotorTimescale = pValue;
155 case Vehicle.BANKING_EFFICIENCY:
156 if (pValue < 0.01f) pValue = 0.01f;
159 case Vehicle.BANKING_MIX:
160 if (pValue < 0.01f) pValue = 0.01f;
163 case Vehicle.BANKING_TIMESCALE:
164 if (pValue < 0.01f) pValue = 0.01f;
167 case Vehicle.BUOYANCY:
168 if (pValue < -1f) pValue = -1f;
169 if (pValue > 1f) pValue = 1f;
170 m_VehicleBuoyancy = pValue;
177 case Vehicle.HOVER_HEIGHT:
178 m_VhoverHeight = pValue;
180 case Vehicle.HOVER_TIMESCALE:
181 if (pValue < 0.01f) pValue = 0.01f;
182 m_VhoverTimescale = pValue;
184 case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
185 if (pValue < 0.01f) pValue = 0.01f;
188 case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
189 if (pValue < 0.01f) pValue = 0.01f;
192 case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
193 if (pValue < 0.01f) pValue = 0.01f;
194 m_linearMotorDecayTimescale = pValue;
196 case Vehicle.LINEAR_MOTOR_TIMESCALE:
197 if (pValue < 0.01f) pValue = 0.01f;
198 m_linearMotorTimescale = pValue;
200 case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
201 if (pValue < 0.1f) pValue = 0.1f;
202 if (pValue > 1.0f) pValue = 1.0f;
203 m_verticalAttractionEfficiency = pValue;
205 case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
206 if (pValue < 0.01f) pValue = 0.01f;
207 m_verticalAttractionTimescale = pValue;
212 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
213 m_angularFrictionTimescale =
new Vector3(pValue, pValue, pValue);
215 case Vehicle.ANGULAR_MOTOR_DIRECTION:
216 m_angularMotorDirection =
new Vector3(pValue, pValue, pValue);
217 m_angularMotorApply = 10;
219 case Vehicle.LINEAR_FRICTION_TIMESCALE:
220 m_linearFrictionTimescale =
new Vector3(pValue, pValue, pValue);
222 case Vehicle.LINEAR_MOTOR_DIRECTION:
223 m_linearMotorDirection =
new Vector3(pValue, pValue, pValue);
224 m_linearMotorDirectionLASTSET =
new Vector3(pValue, pValue, pValue);
226 case Vehicle.LINEAR_MOTOR_OFFSET:
233 internal void ProcessVectorVehicleParam(
Vehicle pParam, Vector3 pValue)
237 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
238 m_angularFrictionTimescale =
new Vector3(pValue.X, pValue.Y, pValue.Z);
240 case Vehicle.ANGULAR_MOTOR_DIRECTION:
241 m_angularMotorDirection =
new Vector3(pValue.X, pValue.Y, pValue.Z);
243 if (m_angularMotorDirection.X > 12.56f) m_angularMotorDirection.X = 12.56f;
244 if (m_angularMotorDirection.X < - 12.56f) m_angularMotorDirection.X = - 12.56f;
245 if (m_angularMotorDirection.Y > 12.56f) m_angularMotorDirection.Y = 12.56f;
246 if (m_angularMotorDirection.Y < - 12.56f) m_angularMotorDirection.Y = - 12.56f;
247 if (m_angularMotorDirection.Z > 12.56f) m_angularMotorDirection.Z = 12.56f;
248 if (m_angularMotorDirection.Z < - 12.56f) m_angularMotorDirection.Z = - 12.56f;
249 m_angularMotorApply = 10;
251 case Vehicle.LINEAR_FRICTION_TIMESCALE:
252 m_linearFrictionTimescale =
new Vector3(pValue.X, pValue.Y, pValue.Z);
254 case Vehicle.LINEAR_MOTOR_DIRECTION:
255 m_linearMotorDirection =
new Vector3(pValue.X, pValue.Y, pValue.Z);
256 m_linearMotorDirectionLASTSET =
new Vector3(pValue.X, pValue.Y, pValue.Z);
258 case Vehicle.LINEAR_MOTOR_OFFSET:
261 case Vehicle.BLOCK_EXIT:
262 m_BlockingEndPoint =
new Vector3(pValue.X, pValue.Y, pValue.Z);
267 internal void ProcessRotationVehicleParam(
Vehicle pParam, Quaternion pValue)
271 case Vehicle.REFERENCE_FRAME:
274 case Vehicle.ROLL_FRAME:
275 m_RollreferenceFrame = pValue;
280 internal void ProcessVehicleFlags(
int pParam,
bool remove)
290 if ((pParam & (
int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (
int)VehicleFlag.HOVER_GLOBAL_HEIGHT)
293 m_Hoverflags &= ~(VehicleFlag.HOVER_GLOBAL_HEIGHT);
295 if ((pParam & (
int)VehicleFlag.HOVER_TERRAIN_ONLY) == (
int)VehicleFlag.HOVER_TERRAIN_ONLY)
298 m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY);
300 if ((pParam & (
int)VehicleFlag.HOVER_UP_ONLY) == (
int)VehicleFlag.HOVER_UP_ONLY)
303 m_Hoverflags &= ~(VehicleFlag.HOVER_UP_ONLY);
305 if ((pParam & (
int)VehicleFlag.HOVER_WATER_ONLY) == (
int)VehicleFlag.HOVER_WATER_ONLY)
308 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY);
310 if ((pParam & (
int)VehicleFlag.LIMIT_MOTOR_UP) == (
int)VehicleFlag.LIMIT_MOTOR_UP)
313 m_flags &= ~(VehicleFlag.LIMIT_MOTOR_UP);
315 if ((pParam & (
int)VehicleFlag.LIMIT_ROLL_ONLY) == (
int)VehicleFlag.LIMIT_ROLL_ONLY)
318 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
320 if ((pParam & (
int)VehicleFlag.MOUSELOOK_BANK) == (
int)VehicleFlag.MOUSELOOK_BANK)
323 m_flags &= ~(VehicleFlag.MOUSELOOK_BANK);
325 if ((pParam & (
int)VehicleFlag.MOUSELOOK_STEER) == (
int)VehicleFlag.MOUSELOOK_STEER)
328 m_flags &= ~(VehicleFlag.MOUSELOOK_STEER);
330 if ((pParam & (
int)VehicleFlag.NO_DEFLECTION_UP) == (
int)VehicleFlag.NO_DEFLECTION_UP)
333 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP);
335 if ((pParam & (
int)VehicleFlag.CAMERA_DECOUPLED) == (
int)VehicleFlag.CAMERA_DECOUPLED)
338 m_flags &= ~(VehicleFlag.CAMERA_DECOUPLED);
340 if ((pParam & (
int)VehicleFlag.NO_X) == (
int)VehicleFlag.NO_X)
343 m_flags &= ~(VehicleFlag.NO_X);
345 if ((pParam & (
int)VehicleFlag.NO_Y) == (
int)VehicleFlag.NO_Y)
348 m_flags &= ~(VehicleFlag.NO_Y);
350 if ((pParam & (
int)VehicleFlag.NO_Z) == (
int)VehicleFlag.NO_Z)
353 m_flags &= ~(VehicleFlag.NO_Z);
355 if ((pParam & (
int)VehicleFlag.LOCK_HOVER_HEIGHT) == (
int)VehicleFlag.LOCK_HOVER_HEIGHT)
358 m_Hoverflags &= ~(VehicleFlag.LOCK_HOVER_HEIGHT);
360 if ((pParam & (
int)VehicleFlag.NO_DEFLECTION) == (
int)VehicleFlag.NO_DEFLECTION)
363 m_flags &= ~(VehicleFlag.NO_DEFLECTION);
365 if ((pParam & (
int)VehicleFlag.LOCK_ROTATION) == (
int)VehicleFlag.LOCK_ROTATION)
368 m_flags &= ~(VehicleFlag.LOCK_ROTATION);
373 if ((pParam & (
int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (
int)VehicleFlag.HOVER_GLOBAL_HEIGHT)
375 m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT | m_flags);
377 if ((pParam & (
int)VehicleFlag.HOVER_TERRAIN_ONLY) == (
int)VehicleFlag.HOVER_TERRAIN_ONLY)
379 m_Hoverflags |= (VehicleFlag.HOVER_TERRAIN_ONLY | m_flags);
381 if ((pParam & (
int)VehicleFlag.HOVER_UP_ONLY) == (
int)VehicleFlag.HOVER_UP_ONLY)
383 m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY | m_flags);
385 if ((pParam & (
int)VehicleFlag.HOVER_WATER_ONLY) == (
int)VehicleFlag.HOVER_WATER_ONLY)
387 m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY | m_flags);
389 if ((pParam & (
int)VehicleFlag.LIMIT_MOTOR_UP) == (
int)VehicleFlag.LIMIT_MOTOR_UP)
391 m_flags |= (VehicleFlag.LIMIT_MOTOR_UP | m_flags);
393 if ((pParam & (
int)VehicleFlag.MOUSELOOK_BANK) == (
int)VehicleFlag.MOUSELOOK_BANK)
395 m_flags |= (VehicleFlag.MOUSELOOK_BANK | m_flags);
397 if ((pParam & (
int)VehicleFlag.MOUSELOOK_STEER) == (
int)VehicleFlag.MOUSELOOK_STEER)
399 m_flags |= (VehicleFlag.MOUSELOOK_STEER | m_flags);
401 if ((pParam & (
int)VehicleFlag.NO_DEFLECTION_UP) == (
int)VehicleFlag.NO_DEFLECTION_UP)
403 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | m_flags);
405 if ((pParam & (
int)VehicleFlag.CAMERA_DECOUPLED) == (
int)VehicleFlag.CAMERA_DECOUPLED)
407 m_flags |= (VehicleFlag.CAMERA_DECOUPLED | m_flags);
409 if ((pParam & (
int)VehicleFlag.NO_X) == (
int)VehicleFlag.NO_X)
411 m_flags |= (VehicleFlag.NO_X);
413 if ((pParam & (
int)VehicleFlag.NO_Y) == (
int)VehicleFlag.NO_Y)
415 m_flags |= (VehicleFlag.NO_Y);
417 if ((pParam & (
int)VehicleFlag.NO_Z) == (
int)VehicleFlag.NO_Z)
419 m_flags |= (VehicleFlag.NO_Z);
421 if ((pParam & (
int)VehicleFlag.LOCK_HOVER_HEIGHT) == (
int)VehicleFlag.LOCK_HOVER_HEIGHT)
423 m_Hoverflags |= (VehicleFlag.LOCK_HOVER_HEIGHT);
425 if ((pParam & (
int)VehicleFlag.NO_DEFLECTION) == (
int)VehicleFlag.NO_DEFLECTION)
427 m_flags |= (VehicleFlag.NO_DEFLECTION);
429 if ((pParam & (
int)VehicleFlag.LOCK_ROTATION) == (
int)VehicleFlag.LOCK_ROTATION)
431 m_flags |= (VehicleFlag.LOCK_ROTATION);
436 internal void ProcessTypeChange(
Vehicle pType)
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;
452 m_VhoverTimescale = 0;
453 m_VehicleBuoyancy = 0;
457 case Vehicle.TYPE_SLED:
458 m_linearFrictionTimescale =
new Vector3(30, 1, 1000);
459 m_angularFrictionTimescale =
new Vector3(1000, 1000, 1000);
460 m_linearMotorDirection = Vector3.Zero;
461 m_linearMotorTimescale = 1000;
462 m_linearMotorDecayTimescale = 120;
463 m_angularMotorDirection = Vector3.Zero;
464 m_angularMotorTimescale = 1000;
465 m_angularMotorDecayTimescale = 120;
468 m_VhoverTimescale = 10;
469 m_VehicleBuoyancy = 0;
479 ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
480 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
481 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
483 case Vehicle.TYPE_CAR:
484 m_linearFrictionTimescale =
new Vector3(100, 2, 1000);
485 m_angularFrictionTimescale =
new Vector3(1000, 1000, 1000);
486 m_linearMotorDirection = Vector3.Zero;
487 m_linearMotorTimescale = 1;
488 m_linearMotorDecayTimescale = 60;
489 m_angularMotorDirection = Vector3.Zero;
490 m_angularMotorTimescale = 1;
491 m_angularMotorDecayTimescale = 0.8f;
494 m_VhoverTimescale = 1000;
495 m_VehicleBuoyancy = 0;
500 m_verticalAttractionEfficiency = 1f;
501 m_verticalAttractionTimescale = 10f;
506 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
507 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY |
508 VehicleFlag.LIMIT_MOTOR_UP);
509 m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY);
511 case Vehicle.TYPE_BOAT:
512 m_linearFrictionTimescale =
new Vector3(10, 3, 2);
513 m_angularFrictionTimescale =
new Vector3(10,10,10);
514 m_linearMotorDirection = Vector3.Zero;
515 m_linearMotorTimescale = 5;
516 m_linearMotorDecayTimescale = 60;
517 m_angularMotorDirection = Vector3.Zero;
518 m_angularMotorTimescale = 4;
519 m_angularMotorDecayTimescale = 4;
522 m_VhoverTimescale = 2;
523 m_VehicleBuoyancy = 1;
528 m_verticalAttractionEfficiency = 0.5f;
529 m_verticalAttractionTimescale = 5f;
534 m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
535 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
536 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
537 m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
538 VehicleFlag.LIMIT_MOTOR_UP);
539 m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY);
541 case Vehicle.TYPE_AIRPLANE:
542 m_linearFrictionTimescale =
new Vector3(200, 10, 5);
543 m_angularFrictionTimescale =
new Vector3(20, 20, 20);
544 m_linearMotorDirection = Vector3.Zero;
545 m_linearMotorTimescale = 2;
546 m_linearMotorDecayTimescale = 60;
547 m_angularMotorDirection = Vector3.Zero;
548 m_angularMotorTimescale = 4;
549 m_angularMotorDecayTimescale = 4;
552 m_VhoverTimescale = 1000;
553 m_VehicleBuoyancy = 0;
558 m_verticalAttractionEfficiency = 0.9f;
559 m_verticalAttractionTimescale = 2f;
564 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
565 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
566 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
567 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
569 case Vehicle.TYPE_BALLOON:
570 m_linearFrictionTimescale =
new Vector3(5, 5, 5);
571 m_angularFrictionTimescale =
new Vector3(10, 10, 10);
572 m_linearMotorDirection = Vector3.Zero;
573 m_linearMotorTimescale = 5;
574 m_linearMotorDecayTimescale = 60;
575 m_angularMotorDirection = Vector3.Zero;
576 m_angularMotorTimescale = 6;
577 m_angularMotorDecayTimescale = 10;
580 m_VhoverTimescale = 10;
581 m_VehicleBuoyancy = 1;
586 m_verticalAttractionEfficiency = 1f;
587 m_verticalAttractionTimescale = 100f;
592 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
593 VehicleFlag.HOVER_UP_ONLY);
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);
602 internal void Enable(IntPtr pBody, OdeScene pParentScene)
604 if (m_type ==
Vehicle.TYPE_NONE)
612 m_lastLinearVelocityVector = Vector3.Zero;
613 m_lastAngularVelocity = Vector3.Zero;
614 m_lastPositionVector = d.BodyGetPosition(
Body);
617 internal void Step(
float pTimestep, OdeScene pParentScene)
619 if (m_body == IntPtr.Zero || m_type ==
Vehicle.TYPE_NONE)
625 MoveLinear(pTimestep, pParentScene);
626 MoveAngular(pTimestep);
627 LimitRotation(pTimestep);
630 private void MoveLinear(
float pTimestep, OdeScene _pParentScene)
632 if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f))
634 if (!d.BodyIsEnabled(Body))
638 Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep);
639 m_lastLinearVelocityVector += (addAmount*10);
643 if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X))
644 m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X;
645 if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y))
646 m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y;
647 if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z))
648 m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z;
651 Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep)));
653 m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f;
659 if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f))
660 m_lastLinearVelocityVector = Vector3.Zero;
664 m_dir = m_lastLinearVelocityVector;
665 d.Quaternion rot = d.BodyGetQuaternion(
Body);
666 Quaternion rotq =
new Quaternion(rot.X, rot.Y, rot.Z, rot.W);
673 Vector3 grav = Vector3.Zero;
677 d.BodyGetMass(
Body, out objMass);
679 grav.Z = _pParentScene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy);
681 d.Vector3 vel_now = d.BodyGetLinearVel(Body);
684 d.Vector3 pos = d.BodyGetPosition(Body);
686 Vector3 posChange =
new Vector3();
687 posChange.X = pos.X - m_lastPositionVector.X;
688 posChange.Y = pos.Y - m_lastPositionVector.Y;
689 posChange.Z = pos.Z - m_lastPositionVector.Z;
690 double Zchange = Math.Abs(posChange.Z);
691 if (m_BlockingEndPoint != Vector3.Zero)
693 if (pos.X >= (m_BlockingEndPoint.X - (
float)1))
695 pos.X -= posChange.X + 1;
696 d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
698 if (pos.Y >= (m_BlockingEndPoint.Y - (
float)1))
700 pos.Y -= posChange.Y + 1;
701 d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
703 if (pos.Z >= (m_BlockingEndPoint.Z - (
float)1))
705 pos.Z -= posChange.Z + 1;
706 d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
710 pos.X += posChange.X + 1;
711 d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
715 pos.Y += posChange.Y + 1;
716 d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
719 if (pos.Z < _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y))
721 pos.Z = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + 2;
722 d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
729 if ((m_Hoverflags &
VehicleFlag.HOVER_WATER_ONLY) != 0)
731 m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight;
733 if ((m_Hoverflags &
VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
735 m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
737 if ((m_Hoverflags &
VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0)
739 m_VhoverTargetHeight = m_VhoverHeight;
742 if ((m_Hoverflags &
VehicleFlag.HOVER_UP_ONLY) != 0)
745 if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
747 if ((m_Hoverflags &
VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
749 if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2)
751 d.BodySetPosition(Body, pos.X, pos.Y, m_VhoverTargetHeight);
756 float herr0 = pos.Z - m_VhoverTargetHeight;
758 if (Math.Abs(herr0) > 0.01f)
760 m_dir.Z = -((herr0 * pTimestep * 50.0f) / m_VhoverTimescale);
779 grav.Z = (float)(grav.Z * 3);
783 grav.Z = (float)(grav.Z * 2);
787 grav.Z = (float)(grav.Z * 1.5);
791 grav.Z = (float)(grav.Z * 1.25);
795 grav.Z = (float)(grav.Z * 1.125);
797 float terraintemp = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y);
798 float postemp = (pos.Z - terraintemp);
801 grav.Z = (float)(grav.Z * 1.037125);
818 m_lastPositionVector = d.BodyGetPosition(Body);
821 d.BodySetLinearVel(Body, m_dir.X, m_dir.Y, m_dir.Z);
823 d.BodyAddForce(Body, grav.X, grav.Y, grav.Z);
827 Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep);
828 m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount;
831 private void MoveAngular(
float pTimestep)
844 d.Vector3 angularVelocity = d.BodyGetAngularVel(Body);
847 if (m_angularMotorApply > 0)
852 m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep);
853 m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep);
854 m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep);
856 m_angularMotorApply--;
867 m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep);
871 Vector3 vertattr = Vector3.Zero;
873 if (m_verticalAttractionTimescale < 300)
875 float VAservo = 0.2f / (m_verticalAttractionTimescale * pTimestep);
877 d.Quaternion rot = d.BodyGetQuaternion(Body);
878 Quaternion rotq =
new Quaternion(rot.X, rot.Y, rot.Z, rot.W);
880 Vector3 verterr = Vector3.Zero;
883 verterr = verterr * rotq;
887 if (verterr.Z < 0.0f)
889 verterr.X = 2.0f - verterr.X;
890 verterr.Y = 2.0f - verterr.Y;
894 verterr = verterr * VAservo;
899 vertattr.X = verterr.Y;
900 vertattr.Y = - verterr.X;
904 float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency);
905 vertattr.X += bounce * angularVelocity.X;
906 vertattr.Y += bounce * angularVelocity.Y;
916 m_lastAngularVelocity = m_angularMotorVelocity + vertattr;
918 if ((m_flags & (
VehicleFlag.NO_DEFLECTION_UP)) != 0)
920 m_lastAngularVelocity.X = 0;
921 m_lastAngularVelocity.Y = 0;
924 if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
926 if (!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
930 m_lastAngularVelocity = Vector3.Zero;
934 Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep);
935 m_lastAngularVelocity -= m_lastAngularVelocity * decayamount;
938 d.BodySetAngularVel (Body, m_lastAngularVelocity.X, m_lastAngularVelocity.Y, m_lastAngularVelocity.Z);
941 internal void LimitRotation(
float timestep)
943 d.Quaternion rot = d.BodyGetQuaternion(Body);
944 Quaternion rotq =
new Quaternion(rot.X, rot.Y, rot.Z, rot.W);
945 d.Quaternion m_rot =
new d.Quaternion();
946 bool changed =
false;
951 if (m_RollreferenceFrame != Quaternion.Identity)
953 if (rotq.X >= m_RollreferenceFrame.X)
955 m_rot.X = rotq.X - (m_RollreferenceFrame.X / 2);
957 if (rotq.Y >= m_RollreferenceFrame.Y)
959 m_rot.Y = rotq.Y - (m_RollreferenceFrame.Y / 2);
961 if (rotq.X <= -m_RollreferenceFrame.X)
963 m_rot.X = rotq.X + (m_RollreferenceFrame.X / 2);
965 if (rotq.Y <= -m_RollreferenceFrame.Y)
967 m_rot.Y = rotq.Y + (m_RollreferenceFrame.Y / 2);
978 d.BodySetQuaternion(Body, ref m_rot);