aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs568
1 files changed, 340 insertions, 228 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 117c878..819635a 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -52,7 +52,7 @@ using OpenSim.Region.Physics.Manager;
52 52
53namespace OpenSim.Region.Physics.BulletSPlugin 53namespace OpenSim.Region.Physics.BulletSPlugin
54{ 54{
55 public class BSDynamics 55 public sealed class BSDynamics
56 { 56 {
57 private BSScene PhysicsScene { get; set; } 57 private BSScene PhysicsScene { get; set; }
58 // the prim this dynamic controller belongs to 58 // the prim this dynamic controller belongs to
@@ -72,8 +72,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
72 // LIMIT_ROLL_ONLY 72 // LIMIT_ROLL_ONLY
73 private Vector3 m_BlockingEndPoint = Vector3.Zero; 73 private Vector3 m_BlockingEndPoint = Vector3.Zero;
74 private Quaternion m_RollreferenceFrame = Quaternion.Identity; 74 private Quaternion m_RollreferenceFrame = Quaternion.Identity;
75 private Quaternion m_referenceFrame = Quaternion.Identity;
76
75 // Linear properties 77 // Linear properties
76 private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time 78 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
77 private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL 80 private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL
78 private Vector3 m_newVelocity = Vector3.Zero; // velocity computed to be applied to body 81 private Vector3 m_newVelocity = Vector3.Zero; // velocity computed to be applied to body
79 private Vector3 m_linearFrictionTimescale = Vector3.Zero; 82 private Vector3 m_linearFrictionTimescale = Vector3.Zero;
@@ -86,7 +89,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
86 89
87 //Angular properties 90 //Angular properties
88 private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor 91 private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor
89 private int m_angularMotorApply = 0; // application frame counter 92 // private int m_angularMotorApply = 0; // application frame counter
90 private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity 93 private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity
91 private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate 94 private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate
92 private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate 95 private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate
@@ -95,19 +98,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin
95 private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body 98 private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body
96 99
97 //Deflection properties 100 //Deflection properties
98 // private float m_angularDeflectionEfficiency = 0; 101 private float m_angularDeflectionEfficiency = 0;
99 // private float m_angularDeflectionTimescale = 0; 102 private float m_angularDeflectionTimescale = 0;
100 // private float m_linearDeflectionEfficiency = 0; 103 private float m_linearDeflectionEfficiency = 0;
101 // private float m_linearDeflectionTimescale = 0; 104 private float m_linearDeflectionTimescale = 0;
102 105
103 //Banking properties 106 //Banking properties
104 // private float m_bankingEfficiency = 0; 107 private float m_bankingEfficiency = 0;
105 // private float m_bankingMix = 0; 108 private float m_bankingMix = 0;
106 // private float m_bankingTimescale = 0; 109 private float m_bankingTimescale = 0;
107 110
108 //Hover and Buoyancy properties 111 //Hover and Buoyancy properties
109 private float m_VhoverHeight = 0f; 112 private float m_VhoverHeight = 0f;
110// private float m_VhoverEfficiency = 0f; 113 private float m_VhoverEfficiency = 0f;
111 private float m_VhoverTimescale = 0f; 114 private float m_VhoverTimescale = 0f;
112 private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height 115 private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
113 private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle. 116 private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle.
@@ -138,10 +141,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
138 switch (pParam) 141 switch (pParam)
139 { 142 {
140 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: 143 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
141 // m_angularDeflectionEfficiency = Math.Max(pValue, 0.01f); 144 m_angularDeflectionEfficiency = Math.Max(pValue, 0.01f);
142 break; 145 break;
143 case Vehicle.ANGULAR_DEFLECTION_TIMESCALE: 146 case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
144 // m_angularDeflectionTimescale = Math.Max(pValue, 0.01f); 147 m_angularDeflectionTimescale = Math.Max(pValue, 0.01f);
145 break; 148 break;
146 case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: 149 case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
147 m_angularMotorDecayTimescale = Math.Max(pValue, 0.01f); 150 m_angularMotorDecayTimescale = Math.Max(pValue, 0.01f);
@@ -150,20 +153,20 @@ namespace OpenSim.Region.Physics.BulletSPlugin
150 m_angularMotorTimescale = Math.Max(pValue, 0.01f); 153 m_angularMotorTimescale = Math.Max(pValue, 0.01f);
151 break; 154 break;
152 case Vehicle.BANKING_EFFICIENCY: 155 case Vehicle.BANKING_EFFICIENCY:
153 // m_bankingEfficiency = Math.Max(pValue, 0.01f); 156 m_bankingEfficiency = Math.Max(-1f, Math.Min(pValue, 1f));
154 break; 157 break;
155 case Vehicle.BANKING_MIX: 158 case Vehicle.BANKING_MIX:
156 // m_bankingMix = Math.Max(pValue, 0.01f); 159 m_bankingMix = Math.Max(pValue, 0.01f);
157 break; 160 break;
158 case Vehicle.BANKING_TIMESCALE: 161 case Vehicle.BANKING_TIMESCALE:
159 // m_bankingTimescale = Math.Max(pValue, 0.01f); 162 m_bankingTimescale = Math.Max(pValue, 0.01f);
160 break; 163 break;
161 case Vehicle.BUOYANCY: 164 case Vehicle.BUOYANCY:
162 m_VehicleBuoyancy = Math.Max(-1f, Math.Min(pValue, 1f)); 165 m_VehicleBuoyancy = Math.Max(-1f, Math.Min(pValue, 1f));
163 break; 166 break;
164// case Vehicle.HOVER_EFFICIENCY: 167 case Vehicle.HOVER_EFFICIENCY:
165// m_VhoverEfficiency = Math.Max(0f, Math.Min(pValue, 1f)); 168 m_VhoverEfficiency = Math.Max(0f, Math.Min(pValue, 1f));
166// break; 169 break;
167 case Vehicle.HOVER_HEIGHT: 170 case Vehicle.HOVER_HEIGHT:
168 m_VhoverHeight = pValue; 171 m_VhoverHeight = pValue;
169 break; 172 break;
@@ -171,10 +174,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
171 m_VhoverTimescale = Math.Max(pValue, 0.01f); 174 m_VhoverTimescale = Math.Max(pValue, 0.01f);
172 break; 175 break;
173 case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: 176 case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
174 // m_linearDeflectionEfficiency = Math.Max(pValue, 0.01f); 177 m_linearDeflectionEfficiency = Math.Max(pValue, 0.01f);
175 break; 178 break;
176 case Vehicle.LINEAR_DEFLECTION_TIMESCALE: 179 case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
177 // m_linearDeflectionTimescale = Math.Max(pValue, 0.01f); 180 m_linearDeflectionTimescale = Math.Max(pValue, 0.01f);
178 break; 181 break;
179 case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: 182 case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
180 m_linearMotorDecayTimescale = Math.Max(pValue, 0.01f); 183 m_linearMotorDecayTimescale = Math.Max(pValue, 0.01f);
@@ -196,7 +199,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
196 break; 199 break;
197 case Vehicle.ANGULAR_MOTOR_DIRECTION: 200 case Vehicle.ANGULAR_MOTOR_DIRECTION:
198 m_angularMotorDirection = new Vector3(pValue, pValue, pValue); 201 m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
199 m_angularMotorApply = 10; 202 // m_angularMotorApply = 100;
200 break; 203 break;
201 case Vehicle.LINEAR_FRICTION_TIMESCALE: 204 case Vehicle.LINEAR_FRICTION_TIMESCALE:
202 m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); 205 m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
@@ -206,7 +209,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
206 m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue); 209 m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue);
207 break; 210 break;
208 case Vehicle.LINEAR_MOTOR_OFFSET: 211 case Vehicle.LINEAR_MOTOR_OFFSET:
209 // m_linearMotorOffset = new Vector3(pValue, pValue, pValue); 212 m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
210 break; 213 break;
211 214
212 } 215 }
@@ -221,15 +224,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
221 m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); 224 m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
222 break; 225 break;
223 case Vehicle.ANGULAR_MOTOR_DIRECTION: 226 case Vehicle.ANGULAR_MOTOR_DIRECTION:
224 m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
225 // Limit requested angular speed to 2 rps= 4 pi rads/sec 227 // Limit requested angular speed to 2 rps= 4 pi rads/sec
226 if (m_angularMotorDirection.X > 12.56f) m_angularMotorDirection.X = 12.56f; 228 pValue.X = Math.Max(-12.56f, Math.Min(pValue.X, 12.56f));
227 if (m_angularMotorDirection.X < - 12.56f) m_angularMotorDirection.X = - 12.56f; 229 pValue.Y = Math.Max(-12.56f, Math.Min(pValue.Y, 12.56f));
228 if (m_angularMotorDirection.Y > 12.56f) m_angularMotorDirection.Y = 12.56f; 230 pValue.Z = Math.Max(-12.56f, Math.Min(pValue.Z, 12.56f));
229 if (m_angularMotorDirection.Y < - 12.56f) m_angularMotorDirection.Y = - 12.56f; 231 m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
230 if (m_angularMotorDirection.Z > 12.56f) m_angularMotorDirection.Z = 12.56f; 232 // m_angularMotorApply = 100;
231 if (m_angularMotorDirection.Z < - 12.56f) m_angularMotorDirection.Z = - 12.56f;
232 m_angularMotorApply = 10;
233 break; 233 break;
234 case Vehicle.LINEAR_FRICTION_TIMESCALE: 234 case Vehicle.LINEAR_FRICTION_TIMESCALE:
235 m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); 235 m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
@@ -239,7 +239,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
239 m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z); 239 m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z);
240 break; 240 break;
241 case Vehicle.LINEAR_MOTOR_OFFSET: 241 case Vehicle.LINEAR_MOTOR_OFFSET:
242 // m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); 242 m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
243 break; 243 break;
244 case Vehicle.BLOCK_EXIT: 244 case Vehicle.BLOCK_EXIT:
245 m_BlockingEndPoint = new Vector3(pValue.X, pValue.Y, pValue.Z); 245 m_BlockingEndPoint = new Vector3(pValue.X, pValue.Y, pValue.Z);
@@ -253,7 +253,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
253 switch (pParam) 253 switch (pParam)
254 { 254 {
255 case Vehicle.REFERENCE_FRAME: 255 case Vehicle.REFERENCE_FRAME:
256 // m_referenceFrame = pValue; 256 m_referenceFrame = pValue;
257 break; 257 break;
258 case Vehicle.ROLL_FRAME: 258 case Vehicle.ROLL_FRAME:
259 m_RollreferenceFrame = pValue; 259 m_RollreferenceFrame = pValue;
@@ -265,21 +265,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
265 { 265 {
266 VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", Prim.LocalID, pParam, remove); 266 VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", Prim.LocalID, pParam, remove);
267 VehicleFlag parm = (VehicleFlag)pParam; 267 VehicleFlag parm = (VehicleFlag)pParam;
268 if (remove) 268 if (pParam == -1)
269 m_flags = (VehicleFlag)0;
270 else
269 { 271 {
270 if (pParam == -1) 272 if (remove)
271 {
272 m_flags = (VehicleFlag)0;
273 }
274 else
275 {
276 m_flags &= ~parm; 273 m_flags &= ~parm;
277 } 274 else
278 } 275 m_flags |= parm;
279 else {
280 m_flags |= parm;
281 } 276 }
282 }//end ProcessVehicleFlags 277 }
283 278
284 internal void ProcessTypeChange(Vehicle pType) 279 internal void ProcessTypeChange(Vehicle pType)
285 { 280 {
@@ -288,99 +283,142 @@ namespace OpenSim.Region.Physics.BulletSPlugin
288 Type = pType; 283 Type = pType;
289 switch (pType) 284 switch (pType)
290 { 285 {
291 case Vehicle.TYPE_NONE: 286 case Vehicle.TYPE_NONE:
292 m_linearFrictionTimescale = new Vector3(0, 0, 0);
293 m_angularFrictionTimescale = new Vector3(0, 0, 0);
294 m_linearMotorDirection = Vector3.Zero; 287 m_linearMotorDirection = Vector3.Zero;
295 m_linearMotorTimescale = 0; 288 m_linearMotorTimescale = 0;
296 m_linearMotorDecayTimescale = 0; 289 m_linearMotorDecayTimescale = 0;
290 m_linearFrictionTimescale = new Vector3(0, 0, 0);
291
297 m_angularMotorDirection = Vector3.Zero; 292 m_angularMotorDirection = Vector3.Zero;
298 m_angularMotorTimescale = 0;
299 m_angularMotorDecayTimescale = 0; 293 m_angularMotorDecayTimescale = 0;
294 m_angularMotorTimescale = 0;
295 m_angularFrictionTimescale = new Vector3(0, 0, 0);
296
300 m_VhoverHeight = 0; 297 m_VhoverHeight = 0;
298 m_VhoverEfficiency = 0;
301 m_VhoverTimescale = 0; 299 m_VhoverTimescale = 0;
302 m_VehicleBuoyancy = 0; 300 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;
303 m_flags = (VehicleFlag)0; 316 m_flags = (VehicleFlag)0;
304 break; 317 break;
305 318
306 case Vehicle.TYPE_SLED: 319 case Vehicle.TYPE_SLED:
307 m_linearFrictionTimescale = new Vector3(30, 1, 1000);
308 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
309 m_linearMotorDirection = Vector3.Zero; 320 m_linearMotorDirection = Vector3.Zero;
310 m_linearMotorTimescale = 1000; 321 m_linearMotorTimescale = 1000;
311 m_linearMotorDecayTimescale = 120; 322 m_linearMotorDecayTimescale = 120;
323 m_linearFrictionTimescale = new Vector3(30, 1, 1000);
324
312 m_angularMotorDirection = Vector3.Zero; 325 m_angularMotorDirection = Vector3.Zero;
313 m_angularMotorTimescale = 1000; 326 m_angularMotorTimescale = 1000;
314 m_angularMotorDecayTimescale = 120; 327 m_angularMotorDecayTimescale = 120;
328 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
329
315 m_VhoverHeight = 0; 330 m_VhoverHeight = 0;
316// m_VhoverEfficiency = 1; 331 m_VhoverEfficiency = 10; // TODO: this looks wrong!!
317 m_VhoverTimescale = 10; 332 m_VhoverTimescale = 10;
318 m_VehicleBuoyancy = 0; 333 m_VehicleBuoyancy = 0;
319 // m_linearDeflectionEfficiency = 1; 334
320 // m_linearDeflectionTimescale = 1; 335 m_linearDeflectionEfficiency = 1;
321 // m_angularDeflectionEfficiency = 1; 336 m_linearDeflectionTimescale = 1;
322 // m_angularDeflectionTimescale = 1000; 337
323 // m_bankingEfficiency = 0; 338 m_angularDeflectionEfficiency = 1;
324 // m_bankingMix = 1; 339 m_angularDeflectionTimescale = 1000;
325 // m_bankingTimescale = 10; 340
326 // m_referenceFrame = Quaternion.Identity; 341 m_verticalAttractionEfficiency = 0;
342 m_verticalAttractionTimescale = 0;
343
344 m_bankingEfficiency = 0;
345 m_bankingTimescale = 10;
346 m_bankingMix = 1;
347
348 m_referenceFrame = Quaternion.Identity;
327 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP); 349 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
328 m_flags &= 350 m_flags &=
329 ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | 351 ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
330 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); 352 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
331 break; 353 break;
332 case Vehicle.TYPE_CAR: 354 case Vehicle.TYPE_CAR:
333 m_linearFrictionTimescale = new Vector3(100, 2, 1000);
334 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
335 m_linearMotorDirection = Vector3.Zero; 355 m_linearMotorDirection = Vector3.Zero;
336 m_linearMotorTimescale = 1; 356 m_linearMotorTimescale = 1;
337 m_linearMotorDecayTimescale = 60; 357 m_linearMotorDecayTimescale = 60;
358 m_linearFrictionTimescale = new Vector3(100, 2, 1000);
359
338 m_angularMotorDirection = Vector3.Zero; 360 m_angularMotorDirection = Vector3.Zero;
339 m_angularMotorTimescale = 1; 361 m_angularMotorTimescale = 1;
340 m_angularMotorDecayTimescale = 0.8f; 362 m_angularMotorDecayTimescale = 0.8f;
363 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
364
341 m_VhoverHeight = 0; 365 m_VhoverHeight = 0;
342// m_VhoverEfficiency = 0; 366 m_VhoverEfficiency = 0;
343 m_VhoverTimescale = 1000; 367 m_VhoverTimescale = 1000;
344 m_VehicleBuoyancy = 0; 368 m_VehicleBuoyancy = 0;
345 // // m_linearDeflectionEfficiency = 1; 369
346 // // m_linearDeflectionTimescale = 2; 370 m_linearDeflectionEfficiency = 1;
347 // // m_angularDeflectionEfficiency = 0; 371 m_linearDeflectionTimescale = 2;
348 // m_angularDeflectionTimescale = 10; 372
373 m_angularDeflectionEfficiency = 0;
374 m_angularDeflectionTimescale = 10;
375
349 m_verticalAttractionEfficiency = 1f; 376 m_verticalAttractionEfficiency = 1f;
350 m_verticalAttractionTimescale = 10f; 377 m_verticalAttractionTimescale = 10f;
351 // m_bankingEfficiency = -0.2f; 378
352 // m_bankingMix = 1; 379 m_bankingEfficiency = -0.2f;
353 // m_bankingTimescale = 1; 380 m_bankingMix = 1;
354 // m_referenceFrame = Quaternion.Identity; 381 m_bankingTimescale = 1;
382
383 m_referenceFrame = Quaternion.Identity;
384 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY
385 | VehicleFlag.HOVER_TERRAIN_ONLY
386 | VehicleFlag.HOVER_GLOBAL_HEIGHT);
355 m_flags |= (VehicleFlag.NO_DEFLECTION_UP 387 m_flags |= (VehicleFlag.NO_DEFLECTION_UP
356 | VehicleFlag.LIMIT_ROLL_ONLY 388 | VehicleFlag.LIMIT_ROLL_ONLY
357 | VehicleFlag.LIMIT_MOTOR_UP); 389 | VehicleFlag.LIMIT_MOTOR_UP
358 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); 390 | VehicleFlag.HOVER_UP_ONLY);
359 m_flags |= (VehicleFlag.HOVER_UP_ONLY);
360 break; 391 break;
361 case Vehicle.TYPE_BOAT: 392 case Vehicle.TYPE_BOAT:
362 m_linearFrictionTimescale = new Vector3(10, 3, 2);
363 m_angularFrictionTimescale = new Vector3(10,10,10);
364 m_linearMotorDirection = Vector3.Zero; 393 m_linearMotorDirection = Vector3.Zero;
365 m_linearMotorTimescale = 5; 394 m_linearMotorTimescale = 5;
366 m_linearMotorDecayTimescale = 60; 395 m_linearMotorDecayTimescale = 60;
396 m_linearFrictionTimescale = new Vector3(10, 3, 2);
397
367 m_angularMotorDirection = Vector3.Zero; 398 m_angularMotorDirection = Vector3.Zero;
368 m_angularMotorTimescale = 4; 399 m_angularMotorTimescale = 4;
369 m_angularMotorDecayTimescale = 4; 400 m_angularMotorDecayTimescale = 4;
401 m_angularFrictionTimescale = new Vector3(10,10,10);
402
370 m_VhoverHeight = 0; 403 m_VhoverHeight = 0;
371// m_VhoverEfficiency = 0.5f; 404 m_VhoverEfficiency = 0.5f;
372 m_VhoverTimescale = 2; 405 m_VhoverTimescale = 2;
373 m_VehicleBuoyancy = 1; 406 m_VehicleBuoyancy = 1;
374 // m_linearDeflectionEfficiency = 0.5f; 407
375 // m_linearDeflectionTimescale = 3; 408 m_linearDeflectionEfficiency = 0.5f;
376 // m_angularDeflectionEfficiency = 0.5f; 409 m_linearDeflectionTimescale = 3;
377 // m_angularDeflectionTimescale = 5; 410
411 m_angularDeflectionEfficiency = 0.5f;
412 m_angularDeflectionTimescale = 5;
413
378 m_verticalAttractionEfficiency = 0.5f; 414 m_verticalAttractionEfficiency = 0.5f;
379 m_verticalAttractionTimescale = 5f; 415 m_verticalAttractionTimescale = 5f;
380 // m_bankingEfficiency = -0.3f; 416
381 // m_bankingMix = 0.8f; 417 m_bankingEfficiency = -0.3f;
382 // m_bankingTimescale = 1; 418 m_bankingMix = 0.8f;
383 // m_referenceFrame = Quaternion.Identity; 419 m_bankingTimescale = 1;
420
421 m_referenceFrame = Quaternion.Identity;
384 m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY 422 m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY
385 | VehicleFlag.HOVER_GLOBAL_HEIGHT 423 | VehicleFlag.HOVER_GLOBAL_HEIGHT
386 | VehicleFlag.LIMIT_ROLL_ONLY 424 | VehicleFlag.LIMIT_ROLL_ONLY
@@ -390,28 +428,35 @@ namespace OpenSim.Region.Physics.BulletSPlugin
390 | VehicleFlag.HOVER_WATER_ONLY); 428 | VehicleFlag.HOVER_WATER_ONLY);
391 break; 429 break;
392 case Vehicle.TYPE_AIRPLANE: 430 case Vehicle.TYPE_AIRPLANE:
393 m_linearFrictionTimescale = new Vector3(200, 10, 5);
394 m_angularFrictionTimescale = new Vector3(20, 20, 20);
395 m_linearMotorDirection = Vector3.Zero; 431 m_linearMotorDirection = Vector3.Zero;
396 m_linearMotorTimescale = 2; 432 m_linearMotorTimescale = 2;
397 m_linearMotorDecayTimescale = 60; 433 m_linearMotorDecayTimescale = 60;
434 m_linearFrictionTimescale = new Vector3(200, 10, 5);
435
398 m_angularMotorDirection = Vector3.Zero; 436 m_angularMotorDirection = Vector3.Zero;
399 m_angularMotorTimescale = 4; 437 m_angularMotorTimescale = 4;
400 m_angularMotorDecayTimescale = 4; 438 m_angularMotorDecayTimescale = 4;
439 m_angularFrictionTimescale = new Vector3(20, 20, 20);
440
401 m_VhoverHeight = 0; 441 m_VhoverHeight = 0;
402// m_VhoverEfficiency = 0.5f; 442 m_VhoverEfficiency = 0.5f;
403 m_VhoverTimescale = 1000; 443 m_VhoverTimescale = 1000;
404 m_VehicleBuoyancy = 0; 444 m_VehicleBuoyancy = 0;
405 // m_linearDeflectionEfficiency = 0.5f; 445
406 // m_linearDeflectionTimescale = 3; 446 m_linearDeflectionEfficiency = 0.5f;
407 // m_angularDeflectionEfficiency = 1; 447 m_linearDeflectionTimescale = 3;
408 // m_angularDeflectionTimescale = 2; 448
449 m_angularDeflectionEfficiency = 1;
450 m_angularDeflectionTimescale = 2;
451
409 m_verticalAttractionEfficiency = 0.9f; 452 m_verticalAttractionEfficiency = 0.9f;
410 m_verticalAttractionTimescale = 2f; 453 m_verticalAttractionTimescale = 2f;
411 // m_bankingEfficiency = 1; 454
412 // m_bankingMix = 0.7f; 455 m_bankingEfficiency = 1;
413 // m_bankingTimescale = 2; 456 m_bankingMix = 0.7f;
414 // m_referenceFrame = Quaternion.Identity; 457 m_bankingTimescale = 2;
458
459 m_referenceFrame = Quaternion.Identity;
415 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY 460 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY
416 | VehicleFlag.HOVER_TERRAIN_ONLY 461 | VehicleFlag.HOVER_TERRAIN_ONLY
417 | VehicleFlag.HOVER_GLOBAL_HEIGHT 462 | VehicleFlag.HOVER_GLOBAL_HEIGHT
@@ -421,28 +466,36 @@ namespace OpenSim.Region.Physics.BulletSPlugin
421 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); 466 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
422 break; 467 break;
423 case Vehicle.TYPE_BALLOON: 468 case Vehicle.TYPE_BALLOON:
424 m_linearFrictionTimescale = new Vector3(5, 5, 5);
425 m_angularFrictionTimescale = new Vector3(10, 10, 10);
426 m_linearMotorDirection = Vector3.Zero; 469 m_linearMotorDirection = Vector3.Zero;
427 m_linearMotorTimescale = 5; 470 m_linearMotorTimescale = 5;
471 m_linearFrictionTimescale = new Vector3(5, 5, 5);
428 m_linearMotorDecayTimescale = 60; 472 m_linearMotorDecayTimescale = 60;
473
429 m_angularMotorDirection = Vector3.Zero; 474 m_angularMotorDirection = Vector3.Zero;
430 m_angularMotorTimescale = 6; 475 m_angularMotorTimescale = 6;
476 m_angularFrictionTimescale = new Vector3(10, 10, 10);
431 m_angularMotorDecayTimescale = 10; 477 m_angularMotorDecayTimescale = 10;
478
432 m_VhoverHeight = 5; 479 m_VhoverHeight = 5;
433// m_VhoverEfficiency = 0.8f; 480 m_VhoverEfficiency = 0.8f;
434 m_VhoverTimescale = 10; 481 m_VhoverTimescale = 10;
435 m_VehicleBuoyancy = 1; 482 m_VehicleBuoyancy = 1;
436 // m_linearDeflectionEfficiency = 0; 483
437 // m_linearDeflectionTimescale = 5; 484 m_linearDeflectionEfficiency = 0;
438 // m_angularDeflectionEfficiency = 0; 485 m_linearDeflectionTimescale = 5;
439 // m_angularDeflectionTimescale = 5; 486
487 m_angularDeflectionEfficiency = 0;
488 m_angularDeflectionTimescale = 5;
489
440 m_verticalAttractionEfficiency = 1f; 490 m_verticalAttractionEfficiency = 1f;
441 m_verticalAttractionTimescale = 100f; 491 m_verticalAttractionTimescale = 100f;
442 // m_bankingEfficiency = 0; 492
443 // m_bankingMix = 0.7f; 493 m_bankingEfficiency = 0;
444 // m_bankingTimescale = 5; 494 m_bankingMix = 0.7f;
445 // m_referenceFrame = Quaternion.Identity; 495 m_bankingTimescale = 5;
496 m_referenceFrame = Quaternion.Identity;
497
498 m_referenceFrame = Quaternion.Identity;
446 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY 499 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY
447 | VehicleFlag.HOVER_TERRAIN_ONLY 500 | VehicleFlag.HOVER_TERRAIN_ONLY
448 | VehicleFlag.HOVER_UP_ONLY 501 | VehicleFlag.HOVER_UP_ONLY
@@ -452,21 +505,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin
452 | VehicleFlag.HOVER_GLOBAL_HEIGHT); 505 | VehicleFlag.HOVER_GLOBAL_HEIGHT);
453 break; 506 break;
454 } 507 }
455 }//end SetDefaultsForType 508 }
456 509
457 // Some of the properties of this prim may have changed. 510 // Some of the properties of this prim may have changed.
458 // Do any updating needed for a vehicle 511 // Do any updating needed for a vehicle
459 public void Refresh() 512 public void Refresh()
460 { 513 {
461 if (!IsActive) 514 if (IsActive)
462 return; 515 {
463 516 // Friction effects are handled by this vehicle code
464 // Set the prim's inertia to zero. The vehicle code handles that and this 517 BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, 0f);
465 // removes the motion and torque actions introduced by Bullet. 518 BulletSimAPI.SetHitFraction2(Prim.PhysBody.ptr, 0f);
466 Vector3 inertia = Vector3.Zero; 519 }
467 // comment out for DEBUG test
468 // BulletSimAPI.SetMassProps2(Prim.BSBody.ptr, Prim.MassRaw, inertia);
469 // BulletSimAPI.UpdateInertiaTensor2(Prim.BSBody.ptr);
470 } 520 }
471 521
472 // One step of the vehicle properties for the next 'pTimestep' seconds. 522 // One step of the vehicle properties for the next 'pTimestep' seconds.
@@ -474,10 +524,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin
474 { 524 {
475 if (!IsActive) return; 525 if (!IsActive) return;
476 526
527 // DEBUG
528 // Because Bullet does apply forces to the vehicle, our last computed
529 // linear and angular velocities are not what is happening now.
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
477 MoveLinear(pTimestep); 536 MoveLinear(pTimestep);
478 MoveAngular(pTimestep); 537 MoveAngular(pTimestep);
479 LimitRotation(pTimestep); 538 LimitRotation(pTimestep);
480 539
540 // DEBUG: Trying to figure out why Bullet goes crazy when the root prim is moved.
541 // BulletSimAPI.SetInterpolationVelocity2(Prim.BSBody.ptr, m_newVelocity, m_lastAngularVelocity); // DEBUG DEBUG DEBUG
542
481 // remember the position so next step we can limit absolute movement effects 543 // remember the position so next step we can limit absolute movement effects
482 m_lastPositionVector = Prim.ForcePosition; 544 m_lastPositionVector = Prim.ForcePosition;
483 545
@@ -489,62 +551,51 @@ namespace OpenSim.Region.Physics.BulletSPlugin
489 // Also does hover and float. 551 // Also does hover and float.
490 private void MoveLinear(float pTimestep) 552 private void MoveLinear(float pTimestep)
491 { 553 {
492 // m_linearMotorDirection is the direction we are moving relative to the vehicle coordinates 554 // m_linearMotorDirection is the target direction we are moving relative to the vehicle coordinates
493 // m_lastLinearVelocityVector is the speed we are moving in that direction 555 // m_lastLinearVelocityVector is the current speed we are moving in that direction
494 if (m_linearMotorDirection.LengthSquared() > 0.001f) 556 if (m_linearMotorDirection.LengthSquared() > 0.001f)
495 { 557 {
496 Vector3 origDir = m_linearMotorDirection; 558 Vector3 origDir = m_linearMotorDirection;
497 Vector3 origVel = m_lastLinearVelocityVector; 559 Vector3 origVel = m_lastLinearVelocityVector;
560 Vector3 vehicleVelocity = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG
498 561
499 // add drive to body 562 // add drive to body
500 // Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale / pTimestep); 563 Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/(m_linearMotorTimescale) * pTimestep;
501 Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/(m_linearMotorTimescale / pTimestep);
502 // lastLinearVelocityVector is the current body velocity vector 564 // lastLinearVelocityVector is the current body velocity vector
503 // RA: Not sure what the *10 is for. A correction for pTimestep?
504 // m_lastLinearVelocityVector += (addAmount*10);
505 m_lastLinearVelocityVector += addAmount; 565 m_lastLinearVelocityVector += addAmount;
506 566
507 // Limit the velocity vector to less than the last set linear motor direction 567 float decayFactor = (1.0f / m_linearMotorDecayTimescale) * pTimestep;
508 if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X)) 568 m_linearMotorDirection *= (1f - decayFactor);
509 m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X; 569
510 if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y)) 570 Vector3 frictionFactor = (Vector3.One / m_linearFrictionTimescale) * pTimestep;
511 m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y; 571 m_lastLinearVelocityVector *= (Vector3.One - frictionFactor);
512 if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z)) 572
513 m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z; 573 // Rotate new object velocity from vehicle relative to world coordinates
514 574 m_newVelocity = m_lastLinearVelocityVector * Prim.ForceOrientation;
515 /* 575
516 // decay applied velocity 576 VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},vehVel={3},add={4},decay={5},frict={6},lmDir={7},lmVel={8},newVel={9}",
517 Vector3 decayfraction = Vector3.One/(m_linearMotorDecayTimescale / pTimestep); 577 Prim.LocalID, origDir, origVel, vehicleVelocity, addAmount, decayFactor, frictionFactor,
518 // (RA: do not know where the 0.5f comes from) 578 m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity);
519 m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f;
520 */
521 float keepfraction = 1.0f - (1.0f / (m_linearMotorDecayTimescale / pTimestep));
522 m_linearMotorDirection *= keepfraction;
523
524 VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},notDecay={4},dir={5},vel={6}",
525 Prim.LocalID, origDir, origVel, addAmount, keepfraction, m_linearMotorDirection, m_lastLinearVelocityVector);
526 } 579 }
527 else 580 else
528 { 581 {
529 // if what remains of direction is very small, zero it. 582 // if what remains of direction is very small, zero it.
530 m_linearMotorDirection = Vector3.Zero; 583 m_linearMotorDirection = Vector3.Zero;
531 m_lastLinearVelocityVector = Vector3.Zero; 584 m_lastLinearVelocityVector = Vector3.Zero;
585 m_newVelocity = Vector3.Zero;
586
532 VDetailLog("{0},MoveLinear,zeroed", Prim.LocalID); 587 VDetailLog("{0},MoveLinear,zeroed", Prim.LocalID);
533 } 588 }
534 589
535 // convert requested object velocity to object relative vector 590 // m_newVelocity is velocity computed from linear motor in world coordinates
536 Quaternion rotq = Prim.ForceOrientation;
537 m_newVelocity = m_lastLinearVelocityVector * rotq;
538
539 // Add the various forces into m_dir which will be our new direction vector (velocity)
540 591
541 // add Gravity and Buoyancy 592 // Gravity and Buoyancy
542 // There is some gravity, make a gravity force vector that is applied after object velocity. 593 // There is some gravity, make a gravity force vector that is applied after object velocity.
543 // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; 594 // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
544 Vector3 grav = Prim.PhysicsScene.DefaultGravity * (Prim.Linkset.LinksetMass * (1f - m_VehicleBuoyancy)); 595 Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy);
545 596
546 /* 597 /*
547 * RA: Not sure why one would do this 598 * RA: Not sure why one would do this unless we are hoping external forces are doing gravity, ...
548 // Preserve the current Z velocity 599 // Preserve the current Z velocity
549 Vector3 vel_now = m_prim.Velocity; 600 Vector3 vel_now = m_prim.Velocity;
550 m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity 601 m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity
@@ -567,6 +618,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
567 } 618 }
568 619
569 // Check if hovering 620 // Check if hovering
621 // m_VhoverEfficiency: 0=bouncy, 1=totally damped
622 // m_VhoverTimescale: time to achieve height
570 if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) 623 if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
571 { 624 {
572 // We should hover, get the target height 625 // We should hover, get the target height
@@ -597,13 +650,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin
597 } 650 }
598 else 651 else
599 { 652 {
600 float herr0 = pos.Z - m_VhoverTargetHeight; 653 float verticalError = pos.Z - m_VhoverTargetHeight;
654 // RA: where does the 50 come from?
655 float verticalCorrectionVelocity = pTimestep * ((verticalError * 50.0f) / m_VhoverTimescale);
601 // Replace Vertical speed with correction figure if significant 656 // Replace Vertical speed with correction figure if significant
602 if (Math.Abs(herr0) > 0.01f) 657 if (Math.Abs(verticalError) > 0.01f)
603 { 658 {
604 m_newVelocity.Z = -((herr0 * pTimestep * 50.0f) / m_VhoverTimescale); 659 m_newVelocity.Z += verticalCorrectionVelocity;
605 //KF: m_VhoverEfficiency is not yet implemented 660 //KF: m_VhoverEfficiency is not yet implemented
606 } 661 }
662 else if (verticalError < -0.01)
663 {
664 m_newVelocity.Z -= verticalCorrectionVelocity;
665 }
607 else 666 else
608 { 667 {
609 m_newVelocity.Z = 0f; 668 m_newVelocity.Z = 0f;
@@ -680,19 +739,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin
680 739
681 // Apply velocity 740 // Apply velocity
682 Prim.ForceVelocity = m_newVelocity; 741 Prim.ForceVelocity = m_newVelocity;
683 // apply gravity force 742 // Prim.AddForce(m_newVelocity * Prim.Linkset.LinksetMass, false);
684 // Why is this set here? The physics engine already does gravity. 743 Prim.AddForce(grav * Prim.Linkset.LinksetMass, false);
685 Prim.AddForce(grav, false, true);
686 744
687 // Apply friction 745 VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},grav={4}",
688 Vector3 keepFraction = Vector3.One - (Vector3.One / (m_linearFrictionTimescale / pTimestep)); 746 Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity, grav);
689 m_lastLinearVelocityVector *= keepFraction;
690
691 VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},grav={4},1Mdecay={5}",
692 Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity, grav, keepFraction);
693 747
694 } // end MoveLinear() 748 } // end MoveLinear()
695 749
750 // =======================================================================
696 // Apply the effect of the angular motor. 751 // Apply the effect of the angular motor.
697 private void MoveAngular(float pTimestep) 752 private void MoveAngular(float pTimestep)
698 { 753 {
@@ -704,94 +759,150 @@ namespace OpenSim.Region.Physics.BulletSPlugin
704 // m_angularFrictionTimescale // body angular velocity decay rate 759 // m_angularFrictionTimescale // body angular velocity decay rate
705 // m_lastAngularVelocity // what was last applied to body 760 // m_lastAngularVelocity // what was last applied to body
706 761
707 // Get what the body is doing, this includes 'external' influences 762 if (m_angularMotorDirection.LengthSquared() > 0.0001)
708 Vector3 angularVelocity = Prim.ForceRotationalVelocity;
709
710 if (m_angularMotorApply > 0)
711 { 763 {
712 // Rather than snapping the angular motor velocity from the old value to
713 // a newly set velocity, this routine steps the value from the previous
714 // value (m_angularMotorVelocity) to the requested value (m_angularMotorDirection).
715 // There are m_angularMotorApply steps.
716 Vector3 origVel = m_angularMotorVelocity; 764 Vector3 origVel = m_angularMotorVelocity;
717 Vector3 origDir = m_angularMotorDirection; 765 Vector3 origDir = m_angularMotorDirection;
718 766
719 // ramp up to new value 767 // new velocity += error / ( time to get there / step interval)
720 // new velocity += error / ( time to get there / step interval) 768 // requested speed - last motor speed
721 // requested speed - last motor speed 769 m_angularMotorVelocity += (m_angularMotorDirection - m_angularMotorVelocity) / (m_angularMotorTimescale / pTimestep);
722 m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep); 770 // decay requested direction
723 m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep); 771 m_angularMotorDirection *= (1.0f - (pTimestep * 1.0f/m_angularMotorDecayTimescale));
724 m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep);
725 772
726 VDetailLog("{0},MoveAngular,angularMotorApply,apply={1},angTScale={2},timeStep={3},origvel={4},origDir={5},vel={6}", 773 VDetailLog("{0},MoveAngular,angularMotorApply,angTScale={1},timeStep={2},origvel={3},origDir={4},vel={5}",
727 Prim.LocalID, m_angularMotorApply, m_angularMotorTimescale, pTimestep, origVel, origDir, m_angularMotorVelocity); 774 Prim.LocalID, m_angularMotorTimescale, pTimestep, origVel, origDir, m_angularMotorVelocity);
728
729 m_angularMotorApply--;
730 } 775 }
731 else 776 else
732 { 777 {
733 // No motor recently applied, keep the body velocity 778 m_angularMotorVelocity = Vector3.Zero;
734 // and decay the velocity 779 }
735 m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep); 780
736 if (m_angularMotorVelocity.LengthSquared() < 0.00001) 781 #region Vertical attactor
737 m_angularMotorVelocity = Vector3.Zero; 782
738 } // end motor section
739
740 // Vertical attractor section
741 Vector3 vertattr = Vector3.Zero; 783 Vector3 vertattr = Vector3.Zero;
742 Vector3 deflection = Vector3.Zero; 784 Vector3 deflection = Vector3.Zero;
743 Vector3 banking = Vector3.Zero; 785 Vector3 banking = Vector3.Zero;
744 786
745 if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero) 787 if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero)
746 { 788 {
747 float VAservo = 0.2f / (m_verticalAttractionTimescale / pTimestep); 789 float VAservo = pTimestep * 0.2f / m_verticalAttractionTimescale;
748 VAservo *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); 790 if (Prim.Linkset.LinksetIsColliding)
791 VAservo = pTimestep * 0.05f / (m_verticalAttractionTimescale);
749 792
750 // get present body rotation 793 VAservo *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency);
751 Quaternion rotq = Prim.ForceOrientation;
752 // vector pointing up
753 Vector3 verterr = Vector3.Zero;
754 verterr.Z = 1.0f;
755 794
756 // rotate it to Body Angle 795 // Create a vector of the vehicle "up" in world coordinates
757 verterr = verterr * rotq; 796 Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation;
758 // verterr.X and .Y are the World error amounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1. 797 // verticalError.X and .Y are the World error amounts. They are 0 when there is no
759 // 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 798 // error (Vehicle Body is 'vertical'), and .Z will be 1. As the body leans to its
760 // negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body. 799 // side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall
800 // and .Z will go // negative. Similar for tilt and |.Y|. .X and .Y must be
801 // modulated to prevent a stable inverted body.
761 802
762 // Error is 0 (no error) to +/- 2 (max error) 803 // Error is 0 (no error) to +/- 2 (max error)
763 if (verterr.Z < 0.0f) 804 if (verticalError.Z < 0.0f)
764 { 805 {
765 verterr.X = 2.0f - verterr.X; 806 verticalError.X = 2.0f - verticalError.X;
766 verterr.Y = 2.0f - verterr.Y; 807 verticalError.Y = 2.0f - verticalError.Y;
767 } 808 }
768 // scale it by VAservo 809 // scale it by VAservo
769 verterr = verterr * VAservo; 810 verticalError = verticalError * VAservo;
770 811
771 // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so 812 // As the body rotates around the X axis, then verticalError.Y increases; Rotated around Y
772 // Change Body angular velocity X based on Y, and Y based on X. Z is not changed. 813 // then .X increases, so change Body angular velocity X based on Y, and Y based on X.
773 vertattr.X = verterr.Y; 814 // Z is not changed.
774 vertattr.Y = - verterr.X; 815 vertattr.X = verticalError.Y;
816 vertattr.Y = - verticalError.X;
775 vertattr.Z = 0f; 817 vertattr.Z = 0f;
776 818
777 // scaling appears better usingsquare-law 819 // scaling appears better usingsquare-law
820 Vector3 angularVelocity = Prim.ForceRotationalVelocity;
778 float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); 821 float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency);
779 vertattr.X += bounce * angularVelocity.X; 822 vertattr.X += bounce * angularVelocity.X;
780 vertattr.Y += bounce * angularVelocity.Y; 823 vertattr.Y += bounce * angularVelocity.Y;
781 824
782 VDetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}", 825 VDetailLog("{0},MoveAngular,verticalAttraction,verticalError={1},bounce={2},vertattr={3}",
783 Prim.LocalID, verterr, bounce, vertattr); 826 Prim.LocalID, verticalError, bounce, vertattr);
784 827
785 } // else vertical attractor is off 828 }
829 #endregion // Vertical attactor
786 830
787 m_lastVertAttractor = vertattr; 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
850 if (m_bankingEfficiency != 0)
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
856 //Use the square of the efficiency, as it looks much more how SL banking works
857 float effSquared = (m_bankingEfficiency*m_bankingEfficiency);
858 if (m_bankingEfficiency < 0)
859 effSquared *= -1; //Keep the negative!
788 860
789 // Bank section tba 861 float mix = Math.Abs(m_bankingMix);
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
790 901
791 // Deflection section tba 902 m_lastVertAttractor = vertattr;
792 903
793 // Sum velocities 904 // Sum velocities
794 m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // + bank + deflection 905 m_lastAngularVelocity = m_angularMotorVelocity + vertattr + banking + deflection;
795 906
796 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) 907 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
797 { 908 {
@@ -806,52 +917,53 @@ namespace OpenSim.Region.Physics.BulletSPlugin
806 VDetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); 917 VDetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity);
807 } 918 }
808 919
809 // apply friction
810 Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep);
811 m_lastAngularVelocity -= m_lastAngularVelocity * decayamount;
812
813 // Apply to the body 920 // Apply to the body
814 Prim.ForceRotationalVelocity = m_lastAngularVelocity; 921 // The above calculates the absolute angular velocity needed
922 // Prim.ForceRotationalVelocity = m_lastAngularVelocity;
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
930 // Apply friction for next time
931 Vector3 decayamount = (Vector3.One / m_angularFrictionTimescale) * pTimestep;
932 m_lastAngularVelocity *= Vector3.One - decayamount;
815 933
816 VDetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", Prim.LocalID, decayamount, m_lastAngularVelocity); 934 VDetailLog("{0},MoveAngular,done,applyAForce={1},decay={2},lastAngular={3}",
935 Prim.LocalID, applyAngularForce, decayamount, m_lastAngularVelocity);
817 } //end MoveAngular 936 } //end MoveAngular
818 937
819 internal void LimitRotation(float timestep) 938 internal void LimitRotation(float timestep)
820 { 939 {
821 Quaternion rotq = Prim.ForceOrientation; 940 Quaternion rotq = Prim.ForceOrientation;
822 Quaternion m_rot = rotq; 941 Quaternion m_rot = rotq;
823 bool changed = false;
824 if (m_RollreferenceFrame != Quaternion.Identity) 942 if (m_RollreferenceFrame != Quaternion.Identity)
825 { 943 {
826 if (rotq.X >= m_RollreferenceFrame.X) 944 if (rotq.X >= m_RollreferenceFrame.X)
827 { 945 {
828 m_rot.X = rotq.X - (m_RollreferenceFrame.X / 2); 946 m_rot.X = rotq.X - (m_RollreferenceFrame.X / 2);
829 changed = true;
830 } 947 }
831 if (rotq.Y >= m_RollreferenceFrame.Y) 948 if (rotq.Y >= m_RollreferenceFrame.Y)
832 { 949 {
833 m_rot.Y = rotq.Y - (m_RollreferenceFrame.Y / 2); 950 m_rot.Y = rotq.Y - (m_RollreferenceFrame.Y / 2);
834 changed = true;
835 } 951 }
836 if (rotq.X <= -m_RollreferenceFrame.X) 952 if (rotq.X <= -m_RollreferenceFrame.X)
837 { 953 {
838 m_rot.X = rotq.X + (m_RollreferenceFrame.X / 2); 954 m_rot.X = rotq.X + (m_RollreferenceFrame.X / 2);
839 changed = true;
840 } 955 }
841 if (rotq.Y <= -m_RollreferenceFrame.Y) 956 if (rotq.Y <= -m_RollreferenceFrame.Y)
842 { 957 {
843 m_rot.Y = rotq.Y + (m_RollreferenceFrame.Y / 2); 958 m_rot.Y = rotq.Y + (m_RollreferenceFrame.Y / 2);
844 changed = true;
845 } 959 }
846 changed = true;
847 } 960 }
848 if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0) 961 if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0)
849 { 962 {
850 m_rot.X = 0; 963 m_rot.X = 0;
851 m_rot.Y = 0; 964 m_rot.Y = 0;
852 changed = true;
853 } 965 }
854 if (changed) 966 if (rotq != m_rot)
855 { 967 {
856 Prim.ForceOrientation = m_rot; 968 Prim.ForceOrientation = m_rot;
857 VDetailLog("{0},LimitRotation,done,orig={1},new={2}", Prim.LocalID, rotq, m_rot); 969 VDetailLog("{0},LimitRotation,done,orig={1},new={2}", Prim.LocalID, rotq, m_rot);