diff options
author | opensim | 2009-09-30 18:51:02 +0200 |
---|---|---|
committer | opensim | 2009-09-30 18:51:02 +0200 |
commit | 827b0fb1993c6f9b1289931a1ac38ff2b810952c (patch) | |
tree | 3c5e7b7fe5b21fdf159d64f1264a9d41ceac7b69 /OpenSim/Region/Physics/OdePlugin/ODEVehicleSettings.cs | |
parent | Finish the (untested) authentication connector (diff) | |
download | opensim-SC-827b0fb1993c6f9b1289931a1ac38ff2b810952c.zip opensim-SC-827b0fb1993c6f9b1289931a1ac38ff2b810952c.tar.gz opensim-SC-827b0fb1993c6f9b1289931a1ac38ff2b810952c.tar.bz2 opensim-SC-827b0fb1993c6f9b1289931a1ac38ff2b810952c.tar.xz |
Commit initial version of KittoFlora's vehicle changes
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 | ||
38 | namespace OpenSim.Region.Physics.OdePlugin | 50 | namespace 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 | { |
270 | Console.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 | /* | ||
616 | if(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 | } |