aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Data/MySQL/MySQLGenericTableHandler.cs6
-rw-r--r--OpenSim/Data/MySQL/MySQLXInventoryData.cs75
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs27
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs224
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs8
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSMotors.cs104
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs20
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs61
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs28
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapes.cs213
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs9
13 files changed, 669 insertions, 110 deletions
diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs
index 86367a1..f6731c0 100644
--- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs
+++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs
@@ -224,6 +224,8 @@ namespace OpenSim.Data.MySQL
224 224
225 public virtual bool Store(T row) 225 public virtual bool Store(T row)
226 { 226 {
227// m_log.DebugFormat("[MYSQL GENERIC TABLE HANDLER]: Store(T row) invoked");
228
227 using (MySqlCommand cmd = new MySqlCommand()) 229 using (MySqlCommand cmd = new MySqlCommand())
228 { 230 {
229 string query = ""; 231 string query = "";
@@ -278,6 +280,10 @@ namespace OpenSim.Data.MySQL
278 280
279 public virtual bool Delete(string[] fields, string[] keys) 281 public virtual bool Delete(string[] fields, string[] keys)
280 { 282 {
283// m_log.DebugFormat(
284// "[MYSQL GENERIC TABLE HANDLER]: Delete(string[] fields, string[] keys) invoked with {0}:{1}",
285// string.Join(",", fields), string.Join(",", keys));
286
281 if (fields.Length != keys.Length) 287 if (fields.Length != keys.Length)
282 return false; 288 return false;
283 289
diff --git a/OpenSim/Data/MySQL/MySQLXInventoryData.cs b/OpenSim/Data/MySQL/MySQLXInventoryData.cs
index caf18a4..cccc500 100644
--- a/OpenSim/Data/MySQL/MySQLXInventoryData.cs
+++ b/OpenSim/Data/MySQL/MySQLXInventoryData.cs
@@ -26,9 +26,10 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
29using System.Data; 30using System.Data;
31using System.Linq;
30using System.Reflection; 32using System.Reflection;
31using System.Collections.Generic;
32using log4net; 33using log4net;
33using MySql.Data.MySqlClient; 34using MySql.Data.MySqlClient;
34using OpenMetaverse; 35using OpenMetaverse;
@@ -118,22 +119,69 @@ namespace OpenSim.Data.MySQL
118 119
119 public class MySqlItemHandler : MySQLGenericTableHandler<XInventoryItem> 120 public class MySqlItemHandler : MySQLGenericTableHandler<XInventoryItem>
120 { 121 {
122// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
123
121 public MySqlItemHandler(string c, string t, string m) : 124 public MySqlItemHandler(string c, string t, string m) :
122 base(c, t, m) 125 base(c, t, m)
123 { 126 {
124 } 127 }
125 128
129 public override bool Delete(string field, string val)
130 {
131 XInventoryItem[] retrievedItems = Get(new string[] { field }, new string[] { val });
132 if (retrievedItems.Length == 0)
133 return false;
134
135 if (!base.Delete(field, val))
136 return false;
137
138 // Don't increment folder version here since Delete(string, string) calls Delete(string[], string[])
139// IncrementFolderVersion(retrievedItems[0].parentFolderID);
140
141 return true;
142 }
143
144 public override bool Delete(string[] fields, string[] vals)
145 {
146 XInventoryItem[] retrievedItems = Get(fields, vals);
147 if (retrievedItems.Length == 0)
148 return false;
149
150 if (!base.Delete(fields, vals))
151 return false;
152
153 HashSet<UUID> deletedItemFolderUUIDs = new HashSet<UUID>();
154
155 Array.ForEach<XInventoryItem>(retrievedItems, i => deletedItemFolderUUIDs.Add(i.parentFolderID));
156
157 foreach (UUID deletedItemFolderUUID in deletedItemFolderUUIDs)
158 IncrementFolderVersion(deletedItemFolderUUID);
159
160 return true;
161 }
162
126 public bool MoveItem(string id, string newParent) 163 public bool MoveItem(string id, string newParent)
127 { 164 {
165 XInventoryItem[] retrievedItems = Get(new string[] { "inventoryID" }, new string[] { id });
166 if (retrievedItems.Length == 0)
167 return false;
168
169 UUID oldParent = retrievedItems[0].parentFolderID;
170
128 using (MySqlCommand cmd = new MySqlCommand()) 171 using (MySqlCommand cmd = new MySqlCommand())
129 { 172 {
130
131 cmd.CommandText = String.Format("update {0} set parentFolderID = ?ParentFolderID where inventoryID = ?InventoryID", m_Realm); 173 cmd.CommandText = String.Format("update {0} set parentFolderID = ?ParentFolderID where inventoryID = ?InventoryID", m_Realm);
132 cmd.Parameters.AddWithValue("?ParentFolderID", newParent); 174 cmd.Parameters.AddWithValue("?ParentFolderID", newParent);
133 cmd.Parameters.AddWithValue("?InventoryID", id); 175 cmd.Parameters.AddWithValue("?InventoryID", id);
134 176
135 return ExecuteNonQuery(cmd) == 0 ? false : true; 177 if (ExecuteNonQuery(cmd) == 0)
178 return false;
136 } 179 }
180
181 IncrementFolderVersion(oldParent);
182 IncrementFolderVersion(newParent);
183
184 return true;
137 } 185 }
138 186
139 public XInventoryItem[] GetActiveGestures(UUID principalID) 187 public XInventoryItem[] GetActiveGestures(UUID principalID)
@@ -184,6 +232,21 @@ namespace OpenSim.Data.MySQL
184 if (!base.Store(item)) 232 if (!base.Store(item))
185 return false; 233 return false;
186 234
235 IncrementFolderVersion(item.parentFolderID);
236
237 return true;
238 }
239
240 private bool IncrementFolderVersion(UUID folderID)
241 {
242 return IncrementFolderVersion(folderID.ToString());
243 }
244
245 private bool IncrementFolderVersion(string folderID)
246 {
247// m_log.DebugFormat("[MYSQL ITEM HANDLER]: Incrementing version on folder {0}", folderID);
248// Util.PrintCallStack();
249
187 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) 250 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
188 { 251 {
189 dbcon.Open(); 252 dbcon.Open();
@@ -193,7 +256,7 @@ namespace OpenSim.Data.MySQL
193 cmd.Connection = dbcon; 256 cmd.Connection = dbcon;
194 257
195 cmd.CommandText = String.Format("update inventoryfolders set version=version+1 where folderID = ?folderID"); 258 cmd.CommandText = String.Format("update inventoryfolders set version=version+1 where folderID = ?folderID");
196 cmd.Parameters.AddWithValue("?folderID", item.parentFolderID.ToString()); 259 cmd.Parameters.AddWithValue("?folderID", folderID);
197 260
198 try 261 try
199 { 262 {
@@ -205,9 +268,11 @@ namespace OpenSim.Data.MySQL
205 } 268 }
206 cmd.Dispose(); 269 cmd.Dispose();
207 } 270 }
271
208 dbcon.Close(); 272 dbcon.Close();
209 } 273 }
274
210 return true; 275 return true;
211 } 276 }
212 } 277 }
213} 278} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 2a5397e..f33c124 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -103,7 +103,7 @@ public sealed class BSCharacter : BSPhysObject
103 PhysicsScene.TaintedObject("BSCharacter.create", delegate() 103 PhysicsScene.TaintedObject("BSCharacter.create", delegate()
104 { 104 {
105 DetailLog("{0},BSCharacter.create,taint", LocalID); 105 DetailLog("{0},BSCharacter.create,taint", LocalID);
106 // New body and shape into BSBody and BSShape 106 // New body and shape into PhysBody and PhysShape
107 PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this, null, null); 107 PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this, null, null);
108 108
109 SetPhysicalProperties(); 109 SetPhysicalProperties();
@@ -126,7 +126,7 @@ public sealed class BSCharacter : BSPhysObject
126 { 126 {
127 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr); 127 BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, PhysBody.ptr);
128 128
129 ZeroMotion(); 129 ZeroMotion(true);
130 ForcePosition = _position; 130 ForcePosition = _position;
131 // Set the velocity and compute the proper friction 131 // Set the velocity and compute the proper friction
132 ForceVelocity = _velocity; 132 ForceVelocity = _velocity;
@@ -218,18 +218,31 @@ public sealed class BSCharacter : BSPhysObject
218 // Do it to the properties so the values get set in the physics engine. 218 // Do it to the properties so the values get set in the physics engine.
219 // Push the setting of the values to the viewer. 219 // Push the setting of the values to the viewer.
220 // Called at taint time! 220 // Called at taint time!
221 public override void ZeroMotion() 221 public override void ZeroMotion(bool inTaintTime)
222 { 222 {
223 _velocity = OMV.Vector3.Zero; 223 _velocity = OMV.Vector3.Zero;
224 _acceleration = OMV.Vector3.Zero; 224 _acceleration = OMV.Vector3.Zero;
225 _rotationalVelocity = OMV.Vector3.Zero; 225 _rotationalVelocity = OMV.Vector3.Zero;
226 226
227 // Zero some other properties directly into the physics engine 227 // Zero some other properties directly into the physics engine
228 BulletSimAPI.SetLinearVelocity2(PhysBody.ptr, OMV.Vector3.Zero); 228 PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate()
229 BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero); 229 {
230 BulletSimAPI.SetInterpolationVelocity2(PhysBody.ptr, OMV.Vector3.Zero, OMV.Vector3.Zero); 230 BulletSimAPI.ClearAllForces2(PhysBody.ptr);
231 BulletSimAPI.ClearForces2(PhysBody.ptr); 231 });
232 } 232 }
233 public override void ZeroAngularMotion(bool inTaintTime)
234 {
235 _rotationalVelocity = OMV.Vector3.Zero;
236
237 PhysicsScene.TaintedObject(inTaintTime, "BSCharacter.ZeroMotion", delegate()
238 {
239 BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero);
240 BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero);
241 // The next also get rid of applied linear force but the linear velocity is untouched.
242 BulletSimAPI.ClearForces2(PhysBody.ptr);
243 });
244 }
245
233 246
234 public override void LockAngularMotion(OMV.Vector3 axis) { return; } 247 public override void LockAngularMotion(OMV.Vector3 axis) { return; }
235 248
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 819635a..dbc9039 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -54,10 +54,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin
54{ 54{
55 public sealed class BSDynamics 55 public sealed class BSDynamics
56 { 56 {
57 private static string LogHeader = "[BULLETSIM VEHICLE]";
58
57 private BSScene PhysicsScene { get; set; } 59 private BSScene PhysicsScene { get; set; }
58 // the prim this dynamic controller belongs to 60 // the prim this dynamic controller belongs to
59 private BSPrim Prim { get; set; } 61 private BSPrim Prim { get; set; }
60 62
63 // mass of the vehicle fetched each time we're calles
64 private float m_vehicleMass;
65
61 // Vehicle properties 66 // Vehicle properties
62 public Vehicle Type { get; set; } 67 public Vehicle Type { get; set; }
63 68
@@ -516,7 +521,29 @@ namespace OpenSim.Region.Physics.BulletSPlugin
516 // Friction effects are handled by this vehicle code 521 // Friction effects are handled by this vehicle code
517 BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, 0f); 522 BulletSimAPI.SetFriction2(Prim.PhysBody.ptr, 0f);
518 BulletSimAPI.SetHitFraction2(Prim.PhysBody.ptr, 0f); 523 BulletSimAPI.SetHitFraction2(Prim.PhysBody.ptr, 0f);
524
525 // BulletSimAPI.SetAngularDamping2(Prim.PhysBody.ptr, 0.8f);
526
527 VDetailLog("{0},BSDynamics.Refresh,zeroingFriction and adding damping", Prim.LocalID);
528 }
529 }
530
531 public bool RemoveBodyDependencies(BSPhysObject prim)
532 {
533 // If active, we need to add our properties back when the body is rebuilt.
534 return IsActive;
535 }
536
537 public void RestoreBodyDependencies(BSPhysObject prim)
538 {
539 if (Prim.LocalID != prim.LocalID)
540 {
541 // The call should be on us by our prim. Error if not.
542 PhysicsScene.Logger.ErrorFormat("{0} RestoreBodyDependencies: called by not my prim. passedLocalID={1}, vehiclePrimLocalID={2}",
543 LogHeader, prim.LocalID, Prim.LocalID);
544 return;
519 } 545 }
546 Refresh();
520 } 547 }
521 548
522 // One step of the vehicle properties for the next 'pTimestep' seconds. 549 // One step of the vehicle properties for the next 'pTimestep' seconds.
@@ -533,16 +560,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin
533 // m_lastLinearVelocityVector = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG: 560 // m_lastLinearVelocityVector = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG:
534 // END DEBUG 561 // END DEBUG
535 562
563 m_vehicleMass = Prim.Linkset.LinksetMass;
564
536 MoveLinear(pTimestep); 565 MoveLinear(pTimestep);
566 // Commented out for debug
537 MoveAngular(pTimestep); 567 MoveAngular(pTimestep);
538 LimitRotation(pTimestep); 568 // Prim.ApplyTorqueImpulse(-Prim.RotationalVelocity * m_vehicleMass, false); // DEBUG DEBUG
569 // Prim.ForceRotationalVelocity = -Prim.RotationalVelocity; // DEBUG DEBUG
539 570
540 // DEBUG: Trying to figure out why Bullet goes crazy when the root prim is moved. 571 LimitRotation(pTimestep);
541 // BulletSimAPI.SetInterpolationVelocity2(Prim.BSBody.ptr, m_newVelocity, m_lastAngularVelocity); // DEBUG DEBUG DEBUG
542 572
543 // remember the position so next step we can limit absolute movement effects 573 // remember the position so next step we can limit absolute movement effects
544 m_lastPositionVector = Prim.ForcePosition; 574 m_lastPositionVector = Prim.ForcePosition;
545 575
576 VDetailLog("{0},BSDynamics.Step,frict={1},grav={2},inertia={3},mass={4}", // DEBUG DEBUG
577 Prim.LocalID,
578 BulletSimAPI.GetFriction2(Prim.PhysBody.ptr),
579 BulletSimAPI.GetGravity2(Prim.PhysBody.ptr),
580 Prim.Inertia,
581 m_vehicleMass
582 );
546 VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", 583 VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
547 Prim.LocalID, Prim.ForcePosition, Prim.Force, Prim.ForceVelocity, Prim.RotationalVelocity); 584 Prim.LocalID, Prim.ForcePosition, Prim.Force, Prim.ForceVelocity, Prim.RotationalVelocity);
548 }// end Step 585 }// end Step
@@ -555,25 +592,26 @@ namespace OpenSim.Region.Physics.BulletSPlugin
555 // m_lastLinearVelocityVector is the current speed we are moving in that direction 592 // m_lastLinearVelocityVector is the current speed we are moving in that direction
556 if (m_linearMotorDirection.LengthSquared() > 0.001f) 593 if (m_linearMotorDirection.LengthSquared() > 0.001f)
557 { 594 {
558 Vector3 origDir = m_linearMotorDirection; 595 Vector3 origDir = m_linearMotorDirection; // DEBUG
559 Vector3 origVel = m_lastLinearVelocityVector; 596 Vector3 origVel = m_lastLinearVelocityVector; // DEBUG
597 // DEBUG: the vehicle velocity rotated to be relative to vehicle coordinates for comparison
560 Vector3 vehicleVelocity = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG 598 Vector3 vehicleVelocity = Prim.ForceVelocity * Quaternion.Inverse(Prim.ForceOrientation); // DEBUG
561 599
562 // add drive to body 600 // Add (desiredVelocity - lastAppliedVelocity) / howLongItShouldTakeToComplete
563 Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/(m_linearMotorTimescale) * pTimestep; 601 Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/(m_linearMotorTimescale) * pTimestep;
564 // lastLinearVelocityVector is the current body velocity vector
565 m_lastLinearVelocityVector += addAmount; 602 m_lastLinearVelocityVector += addAmount;
566 603
567 float decayFactor = (1.0f / m_linearMotorDecayTimescale) * pTimestep; 604 float decayFactor = (1.0f / m_linearMotorDecayTimescale) * pTimestep;
568 m_linearMotorDirection *= (1f - decayFactor); 605 m_linearMotorDirection *= (1f - decayFactor);
569 606
570 Vector3 frictionFactor = (Vector3.One / m_linearFrictionTimescale) * pTimestep;
571 m_lastLinearVelocityVector *= (Vector3.One - frictionFactor);
572
573 // Rotate new object velocity from vehicle relative to world coordinates 607 // Rotate new object velocity from vehicle relative to world coordinates
574 m_newVelocity = m_lastLinearVelocityVector * Prim.ForceOrientation; 608 m_newVelocity = m_lastLinearVelocityVector * Prim.ForceOrientation;
575 609
576 VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},vehVel={3},add={4},decay={5},frict={6},lmDir={7},lmVel={8},newVel={9}", 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}",
577 Prim.LocalID, origDir, origVel, vehicleVelocity, addAmount, decayFactor, frictionFactor, 615 Prim.LocalID, origDir, origVel, vehicleVelocity, addAmount, decayFactor, frictionFactor,
578 m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity); 616 m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity);
579 } 617 }
@@ -607,7 +645,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
607 // If below the terrain, move us above the ground a little. 645 // If below the terrain, move us above the ground a little.
608 float terrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); 646 float terrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos);
609 // Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset. 647 // Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset.
610 // Need to add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass. 648 // TODO: Add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass.
611 // Vector3 rotatedSize = m_prim.Size * m_prim.ForceOrientation; 649 // Vector3 rotatedSize = m_prim.Size * m_prim.ForceOrientation;
612 // if (rotatedSize.Z < terrainHeight) 650 // if (rotatedSize.Z < terrainHeight)
613 if (pos.Z < terrainHeight) 651 if (pos.Z < terrainHeight)
@@ -638,13 +676,15 @@ namespace OpenSim.Region.Physics.BulletSPlugin
638 676
639 if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0) 677 if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0)
640 { 678 {
641 // If body is aready heigher, use its height as target height 679 // If body is already heigher, use its height as target height
642 if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; 680 if (pos.Z > m_VhoverTargetHeight)
681 m_VhoverTargetHeight = pos.Z;
643 } 682 }
644 if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) 683 if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
645 { 684 {
646 if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2) 685 if (Math.Abs(pos.Z - m_VhoverTargetHeight) > 0.2f)
647 { 686 {
687 pos.Z = m_VhoverTargetHeight;
648 Prim.ForcePosition = pos; 688 Prim.ForcePosition = pos;
649 } 689 }
650 } 690 }
@@ -709,25 +749,28 @@ namespace OpenSim.Region.Physics.BulletSPlugin
709 } 749 }
710 } 750 }
711 751
712 // Limit absolute vertical change 752 #region downForce
713 float Zchange = Math.Abs(posChange.Z); 753 Vector3 downForce = Vector3.Zero;
754
714 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) 755 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0)
715 { 756 {
716 if (Zchange > .3) 757 // If the vehicle is motoring into the sky, get it going back down.
717 grav.Z = (float)(grav.Z * 3); 758 // Is this an angular force or both linear and angular??
718 if (Zchange > .15) 759 float distanceAboveGround = pos.Z - terrainHeight;
719 grav.Z = (float)(grav.Z * 2); 760 if (distanceAboveGround > 2f)
720 if (Zchange > .75) 761 {
721 grav.Z = (float)(grav.Z * 1.5); 762 // downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep);
722 if (Zchange > .05) 763 // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale);
723 grav.Z = (float)(grav.Z * 1.25); 764 downForce = new Vector3(0, 0, -distanceAboveGround);
724 if (Zchange > .025) 765 }
725 grav.Z = (float)(grav.Z * 1.125); 766 // TODO: this calculation is all wrong. From the description at
726 float postemp = (pos.Z - terrainHeight); 767 // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce
727 if (postemp > 2.5f) 768 // has a decay factor. This says this force should
728 grav.Z = (float)(grav.Z * 1.037125); 769 // be computed with a motor.
729 VDetailLog("{0},MoveLinear,limitMotorUp,grav={1}", Prim.LocalID, grav); 770 VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}",
771 Prim.LocalID, distanceAboveGround, downForce);
730 } 772 }
773 #endregion // downForce
731 774
732 // If not changing some axis, reduce out velocity 775 // If not changing some axis, reduce out velocity
733 if ((m_flags & (VehicleFlag.NO_X)) != 0) 776 if ((m_flags & (VehicleFlag.NO_X)) != 0)
@@ -737,13 +780,28 @@ namespace OpenSim.Region.Physics.BulletSPlugin
737 if ((m_flags & (VehicleFlag.NO_Z)) != 0) 780 if ((m_flags & (VehicleFlag.NO_Z)) != 0)
738 m_newVelocity.Z = 0; 781 m_newVelocity.Z = 0;
739 782
740 // Apply velocity 783 // Clamp REALLY high or low velocities
784 if (m_newVelocity.LengthSquared() > 1e6f)
785 {
786 m_newVelocity /= m_newVelocity.Length();
787 m_newVelocity *= 1000f;
788 }
789 else if (m_newVelocity.LengthSquared() < 1e-6f)
790 m_newVelocity = Vector3.Zero;
791
792 // Stuff new linear velocity into the vehicle
741 Prim.ForceVelocity = m_newVelocity; 793 Prim.ForceVelocity = m_newVelocity;
742 // Prim.AddForce(m_newVelocity * Prim.Linkset.LinksetMass, false); 794 // Prim.ApplyForceImpulse((m_newVelocity - Prim.Velocity) * m_vehicleMass, false); // DEBUG DEBUG
743 Prim.AddForce(grav * Prim.Linkset.LinksetMass, false);
744 795
745 VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},grav={4}", 796 Vector3 totalDownForce = downForce + grav;
746 Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity, grav); 797 if (totalDownForce != Vector3.Zero)
798 {
799 Prim.AddForce(totalDownForce * m_vehicleMass, false);
800 // Prim.ApplyForceImpulse(totalDownForce * m_vehicleMass, false);
801 }
802
803 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);
747 805
748 } // end MoveLinear() 806 } // end MoveLinear()
749 807
@@ -765,7 +823,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
765 Vector3 origDir = m_angularMotorDirection; 823 Vector3 origDir = m_angularMotorDirection;
766 824
767 // new velocity += error / ( time to get there / step interval) 825 // new velocity += error / ( time to get there / step interval)
768 // requested speed - last motor speed 826 // requested direction - current vehicle direction
769 m_angularMotorVelocity += (m_angularMotorDirection - m_angularMotorVelocity) / (m_angularMotorTimescale / pTimestep); 827 m_angularMotorVelocity += (m_angularMotorDirection - m_angularMotorVelocity) / (m_angularMotorTimescale / pTimestep);
770 // decay requested direction 828 // decay requested direction
771 m_angularMotorDirection *= (1.0f - (pTimestep * 1.0f/m_angularMotorDecayTimescale)); 829 m_angularMotorDirection *= (1.0f - (pTimestep * 1.0f/m_angularMotorDecayTimescale));
@@ -784,10 +842,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
784 Vector3 deflection = Vector3.Zero; 842 Vector3 deflection = Vector3.Zero;
785 Vector3 banking = Vector3.Zero; 843 Vector3 banking = Vector3.Zero;
786 844
845 // If vertical attaction timescale is reasonable and we applied an angular force last time...
787 if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero) 846 if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero)
788 { 847 {
789 float VAservo = pTimestep * 0.2f / m_verticalAttractionTimescale; 848 float VAservo = pTimestep * 0.2f / m_verticalAttractionTimescale;
790 if (Prim.Linkset.LinksetIsColliding) 849 if (Prim.IsColliding)
791 VAservo = pTimestep * 0.05f / (m_verticalAttractionTimescale); 850 VAservo = pTimestep * 0.05f / (m_verticalAttractionTimescale);
792 851
793 VAservo *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); 852 VAservo *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency);
@@ -806,7 +865,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
806 verticalError.X = 2.0f - verticalError.X; 865 verticalError.X = 2.0f - verticalError.X;
807 verticalError.Y = 2.0f - verticalError.Y; 866 verticalError.Y = 2.0f - verticalError.Y;
808 } 867 }
809 // scale it by VAservo 868 // scale it by VAservo (timestep and timescale)
810 verticalError = verticalError * VAservo; 869 verticalError = verticalError * VAservo;
811 870
812 // As the body rotates around the X axis, then verticalError.Y increases; Rotated around Y 871 // As the body rotates around the X axis, then verticalError.Y increases; Rotated around Y
@@ -822,25 +881,30 @@ namespace OpenSim.Region.Physics.BulletSPlugin
822 vertattr.X += bounce * angularVelocity.X; 881 vertattr.X += bounce * angularVelocity.X;
823 vertattr.Y += bounce * angularVelocity.Y; 882 vertattr.Y += bounce * angularVelocity.Y;
824 883
825 VDetailLog("{0},MoveAngular,verticalAttraction,verticalError={1},bounce={2},vertattr={3}", 884 VDetailLog("{0},MoveAngular,verticalAttraction,VAservo={1},effic={2},verticalError={3},bounce={4},vertattr={5}",
826 Prim.LocalID, verticalError, bounce, vertattr); 885 Prim.LocalID, VAservo, m_verticalAttractionEfficiency, verticalError, bounce, vertattr);
827 886
828 } 887 }
829 #endregion // Vertical attactor 888 #endregion // Vertical attactor
830 889
831 #region Deflection 890 #region Deflection
832 891
833 //Forward is the prefered direction, but if the reference frame has changed, we need to take this into account as well
834 if (m_angularDeflectionEfficiency != 0) 892 if (m_angularDeflectionEfficiency != 0)
835 { 893 {
836 Vector3 preferredAxisOfMotion = 894 // Compute a scaled vector that points in the preferred axis (X direction)
895 Vector3 scaledDefaultDirection =
837 new Vector3((pTimestep * 10 * (m_angularDeflectionEfficiency / m_angularDeflectionTimescale)), 0, 0); 896 new Vector3((pTimestep * 10 * (m_angularDeflectionEfficiency / m_angularDeflectionTimescale)), 0, 0);
838 preferredAxisOfMotion *= Quaternion.Add(Prim.ForceOrientation, m_referenceFrame); 897 // Adding the current vehicle orientation and reference frame displaces the orientation to the frame.
898 // Rotate the scaled default axix relative to the actual vehicle direction giving where it should point.
899 Vector3 preferredAxisOfMotion = scaledDefaultDirection * Quaternion.Add(Prim.ForceOrientation, m_referenceFrame);
839 900
901 // Scale by efficiency and timescale
840 deflection = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep; 902 deflection = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep;
841 903
842 VDetailLog("{0},MoveAngular,Deflection,perfAxis={1},deflection={2}", 904 VDetailLog("{0},MoveAngular,Deflection,perfAxis={1},deflection={2}",
843 Prim.LocalID, preferredAxisOfMotion, deflection); 905 Prim.LocalID, preferredAxisOfMotion, deflection);
906 // This deflection computation is not correct.
907 deflection = Vector3.Zero;
844 } 908 }
845 909
846 #endregion 910 #endregion
@@ -875,7 +939,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
875 } 939 }
876 else 940 else
877 banking.Z += (effSquared*(mult*mix))*(m_angularMotorVelocity.X) * 4; 941 banking.Z += (effSquared*(mult*mix))*(m_angularMotorVelocity.X) * 4;
878 if (!Prim.Linkset.LinksetIsColliding && Math.Abs(m_angularMotorVelocity.X) > mix) 942 if (!Prim.IsColliding && Math.Abs(m_angularMotorVelocity.X) > mix)
879 //If they are colliding, we probably shouldn't shove the prim around... probably 943 //If they are colliding, we probably shouldn't shove the prim around... probably
880 { 944 {
881 float angVelZ = m_angularMotorVelocity.X*-1; 945 float angVelZ = m_angularMotorVelocity.X*-1;
@@ -904,6 +968,40 @@ namespace OpenSim.Region.Physics.BulletSPlugin
904 // Sum velocities 968 // Sum velocities
905 m_lastAngularVelocity = m_angularMotorVelocity + vertattr + banking + deflection; 969 m_lastAngularVelocity = m_angularMotorVelocity + vertattr + banking + deflection;
906 970
971 #region Linear Motor Offset
972
973 //Offset section
974 if (m_linearMotorOffset != Vector3.Zero)
975 {
976 //Offset of linear velocity doesn't change the linear velocity,
977 // but causes a torque to be applied, for example...
978 //
979 // IIIII >>> IIIII
980 // IIIII >>> IIIII
981 // IIIII >>> IIIII
982 // ^
983 // | Applying a force at the arrow will cause the object to move forward, but also rotate
984 //
985 //
986 // The torque created is the linear velocity crossed with the offset
987
988 // NOTE: this computation does should be in the linear section
989 // because there we know the impulse being applied.
990 Vector3 torqueFromOffset = Vector3.Zero;
991 // torqueFromOffset = Vector3.Cross(m_linearMotorOffset, appliedImpulse);
992 if (float.IsNaN(torqueFromOffset.X))
993 torqueFromOffset.X = 0;
994 if (float.IsNaN(torqueFromOffset.Y))
995 torqueFromOffset.Y = 0;
996 if (float.IsNaN(torqueFromOffset.Z))
997 torqueFromOffset.Z = 0;
998 torqueFromOffset *= m_vehicleMass;
999 Prim.ApplyTorqueImpulse(torqueFromOffset, true);
1000 VDetailLog("{0},BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset);
1001 }
1002
1003 #endregion
1004
907 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) 1005 if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
908 { 1006 {
909 m_lastAngularVelocity.X = 0; 1007 m_lastAngularVelocity.X = 0;
@@ -914,25 +1012,25 @@ namespace OpenSim.Region.Physics.BulletSPlugin
914 if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) 1012 if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
915 { 1013 {
916 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. 1014 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
917 VDetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); 1015 Prim.ZeroAngularMotion(true);
1016 VDetailLog("{0},MoveAngular,zeroAngularMotion,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity);
1017 }
1018 else
1019 {
1020 // Apply to the body.
1021 // The above calculates the absolute angular velocity needed. Angular velocity is massless.
1022 // Since we are stuffing the angular velocity directly into the object, the computed
1023 // velocity needs to be scaled by the timestep.
1024 Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) - Prim.ForceRotationalVelocity);
1025 Prim.ForceRotationalVelocity = applyAngularForce;
1026
1027 // Decay the angular movement for next time
1028 Vector3 decayamount = (Vector3.One / m_angularFrictionTimescale) * pTimestep;
1029 m_lastAngularVelocity *= Vector3.One - decayamount;
1030
1031 VDetailLog("{0},MoveAngular,done,newRotVel={1},decay={2},lastAngular={3}",
1032 Prim.LocalID, applyAngularForce, decayamount, m_lastAngularVelocity);
918 } 1033 }
919
920 // Apply to the body
921 // The above calculates the absolute angular velocity needed
922 // Prim.ForceRotationalVelocity = m_lastAngularVelocity;
923
924 // Apply a force to overcome current angular velocity
925 Vector3 applyAngularForce = (m_lastAngularVelocity - Prim.ForceRotationalVelocity) * Prim.Linkset.LinksetMass;
926 // Vector3 applyAngularForce = (m_lastAngularVelocity - Prim.ForceRotationalVelocity);
927 // Prim.AddAngularForce(applyAngularForce, false);
928 Prim.ApplyTorqueImpulse(applyAngularForce, false);
929
930 // Apply friction for next time
931 Vector3 decayamount = (Vector3.One / m_angularFrictionTimescale) * pTimestep;
932 m_lastAngularVelocity *= Vector3.One - decayamount;
933
934 VDetailLog("{0},MoveAngular,done,applyAForce={1},decay={2},lastAngular={3}",
935 Prim.LocalID, applyAngularForce, decayamount, m_lastAngularVelocity);
936 } //end MoveAngular 1034 } //end MoveAngular
937 1035
938 internal void LimitRotation(float timestep) 1036 internal void LimitRotation(float timestep)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 3a92f93..436e043 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -49,6 +49,9 @@ public abstract class BSLinkset
49 49
50 switch ((int)physScene.Params.linksetImplementation) 50 switch ((int)physScene.Params.linksetImplementation)
51 { 51 {
52 case (int)LinksetImplementation.Constraint:
53 ret = new BSLinksetConstraints(physScene, parent);
54 break;
52 case (int)LinksetImplementation.Compound: 55 case (int)LinksetImplementation.Compound:
53 ret = new BSLinksetCompound(physScene, parent); 56 ret = new BSLinksetCompound(physScene, parent);
54 break; 57 break;
@@ -56,7 +59,7 @@ public abstract class BSLinkset
56 // ret = new BSLinksetManual(physScene, parent); 59 // ret = new BSLinksetManual(physScene, parent);
57 break; 60 break;
58 default: 61 default:
59 ret = new BSLinksetConstraints(physScene, parent); 62 ret = new BSLinksetCompound(physScene, parent);
60 break; 63 break;
61 } 64 }
62 return ret; 65 return ret;
@@ -97,7 +100,6 @@ public abstract class BSLinkset
97 { 100 {
98 get 101 get
99 { 102 {
100 m_mass = ComputeLinksetMass();
101 return m_mass; 103 return m_mass;
102 } 104 }
103 } 105 }
@@ -138,6 +140,7 @@ public abstract class BSLinkset
138 // Don't add the root to its own linkset 140 // Don't add the root to its own linkset
139 if (!IsRoot(child)) 141 if (!IsRoot(child))
140 AddChildToLinkset(child); 142 AddChildToLinkset(child);
143 m_mass = ComputeLinksetMass();
141 } 144 }
142 return this; 145 return this;
143 } 146 }
@@ -156,6 +159,7 @@ public abstract class BSLinkset
156 return this; 159 return this;
157 } 160 }
158 RemoveChildFromLinkset(child); 161 RemoveChildFromLinkset(child);
162 m_mass = ComputeLinksetMass();
159 } 163 }
160 164
161 // The child is down to a linkset of just itself 165 // The child is down to a linkset of just itself
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
index 12c6d7a..3238c85 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs
@@ -264,6 +264,8 @@ public sealed class BSLinksetCompound : BSLinkset
264 float linksetMass = LinksetMass; 264 float linksetMass = LinksetMass;
265 LinksetRoot.UpdatePhysicalMassProperties(linksetMass); 265 LinksetRoot.UpdatePhysicalMassProperties(linksetMass);
266 266
267 BulletSimAPI.RecalculateCompoundShapeLocalAabb2(LinksetRoot.PhysShape.ptr);
268
267 // DEBUG: see of inter-linkset collisions are causing problems for constraint linksets. 269 // DEBUG: see of inter-linkset collisions are causing problems for constraint linksets.
268 // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, 270 // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr,
269 // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); 271 // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
index d2387fb..c855fda 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs
@@ -184,7 +184,7 @@ public sealed class BSLinksetConstraints : BSLinkset
184 private BSConstraint BuildConstraint(BSPhysObject rootPrim, BSPhysObject childPrim) 184 private BSConstraint BuildConstraint(BSPhysObject rootPrim, BSPhysObject childPrim)
185 { 185 {
186 // Zero motion for children so they don't interpolate 186 // Zero motion for children so they don't interpolate
187 childPrim.ZeroMotion(); 187 childPrim.ZeroMotion(true);
188 188
189 // Relative position normalized to the root prim 189 // Relative position normalized to the root prim
190 // Essentually a vector pointing from center of rootPrim to center of childPrim 190 // Essentually a vector pointing from center of rootPrim to center of childPrim
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs
new file mode 100755
index 0000000..bc6e4c4
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs
@@ -0,0 +1,104 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using OpenMetaverse;
5
6namespace OpenSim.Region.Physics.BulletSPlugin
7{
8public abstract class BSMotor
9{
10 public virtual void Reset() { }
11 public virtual void Zero() { }
12}
13// Can all the incremental stepping be replaced with motor classes?
14public class BSVMotor : BSMotor
15{
16 public Vector3 FrameOfReference { get; set; }
17 public Vector3 Offset { get; set; }
18
19 public float TimeScale { get; set; }
20 public float TargetValueDecayTimeScale { get; set; }
21 public Vector3 CurrentValueReductionTimescale { get; set; }
22 public float Efficiency { get; set; }
23
24 public Vector3 TargetValue { get; private set; }
25 public Vector3 CurrentValue { get; private set; }
26
27
28
29 BSVMotor(float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency)
30 {
31 TimeScale = timeScale;
32 TargetValueDecayTimeScale = decayTimeScale;
33 CurrentValueReductionTimescale = frictionTimeScale;
34 Efficiency = efficiency;
35 }
36 public void SetCurrent(Vector3 current)
37 {
38 CurrentValue = current;
39 }
40 public void SetTarget(Vector3 target)
41 {
42 TargetValue = target;
43 }
44 public Vector3 Step(float timeStep)
45 {
46 if (CurrentValue.LengthSquared() > 0.001f)
47 {
48 // Vector3 origDir = Target; // DEBUG
49 // Vector3 origVel = CurrentValue; // DEBUG
50
51 // Add (desiredVelocity - currentAppliedVelocity) / howLongItShouldTakeToComplete
52 Vector3 addAmount = (TargetValue - CurrentValue)/(TargetValue) * timeStep;
53 CurrentValue += addAmount;
54
55 float decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep;
56 TargetValue *= (1f - decayFactor);
57
58 Vector3 frictionFactor = (Vector3.One / CurrentValueReductionTimescale) * timeStep;
59 CurrentValue *= (Vector3.One - frictionFactor);
60 }
61 else
62 {
63 // if what remains of direction is very small, zero it.
64 TargetValue = Vector3.Zero;
65 CurrentValue = Vector3.Zero;
66
67 // VDetailLog("{0},MoveLinear,zeroed", Prim.LocalID);
68 }
69 return CurrentValue;
70 }
71}
72
73public class BSFMotor : BSMotor
74{
75 public float TimeScale { get; set; }
76 public float DecayTimeScale { get; set; }
77 public float Friction { get; set; }
78 public float Efficiency { get; set; }
79
80 public float Target { get; private set; }
81 public float CurrentValue { get; private set; }
82
83 BSFMotor(float timeScale, float decayTimescale, float friction, float efficiency)
84 {
85 }
86 public void SetCurrent(float target)
87 {
88 }
89 public void SetTarget(float target)
90 {
91 }
92 public float Step(float timeStep)
93 {
94 return 0f;
95 }
96}
97public class BSPIDMotor : BSMotor
98{
99 // TODO: write and use this one
100 BSPIDMotor()
101 {
102 }
103}
104}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index 7127aaf..e803072 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -34,9 +34,17 @@ using OpenSim.Region.Physics.Manager;
34 34
35namespace OpenSim.Region.Physics.BulletSPlugin 35namespace OpenSim.Region.Physics.BulletSPlugin
36{ 36{
37// Class to wrap all objects. 37/*
38// The rest of BulletSim doesn't need to keep checking for avatars or prims 38 * Class to wrap all objects.
39// unless the difference is significant. 39 * The rest of BulletSim doesn't need to keep checking for avatars or prims
40 * unless the difference is significant.
41 *
42 * Variables in the physicsl objects are in three forms:
43 * VariableName: used by the simulator and performs taint operations, etc
44 * RawVariableName: direct reference to the BulletSim storage for the variable value
45 * ForceVariableName: direct reference (store and fetch) to the value in the physics engine.
46 * The last two (and certainly the last one) should be referenced only in taint-time.
47 */
40public abstract class BSPhysObject : PhysicsActor 48public abstract class BSPhysObject : PhysicsActor
41{ 49{
42 protected void BaseInitialize(BSScene parentScene, uint localID, string name, string typeName) 50 protected void BaseInitialize(BSScene parentScene, uint localID, string name, string typeName)
@@ -67,6 +75,9 @@ public abstract class BSPhysObject : PhysicsActor
67 // Set the raw mass but also update physical mass properties (inertia, ...) 75 // Set the raw mass but also update physical mass properties (inertia, ...)
68 public abstract void UpdatePhysicalMassProperties(float mass); 76 public abstract void UpdatePhysicalMassProperties(float mass);
69 77
78 // The last value calculated for the prim's inertia
79 public OMV.Vector3 Inertia { get; set; }
80
70 // Reference to the physical body (btCollisionObject) of this object 81 // Reference to the physical body (btCollisionObject) of this object
71 public BulletBody PhysBody; 82 public BulletBody PhysBody;
72 // Reference to the physical shape (btCollisionShape) of this object 83 // Reference to the physical shape (btCollisionShape) of this object
@@ -96,7 +107,8 @@ public abstract class BSPhysObject : PhysicsActor
96 public abstract bool IsStatic { get; } 107 public abstract bool IsStatic { get; }
97 108
98 // Stop all physical motion. 109 // Stop all physical motion.
99 public abstract void ZeroMotion(); 110 public abstract void ZeroMotion(bool inTaintTime);
111 public abstract void ZeroAngularMotion(bool inTaintTime);
100 112
101 // Step the vehicle simulation for this object. A NOOP if the vehicle was not configured. 113 // Step the vehicle simulation for this object. A NOOP if the vehicle was not configured.
102 public virtual void StepVehicle(float timeStep) { } 114 public virtual void StepVehicle(float timeStep) { }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index aaa0d93..14eb505 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -25,8 +25,6 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28// Uncomment this it enable code to do all shape an body memory management
29// in the C# code.
30using System; 28using System;
31using System.Reflection; 29using System.Reflection;
32using System.Collections.Generic; 30using System.Collections.Generic;
@@ -236,14 +234,27 @@ public sealed class BSPrim : BSPhysObject
236 // Do it to the properties so the values get set in the physics engine. 234 // Do it to the properties so the values get set in the physics engine.
237 // Push the setting of the values to the viewer. 235 // Push the setting of the values to the viewer.
238 // Called at taint time! 236 // Called at taint time!
239 public override void ZeroMotion() 237 public override void ZeroMotion(bool inTaintTime)
240 { 238 {
241 _velocity = OMV.Vector3.Zero; 239 _velocity = OMV.Vector3.Zero;
242 _acceleration = OMV.Vector3.Zero; 240 _acceleration = OMV.Vector3.Zero;
243 _rotationalVelocity = OMV.Vector3.Zero; 241 _rotationalVelocity = OMV.Vector3.Zero;
244 242
245 // Zero some other properties in the physics engine 243 // Zero some other properties in the physics engine
246 BulletSimAPI.ClearAllForces2(PhysBody.ptr); 244 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
245 {
246 BulletSimAPI.ClearAllForces2(PhysBody.ptr);
247 });
248 }
249 public override void ZeroAngularMotion(bool inTaintTime)
250 {
251 _rotationalVelocity = OMV.Vector3.Zero;
252 // Zero some other properties in the physics engine
253 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
254 {
255 BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero);
256 BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero);
257 });
247 } 258 }
248 259
249 public override void LockAngularMotion(OMV.Vector3 axis) 260 public override void LockAngularMotion(OMV.Vector3 axis)
@@ -371,17 +382,18 @@ public sealed class BSPrim : BSPhysObject
371 { 382 {
372 if (IsStatic) 383 if (IsStatic)
373 { 384 {
374 BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, OMV.Vector3.Zero); 385 Inertia = OMV.Vector3.Zero;
386 BulletSimAPI.SetMassProps2(PhysBody.ptr, 0f, Inertia);
375 BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr); 387 BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr);
376 } 388 }
377 else 389 else
378 { 390 {
379 OMV.Vector3 localInertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass); 391 Inertia = BulletSimAPI.CalculateLocalInertia2(PhysShape.ptr, physMass);
380 BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, localInertia); 392 BulletSimAPI.SetMassProps2(PhysBody.ptr, physMass, Inertia);
393 BulletSimAPI.UpdateInertiaTensor2(PhysBody.ptr);
381 // center of mass is at the zero of the object 394 // center of mass is at the zero of the object
382 BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation); 395 // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(PhysBody.ptr, ForcePosition, ForceOrientation);
383 // BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); 396 DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2}", LocalID, physMass, Inertia);
384 DetailLog("{0},BSPrim.UpdateMassProperties,mass={1},localInertia={2}", LocalID, physMass, localInertia);
385 } 397 }
386 } 398 }
387 399
@@ -582,7 +594,7 @@ public sealed class BSPrim : BSPhysObject
582 // DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical); 594 // DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical);
583 SetObjectDynamic(true); 595 SetObjectDynamic(true);
584 // whether phys-to-static or static-to-phys, the object is not moving. 596 // whether phys-to-static or static-to-phys, the object is not moving.
585 ZeroMotion(); 597 ZeroMotion(true);
586 }); 598 });
587 } 599 }
588 } 600 }
@@ -648,6 +660,7 @@ public sealed class BSPrim : BSPhysObject
648 // Recompute any linkset parameters. 660 // Recompute any linkset parameters.
649 // When going from non-physical to physical, this re-enables the constraints that 661 // When going from non-physical to physical, this re-enables the constraints that
650 // had been automatically disabled when the mass was set to zero. 662 // had been automatically disabled when the mass was set to zero.
663 // For compound based linksets, this enables and disables interactions of the children.
651 Linkset.Refresh(this); 664 Linkset.Refresh(this);
652 665
653 DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}", 666 DetailLog("{0},BSPrim.UpdatePhysicalParameters,taintExit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}",
@@ -666,9 +679,9 @@ public sealed class BSPrim : BSPhysObject
666 // Become a Bullet 'static' object type 679 // Become a Bullet 'static' object type
667 CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT); 680 CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_STATIC_OBJECT);
668 // Stop all movement 681 // Stop all movement
669 ZeroMotion(); 682 ZeroMotion(true);
670 // Center of mass is at the center of the object 683 // Center of mass is at the center of the object
671 BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody.ptr, _position, _orientation); 684 // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody.ptr, _position, _orientation);
672 // Mass is zero which disables a bunch of physics stuff in Bullet 685 // Mass is zero which disables a bunch of physics stuff in Bullet
673 UpdatePhysicalMassProperties(0f); 686 UpdatePhysicalMassProperties(0f);
674 // Set collision detection parameters 687 // Set collision detection parameters
@@ -704,7 +717,7 @@ public sealed class BSPrim : BSPhysObject
704 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation); 717 BulletSimAPI.SetTranslation2(PhysBody.ptr, _position, _orientation);
705 718
706 // Center of mass is at the center of the object 719 // Center of mass is at the center of the object
707 BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody.ptr, _position, _orientation); 720 // DEBUG DEBUG BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.PhysBody.ptr, _position, _orientation);
708 721
709 // A dynamic object has mass 722 // A dynamic object has mass
710 UpdatePhysicalMassProperties(RawMass); 723 UpdatePhysicalMassProperties(RawMass);
@@ -958,6 +971,16 @@ public sealed class BSPrim : BSPhysObject
958 }); 971 });
959 } 972 }
960 973
974 public void ApplyForceImpulse(OMV.Vector3 impulse, bool inTaintTime)
975 {
976 OMV.Vector3 applyImpulse = impulse;
977 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyForceImpulse", delegate()
978 {
979 DetailLog("{0},BSPrim.ApplyForceImpulse,taint,tImpulse={1}", LocalID, applyImpulse);
980 BulletSimAPI.ApplyCentralImpulse2(PhysBody.ptr, applyImpulse);
981 });
982 }
983
961 private List<OMV.Vector3> m_accumulatedAngularForces = new List<OMV.Vector3>(); 984 private List<OMV.Vector3> m_accumulatedAngularForces = new List<OMV.Vector3>();
962 public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { 985 public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
963 AddAngularForce(force, pushforce, false); 986 AddAngularForce(force, pushforce, false);
@@ -1001,7 +1024,6 @@ public sealed class BSPrim : BSPhysObject
1001 OMV.Vector3 applyImpulse = impulse; 1024 OMV.Vector3 applyImpulse = impulse;
1002 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyTorqueImpulse", delegate() 1025 PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ApplyTorqueImpulse", delegate()
1003 { 1026 {
1004 DetailLog("{0},BSPrim.ApplyTorqueImpulse,taint,tImpulse={1}", LocalID, applyImpulse);
1005 BulletSimAPI.ApplyTorqueImpulse2(PhysBody.ptr, applyImpulse); 1027 BulletSimAPI.ApplyTorqueImpulse2(PhysBody.ptr, applyImpulse);
1006 }); 1028 });
1007 } 1029 }
@@ -1315,9 +1337,10 @@ public sealed class BSPrim : BSPhysObject
1315 // If this prim is part of a linkset, we must remove and restore the physical 1337 // If this prim is part of a linkset, we must remove and restore the physical
1316 // links if the body is rebuilt. 1338 // links if the body is rebuilt.
1317 bool needToRestoreLinkset = false; 1339 bool needToRestoreLinkset = false;
1340 bool needToRestoreVehicle = false;
1318 1341
1319 // Create the correct physical representation for this type of object. 1342 // Create the correct physical representation for this type of object.
1320 // Updates BSBody and BSShape with the new information. 1343 // Updates PhysBody and PhysShape with the new information.
1321 // Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary. 1344 // Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary.
1322 // Returns 'true' if either the body or the shape was changed. 1345 // Returns 'true' if either the body or the shape was changed.
1323 PhysicsScene.Shapes.GetBodyAndShape(false, PhysicsScene.World, this, null, delegate(BulletBody dBody) 1346 PhysicsScene.Shapes.GetBodyAndShape(false, PhysicsScene.World, this, null, delegate(BulletBody dBody)
@@ -1326,6 +1349,7 @@ public sealed class BSPrim : BSPhysObject
1326 // Remove all the physical dependencies on the old body. 1349 // Remove all the physical dependencies on the old body.
1327 // (Maybe someday make the changing of BSShape an event handled by BSLinkset.) 1350 // (Maybe someday make the changing of BSShape an event handled by BSLinkset.)
1328 needToRestoreLinkset = Linkset.RemoveBodyDependencies(this); 1351 needToRestoreLinkset = Linkset.RemoveBodyDependencies(this);
1352 needToRestoreVehicle = _vehicle.RemoveBodyDependencies(this);
1329 }); 1353 });
1330 1354
1331 if (needToRestoreLinkset) 1355 if (needToRestoreLinkset)
@@ -1333,6 +1357,11 @@ public sealed class BSPrim : BSPhysObject
1333 // If physical body dependencies were removed, restore them 1357 // If physical body dependencies were removed, restore them
1334 Linkset.RestoreBodyDependencies(this); 1358 Linkset.RestoreBodyDependencies(this);
1335 } 1359 }
1360 if (needToRestoreVehicle)
1361 {
1362 // If physical body dependencies were removed, restore them
1363 _vehicle.RestoreBodyDependencies(this);
1364 }
1336 1365
1337 // Make sure the properties are set on the new object 1366 // Make sure the properties are set on the new object
1338 UpdatePhysicalParameters(); 1367 UpdatePhysicalParameters();
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 740f339..1cc607a 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -491,7 +491,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
491 491
492 // Some of the prims operate with special vehicle properties 492 // Some of the prims operate with special vehicle properties
493 ProcessVehicles(timeStep); 493 ProcessVehicles(timeStep);
494 numTaints += _taintOperations.Count;
495 ProcessTaints(); // the vehicles might have added taints 494 ProcessTaints(); // the vehicles might have added taints
496 495
497 // step the physical world one interval 496 // step the physical world one interval
@@ -500,7 +499,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
500 499
501 try 500 try
502 { 501 {
503 // DumpVehicles(); // DEBUG 502 if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG
504 if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount(); 503 if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount();
505 504
506 numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep, 505 numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep,
@@ -509,7 +508,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
509 if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime); 508 if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime);
510 DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}", 509 DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}",
511 DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount); 510 DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount);
512 // DumpVehicles(); // DEBUG 511 if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG
513 } 512 }
514 catch (Exception e) 513 catch (Exception e)
515 { 514 {
@@ -521,7 +520,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
521 collidersCount = 0; 520 collidersCount = 0;
522 } 521 }
523 522
524
525 // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in 523 // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in
526 524
527 // Get a value for 'now' so all the collision and update routines don't have to get their own 525 // Get a value for 'now' so all the collision and update routines don't have to get their own
@@ -724,6 +722,9 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
724 { 722 {
725 if (_taintOperations.Count > 0) // save allocating new list if there is nothing to process 723 if (_taintOperations.Count > 0) // save allocating new list if there is nothing to process
726 { 724 {
725 /*
726 // Code to limit the number of taints processed per step. Meant to limit step time.
727 // Unsure if a good idea as code assumes that taints are done before the step.
727 int taintCount = m_taintsToProcessPerStep; 728 int taintCount = m_taintsToProcessPerStep;
728 TaintCallbackEntry oneCallback = new TaintCallbackEntry(); 729 TaintCallbackEntry oneCallback = new TaintCallbackEntry();
729 while (_taintOperations.Count > 0 && taintCount-- > 0) 730 while (_taintOperations.Count > 0 && taintCount-- > 0)
@@ -752,13 +753,17 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
752 } 753 }
753 } 754 }
754 } 755 }
755 /* 756 if (_taintOperations.Count > 0)
757 {
758 DetailLog("{0},BSScene.ProcessTaints,leftTaintsOnList,numNotProcessed={1}", DetailLogZero, _taintOperations.Count);
759 }
760 */
756 // swizzle a new list into the list location so we can process what's there 761 // swizzle a new list into the list location so we can process what's there
757 List<TaintCallbackEntry> oldList; 762 List<TaintCallbackEntry> oldList;
758 lock (_taintLock) 763 lock (_taintLock)
759 { 764 {
760 oldList = _taintedObjects; 765 oldList = _taintOperations;
761 _taintedObjects = new List<TaintCallbackEntry>(); 766 _taintOperations = new List<TaintCallbackEntry>();
762 } 767 }
763 768
764 foreach (TaintCallbackEntry tcbe in oldList) 769 foreach (TaintCallbackEntry tcbe in oldList)
@@ -774,7 +779,6 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
774 } 779 }
775 } 780 }
776 oldList.Clear(); 781 oldList.Clear();
777 */
778 } 782 }
779 } 783 }
780 784
@@ -1043,7 +1047,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
1043 (s) => { return (float)s.m_maxUpdatesPerFrame; }, 1047 (s) => { return (float)s.m_maxUpdatesPerFrame; },
1044 (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ), 1048 (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ),
1045 new ParameterDefn("MaxTaintsToProcessPerStep", "Number of update taints to process before each simulation step", 1049 new ParameterDefn("MaxTaintsToProcessPerStep", "Number of update taints to process before each simulation step",
1046 100f, 1050 500f,
1047 (s,cf,p,v) => { s.m_taintsToProcessPerStep = cf.GetInt(p, (int)v); }, 1051 (s,cf,p,v) => { s.m_taintsToProcessPerStep = cf.GetInt(p, (int)v); },
1048 (s) => { return (float)s.m_taintsToProcessPerStep; }, 1052 (s) => { return (float)s.m_taintsToProcessPerStep; },
1049 (s,p,l,v) => { s.m_taintsToProcessPerStep = (int)v; } ), 1053 (s,p,l,v) => { s.m_taintsToProcessPerStep = (int)v; } ),
@@ -1097,13 +1101,13 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
1097 (s,cf,p,v) => { s.m_params[0].linearDamping = cf.GetFloat(p, v); }, 1101 (s,cf,p,v) => { s.m_params[0].linearDamping = cf.GetFloat(p, v); },
1098 (s) => { return s.m_params[0].linearDamping; }, 1102 (s) => { return s.m_params[0].linearDamping; },
1099 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearDamping, p, l, v); }, 1103 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearDamping, p, l, v); },
1100 (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, v, v); } ), 1104 (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, v, s.m_params[0].angularDamping); } ),
1101 new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)", 1105 new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)",
1102 0f, 1106 0f,
1103 (s,cf,p,v) => { s.m_params[0].angularDamping = cf.GetFloat(p, v); }, 1107 (s,cf,p,v) => { s.m_params[0].angularDamping = cf.GetFloat(p, v); },
1104 (s) => { return s.m_params[0].angularDamping; }, 1108 (s) => { return s.m_params[0].angularDamping; },
1105 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularDamping, p, l, v); }, 1109 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularDamping, p, l, v); },
1106 (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, v, v); } ), 1110 (s,o,v) => { BulletSimAPI.SetDamping2(o.PhysBody.ptr, s.m_params[0].linearDamping, v); } ),
1107 new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static", 1111 new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static",
1108 0.2f, 1112 0.2f,
1109 (s,cf,p,v) => { s.m_params[0].deactivationTime = cf.GetFloat(p, v); }, 1113 (s,cf,p,v) => { s.m_params[0].deactivationTime = cf.GetFloat(p, v); },
@@ -1473,7 +1477,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
1473 { 1477 {
1474 PhysicsLogging.Write(msg, args); 1478 PhysicsLogging.Write(msg, args);
1475 // Add the Flush() if debugging crashes. Gets all the messages written out. 1479 // Add the Flush() if debugging crashes. Gets all the messages written out.
1476 PhysicsLogging.Flush(); 1480 // PhysicsLogging.Flush();
1477 } 1481 }
1478 // Used to fill in the LocalID when there isn't one. It's the correct number of characters. 1482 // Used to fill in the LocalID when there isn't one. It's the correct number of characters.
1479 public const string DetailLogZero = "0000000000"; 1483 public const string DetailLogZero = "0000000000";
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
new file mode 100755
index 0000000..5e2c4a8
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
@@ -0,0 +1,213 @@
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
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Text;
32
33namespace OpenSim.Region.Physics.BulletSPlugin
34{
35public abstract class BSShape
36{
37 public IntPtr ptr { get; set; }
38 public ShapeData.PhysicsShapeType type { get; set; }
39 public System.UInt64 key { get; set; }
40 public int referenceCount { get; set; }
41 public DateTime lastReferenced { get; set; }
42
43 protected void Initialize()
44 {
45 ptr = IntPtr.Zero;
46 type = ShapeData.PhysicsShapeType.SHAPE_UNKNOWN;
47 key = 0;
48 referenceCount = 0;
49 lastReferenced = DateTime.Now;
50 }
51
52 // Get a reference to a physical shape. Create if it doesn't exist
53 public static BSShape GetShapeReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
54 {
55 BSShape ret = null;
56
57 if (prim.PreferredPhysicalShape == ShapeData.PhysicsShapeType.SHAPE_AVATAR)
58 {
59 // an avatar capsule is close to a native shape (it is not shared)
60 ret = BSShapeNative.GetReference(physicsScene, prim, ShapeData.PhysicsShapeType.SHAPE_AVATAR,
61 ShapeData.FixedShapeKey.KEY_CAPSULE);
62 physicsScene.DetailLog("{0},BSShape.GetShapeReference,avatarCapsule,shape={1}", prim.LocalID, ret);
63 }
64
65 // Compound shapes are handled special as they are rebuilt from scratch.
66 // This isn't too great a hardship since most of the child shapes will already been created.
67 if (ret == null && prim.PreferredPhysicalShape == ShapeData.PhysicsShapeType.SHAPE_COMPOUND)
68 {
69 // Getting a reference to a compound shape gets you the compound shape with the root prim shape added
70 ret = BSShapeCompound.GetReference(prim);
71 physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, ret);
72 }
73
74 if (ret == null)
75 ret = GetShapeReferenceNonSpecial(physicsScene, forceRebuild, prim);
76
77 return ret;
78 }
79 public static BSShape GetShapeReferenceNonSpecial(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
80 {
81 return null;
82 }
83 public static BSShape GetShapeReferenceNonNative(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
84 {
85 return null;
86 }
87
88 // Release the use of a physical shape.
89 public abstract void Dereference(BSScene physicsScene);
90
91 // All shapes have a static call to get a reference to the physical shape
92 // protected abstract static BSShape GetReference();
93
94 public override string ToString()
95 {
96 StringBuilder buff = new StringBuilder();
97 buff.Append("<p=");
98 buff.Append(ptr.ToString("X"));
99 buff.Append(",s=");
100 buff.Append(type.ToString());
101 buff.Append(",k=");
102 buff.Append(key.ToString("X"));
103 buff.Append(",c=");
104 buff.Append(referenceCount.ToString());
105 buff.Append(">");
106 return buff.ToString();
107 }
108}
109
110public class BSShapeNull : BSShape
111{
112 public BSShapeNull()
113 {
114 base.Initialize();
115 }
116 public static BSShape GetReference() { return new BSShapeNull(); }
117 public override void Dereference(BSScene physicsScene) { /* The magic of garbage collection will make this go away */ }
118}
119
120public class BSShapeNative : BSShape
121{
122 private static string LogHeader = "[BULLETSIM SHAPE NATIVE]";
123 public BSShapeNative()
124 {
125 base.Initialize();
126 }
127 public static BSShape GetReference(BSScene physicsScene, BSPhysObject prim,
128 ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey)
129 {
130 // Native shapes are not shared and are always built anew.
131 return new BSShapeNative(physicsScene, prim, shapeType, shapeKey);
132 }
133
134 private BSShapeNative(BSScene physicsScene, BSPhysObject prim,
135 ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey)
136 {
137 ShapeData nativeShapeData = new ShapeData();
138 nativeShapeData.Type = shapeType;
139 nativeShapeData.ID = prim.LocalID;
140 nativeShapeData.Scale = prim.Scale;
141 nativeShapeData.Size = prim.Scale;
142 nativeShapeData.MeshKey = (ulong)shapeKey;
143 nativeShapeData.HullKey = (ulong)shapeKey;
144
145
146 if (shapeType == ShapeData.PhysicsShapeType.SHAPE_AVATAR)
147 {
148 ptr = BulletSimAPI.BuildCapsuleShape2(physicsScene.World.ptr, 1f, 1f, prim.Scale);
149 physicsScene.DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale);
150 }
151 else
152 {
153 ptr = BulletSimAPI.BuildNativeShape2(physicsScene.World.ptr, nativeShapeData);
154 }
155 if (ptr == IntPtr.Zero)
156 {
157 physicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}",
158 LogHeader, prim.LocalID, shapeType);
159 }
160 type = shapeType;
161 key = (UInt64)shapeKey;
162 }
163 // Make this reference to the physical shape go away since native shapes are not shared.
164 public override void Dereference(BSScene physicsScene)
165 {
166 // Native shapes are not tracked and are released immediately
167 physicsScene.DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this);
168 BulletSimAPI.DeleteCollisionShape2(physicsScene.World.ptr, ptr);
169 ptr = IntPtr.Zero;
170 // Garbage collection will free up this instance.
171 }
172}
173
174public class BSShapeMesh : BSShape
175{
176 private static string LogHeader = "[BULLETSIM SHAPE MESH]";
177 private static Dictionary<System.UInt64, BSShapeMesh> Meshes = new Dictionary<System.UInt64, BSShapeMesh>();
178
179 public BSShapeMesh()
180 {
181 base.Initialize();
182 }
183 public static BSShape GetReference() { return new BSShapeNull(); }
184 public override void Dereference(BSScene physicsScene) { }
185}
186
187public class BSShapeHull : BSShape
188{
189 private static string LogHeader = "[BULLETSIM SHAPE HULL]";
190 private static Dictionary<System.UInt64, BSShapeHull> Hulls = new Dictionary<System.UInt64, BSShapeHull>();
191
192 public BSShapeHull()
193 {
194 base.Initialize();
195 }
196 public static BSShape GetReference() { return new BSShapeNull(); }
197 public override void Dereference(BSScene physicsScene) { }
198}
199
200public class BSShapeCompound : BSShape
201{
202 private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]";
203 public BSShapeCompound()
204 {
205 base.Initialize();
206 }
207 public static BSShape GetReference(BSPhysObject prim)
208 {
209 return new BSShapeNull();
210 }
211 public override void Dereference(BSScene physicsScene) { }
212}
213}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
index 702bd77..07149d8 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
@@ -632,6 +632,9 @@ public static extern IntPtr RemoveChildShapeFromCompoundShapeIndex2(IntPtr cShap
632public static extern void RemoveChildShapeFromCompoundShape2(IntPtr cShape, IntPtr removeShape); 632public static extern void RemoveChildShapeFromCompoundShape2(IntPtr cShape, IntPtr removeShape);
633 633
634[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 634[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
635public static extern void RecalculateCompoundShapeLocalAabb2(IntPtr cShape);
636
637[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
635public static extern IntPtr DuplicateCollisionShape2(IntPtr sim, IntPtr srcShape, uint id); 638public static extern IntPtr DuplicateCollisionShape2(IntPtr sim, IntPtr srcShape, uint id);
636 639
637[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 640[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
@@ -919,6 +922,12 @@ public static extern Vector3 GetGravity2(IntPtr obj);
919public static extern void SetDamping2(IntPtr obj, float lin_damping, float ang_damping); 922public static extern void SetDamping2(IntPtr obj, float lin_damping, float ang_damping);
920 923
921[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 924[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
925public static extern void SetLinearDamping2(IntPtr obj, float lin_damping);
926
927[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
928public static extern void SetAngularDamping2(IntPtr obj, float ang_damping);
929
930[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
922public static extern float GetLinearDamping2(IntPtr obj); 931public static extern float GetLinearDamping2(IntPtr obj);
923 932
924[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 933[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]