From 3aee642190add7045f78e522ae7b2221b3566f1e Mon Sep 17 00:00:00 2001
From: UbitUmarov
Date: Sat, 18 Feb 2012 17:42:14 +0000
Subject: changed how vehicle data is stored and passed to physics. use unsafe
 in serializer, tried to control m_dupeInProgress

---
 OpenSim/Region/Framework/Scenes/SOGVehicle.cs      | 336 +++++++++++----------
 .../Region/Framework/Scenes/SceneObjectGroup.cs    |   2 +
 OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs      |  62 +++-
 OpenSim/Region/Physics/ChOdePlugin/OdeUtils.cs     | 294 ++++++++++++++----
 OpenSim/Region/Physics/Manager/PhysicsActor.cs     |   5 +-
 OpenSim/Region/Physics/Manager/VehicleConstants.cs |  45 ++-
 6 files changed, 522 insertions(+), 222 deletions(-)

(limited to 'OpenSim')

diff --git a/OpenSim/Region/Framework/Scenes/SOGVehicle.cs b/OpenSim/Region/Framework/Scenes/SOGVehicle.cs
index b7c93e5..470f403 100644
--- a/OpenSim/Region/Framework/Scenes/SOGVehicle.cs
+++ b/OpenSim/Region/Framework/Scenes/SOGVehicle.cs
@@ -37,9 +37,11 @@ namespace OpenSim.Region.Framework.Scenes
     {
         public Vehicle Type
         {
-            get { return m_type; }
+            get { return vd.m_type; }
         }
 
+        public VehicleData vd;
+/*
         private Vehicle m_type = Vehicle.TYPE_NONE;                     // If a 'VEHICLE', and what kind
         private VehicleFlag m_flags = (VehicleFlag)0;
 
@@ -78,7 +80,13 @@ namespace OpenSim.Region.Framework.Scenes
         private float m_verticalAttractionTimescale = 1000f;        // Timescale > 300  means no vert attractor.
 
         // Axis
-        public Quaternion m_referenceFrame = Quaternion.Identity;      
+        public Quaternion m_referenceFrame = Quaternion.Identity;
+*/
+        public SOGVehicle()
+        {
+            vd = new VehicleData();
+            ProcessTypeChange(Vehicle.TYPE_NONE); // is needed?
+        }
 
         public void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
         {
@@ -89,109 +97,109 @@ namespace OpenSim.Region.Framework.Scenes
                 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
                     if (pValue < 0f) pValue = 0f;
                     if (pValue > 1f) pValue = 1f;
-                    m_angularDeflectionEfficiency = pValue;
+                    vd.m_angularDeflectionEfficiency = pValue;
                     break;
                 case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
                     if (pValue < timestep) pValue = timestep;
-                    m_angularDeflectionTimescale = pValue;
+                    vd.m_angularDeflectionTimescale = pValue;
                     break;
                 case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
                     if (pValue < timestep) pValue = timestep;
                     else if (pValue > 120) pValue = 120;
-                    m_angularMotorDecayTimescale = pValue;
+                    vd.m_angularMotorDecayTimescale = pValue;
                     break;
                 case Vehicle.ANGULAR_MOTOR_TIMESCALE:
                     if (pValue < timestep) pValue = timestep;
-                    m_angularMotorTimescale = pValue;
+                    vd.m_angularMotorTimescale = pValue;
                     break;
                 case Vehicle.BANKING_EFFICIENCY:
                     if (pValue < -1f) pValue = -1f;
                     if (pValue > 1f) pValue = 1f;
-                    m_bankingEfficiency = pValue;
+                    vd.m_bankingEfficiency = pValue;
                     break;
                 case Vehicle.BANKING_MIX:
                     if (pValue < 0f) pValue = 0f;
                     if (pValue > 1f) pValue = 1f;
-                    m_bankingMix = pValue;
+                    vd.m_bankingMix = pValue;
                     break;
                 case Vehicle.BANKING_TIMESCALE:
                     if (pValue < timestep) pValue = timestep;
-                    m_bankingTimescale = pValue;
+                    vd.m_bankingTimescale = pValue;
                     break;
                 case Vehicle.BUOYANCY:
                     if (pValue < -1f) pValue = -1f;
                     if (pValue > 1f) pValue = 1f;
-                    m_VehicleBuoyancy = pValue;
+                    vd.m_VehicleBuoyancy = pValue;
                     break;
                 case Vehicle.HOVER_EFFICIENCY:
                     if (pValue < 0f) pValue = 0f;
                     if (pValue > 1f) pValue = 1f;
-                    m_VhoverEfficiency = pValue;
+                    vd.m_VhoverEfficiency = pValue;
                     break;
                 case Vehicle.HOVER_HEIGHT:
-                    m_VhoverHeight = pValue;
+                    vd.m_VhoverHeight = pValue;
                     break;
                 case Vehicle.HOVER_TIMESCALE:
                     if (pValue < timestep) pValue = timestep;
-                    m_VhoverTimescale = pValue;
+                    vd.m_VhoverTimescale = pValue;
                     break;
                 case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
                     if (pValue < 0f) pValue = 0f;
                     if (pValue > 1f) pValue = 1f;
-                    m_linearDeflectionEfficiency = pValue;
+                    vd.m_linearDeflectionEfficiency = pValue;
                     break;
                 case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
                     if (pValue < timestep) pValue = timestep;
-                    m_linearDeflectionTimescale = pValue;
+                    vd.m_linearDeflectionTimescale = pValue;
                     break;
                 case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
                     //                    if (pValue < timestep) pValue = timestep;
                     // try to make impulses to work a bit better
                     if (pValue < timestep) pValue = timestep;
                     else if (pValue > 120) pValue = 120;
-                    m_linearMotorDecayTimescale = pValue;
+                    vd.m_linearMotorDecayTimescale = pValue;
                     break;
                 case Vehicle.LINEAR_MOTOR_TIMESCALE:
                     if (pValue < timestep) pValue = timestep;
-                    m_linearMotorTimescale = pValue;
+                    vd.m_linearMotorTimescale = pValue;
                     break;
                 case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
                     if (pValue < 0f) pValue = 0f;
                     if (pValue > 1f) pValue = 1f;
-                    m_verticalAttractionEfficiency = pValue;
+                    vd.m_verticalAttractionEfficiency = pValue;
                     break;
                 case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
                     if (pValue < timestep) pValue = timestep;
-                    m_verticalAttractionTimescale = pValue;
+                    vd.m_verticalAttractionTimescale = pValue;
                     break;
 
                 // These are vector properties but the engine lets you use a single float value to
                 // set all of the components to the same value
                 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
                     if (pValue < timestep) pValue = timestep;
-                    m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
+                    vd.m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
                     break;
                 case Vehicle.ANGULAR_MOTOR_DIRECTION:
-                    m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
-                    len = m_angularMotorDirection.Length();
+                    vd.m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
+                    len = vd.m_angularMotorDirection.Length();
                     if (len > 12.566f)
-                        m_angularMotorDirection *= (12.566f / len);
+                        vd.m_angularMotorDirection *= (12.566f / len);
                     break;
                 case Vehicle.LINEAR_FRICTION_TIMESCALE:
                     if (pValue < timestep) pValue = timestep;
-                    m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
+                    vd.m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
                     break;
                 case Vehicle.LINEAR_MOTOR_DIRECTION:
-                    m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
-                    len = m_linearMotorDirection.Length();
+                    vd.m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
+                    len = vd.m_linearMotorDirection.Length();
                     if (len > 30.0f)
-                        m_linearMotorDirection *= (30.0f / len);
+                        vd.m_linearMotorDirection *= (30.0f / len);
                     break;
                 case Vehicle.LINEAR_MOTOR_OFFSET:
-                    m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
-                    len = m_linearMotorOffset.Length();
+                    vd.m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
+                    len = vd.m_linearMotorOffset.Length();
                     if (len > 100.0f)
-                        m_linearMotorOffset *= (100.0f / len);
+                        vd.m_linearMotorOffset *= (100.0f / len);
                     break;
             }
         }//end ProcessFloatVehicleParam
@@ -207,32 +215,32 @@ namespace OpenSim.Region.Framework.Scenes
                     if (pValue.Y < timestep) pValue.Y = timestep;
                     if (pValue.Z < timestep) pValue.Z = timestep;
 
-                    m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
+                    vd.m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
                     break;
                 case Vehicle.ANGULAR_MOTOR_DIRECTION:
-                    m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
+                    vd.m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
                     // Limit requested angular speed to 2 rps= 4 pi rads/sec
-                    len = m_angularMotorDirection.Length();
+                    len = vd.m_angularMotorDirection.Length();
                     if (len > 12.566f)
-                        m_angularMotorDirection *= (12.566f / len);
+                        vd.m_angularMotorDirection *= (12.566f / len);
                     break;
                 case Vehicle.LINEAR_FRICTION_TIMESCALE:
                     if (pValue.X < timestep) pValue.X = timestep;
                     if (pValue.Y < timestep) pValue.Y = timestep;
                     if (pValue.Z < timestep) pValue.Z = timestep;
-                    m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
+                    vd.m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
                     break;
                 case Vehicle.LINEAR_MOTOR_DIRECTION:
-                    m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
-                    len = m_linearMotorDirection.Length();
+                    vd.m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
+                    len = vd.m_linearMotorDirection.Length();
                     if (len > 30.0f)
-                        m_linearMotorDirection *= (30.0f / len);
+                        vd.m_linearMotorDirection *= (30.0f / len);
                     break;
                 case Vehicle.LINEAR_MOTOR_OFFSET:
-                    m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
-                    len = m_linearMotorOffset.Length();
+                    vd.m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
+                    len = vd.m_linearMotorOffset.Length();
                     if (len > 100.0f)
-                        m_linearMotorOffset *= (100.0f / len);
+                        vd.m_linearMotorOffset *= (100.0f / len);
                     break;
             }
         }//end ProcessVectorVehicleParam
@@ -242,7 +250,7 @@ namespace OpenSim.Region.Framework.Scenes
             switch (pParam)
             {
                 case Vehicle.REFERENCE_FRAME:
-                    m_referenceFrame = Quaternion.Inverse(pValue);
+                    vd.m_referenceFrame = Quaternion.Inverse(pValue);
                     break;
             }
         }//end ProcessRotationVehicleParam
@@ -251,169 +259,169 @@ namespace OpenSim.Region.Framework.Scenes
         {
             if (remove)
             {
-                m_flags &= ~((VehicleFlag)pParam);
+                vd.m_flags &= ~((VehicleFlag)pParam);
             }
             else
             {
-                m_flags |= (VehicleFlag)pParam;
+                vd.m_flags |= (VehicleFlag)pParam;
             }
         }//end ProcessVehicleFlags
 
         public void ProcessTypeChange(Vehicle pType)
         {
-            m_linearMotorDirection = Vector3.Zero;
-            m_angularMotorDirection = Vector3.Zero;
+            vd.m_linearMotorDirection = Vector3.Zero;
+            vd.m_angularMotorDirection = Vector3.Zero;
 
-            m_linearMotorOffset = Vector3.Zero;
+            vd.m_linearMotorOffset = Vector3.Zero;
 
-            m_referenceFrame = Quaternion.Identity;
+            vd.m_referenceFrame = Quaternion.Identity;
 
             // Set Defaults For Type
-            m_type = pType;
+            vd.m_type = pType;
             switch (pType)
             {
                 case Vehicle.TYPE_NONE: // none sense this will never exist
-                    m_linearFrictionTimescale = new Vector3(1000, 1000, 1000);
-                    m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
-                    m_linearMotorTimescale = 1000;
-                    m_linearMotorDecayTimescale = 120;
-                    m_angularMotorTimescale = 1000;
-                    m_angularMotorDecayTimescale = 1000;
-                    m_VhoverHeight = 0;
-                    m_VhoverTimescale = 1000;
-                    m_VehicleBuoyancy = 0;
-                    m_flags = (VehicleFlag)0;
+                    vd.m_linearFrictionTimescale = new Vector3(1000, 1000, 1000);
+                    vd.m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
+                    vd.m_linearMotorTimescale = 1000;
+                    vd.m_linearMotorDecayTimescale = 120;
+                    vd.m_angularMotorTimescale = 1000;
+                    vd.m_angularMotorDecayTimescale = 1000;
+                    vd.m_VhoverHeight = 0;
+                    vd.m_VhoverTimescale = 1000;
+                    vd.m_VehicleBuoyancy = 0;
+                    vd.m_flags = (VehicleFlag)0;
                     break;
 
                 case Vehicle.TYPE_SLED:
-                    m_linearFrictionTimescale = new Vector3(30, 1, 1000);
-                    m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
-                    m_linearMotorTimescale = 1000;
-                    m_linearMotorDecayTimescale = 120;
-                    m_angularMotorTimescale = 1000;
-                    m_angularMotorDecayTimescale = 120;
-                    m_VhoverHeight = 0;
-                    m_VhoverEfficiency = 1;
-                    m_VhoverTimescale = 10;
-                    m_VehicleBuoyancy = 0;
-                    m_linearDeflectionEfficiency = 1;
-                    m_linearDeflectionTimescale = 1;
-                    m_angularDeflectionEfficiency = 0;
-                    m_angularDeflectionTimescale = 1000;
-                    m_bankingEfficiency = 0;
-                    m_bankingMix = 1;
-                    m_bankingTimescale = 10;
-                    m_flags &=
+                    vd.m_linearFrictionTimescale = new Vector3(30, 1, 1000);
+                    vd.m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
+                    vd.m_linearMotorTimescale = 1000;
+                    vd.m_linearMotorDecayTimescale = 120;
+                    vd.m_angularMotorTimescale = 1000;
+                    vd.m_angularMotorDecayTimescale = 120;
+                    vd.m_VhoverHeight = 0;
+                    vd.m_VhoverEfficiency = 1;
+                    vd.m_VhoverTimescale = 10;
+                    vd.m_VehicleBuoyancy = 0;
+                    vd.m_linearDeflectionEfficiency = 1;
+                    vd.m_linearDeflectionTimescale = 1;
+                    vd.m_angularDeflectionEfficiency = 0;
+                    vd.m_angularDeflectionTimescale = 1000;
+                    vd.m_bankingEfficiency = 0;
+                    vd.m_bankingMix = 1;
+                    vd.m_bankingTimescale = 10;
+                    vd.m_flags &=
                          ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
                            VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
-                    m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
+                    vd.m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
                     break;
                 case Vehicle.TYPE_CAR:
-                    m_linearFrictionTimescale = new Vector3(100, 2, 1000);
-                    m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
-                    m_linearMotorTimescale = 1;
-                    m_linearMotorDecayTimescale = 60;
-                    m_angularMotorTimescale = 1;
-                    m_angularMotorDecayTimescale = 0.8f;
-                    m_VhoverHeight = 0;
-                    m_VhoverEfficiency = 0;
-                    m_VhoverTimescale = 1000;
-                    m_VehicleBuoyancy = 0;
-                    m_linearDeflectionEfficiency = 1;
-                    m_linearDeflectionTimescale = 2;
-                    m_angularDeflectionEfficiency = 0;
-                    m_angularDeflectionTimescale = 10;
-                    m_verticalAttractionEfficiency = 1f;
-                    m_verticalAttractionTimescale = 10f;
-                    m_bankingEfficiency = -0.2f;
-                    m_bankingMix = 1;
-                    m_bankingTimescale = 1;
-                    m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
-                    m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY |
+                    vd.m_linearFrictionTimescale = new Vector3(100, 2, 1000);
+                    vd.m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
+                    vd.m_linearMotorTimescale = 1;
+                    vd.m_linearMotorDecayTimescale = 60;
+                    vd.m_angularMotorTimescale = 1;
+                    vd.m_angularMotorDecayTimescale = 0.8f;
+                    vd.m_VhoverHeight = 0;
+                    vd.m_VhoverEfficiency = 0;
+                    vd.m_VhoverTimescale = 1000;
+                    vd.m_VehicleBuoyancy = 0;
+                    vd.m_linearDeflectionEfficiency = 1;
+                    vd.m_linearDeflectionTimescale = 2;
+                    vd.m_angularDeflectionEfficiency = 0;
+                    vd.m_angularDeflectionTimescale = 10;
+                    vd.m_verticalAttractionEfficiency = 1f;
+                    vd.m_verticalAttractionTimescale = 10f;
+                    vd.m_bankingEfficiency = -0.2f;
+                    vd.m_bankingMix = 1;
+                    vd.m_bankingTimescale = 1;
+                    vd.m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
+                    vd.m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY |
                                 VehicleFlag.LIMIT_MOTOR_UP | VehicleFlag.HOVER_UP_ONLY);
                     break;
                 case Vehicle.TYPE_BOAT:
-                    m_linearFrictionTimescale = new Vector3(10, 3, 2);
-                    m_angularFrictionTimescale = new Vector3(10, 10, 10);
-                    m_linearMotorTimescale = 5;
-                    m_linearMotorDecayTimescale = 60;
-                    m_angularMotorTimescale = 4;
-                    m_angularMotorDecayTimescale = 4;
-                    m_VhoverHeight = 0;
-                    m_VhoverEfficiency = 0.5f;
-                    m_VhoverTimescale = 2;
-                    m_VehicleBuoyancy = 1;
-                    m_linearDeflectionEfficiency = 0.5f;
-                    m_linearDeflectionTimescale = 3;
-                    m_angularDeflectionEfficiency = 0.5f;
-                    m_angularDeflectionTimescale = 5;
-                    m_verticalAttractionEfficiency = 0.5f;
-                    m_verticalAttractionTimescale = 5f;
-                    m_bankingEfficiency = -0.3f;
-                    m_bankingMix = 0.8f;
-                    m_bankingTimescale = 1;
-                    m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
+                    vd.m_linearFrictionTimescale = new Vector3(10, 3, 2);
+                    vd.m_angularFrictionTimescale = new Vector3(10, 10, 10);
+                    vd.m_linearMotorTimescale = 5;
+                    vd.m_linearMotorDecayTimescale = 60;
+                    vd.m_angularMotorTimescale = 4;
+                    vd.m_angularMotorDecayTimescale = 4;
+                    vd.m_VhoverHeight = 0;
+                    vd.m_VhoverEfficiency = 0.5f;
+                    vd.m_VhoverTimescale = 2;
+                    vd.m_VehicleBuoyancy = 1;
+                    vd.m_linearDeflectionEfficiency = 0.5f;
+                    vd.m_linearDeflectionTimescale = 3;
+                    vd.m_angularDeflectionEfficiency = 0.5f;
+                    vd.m_angularDeflectionTimescale = 5;
+                    vd.m_verticalAttractionEfficiency = 0.5f;
+                    vd.m_verticalAttractionTimescale = 5f;
+                    vd.m_bankingEfficiency = -0.3f;
+                    vd.m_bankingMix = 0.8f;
+                    vd.m_bankingTimescale = 1;
+                    vd.m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
                             VehicleFlag.HOVER_GLOBAL_HEIGHT |
                             VehicleFlag.HOVER_UP_ONLY |
                             VehicleFlag.LIMIT_ROLL_ONLY);
-                    m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
+                    vd.m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
                                 VehicleFlag.LIMIT_MOTOR_UP |
                                 VehicleFlag.HOVER_WATER_ONLY);
                     break;
                 case Vehicle.TYPE_AIRPLANE:
-                    m_linearFrictionTimescale = new Vector3(200, 10, 5);
-                    m_angularFrictionTimescale = new Vector3(20, 20, 20);
-                    m_linearMotorTimescale = 2;
-                    m_linearMotorDecayTimescale = 60;
-                    m_angularMotorTimescale = 4;
-                    m_angularMotorDecayTimescale = 8;
-                    m_VhoverHeight = 0;
-                    m_VhoverEfficiency = 0.5f;
-                    m_VhoverTimescale = 1000;
-                    m_VehicleBuoyancy = 0;
-                    m_linearDeflectionEfficiency = 0.5f;
-                    m_linearDeflectionTimescale = 0.5f;
-                    m_angularDeflectionEfficiency = 1;
-                    m_angularDeflectionTimescale = 2;
-                    m_verticalAttractionEfficiency = 0.9f;
-                    m_verticalAttractionTimescale = 2f;
-                    m_bankingEfficiency = 1;
-                    m_bankingMix = 0.7f;
-                    m_bankingTimescale = 2;
-                    m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY |
+                    vd.m_linearFrictionTimescale = new Vector3(200, 10, 5);
+                    vd.m_angularFrictionTimescale = new Vector3(20, 20, 20);
+                    vd.m_linearMotorTimescale = 2;
+                    vd.m_linearMotorDecayTimescale = 60;
+                    vd.m_angularMotorTimescale = 4;
+                    vd.m_angularMotorDecayTimescale = 8;
+                    vd.m_VhoverHeight = 0;
+                    vd.m_VhoverEfficiency = 0.5f;
+                    vd.m_VhoverTimescale = 1000;
+                    vd.m_VehicleBuoyancy = 0;
+                    vd.m_linearDeflectionEfficiency = 0.5f;
+                    vd.m_linearDeflectionTimescale = 0.5f;
+                    vd.m_angularDeflectionEfficiency = 1;
+                    vd.m_angularDeflectionTimescale = 2;
+                    vd.m_verticalAttractionEfficiency = 0.9f;
+                    vd.m_verticalAttractionTimescale = 2f;
+                    vd.m_bankingEfficiency = 1;
+                    vd.m_bankingMix = 0.7f;
+                    vd.m_bankingTimescale = 2;
+                    vd.m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY |
                         VehicleFlag.HOVER_TERRAIN_ONLY |
                         VehicleFlag.HOVER_GLOBAL_HEIGHT |
                         VehicleFlag.HOVER_UP_ONLY |
                         VehicleFlag.NO_DEFLECTION_UP |
                         VehicleFlag.LIMIT_MOTOR_UP);
-                    m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
+                    vd.m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
                     break;
                 case Vehicle.TYPE_BALLOON:
-                    m_linearFrictionTimescale = new Vector3(5, 5, 5);
-                    m_angularFrictionTimescale = new Vector3(10, 10, 10);
-                    m_linearMotorTimescale = 5;
-                    m_linearMotorDecayTimescale = 60;
-                    m_angularMotorTimescale = 6;
-                    m_angularMotorDecayTimescale = 10;
-                    m_VhoverHeight = 5;
-                    m_VhoverEfficiency = 0.8f;
-                    m_VhoverTimescale = 10;
-                    m_VehicleBuoyancy = 1;
-                    m_linearDeflectionEfficiency = 0;
-                    m_linearDeflectionTimescale = 5;
-                    m_angularDeflectionEfficiency = 0;
-                    m_angularDeflectionTimescale = 5;
-                    m_verticalAttractionEfficiency = 0f;
-                    m_verticalAttractionTimescale = 1000f;
-                    m_bankingEfficiency = 0;
-                    m_bankingMix = 0.7f;
-                    m_bankingTimescale = 5;
-                    m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY |
+                    vd.m_linearFrictionTimescale = new Vector3(5, 5, 5);
+                    vd.m_angularFrictionTimescale = new Vector3(10, 10, 10);
+                    vd.m_linearMotorTimescale = 5;
+                    vd.m_linearMotorDecayTimescale = 60;
+                    vd.m_angularMotorTimescale = 6;
+                    vd.m_angularMotorDecayTimescale = 10;
+                    vd.m_VhoverHeight = 5;
+                    vd.m_VhoverEfficiency = 0.8f;
+                    vd.m_VhoverTimescale = 10;
+                    vd.m_VehicleBuoyancy = 1;
+                    vd.m_linearDeflectionEfficiency = 0;
+                    vd.m_linearDeflectionTimescale = 5;
+                    vd.m_angularDeflectionEfficiency = 0;
+                    vd.m_angularDeflectionTimescale = 5;
+                    vd.m_verticalAttractionEfficiency = 0f;
+                    vd.m_verticalAttractionTimescale = 1000f;
+                    vd.m_bankingEfficiency = 0;
+                    vd.m_bankingMix = 0.7f;
+                    vd.m_bankingTimescale = 5;
+                    vd.m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY |
                         VehicleFlag.HOVER_TERRAIN_ONLY |
                         VehicleFlag.HOVER_UP_ONLY |
                         VehicleFlag.NO_DEFLECTION_UP |
                         VehicleFlag.LIMIT_MOTOR_UP);
-                    m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY |
+                    vd.m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY |
                         VehicleFlag.HOVER_GLOBAL_HEIGHT);
                     break;
             }
@@ -424,7 +432,8 @@ namespace OpenSim.Region.Framework.Scenes
             // crap crap crap
             if (ph == null) // what ??
                 return;
-
+            ph.SetVehicle(vd);
+/*
             ph.VehicleType = (int)m_type;
 
            // Linear properties
@@ -465,6 +474,7 @@ namespace OpenSim.Region.Framework.Scenes
 
             ph.VehicleFlags(~(int)m_flags, true);
             ph.VehicleFlags((int)m_flags, false);
+ */
         }
     }
 }
\ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 324fdb8..1cce4c0 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1965,6 +1965,7 @@ namespace OpenSim.Region.Framework.Scenes
         /// <returns></returns>
         public SceneObjectGroup Copy(bool userExposed)
         {
+            m_dupeInProgress = true;
             SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone();
             dupe.m_isBackedUp = false;
             dupe.m_parts = new MapAndArray<OpenMetaverse.UUID, SceneObjectPart>();
@@ -2048,6 +2049,7 @@ namespace OpenSim.Region.Framework.Scenes
                 ScheduleGroupForFullUpdate();
             }
 
+            m_dupeInProgress = false;
             return dupe;
         }
 
diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
index 6e28bfa..2306309 100644
--- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
@@ -22,7 +22,8 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * Revised March 5th 2010 by Kitto Flora. ODEDynamics.cs 
+ * Revised March 5th 2010 by Kitto Flora. ODEDynamics.cs
+ * Ubit 2012
  * rolled into ODEPrim.cs
  */
 
@@ -38,7 +39,6 @@ using Ode.NET;
 using OpenSim.Framework;
 using OpenSim.Region.Physics.Manager;
 
-
 namespace OpenSim.Region.Physics.OdePlugin
 {
     /// <summary>
@@ -254,6 +254,61 @@ namespace OpenSim.Region.Physics.OdePlugin
         private float m_verticalAttractionTimescale = 500f;			// Timescale > 300  means no vert attractor.
 
         SerialControl m_taintserial = null;
+        object m_taintvehicledata = null;
+
+        public void DoSetVehicle()
+        {
+            VehicleData vd = (VehicleData)m_taintvehicledata;
+
+        m_type = vd.m_type;
+        m_flags = vd.m_flags;
+
+        // Linear properties
+        m_linearMotorDirection = vd.m_linearMotorDirection;
+        m_linearFrictionTimescale = vd.m_linearFrictionTimescale;
+        m_linearMotorDecayTimescale = vd.m_linearMotorDecayTimescale;
+        m_linearMotorTimescale = vd.m_linearMotorTimescale;
+//        m_linearMotorOffset = vd.m_linearMotorOffset;
+
+        //Angular properties
+        m_angularMotorDirection = vd.m_angularMotorDirection;
+        m_angularMotorTimescale = vd.m_angularMotorTimescale;
+        m_angularMotorDecayTimescale = vd.m_angularMotorDecayTimescale;
+        m_angularFrictionTimescale = vd.m_angularFrictionTimescale;
+
+        //Deflection properties
+//        m_angularDeflectionEfficiency = vd.m_angularDeflectionEfficiency;
+//        m_angularDeflectionTimescale = vd.m_angularDeflectionTimescale;
+//        m_linearDeflectionEfficiency = vd.m_linearDeflectionEfficiency;
+//        m_linearDeflectionTimescale = vd.m_linearDeflectionTimescale;
+
+        //Banking properties
+//        m_bankingEfficiency = vd.m_bankingEfficiency;
+//        m_bankingMix = vd.m_bankingMix;
+//        m_bankingTimescale = vd.m_bankingTimescale;
+
+        //Hover and Buoyancy properties
+        m_VhoverHeight = vd.m_VhoverHeight;
+//        m_VhoverEfficiency = vd.m_VhoverEfficiency;
+        m_VhoverTimescale = vd.m_VhoverTimescale;
+        m_VehicleBuoyancy = vd.m_VehicleBuoyancy;
+
+        //Attractor properties
+        m_verticalAttractionEfficiency = vd.m_verticalAttractionEfficiency;
+        m_verticalAttractionTimescale = vd.m_verticalAttractionTimescale;
+
+        // Axis
+//        m_referenceFrame = vd.m_referenceFrame;
+
+
+            m_taintvehicledata = null;
+        }
+
+        public override void SetVehicle(object vdata)
+        {
+            m_taintvehicledata = vdata;
+            _parent_scene.AddPhysicsActorTaint(this);
+        }
 
         public override byte[] Serialize(bool PhysIsRunning)
         {
@@ -1843,6 +1898,9 @@ namespace OpenSim.Region.Physics.OdePlugin
                 if (m_taintCollidesWater != m_collidesWater)
                     changefloatonwater(timestep);
 
+                if (m_taintvehicledata != null)
+                    DoSetVehicle();
+
                 if (m_taintserial != null)
                     DoSerialize(m_taintserial);
 
diff --git a/OpenSim/Region/Physics/ChOdePlugin/OdeUtils.cs b/OpenSim/Region/Physics/ChOdePlugin/OdeUtils.cs
index edd58d3..e7e7bb3 100644
--- a/OpenSim/Region/Physics/ChOdePlugin/OdeUtils.cs
+++ b/OpenSim/Region/Physics/ChOdePlugin/OdeUtils.cs
@@ -1,5 +1,17 @@
-// adapted from libomv removing cpu endian adjust
-// for prims lowlevel serialization
+/* Ubit 2012
+  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// no endian conversion. So can't be use to pass information around diferent cpus with diferent endian
 
 using System;
 using System.IO;
@@ -7,77 +19,168 @@ using OpenMetaverse;
 
 namespace OpenSim.Region.Physics.OdePlugin
 {
-    public class wstreamer
+   
+    unsafe public class wstreamer
     {
-        private MemoryStream st;
+        byte[] buf;
+        int index;
+        byte* src;
 
         public wstreamer()
         {
-            st = new MemoryStream();
+            buf = new byte[1024];
+            index = 0;
+        }
+        public wstreamer(int size)
+        {
+            buf = new byte[size];
+            index = 0;
         }
 
         public byte[] close()
         {
-            byte[] data = st.ToArray();
-            st.Close();
+            byte[] data = new byte[index];
+            Buffer.BlockCopy(buf, 0, data, 0, index); 
             return data;
         }
 
+        public void Seek(int pos)
+        {
+            index = pos;
+        }
+
+        public void Seekrel(int pos)
+        {
+            index += pos;
+        }
+
+        public void Wbyte(byte value)
+        {
+            buf[index++] = value;
+        }
         public void Wshort(short value)
         {
-            st.Write(BitConverter.GetBytes(value), 0, 2);
+            src = (byte*)&value;
+            buf[index++] = *src++;
+            buf[index++] = *src;
         }
         public void Wushort(ushort value)
         {
-            byte[] t = BitConverter.GetBytes(value);
-            st.Write(BitConverter.GetBytes(value), 0, 2);
+            src = (byte*)&value;
+            buf[index++] = *src++;
+            buf[index++] = *src;
         }
         public void Wint(int value)
         {
-            st.Write(BitConverter.GetBytes(value), 0, 4);
+            src = (byte*)&value;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src;
         }
         public void Wuint(uint value)
         {
-            st.Write(BitConverter.GetBytes(value), 0, 4);
+            src = (byte*)&value;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src;
         }
         public void Wlong(long value)
         {
-            st.Write(BitConverter.GetBytes(value), 0, 8);
+            src = (byte*)&value;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src;
         }
         public void Wulong(ulong value)
         {
-            st.Write(BitConverter.GetBytes(value), 0, 8);
+            src = (byte*)&value;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src;
         }
 
         public void Wfloat(float value)
         {
-            st.Write(BitConverter.GetBytes(value), 0, 4);
+            src = (byte*)&value;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src;
         }
 
         public void Wdouble(double value)
         {
-            st.Write(BitConverter.GetBytes(value), 0, 8);
+            src = (byte*)&value;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src;
         }
 
         public void Wvector3(Vector3 value)
         {
-            st.Write(BitConverter.GetBytes(value.X), 0, 4);
-            st.Write(BitConverter.GetBytes(value.Y), 0, 4);
-            st.Write(BitConverter.GetBytes(value.Z), 0, 4);
+            src = (byte*)&value.X;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src;
+            src = (byte*)&value.Y; // it may have padding ??
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src;
+            src = (byte*)&value.Z;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src;
         }
         public void Wquat(Quaternion value)
         {
-            st.Write(BitConverter.GetBytes(value.X), 0, 4);
-            st.Write(BitConverter.GetBytes(value.Y), 0, 4);
-            st.Write(BitConverter.GetBytes(value.Z), 0, 4);
-            st.Write(BitConverter.GetBytes(value.W), 0, 4);
+            src = (byte*)&value.X;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src;
+            src = (byte*)&value.Y; // it may have padding ??
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src;
+            src = (byte*)&value.Z;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src;
+            src = (byte*)&value.W;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src++;
+            buf[index++] = *src;
         }
     }
 
-    public class rstreamer
+    unsafe public class rstreamer
     {
         private byte[] rbuf;
         private int ptr;
+        private byte* dst;
 
         public rstreamer(byte[] data)
         {
@@ -89,78 +192,161 @@ namespace OpenSim.Region.Physics.OdePlugin
         {
         }
 
+        public void Seek(int pos)
+        {
+            ptr = pos;
+        }
+
+        public void Seekrel(int pos)
+        {
+            ptr += pos;
+        }
+
+        public byte Rbyte()
+        {
+            return (byte)rbuf[ptr++];
+        }
+
         public short Rshort()
         {
-            short v = BitConverter.ToInt16(rbuf, ptr);
-            ptr += 2;
+            short v;
+            dst = (byte*)&v;
+            *dst++ = rbuf[ptr++];
+            *dst = rbuf[ptr++];
             return v;
         }
         public ushort Rushort()
         {
-            ushort v = BitConverter.ToUInt16(rbuf, ptr);
-            ptr += 2;
+            ushort v;
+            dst = (byte*)&v;
+            *dst++ = rbuf[ptr++];
+            *dst = rbuf[ptr++];
             return v;
         }
         public int Rint()
         {
-            int v = BitConverter.ToInt32(rbuf, ptr);
-            ptr += 4;
+            int v;
+            dst = (byte*)&v;
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst = rbuf[ptr++];
             return v;
         }
         public uint Ruint()
         {
-            uint v = BitConverter.ToUInt32(rbuf, ptr);
-            ptr += 4;
+            uint v;
+            dst = (byte*)&v;
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst = rbuf[ptr++];
             return v;
         }
         public long Rlong()
         {
-            long v = BitConverter.ToInt64(rbuf, ptr);
-            ptr += 8;
+            long v;
+            dst = (byte*)&v;
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst = rbuf[ptr++];
             return v;
         }
         public ulong Rulong()
         {
-            ulong v = BitConverter.ToUInt64(rbuf, ptr);
-            ptr += 8;
+            ulong v;
+            dst = (byte*)&v;
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst = rbuf[ptr++];
             return v;
         }
         public float Rfloat()
         {
-            float v = BitConverter.ToSingle(rbuf, ptr);
-            ptr += 4;
+            float v;
+            dst = (byte*)&v;
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst = rbuf[ptr++];
             return v;
         }
 
         public double Rdouble()
         {
-            double v = BitConverter.ToDouble(rbuf, ptr);
-            ptr += 8;
+            double v;
+            dst = (byte*)&v;
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst = rbuf[ptr++];
             return v;
         }
 
         public Vector3 Rvector3()
         {
             Vector3 v;
-            v.X = BitConverter.ToSingle(rbuf, ptr);
-            ptr += 4;
-            v.Y = BitConverter.ToSingle(rbuf, ptr);
-            ptr += 4;
-            v.Z = BitConverter.ToSingle(rbuf, ptr);
-            ptr += 4;
+            dst = (byte*)&v.X;
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst = rbuf[ptr++];
+
+            dst = (byte*)&v.Y;
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst = rbuf[ptr++];
+
+            dst = (byte*)&v.Z;
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst = rbuf[ptr++];
             return v;
         }
+
         public Quaternion Rquat()
         {
             Quaternion v;
-            v.X = BitConverter.ToSingle(rbuf, ptr);
-            ptr += 4;
-            v.Y = BitConverter.ToSingle(rbuf, ptr);
-            ptr += 4;
-            v.Z = BitConverter.ToSingle(rbuf, ptr);
-            ptr += 4;
-            v.W = BitConverter.ToSingle(rbuf, ptr);
-            ptr += 4;
+            dst = (byte*)&v.X;
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst = rbuf[ptr++];
+
+            dst = (byte*)&v.Y;
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst = rbuf[ptr++];
+
+            dst = (byte*)&v.Z;
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst = rbuf[ptr++];
+
+            dst = (byte*)&v.W;
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst++ = rbuf[ptr++];
+            *dst = rbuf[ptr++];
+
             return v;
         }
     }
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
index eb0228a..f525e9e 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
@@ -146,6 +146,8 @@ namespace OpenSim.Region.Physics.Manager
         /// </summary>
         public event CollisionUpdate OnCollisionUpdate;
 
+        public virtual void SetVehicle(object vdata) { }
+
         public event OutOfBounds OnOutOfBounds;
 #pragma warning restore 67
 
@@ -153,8 +155,7 @@ namespace OpenSim.Region.Physics.Manager
         {
             get { return new NullPhysicsActor(); }
         }
-
-
+   
         public virtual bool Building { get; set; }
 
         public virtual ContactData ContactData
diff --git a/OpenSim/Region/Physics/Manager/VehicleConstants.cs b/OpenSim/Region/Physics/Manager/VehicleConstants.cs
index f0775c1..8e24b4c 100644
--- a/OpenSim/Region/Physics/Manager/VehicleConstants.cs
+++ b/OpenSim/Region/Physics/Manager/VehicleConstants.cs
@@ -26,6 +26,7 @@
  */
 
 using System;
+using OpenMetaverse;
 
 namespace OpenSim.Region.Physics.Manager
 {
@@ -117,5 +118,47 @@ namespace OpenSim.Region.Physics.Manager
         NO_DEFLECTION = 16392,
         LOCK_ROTATION = 32784
     }
-        
+
+    public struct VehicleData
+    {
+        public Vehicle m_type;
+        public VehicleFlag m_flags;
+
+        // Linear properties
+        public Vector3 m_linearMotorDirection;
+        public Vector3 m_linearFrictionTimescale;
+        public float m_linearMotorDecayTimescale;
+        public float m_linearMotorTimescale;
+        public Vector3 m_linearMotorOffset;
+
+        //Angular properties
+        public Vector3 m_angularMotorDirection;
+        public float m_angularMotorTimescale;
+        public float m_angularMotorDecayTimescale;
+        public Vector3 m_angularFrictionTimescale;
+
+        //Deflection properties
+        public float m_angularDeflectionEfficiency;
+        public float m_angularDeflectionTimescale;
+        public float m_linearDeflectionEfficiency;
+        public float m_linearDeflectionTimescale;
+
+        //Banking properties
+        public float m_bankingEfficiency;
+        public float m_bankingMix;
+        public float m_bankingTimescale;
+
+        //Hover and Buoyancy properties
+        public float m_VhoverHeight;
+        public float m_VhoverEfficiency;
+        public float m_VhoverTimescale;
+        public float m_VehicleBuoyancy;
+
+        //Attractor properties
+        public float m_verticalAttractionEfficiency;
+        public float m_verticalAttractionTimescale;
+
+        // Axis
+        public Quaternion m_referenceFrame;
+    }
 }
-- 
cgit v1.1