diff options
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 307 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs | 191 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 256 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 9 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 40 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs | 2 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs | 93 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs | 4 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs | 7 | ||||
-rw-r--r-- | bin/OpenSimDefaults.ini | 33 | ||||
-rwxr-xr-x | bin/lib32/BulletSim.dll | bin | 551424 -> 551424 bytes | |||
-rwxr-xr-x | bin/lib32/libBulletSim.so | bin | 1707321 -> 1707625 bytes | |||
-rwxr-xr-x | bin/lib64/BulletSim.dll | bin | 699904 -> 699904 bytes | |||
-rwxr-xr-x | bin/lib64/libBulletSim.so | bin | 1844228 -> 1844588 bytes |
14 files changed, 583 insertions, 359 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index dbc9039..95a4134 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | |||
@@ -80,10 +80,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
80 | private Quaternion m_referenceFrame = Quaternion.Identity; | 80 | private Quaternion m_referenceFrame = Quaternion.Identity; |
81 | 81 | ||
82 | // Linear properties | 82 | // Linear properties |
83 | private BSVMotor m_linearMotor = new BSVMotor("LinearMotor"); | ||
83 | private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time | 84 | 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 | 85 | private Vector3 m_linearMotorOffset = Vector3.Zero; // the point of force can be offset from the center |
85 | private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL | 86 | private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL |
86 | private Vector3 m_newVelocity = Vector3.Zero; // velocity computed to be applied to body | ||
87 | private Vector3 m_linearFrictionTimescale = Vector3.Zero; | 87 | private Vector3 m_linearFrictionTimescale = Vector3.Zero; |
88 | private float m_linearMotorDecayTimescale = 0; | 88 | private float m_linearMotorDecayTimescale = 0; |
89 | private float m_linearMotorTimescale = 0; | 89 | private float m_linearMotorTimescale = 0; |
@@ -93,6 +93,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
93 | // private Vector3 m_linearMotorOffset = Vector3.Zero; | 93 | // private Vector3 m_linearMotorOffset = Vector3.Zero; |
94 | 94 | ||
95 | //Angular properties | 95 | //Angular properties |
96 | private BSVMotor m_angularMotor = new BSVMotor("AngularMotor"); | ||
96 | private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor | 97 | private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor |
97 | // private int m_angularMotorApply = 0; // application frame counter | 98 | // private int m_angularMotorApply = 0; // application frame counter |
98 | private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity | 99 | private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity |
@@ -152,10 +153,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
152 | m_angularDeflectionTimescale = Math.Max(pValue, 0.01f); | 153 | m_angularDeflectionTimescale = Math.Max(pValue, 0.01f); |
153 | break; | 154 | break; |
154 | case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: | 155 | case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: |
155 | m_angularMotorDecayTimescale = Math.Max(pValue, 0.01f); | 156 | m_angularMotorDecayTimescale = Math.Max(0.01f, Math.Min(pValue,120)); |
157 | m_angularMotor.TargetValueDecayTimeScale = m_angularMotorDecayTimescale; | ||
156 | break; | 158 | break; |
157 | case Vehicle.ANGULAR_MOTOR_TIMESCALE: | 159 | case Vehicle.ANGULAR_MOTOR_TIMESCALE: |
158 | m_angularMotorTimescale = Math.Max(pValue, 0.01f); | 160 | m_angularMotorTimescale = Math.Max(pValue, 0.01f); |
161 | m_angularMotor.TimeScale = m_angularMotorTimescale; | ||
159 | break; | 162 | break; |
160 | case Vehicle.BANKING_EFFICIENCY: | 163 | case Vehicle.BANKING_EFFICIENCY: |
161 | m_bankingEfficiency = Math.Max(-1f, Math.Min(pValue, 1f)); | 164 | m_bankingEfficiency = Math.Max(-1f, Math.Min(pValue, 1f)); |
@@ -185,10 +188,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
185 | m_linearDeflectionTimescale = Math.Max(pValue, 0.01f); | 188 | m_linearDeflectionTimescale = Math.Max(pValue, 0.01f); |
186 | break; | 189 | break; |
187 | case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: | 190 | case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: |
188 | m_linearMotorDecayTimescale = Math.Max(pValue, 0.01f); | 191 | m_linearMotorDecayTimescale = Math.Max(0.01f, Math.Min(pValue,120)); |
192 | m_linearMotor.TargetValueDecayTimeScale = m_linearMotorDecayTimescale; | ||
189 | break; | 193 | break; |
190 | case Vehicle.LINEAR_MOTOR_TIMESCALE: | 194 | case Vehicle.LINEAR_MOTOR_TIMESCALE: |
191 | m_linearMotorTimescale = Math.Max(pValue, 0.01f); | 195 | m_linearMotorTimescale = Math.Max(pValue, 0.01f); |
196 | m_linearMotor.TimeScale = m_linearMotorTimescale; | ||
192 | break; | 197 | break; |
193 | case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: | 198 | case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: |
194 | m_verticalAttractionEfficiency = Math.Max(0.1f, Math.Min(pValue, 1f)); | 199 | m_verticalAttractionEfficiency = Math.Max(0.1f, Math.Min(pValue, 1f)); |
@@ -201,17 +206,20 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
201 | // set all of the components to the same value | 206 | // set all of the components to the same value |
202 | case Vehicle.ANGULAR_FRICTION_TIMESCALE: | 207 | case Vehicle.ANGULAR_FRICTION_TIMESCALE: |
203 | m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue); | 208 | m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue); |
209 | m_angularMotor.FrictionTimescale = m_angularFrictionTimescale; | ||
204 | break; | 210 | break; |
205 | case Vehicle.ANGULAR_MOTOR_DIRECTION: | 211 | case Vehicle.ANGULAR_MOTOR_DIRECTION: |
206 | m_angularMotorDirection = new Vector3(pValue, pValue, pValue); | 212 | m_angularMotorDirection = new Vector3(pValue, pValue, pValue); |
207 | // m_angularMotorApply = 100; | 213 | m_angularMotor.SetTarget(m_angularMotorDirection); |
208 | break; | 214 | break; |
209 | case Vehicle.LINEAR_FRICTION_TIMESCALE: | 215 | case Vehicle.LINEAR_FRICTION_TIMESCALE: |
210 | m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); | 216 | m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); |
217 | m_linearMotor.FrictionTimescale = m_linearFrictionTimescale; | ||
211 | break; | 218 | break; |
212 | case Vehicle.LINEAR_MOTOR_DIRECTION: | 219 | case Vehicle.LINEAR_MOTOR_DIRECTION: |
213 | m_linearMotorDirection = new Vector3(pValue, pValue, pValue); | 220 | m_linearMotorDirection = new Vector3(pValue, pValue, pValue); |
214 | m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue); | 221 | m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue); |
222 | m_linearMotor.SetTarget(m_linearMotorDirection); | ||
215 | break; | 223 | break; |
216 | case Vehicle.LINEAR_MOTOR_OFFSET: | 224 | case Vehicle.LINEAR_MOTOR_OFFSET: |
217 | m_linearMotorOffset = new Vector3(pValue, pValue, pValue); | 225 | m_linearMotorOffset = new Vector3(pValue, pValue, pValue); |
@@ -227,6 +235,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
227 | { | 235 | { |
228 | case Vehicle.ANGULAR_FRICTION_TIMESCALE: | 236 | case Vehicle.ANGULAR_FRICTION_TIMESCALE: |
229 | m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); | 237 | m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); |
238 | m_angularMotor.FrictionTimescale = m_angularFrictionTimescale; | ||
230 | break; | 239 | break; |
231 | case Vehicle.ANGULAR_MOTOR_DIRECTION: | 240 | case Vehicle.ANGULAR_MOTOR_DIRECTION: |
232 | // Limit requested angular speed to 2 rps= 4 pi rads/sec | 241 | // Limit requested angular speed to 2 rps= 4 pi rads/sec |
@@ -234,14 +243,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
234 | pValue.Y = Math.Max(-12.56f, Math.Min(pValue.Y, 12.56f)); | 243 | pValue.Y = Math.Max(-12.56f, Math.Min(pValue.Y, 12.56f)); |
235 | pValue.Z = Math.Max(-12.56f, Math.Min(pValue.Z, 12.56f)); | 244 | pValue.Z = Math.Max(-12.56f, Math.Min(pValue.Z, 12.56f)); |
236 | m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); | 245 | m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); |
237 | // m_angularMotorApply = 100; | 246 | m_angularMotor.SetTarget(m_angularMotorDirection); |
238 | break; | 247 | break; |
239 | case Vehicle.LINEAR_FRICTION_TIMESCALE: | 248 | case Vehicle.LINEAR_FRICTION_TIMESCALE: |
240 | m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); | 249 | m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); |
250 | m_linearMotor.FrictionTimescale = m_linearFrictionTimescale; | ||
241 | break; | 251 | break; |
242 | case Vehicle.LINEAR_MOTOR_DIRECTION: | 252 | case Vehicle.LINEAR_MOTOR_DIRECTION: |
243 | m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); | 253 | m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); |
244 | m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z); | 254 | m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z); |
255 | m_linearMotor.SetTarget(m_linearMotorDirection); | ||
245 | break; | 256 | break; |
246 | case Vehicle.LINEAR_MOTOR_OFFSET: | 257 | case Vehicle.LINEAR_MOTOR_OFFSET: |
247 | m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); | 258 | m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); |
@@ -319,6 +330,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
319 | 330 | ||
320 | m_referenceFrame = Quaternion.Identity; | 331 | m_referenceFrame = Quaternion.Identity; |
321 | m_flags = (VehicleFlag)0; | 332 | m_flags = (VehicleFlag)0; |
333 | |||
322 | break; | 334 | break; |
323 | 335 | ||
324 | case Vehicle.TYPE_SLED: | 336 | case Vehicle.TYPE_SLED: |
@@ -351,10 +363,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
351 | m_bankingMix = 1; | 363 | m_bankingMix = 1; |
352 | 364 | ||
353 | m_referenceFrame = Quaternion.Identity; | 365 | m_referenceFrame = Quaternion.Identity; |
354 | m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP); | 366 | m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY |
355 | m_flags &= | 367 | | VehicleFlag.HOVER_TERRAIN_ONLY |
356 | ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | | 368 | | VehicleFlag.HOVER_GLOBAL_HEIGHT |
357 | VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); | 369 | | VehicleFlag.HOVER_UP_ONLY); |
370 | m_flags |= (VehicleFlag.NO_DEFLECTION_UP | ||
371 | | VehicleFlag.LIMIT_ROLL_ONLY | ||
372 | | VehicleFlag.LIMIT_MOTOR_UP); | ||
358 | break; | 373 | break; |
359 | case Vehicle.TYPE_CAR: | 374 | case Vehicle.TYPE_CAR: |
360 | m_linearMotorDirection = Vector3.Zero; | 375 | m_linearMotorDirection = Vector3.Zero; |
@@ -510,6 +525,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
510 | | VehicleFlag.HOVER_GLOBAL_HEIGHT); | 525 | | VehicleFlag.HOVER_GLOBAL_HEIGHT); |
511 | break; | 526 | break; |
512 | } | 527 | } |
528 | |||
529 | // Update any physical parameters based on this type. | ||
530 | Refresh(); | ||
531 | |||
532 | m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, | ||
533 | m_linearMotorDecayTimescale, m_linearFrictionTimescale, 1f); | ||
534 | m_linearMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) | ||
535 | m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, | ||
536 | m_angularMotorDecayTimescale, m_angularFrictionTimescale, 1f); | ||
537 | m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) | ||
538 | |||
539 | // m_bankingMotor = new BSVMotor("BankingMotor", ...); | ||
513 | } | 540 | } |
514 | 541 | ||
515 | // Some of the properties of this prim may have changed. | 542 | // Some of the properties of this prim may have changed. |
@@ -518,13 +545,25 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
518 | { | 545 | { |
519 | if (IsActive) | 546 | if (IsActive) |
520 | { | 547 | { |
521 | // Friction effects are handled by this vehicle code | 548 | m_vehicleMass = Prim.Linkset.LinksetMass; |
522 | BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, 0f); | ||
523 | BulletSimAPI.SetHitFraction2(Prim.PhysBody.ptr, 0f); | ||
524 | |||
525 | // BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, 0.8f); | ||
526 | 549 | ||
527 | VDetailLog("{0},BSDynamics.Refresh,zeroingFriction and adding damping", Prim.LocalID); | 550 | // Friction effects are handled by this vehicle code |
551 | float friction = 0f; | ||
552 | BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, friction); | ||
553 | |||
554 | // Moderate angular movement introduced by Bullet. | ||
555 | // TODO: possibly set AngularFactor and LinearFactor for the type of vehicle. | ||
556 | // Maybe compute linear and angular factor and damping from params. | ||
557 | float angularDamping = PhysicsScene.Params.vehicleAngularDamping; | ||
558 | BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, angularDamping); | ||
559 | |||
560 | // DEBUG DEBUG DEBUG: use uniform inertia to smooth movement added by Bullet | ||
561 | // Vector3 localInertia = new Vector3(1f, 1f, 1f); | ||
562 | Vector3 localInertia = new Vector3(m_vehicleMass, m_vehicleMass, m_vehicleMass); | ||
563 | BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); | ||
564 | |||
565 | VDetailLog("{0},BSDynamics.Refresh,frict={1},inert={2},aDamp={3}", | ||
566 | Prim.LocalID, friction, localInertia, angularDamping); | ||
528 | } | 567 | } |
529 | } | 568 | } |
530 | 569 | ||
@@ -551,97 +590,38 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
551 | { | 590 | { |
552 | if (!IsActive) return; | 591 | if (!IsActive) return; |
553 | 592 | ||
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 | |||
565 | MoveLinear(pTimestep); | 593 | MoveLinear(pTimestep); |
566 | // Commented out for debug | ||
567 | MoveAngular(pTimestep); | 594 | MoveAngular(pTimestep); |
568 | // Prim.ApplyTorqueImpulse(-Prim.RotationalVelocity * m_vehicleMass, false); // DEBUG DEBUG | ||
569 | // Prim.ForceRotationalVelocity = -Prim.RotationalVelocity; // DEBUG DEBUG | ||
570 | 595 | ||
571 | LimitRotation(pTimestep); | 596 | LimitRotation(pTimestep); |
572 | 597 | ||
573 | // remember the position so next step we can limit absolute movement effects | 598 | // remember the position so next step we can limit absolute movement effects |
574 | m_lastPositionVector = Prim.ForcePosition; | 599 | m_lastPositionVector = Prim.ForcePosition; |
575 | 600 | ||
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 | ); | ||
583 | VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", | 601 | VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", |
584 | Prim.LocalID, Prim.ForcePosition, Prim.Force, Prim.ForceVelocity, Prim.RotationalVelocity); | 602 | Prim.LocalID, Prim.ForcePosition, Prim.Force, Prim.ForceVelocity, Prim.RotationalVelocity); |
585 | }// end Step | 603 | } |
586 | 604 | ||
587 | // Apply the effect of the linear motor. | 605 | // Apply the effect of the linear motor. |
588 | // Also does hover and float. | 606 | // Also does hover and float. |
589 | private void MoveLinear(float pTimestep) | 607 | private void MoveLinear(float pTimestep) |
590 | { | 608 | { |
591 | // m_linearMotorDirection is the target direction we are moving relative to the vehicle coordinates | 609 | Vector3 linearMotorContribution = m_linearMotor.Step(pTimestep); |
592 | // m_lastLinearVelocityVector is the current speed we are moving in that direction | ||
593 | if (m_linearMotorDirection.LengthSquared() > 0.001f) | ||
594 | { | ||
595 | Vector3 origDir = m_linearMotorDirection; // DEBUG | ||
596 | Vector3 origVel = m_lastLinearVelocityVector; // DEBUG | ||
597 | // DEBUG: the vehicle velocity rotated to be relative to vehicle coordinates for comparison | ||
598 | Vector3 vehicleVelocity = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG | ||
599 | |||
600 | // Add (desiredVelocity - lastAppliedVelocity) / howLongItShouldTakeToComplete | ||
601 | Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/(m_linearMotorTimescale) * pTimestep; | ||
602 | m_lastLinearVelocityVector += addAmount; | ||
603 | |||
604 | float decayFactor = (1.0f / m_linearMotorDecayTimescale) * pTimestep; | ||
605 | m_linearMotorDirection *= (1f - decayFactor); | ||
606 | |||
607 | // Rotate new object velocity from vehicle relative to world coordinates | ||
608 | m_newVelocity = m_lastLinearVelocityVector * Prim.ForceOrientation; | ||
609 | |||
610 | // Apply friction for next time | ||
611 | Vector3 frictionFactor = (Vector3.One / m_linearFrictionTimescale) * pTimestep; | ||
612 | m_lastLinearVelocityVector *= (Vector3.One - frictionFactor); | ||
613 | |||
614 | VDetailLog("{0},MoveLinear,nonZero,origlmDir={1},origlvVel={2},vehVel={3},add={4},decay={5},frict={6},lmDir={7},lvVec={8},newVel={9}", | ||
615 | Prim.LocalID, origDir, origVel, vehicleVelocity, addAmount, decayFactor, frictionFactor, | ||
616 | m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity); | ||
617 | } | ||
618 | else | ||
619 | { | ||
620 | // if what remains of direction is very small, zero it. | ||
621 | m_linearMotorDirection = Vector3.Zero; | ||
622 | m_lastLinearVelocityVector = Vector3.Zero; | ||
623 | m_newVelocity = Vector3.Zero; | ||
624 | |||
625 | VDetailLog("{0},MoveLinear,zeroed", Prim.LocalID); | ||
626 | } | ||
627 | 610 | ||
628 | // m_newVelocity is velocity computed from linear motor in world coordinates | 611 | // Rotate new object velocity from vehicle relative to world coordinates |
612 | linearMotorContribution *= Prim.ForceOrientation; | ||
629 | 613 | ||
614 | // ================================================================== | ||
630 | // Gravity and Buoyancy | 615 | // Gravity and Buoyancy |
631 | // There is some gravity, make a gravity force vector that is applied after object velocity. | 616 | // There is some gravity, make a gravity force vector that is applied after object velocity. |
632 | // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; | 617 | // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; |
633 | Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); | 618 | Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); |
634 | 619 | ||
635 | /* | 620 | // Current vehicle position |
636 | * RA: Not sure why one would do this unless we are hoping external forces are doing gravity, ... | ||
637 | // Preserve the current Z velocity | ||
638 | Vector3 vel_now = m_prim.Velocity; | ||
639 | m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity | ||
640 | */ | ||
641 | |||
642 | Vector3 pos = Prim.ForcePosition; | 621 | Vector3 pos = Prim.ForcePosition; |
643 | // Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f); | ||
644 | 622 | ||
623 | // ================================================================== | ||
624 | Vector3 terrainHeightContribution = Vector3.Zero; | ||
645 | // If below the terrain, move us above the ground a little. | 625 | // If below the terrain, move us above the ground a little. |
646 | float terrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); | 626 | float terrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); |
647 | // Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset. | 627 | // Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset. |
@@ -650,11 +630,14 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
650 | // if (rotatedSize.Z < terrainHeight) | 630 | // if (rotatedSize.Z < terrainHeight) |
651 | if (pos.Z < terrainHeight) | 631 | if (pos.Z < terrainHeight) |
652 | { | 632 | { |
633 | // TODO: correct position by applying force rather than forcing position. | ||
653 | pos.Z = terrainHeight + 2; | 634 | pos.Z = terrainHeight + 2; |
654 | Prim.ForcePosition = pos; | 635 | Prim.ForcePosition = pos; |
655 | VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, terrainHeight, pos); | 636 | VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, terrainHeight, pos); |
656 | } | 637 | } |
657 | 638 | ||
639 | // ================================================================== | ||
640 | Vector3 hoverContribution = Vector3.Zero; | ||
658 | // Check if hovering | 641 | // Check if hovering |
659 | // m_VhoverEfficiency: 0=bouncy, 1=totally damped | 642 | // m_VhoverEfficiency: 0=bouncy, 1=totally damped |
660 | // m_VhoverTimescale: time to achieve height | 643 | // m_VhoverTimescale: time to achieve height |
@@ -694,24 +677,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
694 | // RA: where does the 50 come from? | 677 | // RA: where does the 50 come from? |
695 | float verticalCorrectionVelocity = pTimestep * ((verticalError * 50.0f) / m_VhoverTimescale); | 678 | float verticalCorrectionVelocity = pTimestep * ((verticalError * 50.0f) / m_VhoverTimescale); |
696 | // Replace Vertical speed with correction figure if significant | 679 | // Replace Vertical speed with correction figure if significant |
697 | if (Math.Abs(verticalError) > 0.01f) | 680 | if (verticalError > 0.01f) |
698 | { | 681 | { |
699 | m_newVelocity.Z += verticalCorrectionVelocity; | 682 | hoverContribution = new Vector3(0f, 0f, verticalCorrectionVelocity); |
700 | //KF: m_VhoverEfficiency is not yet implemented | 683 | //KF: m_VhoverEfficiency is not yet implemented |
701 | } | 684 | } |
702 | else if (verticalError < -0.01) | 685 | else if (verticalError < -0.01) |
703 | { | 686 | { |
704 | m_newVelocity.Z -= verticalCorrectionVelocity; | 687 | hoverContribution = new Vector3(0f, 0f, -verticalCorrectionVelocity); |
705 | } | ||
706 | else | ||
707 | { | ||
708 | m_newVelocity.Z = 0f; | ||
709 | } | 688 | } |
710 | } | 689 | } |
711 | 690 | ||
712 | VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", Prim.LocalID, pos, m_newVelocity, m_VhoverHeight, m_VhoverTargetHeight); | 691 | VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", |
692 | Prim.LocalID, pos, hoverContribution, m_VhoverHeight, m_VhoverTargetHeight); | ||
713 | } | 693 | } |
714 | 694 | ||
695 | // ================================================================== | ||
715 | Vector3 posChange = pos - m_lastPositionVector; | 696 | Vector3 posChange = pos - m_lastPositionVector; |
716 | if (m_BlockingEndPoint != Vector3.Zero) | 697 | if (m_BlockingEndPoint != Vector3.Zero) |
717 | { | 698 | { |
@@ -749,70 +730,77 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
749 | } | 730 | } |
750 | } | 731 | } |
751 | 732 | ||
752 | #region downForce | 733 | // ================================================================== |
753 | Vector3 downForce = Vector3.Zero; | 734 | Vector3 limitMotorUpContribution = Vector3.Zero; |
754 | |||
755 | if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) | 735 | if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) |
756 | { | 736 | { |
757 | // If the vehicle is motoring into the sky, get it going back down. | 737 | // If the vehicle is motoring into the sky, get it going back down. |
758 | // Is this an angular force or both linear and angular?? | ||
759 | float distanceAboveGround = pos.Z - terrainHeight; | 738 | float distanceAboveGround = pos.Z - terrainHeight; |
760 | if (distanceAboveGround > 2f) | 739 | if (distanceAboveGround > 1f) |
761 | { | 740 | { |
762 | // downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep); | 741 | // downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep); |
763 | // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); | 742 | // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); |
764 | downForce = new Vector3(0, 0, -distanceAboveGround); | 743 | limitMotorUpContribution = new Vector3(0, 0, -distanceAboveGround); |
765 | } | 744 | } |
766 | // TODO: this calculation is all wrong. From the description at | 745 | // TODO: this calculation is all wrong. From the description at |
767 | // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce | 746 | // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce |
768 | // has a decay factor. This says this force should | 747 | // has a decay factor. This says this force should |
769 | // be computed with a motor. | 748 | // be computed with a motor. |
770 | VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}", | 749 | VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}", |
771 | Prim.LocalID, distanceAboveGround, downForce); | 750 | Prim.LocalID, distanceAboveGround, limitMotorUpContribution); |
772 | } | 751 | } |
773 | #endregion // downForce | 752 | |
753 | // ================================================================== | ||
754 | Vector3 newVelocity = linearMotorContribution | ||
755 | + terrainHeightContribution | ||
756 | + hoverContribution | ||
757 | + limitMotorUpContribution; | ||
774 | 758 | ||
775 | // If not changing some axis, reduce out velocity | 759 | // If not changing some axis, reduce out velocity |
776 | if ((m_flags & (VehicleFlag.NO_X)) != 0) | 760 | if ((m_flags & (VehicleFlag.NO_X)) != 0) |
777 | m_newVelocity.X = 0; | 761 | newVelocity.X = 0; |
778 | if ((m_flags & (VehicleFlag.NO_Y)) != 0) | 762 | if ((m_flags & (VehicleFlag.NO_Y)) != 0) |
779 | m_newVelocity.Y = 0; | 763 | newVelocity.Y = 0; |
780 | if ((m_flags & (VehicleFlag.NO_Z)) != 0) | 764 | if ((m_flags & (VehicleFlag.NO_Z)) != 0) |
781 | m_newVelocity.Z = 0; | 765 | newVelocity.Z = 0; |
782 | 766 | ||
767 | // ================================================================== | ||
783 | // Clamp REALLY high or low velocities | 768 | // Clamp REALLY high or low velocities |
784 | if (m_newVelocity.LengthSquared() > 1e6f) | 769 | float newVelocityLengthSq = newVelocity.LengthSquared(); |
770 | if (newVelocityLengthSq > 1e6f) | ||
785 | { | 771 | { |
786 | m_newVelocity /= m_newVelocity.Length(); | 772 | newVelocity /= newVelocity.Length(); |
787 | m_newVelocity *= 1000f; | 773 | newVelocity *= 1000f; |
788 | } | 774 | } |
789 | else if (m_newVelocity.LengthSquared() < 1e-6f) | 775 | else if (newVelocityLengthSq < 1e-6f) |
790 | m_newVelocity = Vector3.Zero; | 776 | newVelocity = Vector3.Zero; |
791 | 777 | ||
778 | // ================================================================== | ||
792 | // Stuff new linear velocity into the vehicle | 779 | // Stuff new linear velocity into the vehicle |
793 | Prim.ForceVelocity = m_newVelocity; | 780 | Prim.ForceVelocity = newVelocity; |
794 | // Prim.ApplyForceImpulse((m_newVelocity - Prim.Velocity) * m_vehicleMass, false); // DEBUG DEBUG | 781 | // Prim.ApplyForceImpulse((m_newVelocity - Prim.Velocity) * m_vehicleMass, false); // DEBUG DEBUG |
795 | 782 | ||
796 | Vector3 totalDownForce = downForce + grav; | 783 | // Other linear forces are applied as forces. |
784 | Vector3 totalDownForce = grav * m_vehicleMass; | ||
797 | if (totalDownForce != Vector3.Zero) | 785 | if (totalDownForce != Vector3.Zero) |
798 | { | 786 | { |
799 | Prim.AddForce(totalDownForce * m_vehicleMass, false); | 787 | Prim.AddForce(totalDownForce, false); |
800 | // Prim.ApplyForceImpulse(totalDownForce * m_vehicleMass, false); | ||
801 | } | 788 | } |
802 | 789 | ||
803 | VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},primVel={4},totalDown={5}", | 790 | VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},primVel={4},totalDown={5}", |
804 | Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity, Prim.Velocity, totalDownForce); | 791 | Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, |
792 | newVelocity, Prim.Velocity, totalDownForce); | ||
805 | 793 | ||
806 | } // end MoveLinear() | 794 | } // end MoveLinear() |
807 | 795 | ||
808 | // ======================================================================= | 796 | // ======================================================================= |
797 | // ======================================================================= | ||
809 | // Apply the effect of the angular motor. | 798 | // Apply the effect of the angular motor. |
810 | private void MoveAngular(float pTimestep) | 799 | private void MoveAngular(float pTimestep) |
811 | { | 800 | { |
812 | // m_angularMotorDirection // angular velocity requested by LSL motor | 801 | // m_angularMotorDirection // angular velocity requested by LSL motor |
813 | // m_angularMotorApply // application frame counter | ||
814 | // m_angularMotorVelocity // current angular motor velocity (ramps up and down) | 802 | // m_angularMotorVelocity // current angular motor velocity (ramps up and down) |
815 | // m_angularMotorTimescale // motor angular velocity ramp up rate | 803 | // m_angularMotorTimescale // motor angular velocity ramp up time |
816 | // m_angularMotorDecayTimescale // motor angular velocity decay rate | 804 | // m_angularMotorDecayTimescale // motor angular velocity decay rate |
817 | // m_angularFrictionTimescale // body angular velocity decay rate | 805 | // m_angularFrictionTimescale // body angular velocity decay rate |
818 | // m_lastAngularVelocity // what was last applied to body | 806 | // m_lastAngularVelocity // what was last applied to body |
@@ -836,18 +824,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
836 | m_angularMotorVelocity = Vector3.Zero; | 824 | m_angularMotorVelocity = Vector3.Zero; |
837 | } | 825 | } |
838 | 826 | ||
839 | #region Vertical attactor | 827 | Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); |
840 | |||
841 | Vector3 vertattr = Vector3.Zero; | ||
842 | Vector3 deflection = Vector3.Zero; | ||
843 | Vector3 banking = Vector3.Zero; | ||
844 | 828 | ||
829 | // ================================================================== | ||
830 | Vector3 verticalAttractionContribution = Vector3.Zero; | ||
845 | // If vertical attaction timescale is reasonable and we applied an angular force last time... | 831 | // If vertical attaction timescale is reasonable and we applied an angular force last time... |
846 | if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero) | 832 | if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero) |
847 | { | 833 | { |
848 | float VAservo = pTimestep * 0.2f / m_verticalAttractionTimescale; | 834 | float VAservo = pTimestep * 0.2f / m_verticalAttractionTimescale; |
849 | if (Prim.IsColliding) | 835 | if (Prim.IsColliding) |
850 | VAservo = pTimestep * 0.05f / (m_verticalAttractionTimescale); | 836 | VAservo = pTimestep * 0.05f / m_verticalAttractionTimescale; |
851 | 837 | ||
852 | VAservo *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); | 838 | VAservo *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); |
853 | 839 | ||
@@ -871,24 +857,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
871 | // As the body rotates around the X axis, then verticalError.Y increases; Rotated around Y | 857 | // As the body rotates around the X axis, then verticalError.Y increases; Rotated around Y |
872 | // then .X increases, so change Body angular velocity X based on Y, and Y based on X. | 858 | // then .X increases, so change Body angular velocity X based on Y, and Y based on X. |
873 | // Z is not changed. | 859 | // Z is not changed. |
874 | vertattr.X = verticalError.Y; | 860 | verticalAttractionContribution.X = verticalError.Y; |
875 | vertattr.Y = - verticalError.X; | 861 | verticalAttractionContribution.Y = - verticalError.X; |
876 | vertattr.Z = 0f; | 862 | verticalAttractionContribution.Z = 0f; |
877 | 863 | ||
878 | // scaling appears better usingsquare-law | 864 | // scaling appears better usingsquare-law |
879 | Vector3 angularVelocity = Prim.ForceRotationalVelocity; | 865 | Vector3 angularVelocity = Prim.ForceRotationalVelocity; |
880 | float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); | 866 | float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); |
881 | vertattr.X += bounce * angularVelocity.X; | 867 | verticalAttractionContribution.X += bounce * angularVelocity.X; |
882 | vertattr.Y += bounce * angularVelocity.Y; | 868 | verticalAttractionContribution.Y += bounce * angularVelocity.Y; |
883 | 869 | ||
884 | VDetailLog("{0},MoveAngular,verticalAttraction,VAservo={1},effic={2},verticalError={3},bounce={4},vertattr={5}", | 870 | VDetailLog("{0},MoveAngular,verticalAttraction,VAservo={1},effic={2},verticalError={3},bounce={4},vertattr={5}", |
885 | Prim.LocalID, VAservo, m_verticalAttractionEfficiency, verticalError, bounce, vertattr); | 871 | Prim.LocalID, VAservo, m_verticalAttractionEfficiency, verticalError, bounce, verticalAttractionContribution); |
886 | 872 | ||
887 | } | 873 | } |
888 | #endregion // Vertical attactor | ||
889 | |||
890 | #region Deflection | ||
891 | 874 | ||
875 | // ================================================================== | ||
876 | Vector3 deflectionContribution = Vector3.Zero; | ||
892 | if (m_angularDeflectionEfficiency != 0) | 877 | if (m_angularDeflectionEfficiency != 0) |
893 | { | 878 | { |
894 | // Compute a scaled vector that points in the preferred axis (X direction) | 879 | // Compute a scaled vector that points in the preferred axis (X direction) |
@@ -899,18 +884,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
899 | Vector3 preferredAxisOfMotion = scaledDefaultDirection * Quaternion.Add(Prim.ForceOrientation, m_referenceFrame); | 884 | Vector3 preferredAxisOfMotion = scaledDefaultDirection * Quaternion.Add(Prim.ForceOrientation, m_referenceFrame); |
900 | 885 | ||
901 | // Scale by efficiency and timescale | 886 | // Scale by efficiency and timescale |
902 | deflection = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep; | 887 | deflectionContribution = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep; |
903 | 888 | ||
904 | VDetailLog("{0},MoveAngular,Deflection,perfAxis={1},deflection={2}", | 889 | VDetailLog("{0},MoveAngular,Deflection,perfAxis={1},deflection={2}", |
905 | Prim.LocalID, preferredAxisOfMotion, deflection); | 890 | Prim.LocalID, preferredAxisOfMotion, deflectionContribution); |
906 | // This deflection computation is not correct. | 891 | // This deflection computation is not correct. |
907 | deflection = Vector3.Zero; | 892 | deflectionContribution = Vector3.Zero; |
908 | } | 893 | } |
909 | 894 | ||
910 | #endregion | 895 | // ================================================================== |
911 | 896 | Vector3 bankingContribution = Vector3.Zero; | |
912 | #region Banking | ||
913 | |||
914 | if (m_bankingEfficiency != 0) | 897 | if (m_bankingEfficiency != 0) |
915 | { | 898 | { |
916 | Vector3 dir = Vector3.One * Prim.ForceOrientation; | 899 | Vector3 dir = Vector3.One * Prim.ForceOrientation; |
@@ -925,6 +908,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
925 | float mix = Math.Abs(m_bankingMix); | 908 | float mix = Math.Abs(m_bankingMix); |
926 | if (m_angularMotorVelocity.X == 0) | 909 | if (m_angularMotorVelocity.X == 0) |
927 | { | 910 | { |
911 | // The vehicle is stopped | ||
928 | /*if (!parent.Orientation.ApproxEquals(this.m_referenceFrame, 0.25f)) | 912 | /*if (!parent.Orientation.ApproxEquals(this.m_referenceFrame, 0.25f)) |
929 | { | 913 | { |
930 | Vector3 axisAngle; | 914 | Vector3 axisAngle; |
@@ -938,9 +922,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
938 | }*/ | 922 | }*/ |
939 | } | 923 | } |
940 | else | 924 | else |
941 | banking.Z += (effSquared*(mult*mix))*(m_angularMotorVelocity.X) * 4; | 925 | { |
926 | bankingContribution.Z += (effSquared * (mult * mix)) * (m_angularMotorVelocity.X) * 4; | ||
927 | } | ||
928 | |||
929 | //If they are colliding, we probably shouldn't shove the prim around... probably | ||
942 | if (!Prim.IsColliding && Math.Abs(m_angularMotorVelocity.X) > mix) | 930 | if (!Prim.IsColliding && Math.Abs(m_angularMotorVelocity.X) > mix) |
943 | //If they are colliding, we probably shouldn't shove the prim around... probably | ||
944 | { | 931 | { |
945 | float angVelZ = m_angularMotorVelocity.X*-1; | 932 | float angVelZ = m_angularMotorVelocity.X*-1; |
946 | /*if(angVelZ > mix) | 933 | /*if(angVelZ > mix) |
@@ -954,22 +941,23 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
954 | else if (bankingRot.X < -3) | 941 | else if (bankingRot.X < -3) |
955 | bankingRot.X = -3; | 942 | bankingRot.X = -3; |
956 | bankingRot *= Prim.ForceOrientation; | 943 | bankingRot *= Prim.ForceOrientation; |
957 | banking += bankingRot; | 944 | bankingContribution += bankingRot; |
958 | } | 945 | } |
959 | m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency; | 946 | m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency; |
960 | VDetailLog("{0},MoveAngular,Banking,bEff={1},angMotVel={2},banking={3}", | 947 | VDetailLog("{0},MoveAngular,Banking,bEff={1},angMotVel={2},effSq={3},mult={4},mix={5},banking={6}", |
961 | Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, banking); | 948 | Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, effSquared, mult, mix, bankingContribution); |
962 | } | 949 | } |
963 | 950 | ||
964 | #endregion | 951 | // ================================================================== |
965 | 952 | m_lastVertAttractor = verticalAttractionContribution; | |
966 | m_lastVertAttractor = vertattr; | ||
967 | 953 | ||
968 | // Sum velocities | 954 | // Sum velocities |
969 | m_lastAngularVelocity = m_angularMotorVelocity + vertattr + banking + deflection; | 955 | m_lastAngularVelocity = angularMotorContribution |
970 | 956 | + verticalAttractionContribution | |
971 | #region Linear Motor Offset | 957 | + bankingContribution |
958 | + deflectionContribution; | ||
972 | 959 | ||
960 | // ================================================================== | ||
973 | //Offset section | 961 | //Offset section |
974 | if (m_linearMotorOffset != Vector3.Zero) | 962 | if (m_linearMotorOffset != Vector3.Zero) |
975 | { | 963 | { |
@@ -985,8 +973,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
985 | // | 973 | // |
986 | // The torque created is the linear velocity crossed with the offset | 974 | // The torque created is the linear velocity crossed with the offset |
987 | 975 | ||
988 | // NOTE: this computation does should be in the linear section | 976 | // TODO: this computation should be in the linear section |
989 | // because there we know the impulse being applied. | 977 | // because that is where we know the impulse being applied. |
990 | Vector3 torqueFromOffset = Vector3.Zero; | 978 | Vector3 torqueFromOffset = Vector3.Zero; |
991 | // torqueFromOffset = Vector3.Cross(m_linearMotorOffset, appliedImpulse); | 979 | // torqueFromOffset = Vector3.Cross(m_linearMotorOffset, appliedImpulse); |
992 | if (float.IsNaN(torqueFromOffset.X)) | 980 | if (float.IsNaN(torqueFromOffset.X)) |
@@ -1000,8 +988,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1000 | VDetailLog("{0},BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset); | 988 | VDetailLog("{0},BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset); |
1001 | } | 989 | } |
1002 | 990 | ||
1003 | #endregion | 991 | // ================================================================== |
1004 | 992 | // NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement | |
1005 | if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) | 993 | if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) |
1006 | { | 994 | { |
1007 | m_lastAngularVelocity.X = 0; | 995 | m_lastAngularVelocity.X = 0; |
@@ -1009,6 +997,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1009 | VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); | 997 | VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); |
1010 | } | 998 | } |
1011 | 999 | ||
1000 | // ================================================================== | ||
1012 | if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) | 1001 | if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) |
1013 | { | 1002 | { |
1014 | m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. | 1003 | m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. |
@@ -1021,18 +1010,20 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1021 | // The above calculates the absolute angular velocity needed. Angular velocity is massless. | 1010 | // 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 | 1011 | // Since we are stuffing the angular velocity directly into the object, the computed |
1023 | // velocity needs to be scaled by the timestep. | 1012 | // velocity needs to be scaled by the timestep. |
1024 | Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) - Prim.ForceRotationalVelocity); | 1013 | // Also remove any motion that is on the object so added motion is only from vehicle. |
1014 | Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) | ||
1015 | - Prim.ForceRotationalVelocity); | ||
1025 | Prim.ForceRotationalVelocity = applyAngularForce; | 1016 | Prim.ForceRotationalVelocity = applyAngularForce; |
1026 | 1017 | ||
1027 | // Decay the angular movement for next time | 1018 | VDetailLog("{0},MoveAngular,done,newRotVel={1},lastAngular={2}", |
1028 | Vector3 decayamount = (Vector3.One / m_angularFrictionTimescale) * pTimestep; | 1019 | Prim.LocalID, applyAngularForce, m_lastAngularVelocity); |
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); | ||
1033 | } | 1020 | } |
1034 | } //end MoveAngular | 1021 | } |
1035 | 1022 | ||
1023 | // This is from previous instantiations of XXXDynamics.cs. | ||
1024 | // Applies roll reference frame. | ||
1025 | // TODO: is this the right way to separate the code to do this operation? | ||
1026 | // Should this be in MoveAngular()? | ||
1036 | internal void LimitRotation(float timestep) | 1027 | internal void LimitRotation(float timestep) |
1037 | { | 1028 | { |
1038 | Quaternion rotq = Prim.ForceOrientation; | 1029 | Quaternion rotq = Prim.ForceOrientation; |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs new file mode 100755 index 0000000..663b6f4 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMaterials.cs | |||
@@ -0,0 +1,191 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyrightD | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
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 | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | using System; | ||
28 | using System.Collections.Generic; | ||
29 | using System.Text; | ||
30 | using System.Reflection; | ||
31 | using Nini.Config; | ||
32 | |||
33 | namespace OpenSim.Region.Physics.BulletSPlugin | ||
34 | { | ||
35 | |||
36 | public struct MaterialAttributes | ||
37 | { | ||
38 | // Material type values that correspond with definitions for LSL | ||
39 | public enum Material : int | ||
40 | { | ||
41 | Stone = 0, | ||
42 | Metal, | ||
43 | Glass, | ||
44 | Wood, | ||
45 | Flesh, | ||
46 | Plastic, | ||
47 | Rubber, | ||
48 | Light, | ||
49 | // Hereafter are BulletSim additions | ||
50 | Avatar, | ||
51 | NumberOfTypes // the count of types in the enum. | ||
52 | } | ||
53 | // Names must be in the order of the above enum. | ||
54 | public static string[] MaterialNames = { "Stone", "Metal", "Glass", "Wood", | ||
55 | "Flesh", "Plastic", "Rubber", "Light", "Avatar" }; | ||
56 | public static string[] MaterialAttribs = { "Density", "Friction", "Restitution", | ||
57 | "ccdMotionThreshold", "ccdSweptSphereRadius" }; | ||
58 | |||
59 | public MaterialAttributes(string t, float d, float f, float r, float ccdM, float ccdS) | ||
60 | { | ||
61 | type = t; | ||
62 | density = d; | ||
63 | friction = f; | ||
64 | restitution = r; | ||
65 | ccdMotionThreshold = ccdM; | ||
66 | ccdSweptSphereRadius = ccdS; | ||
67 | } | ||
68 | public string type; | ||
69 | public float density; | ||
70 | public float friction; | ||
71 | public float restitution; | ||
72 | public float ccdMotionThreshold; | ||
73 | public float ccdSweptSphereRadius; | ||
74 | } | ||
75 | |||
76 | public static class BSMaterials | ||
77 | { | ||
78 | public static MaterialAttributes[] Attributes; | ||
79 | |||
80 | static BSMaterials() | ||
81 | { | ||
82 | // Attribute sets for both the non-physical and physical instances of materials. | ||
83 | Attributes = new MaterialAttributes[(int)MaterialAttributes.Material.NumberOfTypes * 2]; | ||
84 | } | ||
85 | |||
86 | // This is where all the default material attributes are defined. | ||
87 | public static void InitializeFromDefaults(ConfigurationParameters parms) | ||
88 | { | ||
89 | // public static string[] MaterialNames = { "Stone", "Metal", "Glass", "Wood", | ||
90 | // "Flesh", "Plastic", "Rubber", "Light", "Avatar" }; | ||
91 | float dFriction = parms.defaultFriction; | ||
92 | float dRestitution = parms.defaultRestitution; | ||
93 | float dDensity = parms.defaultDensity; | ||
94 | float dCcdM = parms.ccdMotionThreshold; | ||
95 | float dCcdS = parms.ccdSweptSphereRadius; | ||
96 | Attributes[(int)MaterialAttributes.Material.Stone] = | ||
97 | new MaterialAttributes("stone",dDensity,dFriction,dRestitution, dCcdM, dCcdS); | ||
98 | Attributes[(int)MaterialAttributes.Material.Metal] = | ||
99 | new MaterialAttributes("metal",dDensity,dFriction,dRestitution, dCcdM, dCcdS); | ||
100 | Attributes[(int)MaterialAttributes.Material.Glass] = | ||
101 | new MaterialAttributes("glass",dDensity,dFriction,dRestitution, dCcdM, dCcdS); | ||
102 | Attributes[(int)MaterialAttributes.Material.Wood] = | ||
103 | new MaterialAttributes("wood",dDensity,dFriction,dRestitution, dCcdM, dCcdS); | ||
104 | Attributes[(int)MaterialAttributes.Material.Flesh] = | ||
105 | new MaterialAttributes("flesh",dDensity,dFriction,dRestitution, dCcdM, dCcdS); | ||
106 | Attributes[(int)MaterialAttributes.Material.Plastic] = | ||
107 | new MaterialAttributes("plastic",dDensity,dFriction,dRestitution, dCcdM, dCcdS); | ||
108 | Attributes[(int)MaterialAttributes.Material.Rubber] = | ||
109 | new MaterialAttributes("rubber",dDensity,dFriction,dRestitution, dCcdM, dCcdS); | ||
110 | Attributes[(int)MaterialAttributes.Material.Light] = | ||
111 | new MaterialAttributes("light",dDensity,dFriction,dRestitution, dCcdM, dCcdS); | ||
112 | Attributes[(int)MaterialAttributes.Material.Avatar] = | ||
113 | new MaterialAttributes("avatar",dDensity,dFriction,dRestitution, dCcdM, dCcdS); | ||
114 | |||
115 | Attributes[(int)MaterialAttributes.Material.Stone + (int)MaterialAttributes.Material.NumberOfTypes] = | ||
116 | new MaterialAttributes("stonePhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); | ||
117 | Attributes[(int)MaterialAttributes.Material.Metal + (int)MaterialAttributes.Material.NumberOfTypes] = | ||
118 | new MaterialAttributes("metalPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); | ||
119 | Attributes[(int)MaterialAttributes.Material.Glass + (int)MaterialAttributes.Material.NumberOfTypes] = | ||
120 | new MaterialAttributes("glassPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); | ||
121 | Attributes[(int)MaterialAttributes.Material.Wood + (int)MaterialAttributes.Material.NumberOfTypes] = | ||
122 | new MaterialAttributes("woodPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); | ||
123 | Attributes[(int)MaterialAttributes.Material.Flesh + (int)MaterialAttributes.Material.NumberOfTypes] = | ||
124 | new MaterialAttributes("fleshPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); | ||
125 | Attributes[(int)MaterialAttributes.Material.Plastic + (int)MaterialAttributes.Material.NumberOfTypes] = | ||
126 | new MaterialAttributes("plasticPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); | ||
127 | Attributes[(int)MaterialAttributes.Material.Rubber + (int)MaterialAttributes.Material.NumberOfTypes] = | ||
128 | new MaterialAttributes("rubberPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); | ||
129 | Attributes[(int)MaterialAttributes.Material.Light + (int)MaterialAttributes.Material.NumberOfTypes] = | ||
130 | new MaterialAttributes("lightPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); | ||
131 | Attributes[(int)MaterialAttributes.Material.Avatar + (int)MaterialAttributes.Material.NumberOfTypes] = | ||
132 | new MaterialAttributes("avatarPhysical",dDensity,dFriction,dRestitution, dCcdM, dCcdS); | ||
133 | } | ||
134 | |||
135 | // Under the [BulletSim] section, one can change the individual material | ||
136 | // attribute values. The format of the configuration parameter is: | ||
137 | // <materialName><Attribute>["Physical"] = floatValue | ||
138 | // For instance: | ||
139 | // [BulletSim] | ||
140 | // StoneFriction = 0.2 | ||
141 | // FleshRestitutionPhysical = 0.8 | ||
142 | // Materials can have different parameters for their static and | ||
143 | // physical instantiations. When setting the non-physical value, | ||
144 | // both values are changed. Setting the physical value only changes | ||
145 | // the physical value. | ||
146 | public static void InitializefromParameters(IConfig pConfig) | ||
147 | { | ||
148 | int matType = 0; | ||
149 | foreach (string matName in MaterialAttributes.MaterialNames) | ||
150 | { | ||
151 | foreach (string attribName in MaterialAttributes.MaterialAttribs) | ||
152 | { | ||
153 | string paramName = matName + attribName; | ||
154 | if (pConfig.Contains(paramName)) | ||
155 | { | ||
156 | float paramValue = pConfig.GetFloat(paramName); | ||
157 | SetAttributeValue(matType, attribName, paramValue); | ||
158 | // set the physical value also | ||
159 | SetAttributeValue(matType + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue); | ||
160 | } | ||
161 | paramName += "Physical"; | ||
162 | if (pConfig.Contains(paramName)) | ||
163 | { | ||
164 | float paramValue = pConfig.GetFloat(paramName); | ||
165 | SetAttributeValue(matType + (int)MaterialAttributes.Material.NumberOfTypes, attribName, paramValue); | ||
166 | } | ||
167 | } | ||
168 | matType++; | ||
169 | } | ||
170 | } | ||
171 | |||
172 | private static void SetAttributeValue(int matType, string attribName, float val) | ||
173 | { | ||
174 | MaterialAttributes thisAttrib = Attributes[matType]; | ||
175 | FieldInfo fieldInfo = thisAttrib.GetType().GetField(attribName); | ||
176 | if (fieldInfo != null) | ||
177 | { | ||
178 | fieldInfo.SetValue(thisAttrib, val); | ||
179 | Attributes[matType] = thisAttrib; | ||
180 | } | ||
181 | } | ||
182 | |||
183 | public static MaterialAttributes GetAttributes(MaterialAttributes.Material type, bool isPhysical) | ||
184 | { | ||
185 | int ind = (int)type; | ||
186 | if (isPhysical) ind += (int)MaterialAttributes.Material.NumberOfTypes; | ||
187 | return Attributes[ind]; | ||
188 | } | ||
189 | |||
190 | } | ||
191 | } | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index bc6e4c4..480da2c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | |||
@@ -1,104 +1,152 @@ | |||
1 | using System; | 1 | using System; |
2 | using System.Collections.Generic; | 2 | using System.Collections.Generic; |
3 | using System.Text; | 3 | using System.Text; |
4 | using OpenMetaverse; | 4 | using OpenMetaverse; |
5 | 5 | ||
6 | namespace OpenSim.Region.Physics.BulletSPlugin | 6 | namespace OpenSim.Region.Physics.BulletSPlugin |
7 | { | 7 | { |
8 | public abstract class BSMotor | 8 | public abstract class BSMotor |
9 | { | 9 | { |
10 | public virtual void Reset() { } | 10 | public BSMotor(string useName) |
11 | public virtual void Zero() { } | 11 | { |
12 | } | 12 | UseName = useName; |
13 | // Can all the incremental stepping be replaced with motor classes? | 13 | PhysicsScene = null; |
14 | public class BSVMotor : BSMotor | 14 | } |
15 | { | 15 | public virtual void Reset() { } |
16 | public Vector3 FrameOfReference { get; set; } | 16 | public virtual void Zero() { } |
17 | public Vector3 Offset { get; set; } | 17 | |
18 | 18 | public string UseName { get; private set; } | |
19 | public float TimeScale { get; set; } | 19 | // Used only for outputting debug information. Might not be set so check for null. |
20 | public float TargetValueDecayTimeScale { get; set; } | 20 | public BSScene PhysicsScene { get; set; } |
21 | public Vector3 CurrentValueReductionTimescale { get; set; } | 21 | protected void MDetailLog(string msg, params Object[] parms) |
22 | public float Efficiency { get; set; } | 22 | { |
23 | 23 | if (PhysicsScene != null) | |
24 | public Vector3 TargetValue { get; private set; } | 24 | { |
25 | public Vector3 CurrentValue { get; private set; } | 25 | if (PhysicsScene.VehicleLoggingEnabled) |
26 | 26 | { | |
27 | 27 | PhysicsScene.DetailLog(msg, parms); | |
28 | 28 | } | |
29 | BSVMotor(float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency) | 29 | } |
30 | { | 30 | } |
31 | TimeScale = timeScale; | 31 | } |
32 | TargetValueDecayTimeScale = decayTimeScale; | 32 | // Can all the incremental stepping be replaced with motor classes? |
33 | CurrentValueReductionTimescale = frictionTimeScale; | 33 | public class BSVMotor : BSMotor |
34 | Efficiency = efficiency; | 34 | { |
35 | } | 35 | public Vector3 FrameOfReference { get; set; } |
36 | public void SetCurrent(Vector3 current) | 36 | public Vector3 Offset { get; set; } |
37 | { | 37 | |
38 | CurrentValue = current; | 38 | public float TimeScale { get; set; } |
39 | } | 39 | public float TargetValueDecayTimeScale { get; set; } |
40 | public void SetTarget(Vector3 target) | 40 | public Vector3 FrictionTimescale { get; set; } |
41 | { | 41 | public float Efficiency { get; set; } |
42 | TargetValue = target; | 42 | |
43 | } | 43 | public Vector3 TargetValue { get; private set; } |
44 | public Vector3 Step(float timeStep) | 44 | public Vector3 CurrentValue { get; private set; } |
45 | { | 45 | |
46 | if (CurrentValue.LengthSquared() > 0.001f) | 46 | public BSVMotor(string useName) |
47 | { | 47 | : base(useName) |
48 | // Vector3 origDir = Target; // DEBUG | 48 | { |
49 | // Vector3 origVel = CurrentValue; // DEBUG | 49 | TimeScale = TargetValueDecayTimeScale = Efficiency = 1f; |
50 | 50 | FrictionTimescale = Vector3.Zero; | |
51 | // Add (desiredVelocity - currentAppliedVelocity) / howLongItShouldTakeToComplete | 51 | CurrentValue = TargetValue = Vector3.Zero; |
52 | Vector3 addAmount = (TargetValue - CurrentValue)/(TargetValue) * timeStep; | 52 | } |
53 | CurrentValue += addAmount; | 53 | public BSVMotor(string useName, float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency) |
54 | 54 | : this(useName) | |
55 | float decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep; | 55 | { |
56 | TargetValue *= (1f - decayFactor); | 56 | TimeScale = timeScale; |
57 | 57 | TargetValueDecayTimeScale = decayTimeScale; | |
58 | Vector3 frictionFactor = (Vector3.One / CurrentValueReductionTimescale) * timeStep; | 58 | FrictionTimescale = frictionTimeScale; |
59 | CurrentValue *= (Vector3.One - frictionFactor); | 59 | Efficiency = efficiency; |
60 | } | 60 | CurrentValue = TargetValue = Vector3.Zero; |
61 | else | 61 | } |
62 | { | 62 | public void SetCurrent(Vector3 current) |
63 | // if what remains of direction is very small, zero it. | 63 | { |
64 | TargetValue = Vector3.Zero; | 64 | CurrentValue = current; |
65 | CurrentValue = Vector3.Zero; | 65 | } |
66 | 66 | public void SetTarget(Vector3 target) | |
67 | // VDetailLog("{0},MoveLinear,zeroed", Prim.LocalID); | 67 | { |
68 | } | 68 | TargetValue = target; |
69 | return CurrentValue; | 69 | } |
70 | } | 70 | public Vector3 Step(float timeStep) |
71 | } | 71 | { |
72 | 72 | Vector3 returnCurrent = Vector3.Zero; | |
73 | public class BSFMotor : BSMotor | 73 | if (!CurrentValue.ApproxEquals(TargetValue, 0.01f)) |
74 | { | 74 | { |
75 | public float TimeScale { get; set; } | 75 | Vector3 origTarget = TargetValue; // DEBUG |
76 | public float DecayTimeScale { get; set; } | 76 | Vector3 origCurrVal = CurrentValue; // DEBUG |
77 | public float Friction { get; set; } | 77 | |
78 | public float Efficiency { get; set; } | 78 | // Addition = (desiredVector - currentAppliedVector) / secondsItShouldTakeToComplete |
79 | 79 | Vector3 addAmount = (TargetValue - CurrentValue)/TimeScale * timeStep; | |
80 | public float Target { get; private set; } | 80 | CurrentValue += addAmount; |
81 | public float CurrentValue { get; private set; } | 81 | returnCurrent = CurrentValue; |
82 | 82 | ||
83 | BSFMotor(float timeScale, float decayTimescale, float friction, float efficiency) | 83 | // The desired value reduces to zero when also reduces the difference with current. |
84 | { | 84 | float decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep; |
85 | } | 85 | TargetValue *= (1f - decayFactor); |
86 | public void SetCurrent(float target) | 86 | |
87 | { | 87 | Vector3 frictionFactor = Vector3.Zero; |
88 | } | 88 | frictionFactor = (Vector3.One / FrictionTimescale) * timeStep; |
89 | public void SetTarget(float target) | 89 | CurrentValue *= (Vector3.One - frictionFactor); |
90 | { | 90 | |
91 | } | 91 | MDetailLog("{0},BSVMotor.Step,nonZero,{1},origTarget={2},origCurr={3},timeStep={4},timeScale={5},addAmnt={6},targetDecay={7},decayFact={8},fricTS={9},frictFact={10}", |
92 | public float Step(float timeStep) | 92 | BSScene.DetailLogZero, UseName, origTarget, origCurrVal, |
93 | { | 93 | timeStep, TimeScale, addAmount, |
94 | return 0f; | 94 | TargetValueDecayTimeScale, decayFactor, |
95 | } | 95 | FrictionTimescale, frictionFactor); |
96 | } | 96 | MDetailLog("{0},BSVMotor.Step,nonZero,{1},curr={2},target={3},add={4},decay={5},frict={6},ret={7}", |
97 | public class BSPIDMotor : BSMotor | 97 | BSScene.DetailLogZero, UseName, TargetValue, CurrentValue, |
98 | { | 98 | addAmount, decayFactor, frictionFactor, returnCurrent); |
99 | // TODO: write and use this one | 99 | } |
100 | BSPIDMotor() | 100 | else |
101 | { | 101 | { |
102 | } | 102 | // Difference between what we have and target is small. Motor is done. |
103 | } | 103 | CurrentValue = Vector3.Zero; |
104 | } | 104 | TargetValue = Vector3.Zero; |
105 | |||
106 | MDetailLog("{0},BSVMotor.Step,zero,{1},curr={2},target={3},ret={4}", | ||
107 | BSScene.DetailLogZero, UseName, TargetValue, CurrentValue, returnCurrent); | ||
108 | |||
109 | } | ||
110 | return returnCurrent; | ||
111 | } | ||
112 | public override string ToString() | ||
113 | { | ||
114 | return String.Format("<{0},curr={1},targ={2},decayTS={3},frictTS={4}>", | ||
115 | UseName, CurrentValue, TargetValue, TargetValueDecayTimeScale, FrictionTimescale); | ||
116 | } | ||
117 | } | ||
118 | |||
119 | public class BSFMotor : BSMotor | ||
120 | { | ||
121 | public float TimeScale { get; set; } | ||
122 | public float DecayTimeScale { get; set; } | ||
123 | public float Friction { get; set; } | ||
124 | public float Efficiency { get; set; } | ||
125 | |||
126 | public float Target { get; private set; } | ||
127 | public float CurrentValue { get; private set; } | ||
128 | |||
129 | public BSFMotor(string useName, float timeScale, float decayTimescale, float friction, float efficiency) | ||
130 | : base(useName) | ||
131 | { | ||
132 | } | ||
133 | public void SetCurrent(float target) | ||
134 | { | ||
135 | } | ||
136 | public void SetTarget(float target) | ||
137 | { | ||
138 | } | ||
139 | public float Step(float timeStep) | ||
140 | { | ||
141 | return 0f; | ||
142 | } | ||
143 | } | ||
144 | public class BSPIDMotor : BSMotor | ||
145 | { | ||
146 | // TODO: write and use this one | ||
147 | public BSPIDMotor(string useName) | ||
148 | : base(useName) | ||
149 | { | ||
150 | } | ||
151 | } | ||
152 | } | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 2b3fa25..caa6c46 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -342,13 +342,12 @@ public sealed class BSPrim : BSPhysObject | |||
342 | // TODO: check for out of bounds | 342 | // TODO: check for out of bounds |
343 | 343 | ||
344 | // The above code computes a force to apply to correct any out-of-bounds problems. Apply same. | 344 | // The above code computes a force to apply to correct any out-of-bounds problems. Apply same. |
345 | // TODO: This should be intergrated with a geneal physics action mechanism. | ||
346 | // TODO: This should be moderated with PID'ness. | ||
345 | if (ret) | 347 | if (ret) |
346 | { | 348 | { |
347 | PhysicsScene.TaintedObject(inTaintTime, "BSPrim.PositionSanityCheck:belowTerrain", delegate() | 349 | // Apply upforce and overcome gravity. |
348 | { | 350 | AddForce(upForce - PhysicsScene.DefaultGravity, false, inTaintTime); |
349 | // Apply upforce and overcome gravity. | ||
350 | ForceVelocity = ForceVelocity + upForce - PhysicsScene.DefaultGravity; | ||
351 | }); | ||
352 | } | 351 | } |
353 | return ret; | 352 | return ret; |
354 | } | 353 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 27a78d1..805e670 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -39,23 +39,10 @@ using log4net; | |||
39 | using OpenMetaverse; | 39 | using OpenMetaverse; |
40 | 40 | ||
41 | // TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) | 41 | // TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) |
42 | // Test sculpties (verified that they don't work) | ||
43 | // Compute physics FPS reasonably | ||
44 | // Based on material, set density and friction | 42 | // Based on material, set density and friction |
45 | // Don't use constraints in linksets of non-physical objects. Means having to move children manually. | ||
46 | // Four states of prim: Physical, regular, phantom and selected. Are we modeling these correctly? | ||
47 | // In SL one can set both physical and phantom (gravity, does not effect others, makes collisions with ground) | ||
48 | // At the moment, physical and phantom causes object to drop through the terrain | ||
49 | // Physical phantom objects and related typing (collision options ) | ||
50 | // Check out llVolumeDetect. Must do something for that. | ||
51 | // Use collision masks for collision with terrain and phantom objects | ||
52 | // More efficient memory usage when passing hull information from BSPrim to BulletSim | 43 | // More efficient memory usage when passing hull information from BSPrim to BulletSim |
53 | // Should prim.link() and prim.delink() membership checking happen at taint time? | ||
54 | // Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once. | ||
55 | // Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect | 44 | // Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect |
56 | // Implement LockAngularMotion | 45 | // Implement LockAngularMotion |
57 | // Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation) | ||
58 | // Remove mesh and Hull stuff. Use mesh passed to bullet and use convexdecom from bullet. | ||
59 | // Add PID movement operations. What does ScenePresence.MoveToTarget do? | 46 | // Add PID movement operations. What does ScenePresence.MoveToTarget do? |
60 | // Check terrain size. 128 or 127? | 47 | // Check terrain size. 128 or 127? |
61 | // Raycast | 48 | // Raycast |
@@ -234,6 +221,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
234 | if (m_physicsLoggingEnabled) | 221 | if (m_physicsLoggingEnabled) |
235 | { | 222 | { |
236 | PhysicsLogging = new Logging.LogWriter(m_physicsLoggingDir, m_physicsLoggingPrefix, m_physicsLoggingFileMinutes); | 223 | PhysicsLogging = new Logging.LogWriter(m_physicsLoggingDir, m_physicsLoggingPrefix, m_physicsLoggingFileMinutes); |
224 | PhysicsLogging.ErrorLogger = m_log; // for DEBUG. Let's the logger output error messages. | ||
237 | } | 225 | } |
238 | else | 226 | else |
239 | { | 227 | { |
@@ -308,6 +296,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
308 | // Do any replacements in the parameters | 296 | // Do any replacements in the parameters |
309 | m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName); | 297 | m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName); |
310 | } | 298 | } |
299 | |||
300 | // The material characteristics. | ||
301 | BSMaterials.InitializeFromDefaults(Params); | ||
302 | if (pConfig != null) | ||
303 | { | ||
304 | BSMaterials.InitializefromParameters(pConfig); | ||
305 | } | ||
311 | } | 306 | } |
312 | } | 307 | } |
313 | 308 | ||
@@ -1069,7 +1064,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
1069 | (s,p,l,v) => { s.PID_P = v; } ), | 1064 | (s,p,l,v) => { s.PID_P = v; } ), |
1070 | 1065 | ||
1071 | new ParameterDefn("DefaultFriction", "Friction factor used on new objects", | 1066 | new ParameterDefn("DefaultFriction", "Friction factor used on new objects", |
1072 | 0.5f, | 1067 | 0.2f, |
1073 | (s,cf,p,v) => { s.m_params[0].defaultFriction = cf.GetFloat(p, v); }, | 1068 | (s,cf,p,v) => { s.m_params[0].defaultFriction = cf.GetFloat(p, v); }, |
1074 | (s) => { return s.m_params[0].defaultFriction; }, | 1069 | (s) => { return s.m_params[0].defaultFriction; }, |
1075 | (s,p,l,v) => { s.m_params[0].defaultFriction = v; } ), | 1070 | (s,p,l,v) => { s.m_params[0].defaultFriction = v; } ), |
@@ -1084,7 +1079,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
1084 | (s) => { return s.m_params[0].defaultRestitution; }, | 1079 | (s) => { return s.m_params[0].defaultRestitution; }, |
1085 | (s,p,l,v) => { s.m_params[0].defaultRestitution = v; } ), | 1080 | (s,p,l,v) => { s.m_params[0].defaultRestitution = v; } ), |
1086 | new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)", | 1081 | new ParameterDefn("CollisionMargin", "Margin around objects before collisions are calculated (must be zero!)", |
1087 | 0f, | 1082 | 0.04f, |
1088 | (s,cf,p,v) => { s.m_params[0].collisionMargin = cf.GetFloat(p, v); }, | 1083 | (s,cf,p,v) => { s.m_params[0].collisionMargin = cf.GetFloat(p, v); }, |
1089 | (s) => { return s.m_params[0].collisionMargin; }, | 1084 | (s) => { return s.m_params[0].collisionMargin; }, |
1090 | (s,p,l,v) => { s.m_params[0].collisionMargin = v; } ), | 1085 | (s,p,l,v) => { s.m_params[0].collisionMargin = v; } ), |
@@ -1151,7 +1146,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
1151 | (s) => { return s.m_params[0].terrainImplementation; }, | 1146 | (s) => { return s.m_params[0].terrainImplementation; }, |
1152 | (s,p,l,v) => { s.m_params[0].terrainImplementation = v; } ), | 1147 | (s,p,l,v) => { s.m_params[0].terrainImplementation = v; } ), |
1153 | new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , | 1148 | new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , |
1154 | 0.5f, | 1149 | 0.3f, |
1155 | (s,cf,p,v) => { s.m_params[0].terrainFriction = cf.GetFloat(p, v); }, | 1150 | (s,cf,p,v) => { s.m_params[0].terrainFriction = cf.GetFloat(p, v); }, |
1156 | (s) => { return s.m_params[0].terrainFriction; }, | 1151 | (s) => { return s.m_params[0].terrainFriction; }, |
1157 | (s,p,l,v) => { s.m_params[0].terrainFriction = v; /* TODO: set on real terrain */} ), | 1152 | (s,p,l,v) => { s.m_params[0].terrainFriction = v; /* TODO: set on real terrain */} ), |
@@ -1165,13 +1160,19 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
1165 | (s,cf,p,v) => { s.m_params[0].terrainRestitution = cf.GetFloat(p, v); }, | 1160 | (s,cf,p,v) => { s.m_params[0].terrainRestitution = cf.GetFloat(p, v); }, |
1166 | (s) => { return s.m_params[0].terrainRestitution; }, | 1161 | (s) => { return s.m_params[0].terrainRestitution; }, |
1167 | (s,p,l,v) => { s.m_params[0].terrainRestitution = v; /* TODO: set on real terrain */ } ), | 1162 | (s,p,l,v) => { s.m_params[0].terrainRestitution = v; /* TODO: set on real terrain */ } ), |
1163 | new ParameterDefn("TerrainCollisionMargin", "Margin where collision checking starts" , | ||
1164 | 0.04f, | ||
1165 | (s,cf,p,v) => { s.m_params[0].terrainCollisionMargin = cf.GetFloat(p, v); }, | ||
1166 | (s) => { return s.m_params[0].terrainCollisionMargin; }, | ||
1167 | (s,p,l,v) => { s.m_params[0].terrainCollisionMargin = v; /* TODO: set on real terrain */ } ), | ||
1168 | |||
1168 | new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", | 1169 | new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", |
1169 | 0.2f, | 1170 | 0.2f, |
1170 | (s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); }, | 1171 | (s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); }, |
1171 | (s) => { return s.m_params[0].avatarFriction; }, | 1172 | (s) => { return s.m_params[0].avatarFriction; }, |
1172 | (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarFriction, p, l, v); } ), | 1173 | (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarFriction, p, l, v); } ), |
1173 | new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", | 1174 | new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", |
1174 | 10f, | 1175 | 0.99f, |
1175 | (s,cf,p,v) => { s.m_params[0].avatarStandingFriction = cf.GetFloat(p, v); }, | 1176 | (s,cf,p,v) => { s.m_params[0].avatarStandingFriction = cf.GetFloat(p, v); }, |
1176 | (s) => { return s.m_params[0].avatarStandingFriction; }, | 1177 | (s) => { return s.m_params[0].avatarStandingFriction; }, |
1177 | (s,p,l,v) => { s.m_params[0].avatarStandingFriction = v; } ), | 1178 | (s,p,l,v) => { s.m_params[0].avatarStandingFriction = v; } ), |
@@ -1206,6 +1207,11 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
1206 | (s) => { return s.m_params[0].avatarContactProcessingThreshold; }, | 1207 | (s) => { return s.m_params[0].avatarContactProcessingThreshold; }, |
1207 | (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ), | 1208 | (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ), |
1208 | 1209 | ||
1210 | new ParameterDefn("VehicleAngularDamping", "Factor to damp vehicle angular movement per second (0.0 - 1.0)", | ||
1211 | 0.95f, | ||
1212 | (s,cf,p,v) => { s.m_params[0].vehicleAngularDamping = cf.GetFloat(p, v); }, | ||
1213 | (s) => { return s.m_params[0].vehicleAngularDamping; }, | ||
1214 | (s,p,l,v) => { s.m_params[0].vehicleAngularDamping = v; } ), | ||
1209 | 1215 | ||
1210 | new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", | 1216 | new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", |
1211 | 0f, | 1217 | 0f, |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs index 3ca756c..1450f66 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs | |||
@@ -93,7 +93,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys | |||
93 | { | 93 | { |
94 | m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID, | 94 | m_mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, m_mapInfo.ID, |
95 | m_mapInfo.minCoords, m_mapInfo.maxCoords, | 95 | m_mapInfo.minCoords, m_mapInfo.maxCoords, |
96 | m_mapInfo.heightMap, BSTerrainManager.TERRAIN_COLLISION_MARGIN); | 96 | m_mapInfo.heightMap, PhysicsScene.Params.terrainCollisionMargin); |
97 | 97 | ||
98 | // Create the terrain shape from the mapInfo | 98 | // Create the terrain shape from the mapInfo |
99 | m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr), | 99 | m_mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(m_mapInfo.Ptr), |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index 23fcfd3..cd623f1 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs | |||
@@ -80,8 +80,6 @@ public sealed class BSTerrainManager | |||
80 | // amount to make sure that a bounding box is built for the terrain. | 80 | // amount to make sure that a bounding box is built for the terrain. |
81 | public const float HEIGHT_EQUAL_FUDGE = 0.2f; | 81 | public const float HEIGHT_EQUAL_FUDGE = 0.2f; |
82 | 82 | ||
83 | public const float TERRAIN_COLLISION_MARGIN = 0.0f; | ||
84 | |||
85 | // Until the whole simulator is changed to pass us the region size, we rely on constants. | 83 | // Until the whole simulator is changed to pass us the region size, we rely on constants. |
86 | public Vector3 DefaultRegionSize = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); | 84 | public Vector3 DefaultRegionSize = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); |
87 | 85 | ||
@@ -129,7 +127,8 @@ public sealed class BSTerrainManager | |||
129 | { | 127 | { |
130 | // The ground plane is here to catch things that are trying to drop to negative infinity | 128 | // The ground plane is here to catch things that are trying to drop to negative infinity |
131 | BulletShape groundPlaneShape = new BulletShape( | 129 | BulletShape groundPlaneShape = new BulletShape( |
132 | BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, TERRAIN_COLLISION_MARGIN), | 130 | BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, |
131 | PhysicsScene.Params.terrainCollisionMargin), | ||
133 | BSPhysicsShapeType.SHAPE_GROUNDPLANE); | 132 | BSPhysicsShapeType.SHAPE_GROUNDPLANE); |
134 | m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID, | 133 | m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID, |
135 | BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID, | 134 | BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID, |
@@ -165,17 +164,22 @@ public sealed class BSTerrainManager | |||
165 | // Release all the terrain we have allocated | 164 | // Release all the terrain we have allocated |
166 | public void ReleaseTerrain() | 165 | public void ReleaseTerrain() |
167 | { | 166 | { |
168 | foreach (KeyValuePair<Vector3, BSTerrainPhys> kvp in m_terrains) | 167 | lock (m_terrains) |
169 | { | 168 | { |
170 | kvp.Value.Dispose(); | 169 | foreach (KeyValuePair<Vector3, BSTerrainPhys> kvp in m_terrains) |
170 | { | ||
171 | kvp.Value.Dispose(); | ||
172 | } | ||
173 | m_terrains.Clear(); | ||
171 | } | 174 | } |
172 | m_terrains.Clear(); | ||
173 | } | 175 | } |
174 | 176 | ||
175 | // The simulator wants to set a new heightmap for the terrain. | 177 | // The simulator wants to set a new heightmap for the terrain. |
176 | public void SetTerrain(float[] heightMap) { | 178 | public void SetTerrain(float[] heightMap) { |
177 | float[] localHeightMap = heightMap; | 179 | float[] localHeightMap = heightMap; |
178 | PhysicsScene.TaintedObject("TerrainManager.SetTerrain", delegate() | 180 | // If there are multiple requests for changes to the same terrain between ticks, |
181 | // only do that last one. | ||
182 | PhysicsScene.PostTaintObject("TerrainManager.SetTerrain-"+ m_worldOffset.ToString(), 0, delegate() | ||
179 | { | 183 | { |
180 | if (m_worldOffset != Vector3.Zero && MegaRegionParentPhysicsScene != null) | 184 | if (m_worldOffset != Vector3.Zero && MegaRegionParentPhysicsScene != null) |
181 | { | 185 | { |
@@ -211,6 +215,7 @@ public sealed class BSTerrainManager | |||
211 | // terrain shape is created and added to the body. | 215 | // terrain shape is created and added to the body. |
212 | // This call is most often used to update the heightMap and parameters of the terrain. | 216 | // This call is most often used to update the heightMap and parameters of the terrain. |
213 | // (The above does suggest that some simplification/refactoring is in order.) | 217 | // (The above does suggest that some simplification/refactoring is in order.) |
218 | // Called during taint-time. | ||
214 | private void UpdateTerrain(uint id, float[] heightMap, | 219 | private void UpdateTerrain(uint id, float[] heightMap, |
215 | Vector3 minCoords, Vector3 maxCoords, bool inTaintTime) | 220 | Vector3 minCoords, Vector3 maxCoords, bool inTaintTime) |
216 | { | 221 | { |
@@ -220,7 +225,7 @@ public sealed class BSTerrainManager | |||
220 | // Find high and low points of passed heightmap. | 225 | // Find high and low points of passed heightmap. |
221 | // The min and max passed in is usually the area objects can be in (maximum | 226 | // The min and max passed in is usually the area objects can be in (maximum |
222 | // object height, for instance). The terrain wants the bounding box for the | 227 | // object height, for instance). The terrain wants the bounding box for the |
223 | // terrain so we replace passed min and max Z with the actual terrain min/max Z. | 228 | // terrain so replace passed min and max Z with the actual terrain min/max Z. |
224 | float minZ = float.MaxValue; | 229 | float minZ = float.MaxValue; |
225 | float maxZ = float.MinValue; | 230 | float maxZ = float.MinValue; |
226 | foreach (float height in heightMap) | 231 | foreach (float height in heightMap) |
@@ -238,15 +243,15 @@ public sealed class BSTerrainManager | |||
238 | 243 | ||
239 | Vector3 terrainRegionBase = new Vector3(minCoords.X, minCoords.Y, 0f); | 244 | Vector3 terrainRegionBase = new Vector3(minCoords.X, minCoords.Y, 0f); |
240 | 245 | ||
241 | BSTerrainPhys terrainPhys; | 246 | lock (m_terrains) |
242 | if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys)) | ||
243 | { | 247 | { |
244 | // There is already a terrain in this spot. Free the old and build the new. | 248 | BSTerrainPhys terrainPhys; |
245 | DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}", | 249 | if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys)) |
246 | BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords); | ||
247 | |||
248 | PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateTerrain:UpdateExisting", delegate() | ||
249 | { | 250 | { |
251 | // There is already a terrain in this spot. Free the old and build the new. | ||
252 | DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}", | ||
253 | BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords); | ||
254 | |||
250 | // Remove old terrain from the collection | 255 | // Remove old terrain from the collection |
251 | m_terrains.Remove(terrainRegionBase); | 256 | m_terrains.Remove(terrainRegionBase); |
252 | // Release any physical memory it may be using. | 257 | // Release any physical memory it may be using. |
@@ -271,35 +276,24 @@ public sealed class BSTerrainManager | |||
271 | // I hate doing this, but just bail | 276 | // I hate doing this, but just bail |
272 | return; | 277 | return; |
273 | } | 278 | } |
274 | }); | 279 | } |
275 | } | 280 | else |
276 | else | 281 | { |
277 | { | 282 | // We don't know about this terrain so either we are creating a new terrain or |
278 | // We don't know about this terrain so either we are creating a new terrain or | 283 | // our mega-prim child is giving us a new terrain to add to the phys world |
279 | // our mega-prim child is giving us a new terrain to add to the phys world | ||
280 | |||
281 | // if this is a child terrain, calculate a unique terrain id | ||
282 | uint newTerrainID = id; | ||
283 | if (newTerrainID >= BSScene.CHILDTERRAIN_ID) | ||
284 | newTerrainID = ++m_terrainCount; | ||
285 | |||
286 | float[] heightMapX = heightMap; | ||
287 | Vector3 minCoordsX = minCoords; | ||
288 | Vector3 maxCoordsX = maxCoords; | ||
289 | 284 | ||
290 | DetailLog("{0},UpdateTerrain:NewTerrain,call,id={1}, minC={2}, maxC={3}", | 285 | // if this is a child terrain, calculate a unique terrain id |
291 | BSScene.DetailLogZero, newTerrainID, minCoords, minCoords); | 286 | uint newTerrainID = id; |
287 | if (newTerrainID >= BSScene.CHILDTERRAIN_ID) | ||
288 | newTerrainID = ++m_terrainCount; | ||
292 | 289 | ||
293 | // Code that must happen at taint-time | 290 | DetailLog("{0},UpdateTerrain:NewTerrain,taint,newID={1},minCoord={2},maxCoord={3}", |
294 | PhysicsScene.TaintedObject(inTaintTime, "BSScene.UpdateTerrain:NewTerrain", delegate() | 291 | BSScene.DetailLogZero, newTerrainID, minCoords, minCoords); |
295 | { | ||
296 | DetailLog("{0},UpdateTerrain:NewTerrain,taint,baseX={1},baseY={2}", | ||
297 | BSScene.DetailLogZero, minCoordsX.X, minCoordsX.Y); | ||
298 | BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords); | 292 | BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords); |
299 | m_terrains.Add(terrainRegionBase, newTerrainPhys); | 293 | m_terrains.Add(terrainRegionBase, newTerrainPhys); |
300 | 294 | ||
301 | m_terrainModified = true; | 295 | m_terrainModified = true; |
302 | }); | 296 | } |
303 | } | 297 | } |
304 | } | 298 | } |
305 | 299 | ||
@@ -349,6 +343,7 @@ public sealed class BSTerrainManager | |||
349 | // with the same parameters as last time. | 343 | // with the same parameters as last time. |
350 | if (!m_terrainModified && lastHeightTX == tX && lastHeightTY == tY) | 344 | if (!m_terrainModified && lastHeightTX == tX && lastHeightTY == tY) |
351 | return lastHeight; | 345 | return lastHeight; |
346 | m_terrainModified = false; | ||
352 | 347 | ||
353 | lastHeightTX = tX; | 348 | lastHeightTX = tX; |
354 | lastHeightTY = tY; | 349 | lastHeightTY = tY; |
@@ -358,19 +353,19 @@ public sealed class BSTerrainManager | |||
358 | int offsetY = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; | 353 | int offsetY = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y; |
359 | Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f); | 354 | Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f); |
360 | 355 | ||
361 | BSTerrainPhys physTerrain; | 356 | lock (m_terrains) |
362 | if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain)) | ||
363 | { | 357 | { |
364 | ret = physTerrain.GetHeightAtXYZ(loc - terrainBaseXYZ); | 358 | BSTerrainPhys physTerrain; |
365 | DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXYZ,loc={1},base={2},height={3}", | 359 | if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain)) |
366 | BSScene.DetailLogZero, loc, terrainBaseXYZ, ret); | 360 | { |
367 | } | 361 | ret = physTerrain.GetHeightAtXYZ(loc - terrainBaseXYZ); |
368 | else | 362 | } |
369 | { | 363 | else |
370 | PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}", | 364 | { |
371 | LogHeader, PhysicsScene.RegionName, tX, tY); | 365 | PhysicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}", |
366 | LogHeader, PhysicsScene.RegionName, tX, tY); | ||
367 | } | ||
372 | } | 368 | } |
373 | m_terrainModified = false; | ||
374 | lastHeight = ret; | 369 | lastHeight = ret; |
375 | return ret; | 370 | return ret; |
376 | } | 371 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index dca7150..d7afdeb 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs | |||
@@ -217,8 +217,6 @@ public sealed class BSTerrainMesh : BSTerrainPhys | |||
217 | } | 217 | } |
218 | } | 218 | } |
219 | verticesCount = verticesCount / 3; | 219 | verticesCount = verticesCount / 3; |
220 | physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeVerts,verCount={1}", | ||
221 | BSScene.DetailLogZero, verticesCount); | ||
222 | 220 | ||
223 | for (int yy = 0; yy < sizeY; yy++) | 221 | for (int yy = 0; yy < sizeY; yy++) |
224 | { | 222 | { |
@@ -235,8 +233,6 @@ public sealed class BSTerrainMesh : BSTerrainPhys | |||
235 | indicesCount += 6; | 233 | indicesCount += 6; |
236 | } | 234 | } |
237 | } | 235 | } |
238 | physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,completeIndices,indCount={1}", // DEEBUG DEBUG DEBUG | ||
239 | LogHeader, indicesCount); // DEBUG | ||
240 | ret = true; | 236 | ret = true; |
241 | } | 237 | } |
242 | catch (Exception e) | 238 | catch (Exception e) |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index e60a760..12baee9 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs | |||
@@ -287,6 +287,8 @@ public struct ConfigurationParameters | |||
287 | public float terrainFriction; | 287 | public float terrainFriction; |
288 | public float terrainHitFraction; | 288 | public float terrainHitFraction; |
289 | public float terrainRestitution; | 289 | public float terrainRestitution; |
290 | public float terrainCollisionMargin; | ||
291 | |||
290 | public float avatarFriction; | 292 | public float avatarFriction; |
291 | public float avatarStandingFriction; | 293 | public float avatarStandingFriction; |
292 | public float avatarDensity; | 294 | public float avatarDensity; |
@@ -296,6 +298,8 @@ public struct ConfigurationParameters | |||
296 | public float avatarCapsuleHeight; | 298 | public float avatarCapsuleHeight; |
297 | public float avatarContactProcessingThreshold; | 299 | public float avatarContactProcessingThreshold; |
298 | 300 | ||
301 | public float vehicleAngularDamping; | ||
302 | |||
299 | public float maxPersistantManifoldPoolSize; | 303 | public float maxPersistantManifoldPoolSize; |
300 | public float maxCollisionAlgorithmPoolSize; | 304 | public float maxCollisionAlgorithmPoolSize; |
301 | public float shouldDisableContactPoolDynamicAllocation; | 305 | public float shouldDisableContactPoolDynamicAllocation; |
@@ -482,6 +486,9 @@ public static extern IntPtr BuildNativeShape2(IntPtr world, ShapeData shapeData) | |||
482 | public static extern bool IsNativeShape2(IntPtr shape); | 486 | public static extern bool IsNativeShape2(IntPtr shape); |
483 | 487 | ||
484 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 488 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
489 | public static extern void SetShapeCollisionMargin(IntPtr shape, float margin); | ||
490 | |||
491 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||
485 | public static extern IntPtr BuildCapsuleShape2(IntPtr world, float radius, float height, Vector3 scale); | 492 | public static extern IntPtr BuildCapsuleShape2(IntPtr world, float radius, float height, Vector3 scale); |
486 | 493 | ||
487 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 494 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 8a451ec..e9bdabc 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini | |||
@@ -221,10 +221,10 @@ | |||
221 | ; to false if you have compatibility problems. | 221 | ; to false if you have compatibility problems. |
222 | ;CacheSculptMaps = true | 222 | ;CacheSculptMaps = true |
223 | 223 | ||
224 | ; Choose one of the physics engines below | 224 | ; Choose one of the physics engines below. |
225 | ; OpenDynamicsEngine is by some distance the most developed physics engine | 225 | ; OpenDynamicsEngine is by some distance the most developed physics engine. |
226 | ; basicphysics effectively does not model physics at all, making all objects phantom | 226 | ; BulletSim is a high performance, up-and-coming physics engine. |
227 | 227 | ; basicphysics effectively does not model physics at all, making all objects phantom. | |
228 | physics = OpenDynamicsEngine | 228 | physics = OpenDynamicsEngine |
229 | ;physics = basicphysics | 229 | ;physics = basicphysics |
230 | ;physics = POS | 230 | ;physics = POS |
@@ -908,15 +908,18 @@ | |||
908 | 908 | ||
909 | [BulletSim] | 909 | [BulletSim] |
910 | ; World parameters | 910 | ; World parameters |
911 | DefaultFriction = 0.50 | 911 | DefaultFriction = 0.20 |
912 | DefaultDensity = 10.000006836 | 912 | DefaultDensity = 10.000006836 |
913 | DefaultRestitution = 0.0 | 913 | DefaultRestitution = 0.0 |
914 | Gravity = -9.80665 | 914 | Gravity = -9.80665 |
915 | 915 | ||
916 | TerrainFriction = 0.50 | 916 | TerrainFriction = 0.30 |
917 | TerrainHitFriction = 0.8 | 917 | TerrainHitFraction = 0.8 |
918 | TerrainRestitution = 0 | 918 | TerrainRestitution = 0 |
919 | TerrainCollisionMargin = 0.04 | ||
920 | |||
919 | AvatarFriction = 0.2 | 921 | AvatarFriction = 0.2 |
922 | AvatarStandingFriction = 0.99 | ||
920 | AvatarRestitution = 0.0 | 923 | AvatarRestitution = 0.0 |
921 | AvatarDensity = 60.0 | 924 | AvatarDensity = 60.0 |
922 | AvatarCapsuleWidth = 0.6 | 925 | AvatarCapsuleWidth = 0.6 |
@@ -930,27 +933,15 @@ | |||
930 | LinearDamping = 0.0 | 933 | LinearDamping = 0.0 |
931 | AngularDamping = 0.0 | 934 | AngularDamping = 0.0 |
932 | DeactivationTime = 0.2 | 935 | DeactivationTime = 0.2 |
933 | LinearSleepingThreshold = 0.8 | 936 | CollisionMargin = 0.04 |
934 | AngularSleepingThreshold = 1.0 | ||
935 | CcdMotionThreshold = 0.0 | ||
936 | CcdSweptSphereRadius = 0.0 | ||
937 | ContactProcessingThreshold = 0.1 | ||
938 | ; If setting a pool size, also disable dynamic allocation (default pool size is 4096 with dynamic alloc) | ||
939 | MaxPersistantManifoldPoolSize = 0 | ||
940 | ShouldDisableContactPoolDynamicAllocation = False | ||
941 | ShouldForceUpdateAllAabbs = False | ||
942 | ShouldRandomizeSolverOrder = True | ||
943 | ShouldSplitSimulationIslands = True | ||
944 | ShouldEnableFrictionCaching = False | ||
945 | NumberOfSolverIterations = 0 | ||
946 | 937 | ||
947 | ; Linkset constraint parameters | 938 | ; Linkset constraint parameters |
939 | LinkImplementation = 1 ; 0=constraint, 1=compound | ||
948 | LinkConstraintUseFrameOffset = False | 940 | LinkConstraintUseFrameOffset = False |
949 | LinkConstraintEnableTransMotor = True | 941 | LinkConstraintEnableTransMotor = True |
950 | LinkConstraintTransMotorMaxVel = 5.0 | 942 | LinkConstraintTransMotorMaxVel = 5.0 |
951 | LinkConstraintTransMotorMaxForce = 0.1 | 943 | LinkConstraintTransMotorMaxForce = 0.1 |
952 | 944 | ||
953 | |||
954 | ; Whether to mesh sculpties | 945 | ; Whether to mesh sculpties |
955 | MeshSculptedPrim = true | 946 | MeshSculptedPrim = true |
956 | 947 | ||
diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll index 2ae1c75..38b11cd 100755 --- a/bin/lib32/BulletSim.dll +++ b/bin/lib32/BulletSim.dll | |||
Binary files differ | |||
diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so index d4852a5..f59ec97 100755 --- a/bin/lib32/libBulletSim.so +++ b/bin/lib32/libBulletSim.so | |||
Binary files differ | |||
diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll index 77cf7e3..1861d6d 100755 --- a/bin/lib64/BulletSim.dll +++ b/bin/lib64/BulletSim.dll | |||
Binary files differ | |||
diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so index 4ec62b2..e9b8845 100755 --- a/bin/lib64/libBulletSim.so +++ b/bin/lib64/libBulletSim.so | |||
Binary files differ | |||