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