diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Data/MySQL/MySQLGenericTableHandler.cs | 6 | ||||
-rw-r--r-- | OpenSim/Data/MySQL/MySQLXInventoryData.cs | 75 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 27 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | 224 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 8 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | 2 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs | 2 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs | 104 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | 20 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 61 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 28 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | 213 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs | 9 |
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 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | ||
29 | using System.Data; | 30 | using System.Data; |
31 | using System.Linq; | ||
30 | using System.Reflection; | 32 | using System.Reflection; |
31 | using System.Collections.Generic; | ||
32 | using log4net; | 33 | using log4net; |
33 | using MySql.Data.MySqlClient; | 34 | using MySql.Data.MySqlClient; |
34 | using OpenMetaverse; | 35 | using 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 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | using OpenMetaverse; | ||
5 | |||
6 | namespace OpenSim.Region.Physics.BulletSPlugin | ||
7 | { | ||
8 | public 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? | ||
14 | public 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 | |||
73 | public 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 | } | ||
97 | public 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 | ||
35 | namespace OpenSim.Region.Physics.BulletSPlugin | 35 | namespace 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 | */ | ||
40 | public abstract class BSPhysObject : PhysicsActor | 48 | public 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. | ||
30 | using System; | 28 | using System; |
31 | using System.Reflection; | 29 | using System.Reflection; |
32 | using System.Collections.Generic; | 30 | using 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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Linq; | ||
31 | using System.Text; | ||
32 | |||
33 | namespace OpenSim.Region.Physics.BulletSPlugin | ||
34 | { | ||
35 | public 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 | |||
110 | public 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 | |||
120 | public 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 | |||
174 | public 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 | |||
187 | public 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 | |||
200 | public 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 | |||
632 | public static extern void RemoveChildShapeFromCompoundShape2(IntPtr cShape, IntPtr removeShape); | 632 | public static extern void RemoveChildShapeFromCompoundShape2(IntPtr cShape, IntPtr removeShape); |
633 | 633 | ||
634 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 634 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
635 | public static extern void RecalculateCompoundShapeLocalAabb2(IntPtr cShape); | ||
636 | |||
637 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||
635 | public static extern IntPtr DuplicateCollisionShape2(IntPtr sim, IntPtr srcShape, uint id); | 638 | public 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); | |||
919 | public static extern void SetDamping2(IntPtr obj, float lin_damping, float ang_damping); | 922 | public 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] |
925 | public static extern void SetLinearDamping2(IntPtr obj, float lin_damping); | ||
926 | |||
927 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||
928 | public static extern void SetAngularDamping2(IntPtr obj, float ang_damping); | ||
929 | |||
930 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||
922 | public static extern float GetLinearDamping2(IntPtr obj); | 931 | public static extern float GetLinearDamping2(IntPtr obj); |
923 | 932 | ||
924 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 933 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |