aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs1051
1 files changed, 544 insertions, 507 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 819635a..5a9f135 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -23,7 +23,7 @@
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * 26 */
27 27
28/* RA: June 14, 2011. Copied from ODEDynamics.cs and converted to 28/* RA: June 14, 2011. Copied from ODEDynamics.cs and converted to
29 * call the BulletSim system. 29 * call the BulletSim system.
@@ -52,15 +52,19 @@ using OpenSim.Region.Physics.Manager;
52 52
53namespace OpenSim.Region.Physics.BulletSPlugin 53namespace OpenSim.Region.Physics.BulletSPlugin
54{ 54{
55 public sealed class BSDynamics 55 public class BSDynamics
56 { 56 {
57 private BSScene PhysicsScene { get; set; } 57 private int frcount = 0; // Used to limit dynamics debug output to
58 // the prim this dynamic controller belongs to 58 // every 100th frame
59 private BSPrim Prim { get; set; }
60 59
61 // Vehicle properties 60 private BSPrim m_prim; // the prim this dynamic controller belongs to
62 public Vehicle Type { get; set; }
63 61
62 // Vehicle properties
63 private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind
64 public Vehicle Type
65 {
66 get { return m_type; }
67 }
64 // private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier 68 // private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier
65 private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings: 69 private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings:
66 // HOVER_TERRAIN_ONLY 70 // HOVER_TERRAIN_ONLY
@@ -70,15 +74,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
70 // HOVER_UP_ONLY 74 // HOVER_UP_ONLY
71 // LIMIT_MOTOR_UP 75 // LIMIT_MOTOR_UP
72 // LIMIT_ROLL_ONLY 76 // LIMIT_ROLL_ONLY
77 private VehicleFlag m_Hoverflags = (VehicleFlag)0;
73 private Vector3 m_BlockingEndPoint = Vector3.Zero; 78 private Vector3 m_BlockingEndPoint = Vector3.Zero;
74 private Quaternion m_RollreferenceFrame = Quaternion.Identity; 79 private Quaternion m_RollreferenceFrame = Quaternion.Identity;
75 private Quaternion m_referenceFrame = Quaternion.Identity;
76
77 // Linear properties 80 // Linear properties
78 private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time 81 private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time
79 private Vector3 m_linearMotorOffset = Vector3.Zero; // the point of force can be offset from the center
80 private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL 82 private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL
81 private Vector3 m_newVelocity = Vector3.Zero; // velocity computed to be applied to body 83 private Vector3 m_dir = Vector3.Zero; // velocity applied to body
82 private Vector3 m_linearFrictionTimescale = Vector3.Zero; 84 private Vector3 m_linearFrictionTimescale = Vector3.Zero;
83 private float m_linearMotorDecayTimescale = 0; 85 private float m_linearMotorDecayTimescale = 0;
84 private float m_linearMotorTimescale = 0; 86 private float m_linearMotorTimescale = 0;
@@ -89,28 +91,28 @@ namespace OpenSim.Region.Physics.BulletSPlugin
89 91
90 //Angular properties 92 //Angular properties
91 private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor 93 private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor
92 // private int m_angularMotorApply = 0; // application frame counter 94 private int m_angularMotorApply = 0; // application frame counter
93 private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity 95 private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity
94 private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate 96 private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate
95 private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate 97 private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate
96 private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate 98 private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate
97 private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body 99 private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body
98 private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body 100 // private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body
99 101
100 //Deflection properties 102 //Deflection properties
101 private float m_angularDeflectionEfficiency = 0; 103 // private float m_angularDeflectionEfficiency = 0;
102 private float m_angularDeflectionTimescale = 0; 104 // private float m_angularDeflectionTimescale = 0;
103 private float m_linearDeflectionEfficiency = 0; 105 // private float m_linearDeflectionEfficiency = 0;
104 private float m_linearDeflectionTimescale = 0; 106 // private float m_linearDeflectionTimescale = 0;
105 107
106 //Banking properties 108 //Banking properties
107 private float m_bankingEfficiency = 0; 109 // private float m_bankingEfficiency = 0;
108 private float m_bankingMix = 0; 110 // private float m_bankingMix = 0;
109 private float m_bankingTimescale = 0; 111 // private float m_bankingTimescale = 0;
110 112
111 //Hover and Buoyancy properties 113 //Hover and Buoyancy properties
112 private float m_VhoverHeight = 0f; 114 private float m_VhoverHeight = 0f;
113 private float m_VhoverEfficiency = 0f; 115// private float m_VhoverEfficiency = 0f;
114 private float m_VhoverTimescale = 0f; 116 private float m_VhoverTimescale = 0f;
115 private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height 117 private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
116 private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle. 118 private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle.
@@ -122,74 +124,86 @@ namespace OpenSim.Region.Physics.BulletSPlugin
122 private float m_verticalAttractionEfficiency = 1.0f; // damped 124 private float m_verticalAttractionEfficiency = 1.0f; // damped
123 private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. 125 private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor.
124 126
125 public BSDynamics(BSScene myScene, BSPrim myPrim) 127 public BSDynamics(BSPrim myPrim)
126 {
127 PhysicsScene = myScene;
128 Prim = myPrim;
129 Type = Vehicle.TYPE_NONE;
130 }
131
132 // Return 'true' if this vehicle is doing vehicle things
133 public bool IsActive
134 { 128 {
135 get { return Type != Vehicle.TYPE_NONE; } 129 m_prim = myPrim;
130 m_type = Vehicle.TYPE_NONE;
136 } 131 }
137 132
138 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) 133 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue, float timestep)
139 { 134 {
140 VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue); 135 DetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
141 switch (pParam) 136 switch (pParam)
142 { 137 {
143 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: 138 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
144 m_angularDeflectionEfficiency = Math.Max(pValue, 0.01f); 139 if (pValue < 0.01f) pValue = 0.01f;
140 // m_angularDeflectionEfficiency = pValue;
145 break; 141 break;
146 case Vehicle.ANGULAR_DEFLECTION_TIMESCALE: 142 case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
147 m_angularDeflectionTimescale = Math.Max(pValue, 0.01f); 143 if (pValue < 0.01f) pValue = 0.01f;
144 // m_angularDeflectionTimescale = pValue;
148 break; 145 break;
149 case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: 146 case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
150 m_angularMotorDecayTimescale = Math.Max(pValue, 0.01f); 147 if (pValue < 0.01f) pValue = 0.01f;
148 m_angularMotorDecayTimescale = pValue;
151 break; 149 break;
152 case Vehicle.ANGULAR_MOTOR_TIMESCALE: 150 case Vehicle.ANGULAR_MOTOR_TIMESCALE:
153 m_angularMotorTimescale = Math.Max(pValue, 0.01f); 151 if (pValue < 0.01f) pValue = 0.01f;
152 m_angularMotorTimescale = pValue;
154 break; 153 break;
155 case Vehicle.BANKING_EFFICIENCY: 154 case Vehicle.BANKING_EFFICIENCY:
156 m_bankingEfficiency = Math.Max(-1f, Math.Min(pValue, 1f)); 155 if (pValue < 0.01f) pValue = 0.01f;
156 // m_bankingEfficiency = pValue;
157 break; 157 break;
158 case Vehicle.BANKING_MIX: 158 case Vehicle.BANKING_MIX:
159 m_bankingMix = Math.Max(pValue, 0.01f); 159 if (pValue < 0.01f) pValue = 0.01f;
160 // m_bankingMix = pValue;
160 break; 161 break;
161 case Vehicle.BANKING_TIMESCALE: 162 case Vehicle.BANKING_TIMESCALE:
162 m_bankingTimescale = Math.Max(pValue, 0.01f); 163 if (pValue < 0.01f) pValue = 0.01f;
164 // m_bankingTimescale = pValue;
163 break; 165 break;
164 case Vehicle.BUOYANCY: 166 case Vehicle.BUOYANCY:
165 m_VehicleBuoyancy = Math.Max(-1f, Math.Min(pValue, 1f)); 167 if (pValue < -1f) pValue = -1f;
166 break; 168 if (pValue > 1f) pValue = 1f;
167 case Vehicle.HOVER_EFFICIENCY: 169 m_VehicleBuoyancy = pValue;
168 m_VhoverEfficiency = Math.Max(0f, Math.Min(pValue, 1f)); 170 break;
169 break; 171// case Vehicle.HOVER_EFFICIENCY:
172// if (pValue < 0f) pValue = 0f;
173// if (pValue > 1f) pValue = 1f;
174// m_VhoverEfficiency = pValue;
175// break;
170 case Vehicle.HOVER_HEIGHT: 176 case Vehicle.HOVER_HEIGHT:
171 m_VhoverHeight = pValue; 177 m_VhoverHeight = pValue;
172 break; 178 break;
173 case Vehicle.HOVER_TIMESCALE: 179 case Vehicle.HOVER_TIMESCALE:
174 m_VhoverTimescale = Math.Max(pValue, 0.01f); 180 if (pValue < 0.01f) pValue = 0.01f;
181 m_VhoverTimescale = pValue;
175 break; 182 break;
176 case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: 183 case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
177 m_linearDeflectionEfficiency = Math.Max(pValue, 0.01f); 184 if (pValue < 0.01f) pValue = 0.01f;
185 // m_linearDeflectionEfficiency = pValue;
178 break; 186 break;
179 case Vehicle.LINEAR_DEFLECTION_TIMESCALE: 187 case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
180 m_linearDeflectionTimescale = Math.Max(pValue, 0.01f); 188 if (pValue < 0.01f) pValue = 0.01f;
189 // m_linearDeflectionTimescale = pValue;
181 break; 190 break;
182 case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: 191 case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
183 m_linearMotorDecayTimescale = Math.Max(pValue, 0.01f); 192 if (pValue < 0.01f) pValue = 0.01f;
193 m_linearMotorDecayTimescale = pValue;
184 break; 194 break;
185 case Vehicle.LINEAR_MOTOR_TIMESCALE: 195 case Vehicle.LINEAR_MOTOR_TIMESCALE:
186 m_linearMotorTimescale = Math.Max(pValue, 0.01f); 196 if (pValue < 0.01f) pValue = 0.01f;
197 m_linearMotorTimescale = pValue;
187 break; 198 break;
188 case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: 199 case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
189 m_verticalAttractionEfficiency = Math.Max(0.1f, Math.Min(pValue, 1f)); 200 if (pValue < 0.1f) pValue = 0.1f; // Less goes unstable
201 if (pValue > 1.0f) pValue = 1.0f;
202 m_verticalAttractionEfficiency = pValue;
190 break; 203 break;
191 case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: 204 case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
192 m_verticalAttractionTimescale = Math.Max(pValue, 0.01f); 205 if (pValue < 0.01f) pValue = 0.01f;
206 m_verticalAttractionTimescale = pValue;
193 break; 207 break;
194 208
195 // These are vector properties but the engine lets you use a single float value to 209 // These are vector properties but the engine lets you use a single float value to
@@ -199,7 +213,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
199 break; 213 break;
200 case Vehicle.ANGULAR_MOTOR_DIRECTION: 214 case Vehicle.ANGULAR_MOTOR_DIRECTION:
201 m_angularMotorDirection = new Vector3(pValue, pValue, pValue); 215 m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
202 // m_angularMotorApply = 100; 216 m_angularMotorApply = 10;
203 break; 217 break;
204 case Vehicle.LINEAR_FRICTION_TIMESCALE: 218 case Vehicle.LINEAR_FRICTION_TIMESCALE:
205 m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); 219 m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
@@ -209,27 +223,30 @@ namespace OpenSim.Region.Physics.BulletSPlugin
209 m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue); 223 m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue);
210 break; 224 break;
211 case Vehicle.LINEAR_MOTOR_OFFSET: 225 case Vehicle.LINEAR_MOTOR_OFFSET:
212 m_linearMotorOffset = new Vector3(pValue, pValue, pValue); 226 // m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
213 break; 227 break;
214 228
215 } 229 }
216 }//end ProcessFloatVehicleParam 230 }//end ProcessFloatVehicleParam
217 231
218 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue) 232 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue, float timestep)
219 { 233 {
220 VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue); 234 DetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
221 switch (pParam) 235 switch (pParam)
222 { 236 {
223 case Vehicle.ANGULAR_FRICTION_TIMESCALE: 237 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
224 m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); 238 m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
225 break; 239 break;
226 case Vehicle.ANGULAR_MOTOR_DIRECTION: 240 case Vehicle.ANGULAR_MOTOR_DIRECTION:
227 // Limit requested angular speed to 2 rps= 4 pi rads/sec
228 pValue.X = Math.Max(-12.56f, Math.Min(pValue.X, 12.56f));
229 pValue.Y = Math.Max(-12.56f, Math.Min(pValue.Y, 12.56f));
230 pValue.Z = Math.Max(-12.56f, Math.Min(pValue.Z, 12.56f));
231 m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); 241 m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
232 // m_angularMotorApply = 100; 242 // Limit requested angular speed to 2 rps= 4 pi rads/sec
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;
233 break; 250 break;
234 case Vehicle.LINEAR_FRICTION_TIMESCALE: 251 case Vehicle.LINEAR_FRICTION_TIMESCALE:
235 m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); 252 m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
@@ -239,7 +256,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
239 m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z); 256 m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z);
240 break; 257 break;
241 case Vehicle.LINEAR_MOTOR_OFFSET: 258 case Vehicle.LINEAR_MOTOR_OFFSET:
242 m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); 259 // m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
243 break; 260 break;
244 case Vehicle.BLOCK_EXIT: 261 case Vehicle.BLOCK_EXIT:
245 m_BlockingEndPoint = new Vector3(pValue.X, pValue.Y, pValue.Z); 262 m_BlockingEndPoint = new Vector3(pValue.X, pValue.Y, pValue.Z);
@@ -249,11 +266,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
249 266
250 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) 267 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
251 { 268 {
252 VDetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", Prim.LocalID, pParam, pValue); 269 DetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
253 switch (pParam) 270 switch (pParam)
254 { 271 {
255 case Vehicle.REFERENCE_FRAME: 272 case Vehicle.REFERENCE_FRAME:
256 m_referenceFrame = pValue; 273 // m_referenceFrame = pValue;
257 break; 274 break;
258 case Vehicle.ROLL_FRAME: 275 case Vehicle.ROLL_FRAME:
259 m_RollreferenceFrame = pValue; 276 m_RollreferenceFrame = pValue;
@@ -263,492 +280,575 @@ namespace OpenSim.Region.Physics.BulletSPlugin
263 280
264 internal void ProcessVehicleFlags(int pParam, bool remove) 281 internal void ProcessVehicleFlags(int pParam, bool remove)
265 { 282 {
266 VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", Prim.LocalID, pParam, remove); 283 DetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", m_prim.LocalID, pParam, remove);
267 VehicleFlag parm = (VehicleFlag)pParam; 284 if (remove)
268 if (pParam == -1) 285 {
269 m_flags = (VehicleFlag)0; 286 if (pParam == -1)
287 {
288 m_flags = (VehicleFlag)0;
289 m_Hoverflags = (VehicleFlag)0;
290 return;
291 }
292 if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT)
293 {
294 if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != (VehicleFlag)0)
295 m_Hoverflags &= ~(VehicleFlag.HOVER_GLOBAL_HEIGHT);
296 }
297 if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
298 {
299 if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != (VehicleFlag)0)
300 m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY);
301 }
302 if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
303 {
304 if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != (VehicleFlag)0)
305 m_Hoverflags &= ~(VehicleFlag.HOVER_UP_ONLY);
306 }
307 if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
308 {
309 if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != (VehicleFlag)0)
310 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY);
311 }
312 if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
313 {
314 if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != (VehicleFlag)0)
315 m_flags &= ~(VehicleFlag.LIMIT_MOTOR_UP);
316 }
317 if ((pParam & (int)VehicleFlag.LIMIT_ROLL_ONLY) == (int)VehicleFlag.LIMIT_ROLL_ONLY)
318 {
319 if ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) != (VehicleFlag)0)
320 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
321 }
322 if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
323 {
324 if ((m_flags & VehicleFlag.MOUSELOOK_BANK) != (VehicleFlag)0)
325 m_flags &= ~(VehicleFlag.MOUSELOOK_BANK);
326 }
327 if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
328 {
329 if ((m_flags & VehicleFlag.MOUSELOOK_STEER) != (VehicleFlag)0)
330 m_flags &= ~(VehicleFlag.MOUSELOOK_STEER);
331 }
332 if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
333 {
334 if ((m_flags & VehicleFlag.NO_DEFLECTION_UP) != (VehicleFlag)0)
335 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP);
336 }
337 if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
338 {
339 if ((m_flags & VehicleFlag.CAMERA_DECOUPLED) != (VehicleFlag)0)
340 m_flags &= ~(VehicleFlag.CAMERA_DECOUPLED);
341 }
342 if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
343 {
344 if ((m_flags & VehicleFlag.NO_X) != (VehicleFlag)0)
345 m_flags &= ~(VehicleFlag.NO_X);
346 }
347 if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
348 {
349 if ((m_flags & VehicleFlag.NO_Y) != (VehicleFlag)0)
350 m_flags &= ~(VehicleFlag.NO_Y);
351 }
352 if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
353 {
354 if ((m_flags & VehicleFlag.NO_Z) != (VehicleFlag)0)
355 m_flags &= ~(VehicleFlag.NO_Z);
356 }
357 if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT)
358 {
359 if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != (VehicleFlag)0)
360 m_Hoverflags &= ~(VehicleFlag.LOCK_HOVER_HEIGHT);
361 }
362 if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
363 {
364 if ((m_flags & VehicleFlag.NO_DEFLECTION) != (VehicleFlag)0)
365 m_flags &= ~(VehicleFlag.NO_DEFLECTION);
366 }
367 if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
368 {
369 if ((m_flags & VehicleFlag.LOCK_ROTATION) != (VehicleFlag)0)
370 m_flags &= ~(VehicleFlag.LOCK_ROTATION);
371 }
372 }
270 else 373 else
271 { 374 {
272 if (remove) 375 if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT)
273 m_flags &= ~parm; 376 {
274 else 377 m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT | m_flags);
275 m_flags |= parm; 378 }
379 if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
380 {
381 m_Hoverflags |= (VehicleFlag.HOVER_TERRAIN_ONLY | m_flags);
382 }
383 if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
384 {
385 m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY | m_flags);
386 }
387 if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
388 {
389 m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY | m_flags);
390 }
391 if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
392 {
393 m_flags |= (VehicleFlag.LIMIT_MOTOR_UP | m_flags);
394 }
395 if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
396 {
397 m_flags |= (VehicleFlag.MOUSELOOK_BANK | m_flags);
398 }
399 if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
400 {
401 m_flags |= (VehicleFlag.MOUSELOOK_STEER | m_flags);
402 }
403 if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
404 {
405 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | m_flags);
406 }
407 if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
408 {
409 m_flags |= (VehicleFlag.CAMERA_DECOUPLED | m_flags);
410 }
411 if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
412 {
413 m_flags |= (VehicleFlag.NO_X);
414 }
415 if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
416 {
417 m_flags |= (VehicleFlag.NO_Y);
418 }
419 if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
420 {
421 m_flags |= (VehicleFlag.NO_Z);
422 }
423 if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT)
424 {
425 m_Hoverflags |= (VehicleFlag.LOCK_HOVER_HEIGHT);
426 }
427 if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
428 {
429 m_flags |= (VehicleFlag.NO_DEFLECTION);
430 }
431 if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
432 {
433 m_flags |= (VehicleFlag.LOCK_ROTATION);
434 }
276 } 435 }
277 } 436 }//end ProcessVehicleFlags
278 437
279 internal void ProcessTypeChange(Vehicle pType) 438 internal void ProcessTypeChange(Vehicle pType)
280 { 439 {
281 VDetailLog("{0},ProcessTypeChange,type={1}", Prim.LocalID, pType); 440 DetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType);
282 // Set Defaults For Type 441 // Set Defaults For Type
283 Type = pType; 442 m_type = pType;
284 switch (pType) 443 switch (pType)
285 { 444 {
286 case Vehicle.TYPE_NONE: 445 case Vehicle.TYPE_NONE:
446 m_linearFrictionTimescale = new Vector3(0, 0, 0);
447 m_angularFrictionTimescale = new Vector3(0, 0, 0);
287 m_linearMotorDirection = Vector3.Zero; 448 m_linearMotorDirection = Vector3.Zero;
288 m_linearMotorTimescale = 0; 449 m_linearMotorTimescale = 0;
289 m_linearMotorDecayTimescale = 0; 450 m_linearMotorDecayTimescale = 0;
290 m_linearFrictionTimescale = new Vector3(0, 0, 0);
291
292 m_angularMotorDirection = Vector3.Zero; 451 m_angularMotorDirection = Vector3.Zero;
293 m_angularMotorDecayTimescale = 0;
294 m_angularMotorTimescale = 0; 452 m_angularMotorTimescale = 0;
295 m_angularFrictionTimescale = new Vector3(0, 0, 0); 453 m_angularMotorDecayTimescale = 0;
296
297 m_VhoverHeight = 0; 454 m_VhoverHeight = 0;
298 m_VhoverEfficiency = 0;
299 m_VhoverTimescale = 0; 455 m_VhoverTimescale = 0;
300 m_VehicleBuoyancy = 0; 456 m_VehicleBuoyancy = 0;
301
302 m_linearDeflectionEfficiency = 1;
303 m_linearDeflectionTimescale = 1;
304
305 m_angularDeflectionEfficiency = 0;
306 m_angularDeflectionTimescale = 1000;
307
308 m_verticalAttractionEfficiency = 0;
309 m_verticalAttractionTimescale = 0;
310
311 m_bankingEfficiency = 0;
312 m_bankingTimescale = 1000;
313 m_bankingMix = 1;
314
315 m_referenceFrame = Quaternion.Identity;
316 m_flags = (VehicleFlag)0; 457 m_flags = (VehicleFlag)0;
317 break; 458 break;
318 459
319 case Vehicle.TYPE_SLED: 460 case Vehicle.TYPE_SLED:
461 m_linearFrictionTimescale = new Vector3(30, 1, 1000);
462 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
320 m_linearMotorDirection = Vector3.Zero; 463 m_linearMotorDirection = Vector3.Zero;
321 m_linearMotorTimescale = 1000; 464 m_linearMotorTimescale = 1000;
322 m_linearMotorDecayTimescale = 120; 465 m_linearMotorDecayTimescale = 120;
323 m_linearFrictionTimescale = new Vector3(30, 1, 1000);
324
325 m_angularMotorDirection = Vector3.Zero; 466 m_angularMotorDirection = Vector3.Zero;
326 m_angularMotorTimescale = 1000; 467 m_angularMotorTimescale = 1000;
327 m_angularMotorDecayTimescale = 120; 468 m_angularMotorDecayTimescale = 120;
328 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
329
330 m_VhoverHeight = 0; 469 m_VhoverHeight = 0;
331 m_VhoverEfficiency = 10; // TODO: this looks wrong!! 470// m_VhoverEfficiency = 1;
332 m_VhoverTimescale = 10; 471 m_VhoverTimescale = 10;
333 m_VehicleBuoyancy = 0; 472 m_VehicleBuoyancy = 0;
334 473 // m_linearDeflectionEfficiency = 1;
335 m_linearDeflectionEfficiency = 1; 474 // m_linearDeflectionTimescale = 1;
336 m_linearDeflectionTimescale = 1; 475 // m_angularDeflectionEfficiency = 1;
337 476 // m_angularDeflectionTimescale = 1000;
338 m_angularDeflectionEfficiency = 1; 477 // m_bankingEfficiency = 0;
339 m_angularDeflectionTimescale = 1000; 478 // m_bankingMix = 1;
340 479 // m_bankingTimescale = 10;
341 m_verticalAttractionEfficiency = 0; 480 // m_referenceFrame = Quaternion.Identity;
342 m_verticalAttractionTimescale = 0; 481 m_Hoverflags &=
343
344 m_bankingEfficiency = 0;
345 m_bankingTimescale = 10;
346 m_bankingMix = 1;
347
348 m_referenceFrame = Quaternion.Identity;
349 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
350 m_flags &=
351 ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | 482 ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
352 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); 483 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
484 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
353 break; 485 break;
354 case Vehicle.TYPE_CAR: 486 case Vehicle.TYPE_CAR:
487 m_linearFrictionTimescale = new Vector3(100, 2, 1000);
488 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
355 m_linearMotorDirection = Vector3.Zero; 489 m_linearMotorDirection = Vector3.Zero;
356 m_linearMotorTimescale = 1; 490 m_linearMotorTimescale = 1;
357 m_linearMotorDecayTimescale = 60; 491 m_linearMotorDecayTimescale = 60;
358 m_linearFrictionTimescale = new Vector3(100, 2, 1000);
359
360 m_angularMotorDirection = Vector3.Zero; 492 m_angularMotorDirection = Vector3.Zero;
361 m_angularMotorTimescale = 1; 493 m_angularMotorTimescale = 1;
362 m_angularMotorDecayTimescale = 0.8f; 494 m_angularMotorDecayTimescale = 0.8f;
363 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
364
365 m_VhoverHeight = 0; 495 m_VhoverHeight = 0;
366 m_VhoverEfficiency = 0; 496// m_VhoverEfficiency = 0;
367 m_VhoverTimescale = 1000; 497 m_VhoverTimescale = 1000;
368 m_VehicleBuoyancy = 0; 498 m_VehicleBuoyancy = 0;
369 499 // // m_linearDeflectionEfficiency = 1;
370 m_linearDeflectionEfficiency = 1; 500 // // m_linearDeflectionTimescale = 2;
371 m_linearDeflectionTimescale = 2; 501 // // m_angularDeflectionEfficiency = 0;
372 502 // m_angularDeflectionTimescale = 10;
373 m_angularDeflectionEfficiency = 0;
374 m_angularDeflectionTimescale = 10;
375
376 m_verticalAttractionEfficiency = 1f; 503 m_verticalAttractionEfficiency = 1f;
377 m_verticalAttractionTimescale = 10f; 504 m_verticalAttractionTimescale = 10f;
378 505 // m_bankingEfficiency = -0.2f;
379 m_bankingEfficiency = -0.2f; 506 // m_bankingMix = 1;
380 m_bankingMix = 1; 507 // m_bankingTimescale = 1;
381 m_bankingTimescale = 1; 508 // m_referenceFrame = Quaternion.Identity;
382 509 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
383 m_referenceFrame = Quaternion.Identity; 510 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY |
384 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY 511 VehicleFlag.LIMIT_MOTOR_UP);
385 | VehicleFlag.HOVER_TERRAIN_ONLY 512 m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY);
386 | VehicleFlag.HOVER_GLOBAL_HEIGHT);
387 m_flags |= (VehicleFlag.NO_DEFLECTION_UP
388 | VehicleFlag.LIMIT_ROLL_ONLY
389 | VehicleFlag.LIMIT_MOTOR_UP
390 | VehicleFlag.HOVER_UP_ONLY);
391 break; 513 break;
392 case Vehicle.TYPE_BOAT: 514 case Vehicle.TYPE_BOAT:
515 m_linearFrictionTimescale = new Vector3(10, 3, 2);
516 m_angularFrictionTimescale = new Vector3(10,10,10);
393 m_linearMotorDirection = Vector3.Zero; 517 m_linearMotorDirection = Vector3.Zero;
394 m_linearMotorTimescale = 5; 518 m_linearMotorTimescale = 5;
395 m_linearMotorDecayTimescale = 60; 519 m_linearMotorDecayTimescale = 60;
396 m_linearFrictionTimescale = new Vector3(10, 3, 2);
397
398 m_angularMotorDirection = Vector3.Zero; 520 m_angularMotorDirection = Vector3.Zero;
399 m_angularMotorTimescale = 4; 521 m_angularMotorTimescale = 4;
400 m_angularMotorDecayTimescale = 4; 522 m_angularMotorDecayTimescale = 4;
401 m_angularFrictionTimescale = new Vector3(10,10,10);
402
403 m_VhoverHeight = 0; 523 m_VhoverHeight = 0;
404 m_VhoverEfficiency = 0.5f; 524// m_VhoverEfficiency = 0.5f;
405 m_VhoverTimescale = 2; 525 m_VhoverTimescale = 2;
406 m_VehicleBuoyancy = 1; 526 m_VehicleBuoyancy = 1;
407 527 // m_linearDeflectionEfficiency = 0.5f;
408 m_linearDeflectionEfficiency = 0.5f; 528 // m_linearDeflectionTimescale = 3;
409 m_linearDeflectionTimescale = 3; 529 // m_angularDeflectionEfficiency = 0.5f;
410 530 // m_angularDeflectionTimescale = 5;
411 m_angularDeflectionEfficiency = 0.5f;
412 m_angularDeflectionTimescale = 5;
413
414 m_verticalAttractionEfficiency = 0.5f; 531 m_verticalAttractionEfficiency = 0.5f;
415 m_verticalAttractionTimescale = 5f; 532 m_verticalAttractionTimescale = 5f;
416 533 // m_bankingEfficiency = -0.3f;
417 m_bankingEfficiency = -0.3f; 534 // m_bankingMix = 0.8f;
418 m_bankingMix = 0.8f; 535 // m_bankingTimescale = 1;
419 m_bankingTimescale = 1; 536 // m_referenceFrame = Quaternion.Identity;
420 537 m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
421 m_referenceFrame = Quaternion.Identity; 538 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
422 m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY 539 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
423 | VehicleFlag.HOVER_GLOBAL_HEIGHT 540 m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
424 | VehicleFlag.LIMIT_ROLL_ONLY 541 VehicleFlag.LIMIT_MOTOR_UP);
425 | VehicleFlag.HOVER_UP_ONLY); 542 m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY);
426 m_flags |= (VehicleFlag.NO_DEFLECTION_UP
427 | VehicleFlag.LIMIT_MOTOR_UP
428 | VehicleFlag.HOVER_WATER_ONLY);
429 break; 543 break;
430 case Vehicle.TYPE_AIRPLANE: 544 case Vehicle.TYPE_AIRPLANE:
545 m_linearFrictionTimescale = new Vector3(200, 10, 5);
546 m_angularFrictionTimescale = new Vector3(20, 20, 20);
431 m_linearMotorDirection = Vector3.Zero; 547 m_linearMotorDirection = Vector3.Zero;
432 m_linearMotorTimescale = 2; 548 m_linearMotorTimescale = 2;
433 m_linearMotorDecayTimescale = 60; 549 m_linearMotorDecayTimescale = 60;
434 m_linearFrictionTimescale = new Vector3(200, 10, 5);
435
436 m_angularMotorDirection = Vector3.Zero; 550 m_angularMotorDirection = Vector3.Zero;
437 m_angularMotorTimescale = 4; 551 m_angularMotorTimescale = 4;
438 m_angularMotorDecayTimescale = 4; 552 m_angularMotorDecayTimescale = 4;
439 m_angularFrictionTimescale = new Vector3(20, 20, 20);
440
441 m_VhoverHeight = 0; 553 m_VhoverHeight = 0;
442 m_VhoverEfficiency = 0.5f; 554// m_VhoverEfficiency = 0.5f;
443 m_VhoverTimescale = 1000; 555 m_VhoverTimescale = 1000;
444 m_VehicleBuoyancy = 0; 556 m_VehicleBuoyancy = 0;
445 557 // m_linearDeflectionEfficiency = 0.5f;
446 m_linearDeflectionEfficiency = 0.5f; 558 // m_linearDeflectionTimescale = 3;
447 m_linearDeflectionTimescale = 3; 559 // m_angularDeflectionEfficiency = 1;
448 560 // m_angularDeflectionTimescale = 2;
449 m_angularDeflectionEfficiency = 1;
450 m_angularDeflectionTimescale = 2;
451
452 m_verticalAttractionEfficiency = 0.9f; 561 m_verticalAttractionEfficiency = 0.9f;
453 m_verticalAttractionTimescale = 2f; 562 m_verticalAttractionTimescale = 2f;
454 563 // m_bankingEfficiency = 1;
455 m_bankingEfficiency = 1; 564 // m_bankingMix = 0.7f;
456 m_bankingMix = 0.7f; 565 // m_bankingTimescale = 2;
457 m_bankingTimescale = 2; 566 // m_referenceFrame = Quaternion.Identity;
458 567 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
459 m_referenceFrame = Quaternion.Identity; 568 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
460 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY 569 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
461 | VehicleFlag.HOVER_TERRAIN_ONLY
462 | VehicleFlag.HOVER_GLOBAL_HEIGHT
463 | VehicleFlag.HOVER_UP_ONLY
464 | VehicleFlag.NO_DEFLECTION_UP
465 | VehicleFlag.LIMIT_MOTOR_UP);
466 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); 570 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
467 break; 571 break;
468 case Vehicle.TYPE_BALLOON: 572 case Vehicle.TYPE_BALLOON:
573 m_linearFrictionTimescale = new Vector3(5, 5, 5);
574 m_angularFrictionTimescale = new Vector3(10, 10, 10);
469 m_linearMotorDirection = Vector3.Zero; 575 m_linearMotorDirection = Vector3.Zero;
470 m_linearMotorTimescale = 5; 576 m_linearMotorTimescale = 5;
471 m_linearFrictionTimescale = new Vector3(5, 5, 5);
472 m_linearMotorDecayTimescale = 60; 577 m_linearMotorDecayTimescale = 60;
473
474 m_angularMotorDirection = Vector3.Zero; 578 m_angularMotorDirection = Vector3.Zero;
475 m_angularMotorTimescale = 6; 579 m_angularMotorTimescale = 6;
476 m_angularFrictionTimescale = new Vector3(10, 10, 10);
477 m_angularMotorDecayTimescale = 10; 580 m_angularMotorDecayTimescale = 10;
478
479 m_VhoverHeight = 5; 581 m_VhoverHeight = 5;
480 m_VhoverEfficiency = 0.8f; 582// m_VhoverEfficiency = 0.8f;
481 m_VhoverTimescale = 10; 583 m_VhoverTimescale = 10;
482 m_VehicleBuoyancy = 1; 584 m_VehicleBuoyancy = 1;
483 585 // m_linearDeflectionEfficiency = 0;
484 m_linearDeflectionEfficiency = 0; 586 // m_linearDeflectionTimescale = 5;
485 m_linearDeflectionTimescale = 5; 587 // m_angularDeflectionEfficiency = 0;
486 588 // m_angularDeflectionTimescale = 5;
487 m_angularDeflectionEfficiency = 0;
488 m_angularDeflectionTimescale = 5;
489
490 m_verticalAttractionEfficiency = 1f; 589 m_verticalAttractionEfficiency = 1f;
491 m_verticalAttractionTimescale = 100f; 590 m_verticalAttractionTimescale = 100f;
492 591 // m_bankingEfficiency = 0;
493 m_bankingEfficiency = 0; 592 // m_bankingMix = 0.7f;
494 m_bankingMix = 0.7f; 593 // m_bankingTimescale = 5;
495 m_bankingTimescale = 5; 594 // m_referenceFrame = Quaternion.Identity;
496 m_referenceFrame = Quaternion.Identity; 595 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
497 596 VehicleFlag.HOVER_UP_ONLY);
498 m_referenceFrame = Quaternion.Identity; 597 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
499 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY 598 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
500 | VehicleFlag.HOVER_TERRAIN_ONLY 599 m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT);
501 | VehicleFlag.HOVER_UP_ONLY
502 | VehicleFlag.NO_DEFLECTION_UP
503 | VehicleFlag.LIMIT_MOTOR_UP);
504 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY
505 | VehicleFlag.HOVER_GLOBAL_HEIGHT);
506 break; 600 break;
507 } 601 }
508 } 602 }//end SetDefaultsForType
509 603
510 // Some of the properties of this prim may have changed.
511 // Do any updating needed for a vehicle
512 public void Refresh()
513 {
514 if (IsActive)
515 {
516 // Friction effects are handled by this vehicle code
517 BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, 0f);
518 BulletSimAPI.SetHitFraction2(Prim.PhysBody.ptr, 0f);
519 }
520 }
521
522 // One step of the vehicle properties for the next 'pTimestep' seconds.
523 internal void Step(float pTimestep) 604 internal void Step(float pTimestep)
524 { 605 {
525 if (!IsActive) return; 606 if (m_type == Vehicle.TYPE_NONE) return;
526 607
527 // DEBUG 608 frcount++; // used to limit debug comment output
528 // Because Bullet does apply forces to the vehicle, our last computed 609 if (frcount > 100)
529 // linear and angular velocities are not what is happening now. 610 frcount = 0;
530 // Vector3 externalAngularVelocity = Prim.ForceRotationalVelocity - m_lastAngularVelocity;
531 // m_lastAngularVelocity += (externalAngularVelocity * 0.5f) * pTimestep;
532 // m_lastAngularVelocity = Prim.ForceRotationalVelocity; // DEBUG: account for what Bullet did last time
533 // m_lastLinearVelocityVector = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG:
534 // END DEBUG
535 611
536 MoveLinear(pTimestep); 612 MoveLinear(pTimestep);
537 MoveAngular(pTimestep); 613 MoveAngular(pTimestep);
538 LimitRotation(pTimestep); 614 LimitRotation(pTimestep);
539 615
540 // DEBUG: Trying to figure out why Bullet goes crazy when the root prim is moved. 616 DetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
541 // BulletSimAPI.SetInterpolationVelocity2(Prim.BSBody.ptr, m_newVelocity, m_lastAngularVelocity); // DEBUG DEBUG DEBUG 617 m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity);
542
543 // remember the position so next step we can limit absolute movement effects
544 m_lastPositionVector = Prim.ForcePosition;
545
546 VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
547 Prim.LocalID, Prim.ForcePosition, Prim.Force, Prim.ForceVelocity, Prim.RotationalVelocity);
548 }// end Step 618 }// end Step
549 619
550 // Apply the effect of the linear motor.
551 // Also does hover and float.
552 private void MoveLinear(float pTimestep) 620 private void MoveLinear(float pTimestep)
553 { 621 {
554 // m_linearMotorDirection is the target direction we are moving relative to the vehicle coordinates 622 // requested m_linearMotorDirection is significant
555 // m_lastLinearVelocityVector is the current speed we are moving in that direction 623 // if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f))
556 if (m_linearMotorDirection.LengthSquared() > 0.001f) 624 if (m_linearMotorDirection.LengthSquared() > 0.0001f)
557 { 625 {
558 Vector3 origDir = m_linearMotorDirection; 626 Vector3 origDir = m_linearMotorDirection;
559 Vector3 origVel = m_lastLinearVelocityVector; 627 Vector3 origVel = m_lastLinearVelocityVector;
560 Vector3 vehicleVelocity = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG
561 628
562 // add drive to body 629 // add drive to body
563 Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/(m_linearMotorTimescale) * pTimestep; 630 // Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep);
564 // lastLinearVelocityVector is the current body velocity vector 631 Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale);
632 // lastLinearVelocityVector is the current body velocity vector?
633 // RA: Not sure what the *10 is for. A correction for pTimestep?
634 // m_lastLinearVelocityVector += (addAmount*10);
635 m_lastLinearVelocityVector += addAmount;
636
637 // This will work temporarily, but we really need to compare speed on an axis
638 // KF: Limit body velocity to applied velocity?
639 // Limit the velocity vector to less than the last set linear motor direction
640 if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X))
641 m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X;
642 if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y))
643 m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y;
644 if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z))
645 m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z;
646
647 // decay applied velocity
648 Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep)));
649 m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f;
650
651 /*
652 Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/m_linearMotorTimescale;
565 m_lastLinearVelocityVector += addAmount; 653 m_lastLinearVelocityVector += addAmount;
566 654
567 float decayFactor = (1.0f / m_linearMotorDecayTimescale) * pTimestep; 655 float decayfraction = (1.0f - 1.0f / m_linearMotorDecayTimescale);
568 m_linearMotorDirection *= (1f - decayFactor); 656 m_linearMotorDirection *= decayfraction;
569 657
570 Vector3 frictionFactor = (Vector3.One / m_linearFrictionTimescale) * pTimestep; 658 */
571 m_lastLinearVelocityVector *= (Vector3.One - frictionFactor);
572 659
573 // Rotate new object velocity from vehicle relative to world coordinates 660 DetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}",
574 m_newVelocity = m_lastLinearVelocityVector * Prim.ForceOrientation; 661 m_prim.LocalID, origDir, origVel, addAmount, decayfraction, m_linearMotorDirection, m_lastLinearVelocityVector);
575
576 VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},vehVel={3},add={4},decay={5},frict={6},lmDir={7},lmVel={8},newVel={9}",
577 Prim.LocalID, origDir, origVel, vehicleVelocity, addAmount, decayFactor, frictionFactor,
578 m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity);
579 } 662 }
580 else 663 else
581 { 664 {
582 // if what remains of direction is very small, zero it. 665 // if what remains of applied is small, zero it.
666 // if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f))
667 // m_lastLinearVelocityVector = Vector3.Zero;
583 m_linearMotorDirection = Vector3.Zero; 668 m_linearMotorDirection = Vector3.Zero;
584 m_lastLinearVelocityVector = Vector3.Zero; 669 m_lastLinearVelocityVector = Vector3.Zero;
585 m_newVelocity = Vector3.Zero;
586
587 VDetailLog("{0},MoveLinear,zeroed", Prim.LocalID);
588 } 670 }
589 671
590 // m_newVelocity is velocity computed from linear motor in world coordinates 672 // convert requested object velocity to world-referenced vector
673 Quaternion rotq = m_prim.Orientation;
674 m_dir = m_lastLinearVelocityVector * rotq;
591 675
592 // Gravity and Buoyancy 676 // Add the various forces into m_dir which will be our new direction vector (velocity)
677
678 // add Gravity and Buoyancy
679 // KF: So far I have found no good method to combine a script-requested
680 // .Z velocity and gravity. Therefore only 0g will used script-requested
681 // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only.
682 Vector3 grav = Vector3.Zero;
593 // There is some gravity, make a gravity force vector that is applied after object velocity. 683 // There is some gravity, make a gravity force vector that is applied after object velocity.
594 // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; 684 // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
595 Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); 685 grav.Z = m_prim.Scene.DefaultGravity.Z * m_prim.Mass * (1f - m_VehicleBuoyancy);
596
597 /*
598 * RA: Not sure why one would do this unless we are hoping external forces are doing gravity, ...
599 // Preserve the current Z velocity 686 // Preserve the current Z velocity
600 Vector3 vel_now = m_prim.Velocity; 687 Vector3 vel_now = m_prim.Velocity;
601 m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity 688 m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity
602 */
603 689
604 Vector3 pos = Prim.ForcePosition; 690 Vector3 pos = m_prim.Position;
691 Vector3 posChange = pos;
605// 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); 692// Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f);
693 double Zchange = Math.Abs(posChange.Z);
694 if (m_BlockingEndPoint != Vector3.Zero)
695 {
696 bool changed = false;
697 if (pos.X >= (m_BlockingEndPoint.X - (float)1))
698 {
699 pos.X -= posChange.X + 1;
700 changed = true;
701 }
702 if (pos.Y >= (m_BlockingEndPoint.Y - (float)1))
703 {
704 pos.Y -= posChange.Y + 1;
705 changed = true;
706 }
707 if (pos.Z >= (m_BlockingEndPoint.Z - (float)1))
708 {
709 pos.Z -= posChange.Z + 1;
710 changed = true;
711 }
712 if (pos.X <= 0)
713 {
714 pos.X += posChange.X + 1;
715 changed = true;
716 }
717 if (pos.Y <= 0)
718 {
719 pos.Y += posChange.Y + 1;
720 changed = true;
721 }
722 if (changed)
723 {
724 m_prim.Position = pos;
725 DetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
726 m_prim.LocalID, m_BlockingEndPoint, posChange, pos);
727 }
728 }
606 729
607 // If below the terrain, move us above the ground a little. 730 // If below the terrain, move us above the ground a little.
608 float terrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); 731 if (pos.Z < m_prim.Scene.GetTerrainHeightAtXYZ(pos))
609 // Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset.
610 // Need to add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass.
611 // Vector3 rotatedSize = m_prim.Size * m_prim.ForceOrientation;
612 // if (rotatedSize.Z < terrainHeight)
613 if (pos.Z < terrainHeight)
614 { 732 {
615 pos.Z = terrainHeight + 2; 733 pos.Z = m_prim.Scene.GetTerrainHeightAtXYZ(pos) + 2;
616 Prim.ForcePosition = pos; 734 m_prim.Position = pos;
617 VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, terrainHeight, pos); 735 DetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos);
618 } 736 }
619 737
620 // Check if hovering 738 // Check if hovering
621 // m_VhoverEfficiency: 0=bouncy, 1=totally damped 739 if ((m_Hoverflags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
622 // m_VhoverTimescale: time to achieve height
623 if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
624 { 740 {
625 // We should hover, get the target height 741 // We should hover, get the target height
626 if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0) 742 if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != 0)
627 { 743 {
628 m_VhoverTargetHeight = Prim.PhysicsScene.GetWaterLevelAtXYZ(pos) + m_VhoverHeight; 744 m_VhoverTargetHeight = m_prim.Scene.GetWaterLevel() + m_VhoverHeight;
629 } 745 }
630 if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) 746 if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
631 { 747 {
632 m_VhoverTargetHeight = terrainHeight + m_VhoverHeight; 748 m_VhoverTargetHeight = m_prim.Scene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
633 } 749 }
634 if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) 750 if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0)
635 { 751 {
636 m_VhoverTargetHeight = m_VhoverHeight; 752 m_VhoverTargetHeight = m_VhoverHeight;
637 } 753 }
638 754
639 if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0) 755 if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != 0)
640 { 756 {
641 // If body is aready heigher, use its height as target height 757 // If body is aready heigher, use its height as target height
642 if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; 758 if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
643 } 759 }
644 if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) 760 if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
645 { 761 {
646 if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2) 762 if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2)
647 { 763 {
648 Prim.ForcePosition = pos; 764 m_prim.Position = pos;
649 } 765 }
650 } 766 }
651 else 767 else
652 { 768 {
653 float verticalError = pos.Z - m_VhoverTargetHeight; 769 float herr0 = pos.Z - m_VhoverTargetHeight;
654 // RA: where does the 50 come from?
655 float verticalCorrectionVelocity = pTimestep * ((verticalError * 50.0f) / m_VhoverTimescale);
656 // Replace Vertical speed with correction figure if significant 770 // Replace Vertical speed with correction figure if significant
657 if (Math.Abs(verticalError) > 0.01f) 771 if (Math.Abs(herr0) > 0.01f)
658 { 772 {
659 m_newVelocity.Z += verticalCorrectionVelocity; 773 m_dir.Z = -((herr0 * pTimestep * 50.0f) / m_VhoverTimescale);
660 //KF: m_VhoverEfficiency is not yet implemented 774 //KF: m_VhoverEfficiency is not yet implemented
661 } 775 }
662 else if (verticalError < -0.01)
663 {
664 m_newVelocity.Z -= verticalCorrectionVelocity;
665 }
666 else 776 else
667 { 777 {
668 m_newVelocity.Z = 0f; 778 m_dir.Z = 0f;
669 } 779 }
670 } 780 }
671 781
672 VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", Prim.LocalID, pos, m_newVelocity, m_VhoverHeight, m_VhoverTargetHeight); 782 DetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight);
673 }
674 783
675 Vector3 posChange = pos - m_lastPositionVector; 784// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped
676 if (m_BlockingEndPoint != Vector3.Zero) 785// m_VhoverTimescale = 0f; // time to acheive height
677 { 786// pTimestep is time since last frame,in secs
678 bool changed = false;
679 if (pos.X >= (m_BlockingEndPoint.X - (float)1))
680 {
681 pos.X -= posChange.X + 1;
682 changed = true;
683 }
684 if (pos.Y >= (m_BlockingEndPoint.Y - (float)1))
685 {
686 pos.Y -= posChange.Y + 1;
687 changed = true;
688 }
689 if (pos.Z >= (m_BlockingEndPoint.Z - (float)1))
690 {
691 pos.Z -= posChange.Z + 1;
692 changed = true;
693 }
694 if (pos.X <= 0)
695 {
696 pos.X += posChange.X + 1;
697 changed = true;
698 }
699 if (pos.Y <= 0)
700 {
701 pos.Y += posChange.Y + 1;
702 changed = true;
703 }
704 if (changed)
705 {
706 Prim.ForcePosition = pos;
707 VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
708 Prim.LocalID, m_BlockingEndPoint, posChange, pos);
709 }
710 } 787 }
711 788
712 // Limit absolute vertical change
713 float Zchange = Math.Abs(posChange.Z);
714 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) 789 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0)
715 { 790 {
791 //Start Experimental Values
716 if (Zchange > .3) 792 if (Zchange > .3)
793 {
717 grav.Z = (float)(grav.Z * 3); 794 grav.Z = (float)(grav.Z * 3);
795 }
718 if (Zchange > .15) 796 if (Zchange > .15)
797 {
719 grav.Z = (float)(grav.Z * 2); 798 grav.Z = (float)(grav.Z * 2);
799 }
720 if (Zchange > .75) 800 if (Zchange > .75)
801 {
721 grav.Z = (float)(grav.Z * 1.5); 802 grav.Z = (float)(grav.Z * 1.5);
803 }
722 if (Zchange > .05) 804 if (Zchange > .05)
805 {
723 grav.Z = (float)(grav.Z * 1.25); 806 grav.Z = (float)(grav.Z * 1.25);
807 }
724 if (Zchange > .025) 808 if (Zchange > .025)
809 {
725 grav.Z = (float)(grav.Z * 1.125); 810 grav.Z = (float)(grav.Z * 1.125);
726 float postemp = (pos.Z - terrainHeight); 811 }
812 float terraintemp = m_prim.Scene.GetTerrainHeightAtXYZ(pos);
813 float postemp = (pos.Z - terraintemp);
727 if (postemp > 2.5f) 814 if (postemp > 2.5f)
815 {
728 grav.Z = (float)(grav.Z * 1.037125); 816 grav.Z = (float)(grav.Z * 1.037125);
729 VDetailLog("{0},MoveLinear,limitMotorUp,grav={1}", Prim.LocalID, grav); 817 }
818 DetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav);
819 //End Experimental Values
730 } 820 }
731
732 // If not changing some axis, reduce out velocity
733 if ((m_flags & (VehicleFlag.NO_X)) != 0) 821 if ((m_flags & (VehicleFlag.NO_X)) != 0)
734 m_newVelocity.X = 0; 822 {
823 m_dir.X = 0;
824 }
735 if ((m_flags & (VehicleFlag.NO_Y)) != 0) 825 if ((m_flags & (VehicleFlag.NO_Y)) != 0)
736 m_newVelocity.Y = 0; 826 {
827 m_dir.Y = 0;
828 }
737 if ((m_flags & (VehicleFlag.NO_Z)) != 0) 829 if ((m_flags & (VehicleFlag.NO_Z)) != 0)
738 m_newVelocity.Z = 0; 830 {
831 m_dir.Z = 0;
832 }
833
834 m_lastPositionVector = m_prim.Position;
739 835
740 // Apply velocity 836 // Apply velocity
741 Prim.ForceVelocity = m_newVelocity; 837 m_prim.Velocity = m_dir;
742 // Prim.AddForce(m_newVelocity * Prim.Linkset.LinksetMass, false); 838 // apply gravity force
743 Prim.AddForce(grav * Prim.Linkset.LinksetMass, false); 839 // Why is this set here? The physics engine already does gravity.
840 // m_prim.AddForce(grav, false);
841 // m_prim.Force = grav;
744 842
745 VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},grav={4}", 843 // Apply friction
746 Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity, grav); 844 Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep);
845 m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount;
846
847 DetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}",
848 m_prim.LocalID, m_lastPositionVector, m_dir, grav, decayamount);
747 849
748 } // end MoveLinear() 850 } // end MoveLinear()
749 851
750 // =======================================================================
751 // Apply the effect of the angular motor.
752 private void MoveAngular(float pTimestep) 852 private void MoveAngular(float pTimestep)
753 { 853 {
754 // m_angularMotorDirection // angular velocity requested by LSL motor 854 // m_angularMotorDirection // angular velocity requested by LSL motor
@@ -759,223 +859,160 @@ namespace OpenSim.Region.Physics.BulletSPlugin
759 // m_angularFrictionTimescale // body angular velocity decay rate 859 // m_angularFrictionTimescale // body angular velocity decay rate
760 // m_lastAngularVelocity // what was last applied to body 860 // m_lastAngularVelocity // what was last applied to body
761 861
762 if (m_angularMotorDirection.LengthSquared() > 0.0001) 862 // Get what the body is doing, this includes 'external' influences
763 { 863 Vector3 angularVelocity = m_prim.RotationalVelocity;
764 Vector3 origVel = m_angularMotorVelocity;
765 Vector3 origDir = m_angularMotorDirection;
766
767 // new velocity += error / ( time to get there / step interval)
768 // requested speed - last motor speed
769 m_angularMotorVelocity += (m_angularMotorDirection - m_angularMotorVelocity) / (m_angularMotorTimescale / pTimestep);
770 // decay requested direction
771 m_angularMotorDirection *= (1.0f - (pTimestep * 1.0f/m_angularMotorDecayTimescale));
772 864
773 VDetailLog("{0},MoveAngular,angularMotorApply,angTScale={1},timeStep={2},origvel={3},origDir={4},vel={5}", 865 if (m_angularMotorApply > 0)
774 Prim.LocalID, m_angularMotorTimescale, pTimestep, origVel, origDir, m_angularMotorVelocity); 866 {
867 // Rather than snapping the angular motor velocity from the old value to
868 // a newly set velocity, this routine steps the value from the previous
869 // value (m_angularMotorVelocity) to the requested value (m_angularMotorDirection).
870 // There are m_angularMotorApply steps.
871 Vector3 origAngularVelocity = m_angularMotorVelocity;
872 // ramp up to new value
873 // current velocity += error / (time to get there / step interval)
874 // requested speed - last motor speed
875 m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep);
876 m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep);
877 m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep);
878
879 DetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}",
880 m_prim.LocalID,m_angularMotorApply,origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity);
881
882 m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected
883 // velocity may still be acheived.
775 } 884 }
776 else 885 else
777 { 886 {
778 m_angularMotorVelocity = Vector3.Zero; 887 // No motor recently applied, keep the body velocity
779 } 888 // and decay the velocity
780 889 m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep);
781 #region Vertical attactor 890 } // end motor section
782 891
892 // Vertical attractor section
783 Vector3 vertattr = Vector3.Zero; 893 Vector3 vertattr = Vector3.Zero;
784 Vector3 deflection = Vector3.Zero; 894 if (m_verticalAttractionTimescale < 300)
785 Vector3 banking = Vector3.Zero;
786
787 if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero)
788 { 895 {
789 float VAservo = pTimestep * 0.2f / m_verticalAttractionTimescale; 896 float VAservo = 0.2f / (m_verticalAttractionTimescale * pTimestep);
790 if (Prim.Linkset.LinksetIsColliding) 897 // get present body rotation
791 VAservo = pTimestep * 0.05f / (m_verticalAttractionTimescale); 898 Quaternion rotq = m_prim.Orientation;
792 899 // make a vector pointing up
793 VAservo *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); 900 Vector3 verterr = Vector3.Zero;
794 901 verterr.Z = 1.0f;
795 // Create a vector of the vehicle "up" in world coordinates 902 // rotate it to Body Angle
796 Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; 903 verterr = verterr * rotq;
797 // verticalError.X and .Y are the World error amounts. They are 0 when there is no 904 // verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1.
798 // error (Vehicle Body is 'vertical'), and .Z will be 1. As the body leans to its 905 // As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go
799 // side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall 906 // negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body.
800 // and .Z will go // negative. Similar for tilt and |.Y|. .X and .Y must be 907 if (verterr.Z < 0.0f)
801 // modulated to prevent a stable inverted body.
802
803 // Error is 0 (no error) to +/- 2 (max error)
804 if (verticalError.Z < 0.0f)
805 { 908 {
806 verticalError.X = 2.0f - verticalError.X; 909 verterr.X = 2.0f - verterr.X;
807 verticalError.Y = 2.0f - verticalError.Y; 910 verterr.Y = 2.0f - verterr.Y;
808 } 911 }
912 // Error is 0 (no error) to +/- 2 (max error)
809 // scale it by VAservo 913 // scale it by VAservo
810 verticalError = verticalError * VAservo; 914 verterr = verterr * VAservo;
811 915
812 // As the body rotates around the X axis, then verticalError.Y increases; Rotated around Y 916 // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so
813 // then .X increases, so change Body angular velocity X based on Y, and Y based on X. 917 // Change Body angular velocity X based on Y, and Y based on X. Z is not changed.
814 // Z is not changed. 918 vertattr.X = verterr.Y;
815 vertattr.X = verticalError.Y; 919 vertattr.Y = - verterr.X;
816 vertattr.Y = - verticalError.X;
817 vertattr.Z = 0f; 920 vertattr.Z = 0f;
818 921
819 // scaling appears better usingsquare-law 922 // scaling appears better usingsquare-law
820 Vector3 angularVelocity = Prim.ForceRotationalVelocity;
821 float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); 923 float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency);
822 vertattr.X += bounce * angularVelocity.X; 924 vertattr.X += bounce * angularVelocity.X;
823 vertattr.Y += bounce * angularVelocity.Y; 925 vertattr.Y += bounce * angularVelocity.Y;
824 926
825 VDetailLog("{0},MoveAngular,verticalAttraction,verticalError={1},bounce={2},vertattr={3}", 927 DetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}",
826 Prim.LocalID, verticalError, bounce, vertattr); 928 m_prim.LocalID, verterr, bounce, vertattr);
827
828 }
829 #endregion // Vertical attactor
830
831 #region Deflection
832
833 //Forward is the prefered direction, but if the reference frame has changed, we need to take this into account as well
834 if (m_angularDeflectionEfficiency != 0)
835 {
836 Vector3 preferredAxisOfMotion =
837 new Vector3((pTimestep * 10 * (m_angularDeflectionEfficiency / m_angularDeflectionTimescale)), 0, 0);
838 preferredAxisOfMotion *= Quaternion.Add(Prim.ForceOrientation, m_referenceFrame);
839
840 deflection = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep;
841
842 VDetailLog("{0},MoveAngular,Deflection,perfAxis={1},deflection={2}",
843 Prim.LocalID, preferredAxisOfMotion, deflection);
844 }
845
846 #endregion
847
848 #region Banking
849 929
850 if (m_bankingEfficiency != 0) 930 } // else vertical attractor is off
851 {
852 Vector3 dir = Vector3.One * Prim.ForceOrientation;
853 float mult = (m_bankingMix*m_bankingMix)*-1*(m_bankingMix < 0 ? -1 : 1);
854 //Changes which way it banks in and out of turns
855 931
856 //Use the square of the efficiency, as it looks much more how SL banking works 932 // m_lastVertAttractor = vertattr;
857 float effSquared = (m_bankingEfficiency*m_bankingEfficiency);
858 if (m_bankingEfficiency < 0)
859 effSquared *= -1; //Keep the negative!
860 933
861 float mix = Math.Abs(m_bankingMix); 934 // Bank section tba
862 if (m_angularMotorVelocity.X == 0)
863 {
864 /*if (!parent.Orientation.ApproxEquals(this.m_referenceFrame, 0.25f))
865 {
866 Vector3 axisAngle;
867 float angle;
868 parent.Orientation.GetAxisAngle(out axisAngle, out angle);
869 Vector3 rotatedVel = parent.Velocity * parent.Orientation;
870 if ((rotatedVel.X < 0 && axisAngle.Y > 0) || (rotatedVel.X > 0 && axisAngle.Y < 0))
871 m_angularMotorVelocity.X += (effSquared * (mult * mix)) * (1f) * 10;
872 else
873 m_angularMotorVelocity.X += (effSquared * (mult * mix)) * (-1f) * 10;
874 }*/
875 }
876 else
877 banking.Z += (effSquared*(mult*mix))*(m_angularMotorVelocity.X) * 4;
878 if (!Prim.Linkset.LinksetIsColliding && Math.Abs(m_angularMotorVelocity.X) > mix)
879 //If they are colliding, we probably shouldn't shove the prim around... probably
880 {
881 float angVelZ = m_angularMotorVelocity.X*-1;
882 /*if(angVelZ > mix)
883 angVelZ = mix;
884 else if(angVelZ < -mix)
885 angVelZ = -mix;*/
886 //This controls how fast and how far the banking occurs
887 Vector3 bankingRot = new Vector3(angVelZ*(effSquared*mult), 0, 0);
888 if (bankingRot.X > 3)
889 bankingRot.X = 3;
890 else if (bankingRot.X < -3)
891 bankingRot.X = -3;
892 bankingRot *= Prim.ForceOrientation;
893 banking += bankingRot;
894 }
895 m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency;
896 VDetailLog("{0},MoveAngular,Banking,bEff={1},angMotVel={2},banking={3}",
897 Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, banking);
898 }
899
900 #endregion
901 935
902 m_lastVertAttractor = vertattr; 936 // Deflection section tba
903 937
904 // Sum velocities 938 // Sum velocities
905 m_lastAngularVelocity = m_angularMotorVelocity + vertattr + banking + deflection; 939 m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // + bank + deflection
906 940
907 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) 941 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
908 { 942 {
909 m_lastAngularVelocity.X = 0; 943 m_lastAngularVelocity.X = 0;
910 m_lastAngularVelocity.Y = 0; 944 m_lastAngularVelocity.Y = 0;
911 VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); 945 DetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
912 } 946 }
913 947
914 if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) 948 if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
915 { 949 {
916 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. 950 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
917 VDetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); 951 DetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
918 } 952 }
919 953
920 // Apply to the body 954 // apply friction
921 // The above calculates the absolute angular velocity needed 955 Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep);
922 // Prim.ForceRotationalVelocity = m_lastAngularVelocity; 956 m_lastAngularVelocity -= m_lastAngularVelocity * decayamount;
923
924 // Apply a force to overcome current angular velocity
925 Vector3 applyAngularForce = (m_lastAngularVelocity - Prim.ForceRotationalVelocity) * Prim.Linkset.LinksetMass;
926 // Vector3 applyAngularForce = (m_lastAngularVelocity - Prim.ForceRotationalVelocity);
927 // Prim.AddAngularForce(applyAngularForce, false);
928 Prim.ApplyTorqueImpulse(applyAngularForce, false);
929 957
930 // Apply friction for next time 958 // Apply to the body
931 Vector3 decayamount = (Vector3.One / m_angularFrictionTimescale) * pTimestep; 959 m_prim.RotationalVelocity = m_lastAngularVelocity;
932 m_lastAngularVelocity *= Vector3.One - decayamount;
933 960
934 VDetailLog("{0},MoveAngular,done,applyAForce={1},decay={2},lastAngular={3}", 961 DetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", m_prim.LocalID, decayamount, m_lastAngularVelocity);
935 Prim.LocalID, applyAngularForce, decayamount, m_lastAngularVelocity);
936 } //end MoveAngular 962 } //end MoveAngular
937 963
938 internal void LimitRotation(float timestep) 964 internal void LimitRotation(float timestep)
939 { 965 {
940 Quaternion rotq = Prim.ForceOrientation; 966 Quaternion rotq = m_prim.Orientation;
941 Quaternion m_rot = rotq; 967 Quaternion m_rot = rotq;
968 bool changed = false;
942 if (m_RollreferenceFrame != Quaternion.Identity) 969 if (m_RollreferenceFrame != Quaternion.Identity)
943 { 970 {
944 if (rotq.X >= m_RollreferenceFrame.X) 971 if (rotq.X >= m_RollreferenceFrame.X)
945 { 972 {
946 m_rot.X = rotq.X - (m_RollreferenceFrame.X / 2); 973 m_rot.X = rotq.X - (m_RollreferenceFrame.X / 2);
974 changed = true;
947 } 975 }
948 if (rotq.Y >= m_RollreferenceFrame.Y) 976 if (rotq.Y >= m_RollreferenceFrame.Y)
949 { 977 {
950 m_rot.Y = rotq.Y - (m_RollreferenceFrame.Y / 2); 978 m_rot.Y = rotq.Y - (m_RollreferenceFrame.Y / 2);
979 changed = true;
951 } 980 }
952 if (rotq.X <= -m_RollreferenceFrame.X) 981 if (rotq.X <= -m_RollreferenceFrame.X)
953 { 982 {
954 m_rot.X = rotq.X + (m_RollreferenceFrame.X / 2); 983 m_rot.X = rotq.X + (m_RollreferenceFrame.X / 2);
984 changed = true;
955 } 985 }
956 if (rotq.Y <= -m_RollreferenceFrame.Y) 986 if (rotq.Y <= -m_RollreferenceFrame.Y)
957 { 987 {
958 m_rot.Y = rotq.Y + (m_RollreferenceFrame.Y / 2); 988 m_rot.Y = rotq.Y + (m_RollreferenceFrame.Y / 2);
989 changed = true;
959 } 990 }
991 changed = true;
960 } 992 }
961 if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0) 993 if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0)
962 { 994 {
963 m_rot.X = 0; 995 m_rot.X = 0;
964 m_rot.Y = 0; 996 m_rot.Y = 0;
997 changed = true;
965 } 998 }
966 if (rotq != m_rot) 999 if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0)
967 { 1000 {
968 Prim.ForceOrientation = m_rot; 1001 m_rot.X = 0;
969 VDetailLog("{0},LimitRotation,done,orig={1},new={2}", Prim.LocalID, rotq, m_rot); 1002 m_rot.Y = 0;
1003 changed = true;
970 } 1004 }
1005 if (changed)
1006 m_prim.Orientation = m_rot;
971 1007
1008 DetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot);
972 } 1009 }
973 1010
974 // Invoke the detailed logger and output something if it's enabled. 1011 // Invoke the detailed logger and output something if it's enabled.
975 private void VDetailLog(string msg, params Object[] args) 1012 private void DetailLog(string msg, params Object[] args)
976 { 1013 {
977 if (Prim.PhysicsScene.VehicleLoggingEnabled) 1014 if (m_prim.Scene.VehicleLoggingEnabled)
978 Prim.PhysicsScene.DetailLog(msg, args); 1015 m_prim.Scene.PhysicsLogging.Write(msg, args);
979 } 1016 }
980 } 1017 }
981} 1018}