aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/OdePlugin/ODEDynamics.c_comments
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEDynamics.c_comments (renamed from OpenSim/Region/Physics/OdePlugin/ODEVehicleSettings.cs)558
1 files changed, 281 insertions, 277 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEVehicleSettings.cs b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.c_comments
index a547c3e..1060aa6 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEVehicleSettings.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.c_comments
@@ -1,4 +1,16 @@
1/* 1/*
2 * Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces
3 * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
4 * ODEPrim.cs contains methods dealing with Prim editing, Prim
5 * characteristics and Kinetic motion.
6 * ODEDynamics.cs contains methods dealing with Prim Physical motion
7 * (dynamics) and the associated settings. Old Linear and angular
8 * motors for dynamic motion have been replace with MoveLinear()
9 * and MoveAngular(); 'Physical' is used only to switch ODE dynamic
10 * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
11 * switch between 'VEHICLE' parameter use and general dynamics
12 * settings use.
13 *
2 * Copyright (c) Contributors, http://opensimulator.org/ 14 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 15 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 16 *
@@ -37,10 +49,10 @@ using OpenSim.Region.Physics.Manager;
37 49
38namespace OpenSim.Region.Physics.OdePlugin 50namespace OpenSim.Region.Physics.OdePlugin
39{ 51{
40 public class ODEVehicleSettings 52 public class ODEDynamics
41 { 53 {
42 public Vehicle Type 54 public Vehicle Type
43 { 55 {
44 get { return m_type; } 56 get { return m_type; }
45 } 57 }
46 58
@@ -49,49 +61,71 @@ namespace OpenSim.Region.Physics.OdePlugin
49 get { return m_body; } 61 get { return m_body; }
50 } 62 }
51 63
52 private int frcount = 0; 64 private int frcount = 0; // Used to limit dynamics debug output to
53 // private float frmod = 3.0f; 65 // every 100th frame
54 66
55 private Vehicle m_type = Vehicle.TYPE_NONE;
56 // private OdeScene m_parentScene = null; 67 // private OdeScene m_parentScene = null;
57 private IntPtr m_body = IntPtr.Zero; 68 private IntPtr m_body = IntPtr.Zero;
58 private IntPtr m_jointGroup = IntPtr.Zero; 69 private IntPtr m_jointGroup = IntPtr.Zero;
59 private IntPtr m_aMotor = IntPtr.Zero; 70 private IntPtr m_aMotor = IntPtr.Zero;
60 private IntPtr m_lMotor1 = IntPtr.Zero; 71
61 // private IntPtr m_lMotor2 = IntPtr.Zero;
62 // private IntPtr m_lMotor3 = IntPtr.Zero;
63 72
64 // Vehicle properties 73 // Vehicle properties
65 // private Quaternion m_referenceFrame = Quaternion.Identity; 74 private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind
66 private Vector3 m_angularFrictionTimescale = Vector3.Zero; 75 // private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier
67 private Vector3 m_angularMotorDirection = Vector3.Zero; 76 private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings:
68 private Vector3 m_angularMotorDirectionLASTSET = Vector3.Zero; 77 // HOVER_TERRAIN_ONLY
78 // HOVER_GLOBAL_HEIGHT
79 // NO_DEFLECTION_UP
80 // HOVER_WATER_ONLY
81 // HOVER_UP_ONLY
82 // LIMIT_MOTOR_UP
83 // LIMIT_ROLL_ONLY
84
85 // Linear properties
86 private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time
87 private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL
88 private Vector3 m_dir = Vector3.Zero; // velocity applied to body
69 private Vector3 m_linearFrictionTimescale = Vector3.Zero; 89 private Vector3 m_linearFrictionTimescale = Vector3.Zero;
70 private Vector3 m_linearMotorDirection = Vector3.Zero; 90 private float m_linearMotorDecayTimescale = 0;
71 private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; 91 private float m_linearMotorTimescale = 0;
92 private Vector3 m_lastLinearVelocityVector = Vector3.Zero;
93 // private bool m_LinearMotorSetLastFrame = false;
72 // private Vector3 m_linearMotorOffset = Vector3.Zero; 94 // private Vector3 m_linearMotorOffset = Vector3.Zero;
73 // private float m_angularDeflectionEfficiency = 0; 95
74 // private float m_angularDeflectionTimescale = 0; 96 //Angular properties
97 private Vector3 m_angularMotorDirection = Vector3.Zero;
98 private Vector3 m_angularMotorDirectionLASTSET = Vector3.Zero;
99 private Vector3 m_angularFrictionTimescale = Vector3.Zero;
75 private float m_angularMotorDecayTimescale = 0; 100 private float m_angularMotorDecayTimescale = 0;
76 private float m_angularMotorTimescale = 0; 101 private float m_angularMotorTimescale = 0;
102 private Vector3 m_lastAngularVelocityVector = Vector3.Zero;
103
104 //Deflection properties
105 // private float m_angularDeflectionEfficiency = 0;
106 // private float m_angularDeflectionTimescale = 0;
107 // private float m_linearDeflectionEfficiency = 0;
108 // private float m_linearDeflectionTimescale = 0;
109
110 //Banking properties
77 // private float m_bankingEfficiency = 0; 111 // private float m_bankingEfficiency = 0;
78 // private float m_bankingMix = 0; 112 // private float m_bankingMix = 0;
79 // private float m_bankingTimescale = 0; 113 // private float m_bankingTimescale = 0;
80 // private float m_buoyancy = 0; 114
81 // private float m_hoverHeight = 0; 115 //Hover and Buoyancy properties
82 // private float m_hoverEfficiency = 0; 116 private float m_VhoverHeight = 0f;
83 // private float m_hoverTimescale = 0; 117 private float m_VhoverEfficiency = 0f;
84 // private float m_linearDeflectionEfficiency = 0; 118 private float m_VhoverTimescale = 0f;
85 // private float m_linearDeflectionTimescale = 0; 119 private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
86 private float m_linearMotorDecayTimescale = 0; 120 private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle.
87 private float m_linearMotorTimescale = 0; 121 // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
122 // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
123 // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
124
125 //Attractor properties
88 private float m_verticalAttractionEfficiency = 0; 126 private float m_verticalAttractionEfficiency = 0;
89 private float m_verticalAttractionTimescale = 0; 127 private float m_verticalAttractionTimescale = 0;
90 private Vector3 m_lastLinearVelocityVector = Vector3.Zero; 128
91 private Vector3 m_lastAngularVelocityVector = Vector3.Zero;
92 private VehicleFlag m_flags = (VehicleFlag) 0;
93
94 // private bool m_LinearMotorSetLastFrame = false;
95 129
96 130
97 131
@@ -129,17 +163,21 @@ namespace OpenSim.Region.Physics.OdePlugin
129 // m_bankingTimescale = pValue; 163 // m_bankingTimescale = pValue;
130 break; 164 break;
131 case Vehicle.BUOYANCY: 165 case Vehicle.BUOYANCY:
132 // m_buoyancy = pValue; 166 if (pValue < -1f) pValue = -1f;
167 if (pValue > 1f) pValue = 1f;
168 m_VehicleBuoyancy = pValue;
133 break; 169 break;
134 case Vehicle.HOVER_EFFICIENCY: 170 case Vehicle.HOVER_EFFICIENCY:
135 // m_hoverEfficiency = pValue; 171 if (pValue < 0f) pValue = 0f;
172 if (pValue > 1f) pValue = 1f;
173 m_VhoverEfficiency = pValue;
136 break; 174 break;
137 case Vehicle.HOVER_HEIGHT: 175 case Vehicle.HOVER_HEIGHT:
138 // m_hoverHeight = pValue; 176 m_VhoverHeight = pValue;
139 break; 177 break;
140 case Vehicle.HOVER_TIMESCALE: 178 case Vehicle.HOVER_TIMESCALE:
141 if (pValue < 0.01f) pValue = 0.01f; 179 if (pValue < 0.01f) pValue = 0.01f;
142 // m_hoverTimescale = pValue; 180 m_VhoverTimescale = pValue;
143 break; 181 break;
144 case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: 182 case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
145 if (pValue < 0.01f) pValue = 0.01f; 183 if (pValue < 0.01f) pValue = 0.01f;
@@ -158,7 +196,8 @@ namespace OpenSim.Region.Physics.OdePlugin
158 m_linearMotorTimescale = pValue; 196 m_linearMotorTimescale = pValue;
159 break; 197 break;
160 case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: 198 case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
161 if (pValue < 0.01f) pValue = 0.01f; 199 if (pValue < 0.0f) pValue = 0.0f;
200 if (pValue > 1.0f) pValue = 1.0f;
162 m_verticalAttractionEfficiency = pValue; 201 m_verticalAttractionEfficiency = pValue;
163 break; 202 break;
164 case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: 203 case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
@@ -187,8 +226,8 @@ namespace OpenSim.Region.Physics.OdePlugin
187 break; 226 break;
188 227
189 } 228 }
190 Reset(); 229
191 } 230 }//end ProcessFloatVehicleParam
192 231
193 internal void ProcessVectorVehicleParam(Vehicle pParam, PhysicsVector pValue) 232 internal void ProcessVectorVehicleParam(Vehicle pParam, PhysicsVector pValue)
194 { 233 {
@@ -212,8 +251,8 @@ namespace OpenSim.Region.Physics.OdePlugin
212 // m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); 251 // m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
213 break; 252 break;
214 } 253 }
215 Reset(); 254
216 } 255 }//end ProcessVectorVehicleParam
217 256
218 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) 257 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
219 { 258 {
@@ -223,113 +262,14 @@ namespace OpenSim.Region.Physics.OdePlugin
223 // m_referenceFrame = pValue; 262 // m_referenceFrame = pValue;
224 break; 263 break;
225 } 264 }
226 Reset();
227 }
228
229 internal void ProcessTypeChange(Vehicle pType)
230 {
231 if (m_type == Vehicle.TYPE_NONE && pType != Vehicle.TYPE_NONE)
232 {
233 // Activate whatever it is
234 SetDefaultsForType(pType);
235 Reset();
236 }
237 else if (m_type != Vehicle.TYPE_NONE && pType != Vehicle.TYPE_NONE)
238 {
239 // Set properties
240 SetDefaultsForType(pType);
241 // then reset
242 Reset();
243 }
244 else if (m_type != Vehicle.TYPE_NONE && pType == Vehicle.TYPE_NONE)
245 {
246 m_type = pType;
247 Destroy();
248 }
249 }
250
251 internal void Disable()
252 {
253 if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE)
254 return;
255
256 if (m_aMotor != IntPtr.Zero)
257 {
258
259 }
260
261 }
262
263 internal void Enable(IntPtr pBody, OdeScene pParentScene)
264 {
265 if (m_type == Vehicle.TYPE_NONE)
266 return;
267
268 m_body = pBody;
269 // m_parentScene = pParentScene;
270 if (m_jointGroup == IntPtr.Zero)
271 m_jointGroup = d.JointGroupCreate(3);
272
273 if (pBody != IntPtr.Zero)
274 {
275
276 if (m_lMotor1 == IntPtr.Zero)
277 {
278 d.BodySetAutoDisableFlag(Body, false);
279 m_lMotor1 = d.JointCreateLMotor(pParentScene.world, m_jointGroup);
280 d.JointSetLMotorNumAxes(m_lMotor1, 1);
281 d.JointAttach(m_lMotor1, Body, IntPtr.Zero);
282 }
283
284 if (m_aMotor == IntPtr.Zero)
285 {
286 m_aMotor = d.JointCreateAMotor(pParentScene.world, m_jointGroup);
287 d.JointSetAMotorNumAxes(m_aMotor, 3);
288 d.JointAttach(m_aMotor, Body, IntPtr.Zero);
289 }
290 }
291 }
292
293 internal void Reset()
294 {
295 if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE)
296 return;
297 265
298 } 266 }//end ProcessRotationVehicleParam
299 267
300 internal void Destroy() 268 internal void ProcessTypeChange(Vehicle pType)
301 {
302 if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE)
303 return;
304 if (m_aMotor != IntPtr.Zero)
305 {
306 d.JointDestroy(m_aMotor);
307 }
308 if (m_lMotor1 != IntPtr.Zero)
309 {
310 d.JointDestroy(m_lMotor1);
311 }
312
313 }
314
315 internal void Step(float pTimestep)
316 {
317 if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE)
318 return;
319 frcount++;
320 if (frcount > 100)
321 frcount = 0;
322
323 VerticalAttractor(pTimestep);
324 LinearMotor(pTimestep);
325
326
327 AngularMotor(pTimestep);
328
329 }
330
331 private void SetDefaultsForType(Vehicle pType)
332 { 269 {
270Console.WriteLine("ProcessTypeChange to " + pType);
271
272 // Set Defaults For Type
333 m_type = pType; 273 m_type = pType;
334 switch (pType) 274 switch (pType)
335 { 275 {
@@ -342,10 +282,10 @@ namespace OpenSim.Region.Physics.OdePlugin
342 m_angularMotorDirection = Vector3.Zero; 282 m_angularMotorDirection = Vector3.Zero;
343 m_angularMotorTimescale = 1000; 283 m_angularMotorTimescale = 1000;
344 m_angularMotorDecayTimescale = 120; 284 m_angularMotorDecayTimescale = 120;
345 // m_hoverHeight = 0; 285 m_VhoverHeight = 0;
346 // m_hoverEfficiency = 10; 286 m_VhoverEfficiency = 1;
347 // m_hoverTimescale = 10; 287 m_VhoverTimescale = 10;
348 // m_buoyancy = 0; 288 m_VehicleBuoyancy = 0;
349 // m_linearDeflectionEfficiency = 1; 289 // m_linearDeflectionEfficiency = 1;
350 // m_linearDeflectionTimescale = 1; 290 // m_linearDeflectionTimescale = 1;
351 // m_angularDeflectionEfficiency = 1; 291 // m_angularDeflectionEfficiency = 1;
@@ -368,10 +308,10 @@ namespace OpenSim.Region.Physics.OdePlugin
368 m_angularMotorDirection = Vector3.Zero; 308 m_angularMotorDirection = Vector3.Zero;
369 m_angularMotorTimescale = 1; 309 m_angularMotorTimescale = 1;
370 m_angularMotorDecayTimescale = 0.8f; 310 m_angularMotorDecayTimescale = 0.8f;
371 // m_hoverHeight = 0; 311 m_VhoverHeight = 0;
372 // // m_hoverEfficiency = 0; 312 m_VhoverEfficiency = 0;
373 // // m_hoverTimescale = 1000; 313 m_VhoverTimescale = 1000;
374 // // m_buoyancy = 0; 314 m_VehicleBuoyancy = 0;
375 // // m_linearDeflectionEfficiency = 1; 315 // // m_linearDeflectionEfficiency = 1;
376 // // m_linearDeflectionTimescale = 2; 316 // // m_linearDeflectionTimescale = 2;
377 // // m_angularDeflectionEfficiency = 0; 317 // // m_angularDeflectionEfficiency = 0;
@@ -395,10 +335,10 @@ namespace OpenSim.Region.Physics.OdePlugin
395 m_angularMotorDirection = Vector3.Zero; 335 m_angularMotorDirection = Vector3.Zero;
396 m_angularMotorTimescale = 4; 336 m_angularMotorTimescale = 4;
397 m_angularMotorDecayTimescale = 4; 337 m_angularMotorDecayTimescale = 4;
398 // m_hoverHeight = 0; 338 m_VhoverHeight = 0;
399 // m_hoverEfficiency = 0.5f; 339 m_VhoverEfficiency = 0.5f;
400 // m_hoverTimescale = 2; 340 m_VhoverTimescale = 2;
401 // m_buoyancy = 1; 341 m_VehicleBuoyancy = 1;
402 // m_linearDeflectionEfficiency = 0.5f; 342 // m_linearDeflectionEfficiency = 0.5f;
403 // m_linearDeflectionTimescale = 3; 343 // m_linearDeflectionTimescale = 3;
404 // m_angularDeflectionEfficiency = 0.5f; 344 // m_angularDeflectionEfficiency = 0.5f;
@@ -409,8 +349,9 @@ namespace OpenSim.Region.Physics.OdePlugin
409 // m_bankingMix = 0.8f; 349 // m_bankingMix = 0.8f;
410 // m_bankingTimescale = 1; 350 // m_bankingTimescale = 1;
411 // m_referenceFrame = Quaternion.Identity; 351 // m_referenceFrame = Quaternion.Identity;
412 m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); 352 m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.LIMIT_ROLL_ONLY |
413 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_UP_ONLY | 353 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
354 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY |
414 VehicleFlag.LIMIT_MOTOR_UP); 355 VehicleFlag.LIMIT_MOTOR_UP);
415 break; 356 break;
416 case Vehicle.TYPE_AIRPLANE: 357 case Vehicle.TYPE_AIRPLANE:
@@ -422,10 +363,10 @@ namespace OpenSim.Region.Physics.OdePlugin
422 m_angularMotorDirection = Vector3.Zero; 363 m_angularMotorDirection = Vector3.Zero;
423 m_angularMotorTimescale = 4; 364 m_angularMotorTimescale = 4;
424 m_angularMotorDecayTimescale = 4; 365 m_angularMotorDecayTimescale = 4;
425 // m_hoverHeight = 0; 366 m_VhoverHeight = 0;
426 // m_hoverEfficiency = 0.5f; 367 m_VhoverEfficiency = 0.5f;
427 // m_hoverTimescale = 1000; 368 m_VhoverTimescale = 1000;
428 // m_buoyancy = 0; 369 m_VehicleBuoyancy = 0;
429 // m_linearDeflectionEfficiency = 0.5f; 370 // m_linearDeflectionEfficiency = 0.5f;
430 // m_linearDeflectionTimescale = 3; 371 // m_linearDeflectionTimescale = 3;
431 // m_angularDeflectionEfficiency = 1; 372 // m_angularDeflectionEfficiency = 1;
@@ -449,10 +390,10 @@ namespace OpenSim.Region.Physics.OdePlugin
449 m_angularMotorDirection = Vector3.Zero; 390 m_angularMotorDirection = Vector3.Zero;
450 m_angularMotorTimescale = 6; 391 m_angularMotorTimescale = 6;
451 m_angularMotorDecayTimescale = 10; 392 m_angularMotorDecayTimescale = 10;
452 // m_hoverHeight = 5; 393 m_VhoverHeight = 5;
453 // m_hoverEfficiency = 0.8f; 394 m_VhoverEfficiency = 0.8f;
454 // m_hoverTimescale = 10; 395 m_VhoverTimescale = 10;
455 // m_buoyancy = 1; 396 m_VehicleBuoyancy = 1;
456 // m_linearDeflectionEfficiency = 0; 397 // m_linearDeflectionEfficiency = 0;
457 // m_linearDeflectionTimescale = 5; 398 // m_linearDeflectionTimescale = 5;
458 // m_angularDeflectionEfficiency = 0; 399 // m_angularDeflectionEfficiency = 0;
@@ -463,106 +404,165 @@ namespace OpenSim.Region.Physics.OdePlugin
463 // m_bankingMix = 0.7f; 404 // m_bankingMix = 0.7f;
464 // m_bankingTimescale = 5; 405 // m_bankingTimescale = 5;
465 // m_referenceFrame = Quaternion.Identity; 406 // m_referenceFrame = Quaternion.Identity;
466 m_flags = (VehicleFlag)0; 407 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
408 VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
409 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
467 break; 410 break;
468 411
469 } 412 }
470 } 413 }//end SetDefaultsForType
471
472 private void VerticalAttractor(float pTimestep)
473 {
474 // The purpose of this routine here is to quickly stabilize the Body while it's popped up in the air.
475 // The amotor needs a few seconds to stabilize so without it, the avatar shoots up sky high when you
476 // change appearance and when you enter the simulator
477 // After this routine is done, the amotor stabilizes much quicker
478 d.Mass objMass;
479 d.BodyGetMass(Body, out objMass);
480 //d.BodyGetS
481 414
482 d.Vector3 feet; 415 internal void Enable(IntPtr pBody, OdeScene pParentScene)
483 d.Vector3 head; 416 {
484 d.BodyGetRelPointPos(m_body, 0.0f, 0.0f, -1.0f, out feet); 417//Console.WriteLine("Enable m_type=" + m_type + " m_VehicleBuoyancy=" + m_VehicleBuoyancy);
485 d.BodyGetRelPointPos(m_body, 0.0f, 0.0f, 1.0f, out head); 418 if (m_type == Vehicle.TYPE_NONE)
486 float posture = head.Z - feet.Z; 419 return;
487 420
488 //Console.WriteLine(String.Format("head: <{0},{1},{2}>, feet:<{3},{4},{5}> diff:<{6},{7},{8}>", head.X, head.Y, head.Z, feet.X, 421 m_body = pBody;
489 // feet.Y, feet.Z, head.X - feet.X, head.Y - feet.Y, head.Z - feet.Z)); 422 //KF: This used to set up the linear and angular joints
490 //Console.WriteLine(String.Format("diff:<{0},{1},{2}>",head.X - feet.X, head.Y - feet.Y, head.Z - feet.Z));
491
492 // restoring force proportional to lack of posture:
493 float servo = (2.5f - posture) * (objMass.mass * m_verticalAttractionEfficiency / (m_verticalAttractionTimescale * pTimestep)) * objMass.mass;
494 d.BodyAddForceAtRelPos(m_body, 0.0f, 0.0f, servo, 0.0f, 0.0f, 1.0f);
495 d.BodyAddForceAtRelPos(m_body, 0.0f, 0.0f, -servo, 0.0f, 0.0f, -1.0f);
496 //d.BodyAddTorque(m_body, (head.X - feet.X) * servo, (head.Y - feet.Y) * servo, (head.Z - feet.Z) * servo);
497 //d.Matrix3 bodyrotation = d.BodyGetRotation(Body);
498 //m_log.Info("[PHYSICSAV]: Rotation: " + bodyrotation.M00 + " : " + bodyrotation.M01 + " : " + bodyrotation.M02 + " : " + bodyrotation.M10 + " : " + bodyrotation.M11 + " : " + bodyrotation.M12 + " : " + bodyrotation.M20 + " : " + bodyrotation.M21 + " : " + bodyrotation.M22);
499 } 423 }
500 424
501 private void LinearMotor(float pTimestep) 425 internal void Step(float pTimestep, OdeScene pParentScene)
502 { 426 {
427 if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE)
428 return;
429 frcount++; // used to limit debug comment output
430 if (frcount > 100)
431 frcount = 0;
503 432
504 if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) 433 MoveLinear(pTimestep, pParentScene);
434 MoveAngular(pTimestep);
435 }// end Step
436
437 private void MoveLinear(float pTimestep, OdeScene _pParentScene)
438 {
439 if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) // requested m_linearMotorDirection is significant
505 { 440 {
506 441 if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
507 Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep);
508 m_lastLinearVelocityVector += (addAmount*10);
509 442
443 // add drive to body
444 Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep);
445 m_lastLinearVelocityVector += (addAmount*10); // lastLinearVelocityVector is the current body velocity vector?
446
510 // This will work temporarily, but we really need to compare speed on an axis 447 // This will work temporarily, but we really need to compare speed on an axis
448 // KF: Limit body velocity to applied velocity?
511 if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X)) 449 if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X))
512 m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X; 450 m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X;
513 if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y)) 451 if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y))
514 m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y; 452 m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y;
515 if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z)) 453 if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z))
516 m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z; 454 m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z;
517 //Console.WriteLine("add: " + addAmount); 455
518 456 // decay applied velocity
519 Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep))); 457 Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep)));
520 //Console.WriteLine("decay: " + decayfraction); 458 //Console.WriteLine("decay: " + decayfraction);
521
522 m_linearMotorDirection -= m_linearMotorDirection * decayfraction; 459 m_linearMotorDirection -= m_linearMotorDirection * decayfraction;
523 //Console.WriteLine("actual: " + m_linearMotorDirection); 460 //Console.WriteLine("actual: " + m_linearMotorDirection);
524 } 461 }
525 462 else
526 //System.Console.WriteLine(m_linearMotorDirection + " " + m_lastLinearVelocityVector); 463 { // requested is not significant
527 464 // if what remains of applied is small, zero it.
528 SetLinearMotorProperties(); 465 if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f))
529 466 m_lastLinearVelocityVector = Vector3.Zero;
467 }
468
469
470 // convert requested object velocity to world-referenced vector
471 m_dir = m_lastLinearVelocityVector;
472 d.Quaternion rot = d.BodyGetQuaternion(Body);
473 Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
474 m_dir *= rotq; // apply obj rotation to velocity vector
475
476 // add Gravity andBuoyancy
477 // KF: So far I have found no good method to combine a script-requested
478 // .Z velocity and gravity. Therefore only 0g will used script-requested
479 // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only.
480 Vector3 grav = Vector3.Zero;
481 if(m_VehicleBuoyancy < 1.0f)
482 {
483 // There is some gravity, make a gravity force vector
484 // that is applied after object velocity.
485 d.Mass objMass;
486 d.BodyGetMass(Body, out objMass);
487 // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
488 grav.Z = _pParentScene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy);
489 // Preserve the current Z velocity
490 d.Vector3 vel_now = d.BodyGetLinearVel(Body);
491 m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity
492 } // else its 1.0, no gravity.
493
494 // Check if hovering
495 if( (m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
496 {
497 // We should hover, get the target height
498 d.Vector3 pos = d.BodyGetPosition(Body);
499 if((m_flags & VehicleFlag.HOVER_WATER_ONLY) == VehicleFlag.HOVER_WATER_ONLY)
500 {
501 m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight;
502 }
503 else if((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) == VehicleFlag.HOVER_TERRAIN_ONLY)
504 {
505 m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
506 }
507 else if((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == VehicleFlag.HOVER_GLOBAL_HEIGHT)
508 {
509 m_VhoverTargetHeight = m_VhoverHeight;
510 }
511
512 if((m_flags & VehicleFlag.HOVER_UP_ONLY) == VehicleFlag.HOVER_UP_ONLY)
513 {
514 // If body is aready heigher, use its height as target height
515 if(pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
516 }
517
518// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped
519// m_VhoverTimescale = 0f; // time to acheive height
520// pTimestep is time since last frame,in secs
521 float herr0 = pos.Z - m_VhoverTargetHeight;
522//if(frcount == 0) Console.WriteLine("herr0=" + herr0);
523 // Replace Vertical speed with correction figure if significant
524 if(Math.Abs(herr0) > 0.01f )
525 {
526 d.Mass objMass;
527 d.BodyGetMass(Body, out objMass);
528 m_dir.Z = - ( (herr0 * pTimestep * 50.0f) / m_VhoverTimescale);
529 // m_VhoverEfficiency is not yet implemented
530 }
531 else
532 {
533 m_dir.Z = 0f;
534 }
535 }
536
537 // Apply velocity
538 d.BodySetLinearVel(Body, m_dir.X, m_dir.Y, m_dir.Z);
539//if(frcount == 0) Console.WriteLine("Move " + Body + ":"+ m_dir.X + " " + m_dir.Y + " " + m_dir.Z);
540 // apply gravity force
541 d.BodyAddForce(Body, grav.X, grav.Y, grav.Z);
542//if(frcount == 0) Console.WriteLine("Force " + Body + ":" + grav.X + " " + grav.Y + " " + grav.Z);
543
544
545 // apply friction
530 Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); 546 Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep);
531 m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount; 547 m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount;
532 548 } // end MoveLinear()
533 //m_linearMotorDirection *= decayamount; 549
534 550 private void MoveAngular(float pTimestep)
535 }
536
537 private void SetLinearMotorProperties()
538 {
539 Vector3 dirNorm = m_lastLinearVelocityVector;
540 dirNorm.Normalize();
541
542 d.Mass objMass;
543 d.BodyGetMass(Body, out objMass);
544 d.Quaternion rot = d.BodyGetQuaternion(Body);
545 Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W);
546 dirNorm *= rotq;
547 if (m_lMotor1 != IntPtr.Zero)
548 {
549
550 d.JointSetLMotorAxis(m_lMotor1, 0, 1, dirNorm.X, dirNorm.Y, dirNorm.Z);
551 d.JointSetLMotorParam(m_lMotor1, (int)dParam.Vel, m_lastLinearVelocityVector.Length());
552
553 d.JointSetLMotorParam(m_lMotor1, (int)dParam.FMax, 35f * objMass.mass);
554 }
555
556 }
557
558 private void AngularMotor(float pTimestep)
559 { 551 {
552
553 // m_angularMotorDirection is the latest value from the script, and is decayed here
554 // m_angularMotorDirectionLASTSET is the latest value from the script
555 // m_lastAngularVelocityVector is what is being applied to the Body, varied up and down here
556
560 if (!m_angularMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) 557 if (!m_angularMotorDirection.ApproxEquals(Vector3.Zero, 0.01f))
561 { 558 {
562 559 if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
560 // ramp up to new value
563 Vector3 addAmount = m_angularMotorDirection / (m_angularMotorTimescale / pTimestep); 561 Vector3 addAmount = m_angularMotorDirection / (m_angularMotorTimescale / pTimestep);
564 m_lastAngularVelocityVector += (addAmount * 10); 562 m_lastAngularVelocityVector += (addAmount * 10f);
563//if(frcount == 0) Console.WriteLine("add: " + addAmount);
565 564
565 // limit applied value to what was set by script
566 // This will work temporarily, but we really need to compare speed on an axis 566 // This will work temporarily, but we really need to compare speed on an axis
567 if (Math.Abs(m_lastAngularVelocityVector.X) > Math.Abs(m_angularMotorDirectionLASTSET.X)) 567 if (Math.Abs(m_lastAngularVelocityVector.X) > Math.Abs(m_angularMotorDirectionLASTSET.X))
568 m_lastAngularVelocityVector.X = m_angularMotorDirectionLASTSET.X; 568 m_lastAngularVelocityVector.X = m_angularMotorDirectionLASTSET.X;
@@ -570,57 +570,61 @@ namespace OpenSim.Region.Physics.OdePlugin
570 m_lastAngularVelocityVector.Y = m_angularMotorDirectionLASTSET.Y; 570 m_lastAngularVelocityVector.Y = m_angularMotorDirectionLASTSET.Y;
571 if (Math.Abs(m_lastAngularVelocityVector.Z) > Math.Abs(m_angularMotorDirectionLASTSET.Z)) 571 if (Math.Abs(m_lastAngularVelocityVector.Z) > Math.Abs(m_angularMotorDirectionLASTSET.Z))
572 m_lastAngularVelocityVector.Z = m_angularMotorDirectionLASTSET.Z; 572 m_lastAngularVelocityVector.Z = m_angularMotorDirectionLASTSET.Z;
573 //Console.WriteLine("add: " + addAmount);
574 573
574 // decay the requested value
575 Vector3 decayfraction = ((Vector3.One / (m_angularMotorDecayTimescale / pTimestep))); 575 Vector3 decayfraction = ((Vector3.One / (m_angularMotorDecayTimescale / pTimestep)));
576 //Console.WriteLine("decay: " + decayfraction); 576 //Console.WriteLine("decay: " + decayfraction);
577
578 m_angularMotorDirection -= m_angularMotorDirection * decayfraction; 577 m_angularMotorDirection -= m_angularMotorDirection * decayfraction;
579 //Console.WriteLine("actual: " + m_linearMotorDirection); 578 //Console.WriteLine("actual: " + m_linearMotorDirection);
580 } 579 }
581 580 // KF: m_lastAngularVelocityVector is rotational speed in rad/sec ?
582 //System.Console.WriteLine(m_linearMotorDirection + " " + m_lastLinearVelocityVector); 581
583 582 // Vertical attractor section
584 SetAngularMotorProperties(); 583
585 584// d.Mass objMass;
585// d.BodyGetMass(Body, out objMass);
586// float servo = 100f * objMass.mass * m_verticalAttractionEfficiency / (m_verticalAttractionTimescale * pTimestep);
587 float servo = 0.1f * m_verticalAttractionEfficiency / (m_verticalAttractionTimescale * pTimestep);
588 // get present body rotation
589 d.Quaternion rot = d.BodyGetQuaternion(Body);
590 Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W);
591 // make a vector pointing up
592 Vector3 verterr = Vector3.Zero;
593 verterr.Z = 1.0f;
594 // rotate it to Body Angle
595 verterr = verterr * rotq;
596 // 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.
597 // 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
598 // negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body.
599 if (verterr.Z < 0.0f)
600 {
601 verterr.X = 2.0f - verterr.X;
602 verterr.Y = 2.0f - verterr.Y;
603 }
604 // Error is 0 (no error) to +/- 2 (max error)
605 // scale it by servo
606 verterr = verterr * servo;
607
608 // rotate to object frame
609 // verterr = verterr * rotq;
610
611 // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so
612 // Change Body angular velocity X based on Y, and Y based on X. Z is not changed.
613 m_lastAngularVelocityVector.X += verterr.Y;
614 m_lastAngularVelocityVector.Y -= verterr.X;
615/*
616if(frcount == 0)
617 {
618// Console.WriteLine("AngleMotor " + m_lastAngularVelocityVector);
619 Console.WriteLine(String.Format("VA Body:{0} servo:{1} err:<{2},{3},{4}> VAE:{5}",
620 Body, servo, verterr.X, verterr.Y, verterr.Z, m_verticalAttractionEfficiency));
621 }
622 */
623 d.BodySetAngularVel (Body, m_lastAngularVelocityVector.X, m_lastAngularVelocityVector.Y, m_lastAngularVelocityVector.Z);
624 // apply friction
586 Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep); 625 Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep);
587 m_lastAngularVelocityVector -= m_lastAngularVelocityVector * decayamount; 626 m_lastAngularVelocityVector -= m_lastAngularVelocityVector * decayamount;
588 627
589 //m_linearMotorDirection *= decayamount; 628 } //end MoveAngular
590
591 }
592 private void SetAngularMotorProperties()
593 {
594
595
596
597 d.Mass objMass;
598 d.BodyGetMass(Body, out objMass);
599 //d.Quaternion rot = d.BodyGetQuaternion(Body);
600 //Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W);
601 Vector3 axis0 = Vector3.UnitX;
602 Vector3 axis1 = Vector3.UnitY;
603 Vector3 axis2 = Vector3.UnitZ;
604 //axis0 *= rotq;
605 //axis1 *= rotq;
606 //axis2 *= rotq;
607
608
609
610 if (m_aMotor != IntPtr.Zero)
611 {
612 d.JointSetAMotorAxis(m_aMotor, 0, 1, axis0.X, axis0.Y, axis0.Z);
613 d.JointSetAMotorAxis(m_aMotor, 1, 1, axis1.X, axis1.Y, axis1.Z);
614 d.JointSetAMotorAxis(m_aMotor, 2, 1, axis2.X, axis2.Y, axis2.Z);
615 d.JointSetAMotorParam(m_aMotor, (int)dParam.FMax, 30*objMass.mass);
616 d.JointSetAMotorParam(m_aMotor, (int)dParam.FMax2, 30*objMass.mass);
617 d.JointSetAMotorParam(m_aMotor, (int)dParam.FMax3, 30 * objMass.mass);
618 d.JointSetAMotorParam(m_aMotor, (int)dParam.Vel, m_lastAngularVelocityVector.X);
619 d.JointSetAMotorParam(m_aMotor, (int)dParam.Vel2, m_lastAngularVelocityVector.Y);
620 d.JointSetAMotorParam(m_aMotor, (int)dParam.Vel3, m_lastAngularVelocityVector.Z);
621
622 }
623 }
624
625 } 629 }
626} 630}