diff options
author | Robert Adams | 2012-09-23 18:39:46 -0700 |
---|---|---|
committer | Robert Adams | 2012-09-27 22:01:37 -0700 |
commit | d016051fa028a485b09fac47b3fa3d8fd08e207a (patch) | |
tree | 8f483976bb64b1328439b76754675126b09943b0 /OpenSim/Region/Physics | |
parent | BulletSim: fix regression that caused cylindar shapes to have a box collision... (diff) | |
download | opensim-SC-d016051fa028a485b09fac47b3fa3d8fd08e207a.zip opensim-SC-d016051fa028a485b09fac47b3fa3d8fd08e207a.tar.gz opensim-SC-d016051fa028a485b09fac47b3fa3d8fd08e207a.tar.bz2 opensim-SC-d016051fa028a485b09fac47b3fa3d8fd08e207a.tar.xz |
BulletSim: renamed members of BulletShape, BulletSim and BulletBody
so the members case is consistant. Caused modifications everywhere.
New logic in BSShapeCollection to track use and sharing of shapes.
I just reslized, though, that shapes cannot be shared because the
shape's UserPointer is the localID of the prim and is required
for tracking collisions. More changes coming.
Added DuplicateCollisionShape2() to API and changed BuildNativeShape2
to take a ShapeData structure so don't have to pass so many parameters.
This matches the latest version of BulletSim.dll.
Additions and removal of DetailLog() statements for debugging.
Diffstat (limited to 'OpenSim/Region/Physics')
11 files changed, 482 insertions, 270 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs index 683bc51..ff271fe 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs | |||
@@ -44,7 +44,7 @@ public class BS6DofConstraint : BSConstraint | |||
44 | m_body1 = obj1; | 44 | m_body1 = obj1; |
45 | m_body2 = obj2; | 45 | m_body2 = obj2; |
46 | m_constraint = new BulletConstraint( | 46 | m_constraint = new BulletConstraint( |
47 | BulletSimAPI.Create6DofConstraint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr, | 47 | BulletSimAPI.Create6DofConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr, |
48 | frame1, frame1rot, | 48 | frame1, frame1rot, |
49 | frame2, frame2rot, | 49 | frame2, frame2rot, |
50 | useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); | 50 | useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); |
@@ -59,7 +59,7 @@ public class BS6DofConstraint : BSConstraint | |||
59 | m_body1 = obj1; | 59 | m_body1 = obj1; |
60 | m_body2 = obj2; | 60 | m_body2 = obj2; |
61 | m_constraint = new BulletConstraint( | 61 | m_constraint = new BulletConstraint( |
62 | BulletSimAPI.Create6DofConstraintToPoint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr, | 62 | BulletSimAPI.Create6DofConstraintToPoint2(m_world.ptr, m_body1.ptr, m_body2.ptr, |
63 | joinPoint, | 63 | joinPoint, |
64 | useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); | 64 | useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); |
65 | m_enabled = true; | 65 | m_enabled = true; |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 014cd99..e4b1dd4 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -114,7 +114,7 @@ public class BSCharacter : BSPhysObject | |||
114 | // Set the buoyancy for flying. This will be refactored when all the settings happen in C# | 114 | // Set the buoyancy for flying. This will be refactored when all the settings happen in C# |
115 | BulletSimAPI.SetObjectBuoyancy(PhysicsScene.WorldID, LocalID, _buoyancy); | 115 | BulletSimAPI.SetObjectBuoyancy(PhysicsScene.WorldID, LocalID, _buoyancy); |
116 | 116 | ||
117 | BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(PhysicsScene.World.Ptr, LocalID)); | 117 | BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(PhysicsScene.World.ptr, LocalID)); |
118 | }); | 118 | }); |
119 | 119 | ||
120 | return; | 120 | return; |
@@ -189,10 +189,10 @@ public class BSCharacter : BSPhysObject | |||
189 | _rotationalVelocity = OMV.Vector3.Zero; | 189 | _rotationalVelocity = OMV.Vector3.Zero; |
190 | 190 | ||
191 | // Zero some other properties directly into the physics engine | 191 | // Zero some other properties directly into the physics engine |
192 | BulletSimAPI.SetLinearVelocity2(BSBody.Ptr, OMV.Vector3.Zero); | 192 | BulletSimAPI.SetLinearVelocity2(BSBody.ptr, OMV.Vector3.Zero); |
193 | BulletSimAPI.SetAngularVelocity2(BSBody.Ptr, OMV.Vector3.Zero); | 193 | BulletSimAPI.SetAngularVelocity2(BSBody.ptr, OMV.Vector3.Zero); |
194 | BulletSimAPI.SetInterpolationVelocity2(BSBody.Ptr, OMV.Vector3.Zero, OMV.Vector3.Zero); | 194 | BulletSimAPI.SetInterpolationVelocity2(BSBody.ptr, OMV.Vector3.Zero, OMV.Vector3.Zero); |
195 | BulletSimAPI.ClearForces2(BSBody.Ptr); | 195 | BulletSimAPI.ClearForces2(BSBody.ptr); |
196 | } | 196 | } |
197 | 197 | ||
198 | public override void LockAngularMotion(OMV.Vector3 axis) { return; } | 198 | public override void LockAngularMotion(OMV.Vector3 axis) { return; } |
@@ -437,7 +437,7 @@ public class BSCharacter : BSPhysObject | |||
437 | PhysicsScene.TaintedObject("BSCharacter.AddForce", delegate() | 437 | PhysicsScene.TaintedObject("BSCharacter.AddForce", delegate() |
438 | { | 438 | { |
439 | DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force); | 439 | DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force); |
440 | BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force); | 440 | BulletSimAPI.SetObjectForce2(BSBody.ptr, _force); |
441 | }); | 441 | }); |
442 | } | 442 | } |
443 | else | 443 | else |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs index 1376a29..c21252b 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs | |||
@@ -49,7 +49,7 @@ public abstract class BSConstraint : IDisposable | |||
49 | if (m_enabled) | 49 | if (m_enabled) |
50 | { | 50 | { |
51 | m_enabled = false; | 51 | m_enabled = false; |
52 | bool success = BulletSimAPI.DestroyConstraint2(m_world.Ptr, m_constraint.Ptr); | 52 | bool success = BulletSimAPI.DestroyConstraint2(m_world.ptr, m_constraint.Ptr); |
53 | m_world.scene.DetailLog("{0},BSConstraint.Dispose,taint,body1={1},body2={2},success={3}", BSScene.DetailLogZero, m_body1.ID, m_body2.ID, success); | 53 | m_world.scene.DetailLog("{0},BSConstraint.Dispose,taint,body1={1},body2={2},success={3}", BSScene.DetailLogZero, m_body1.ID, m_body2.ID, success); |
54 | m_constraint.Ptr = System.IntPtr.Zero; | 54 | m_constraint.Ptr = System.IntPtr.Zero; |
55 | } | 55 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs index d68048b..a6e4235 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs | |||
@@ -1,55 +1,55 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyrightD | 9 | * * Redistributions in binary form must reproduce the above copyrightD |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSimulator Project nor the | 12 | * * Neither the name of the OpenSimulator Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | using System; | 27 | using System; |
28 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
29 | using System.Text; | 29 | using System.Text; |
30 | using OpenMetaverse; | 30 | using OpenMetaverse; |
31 | 31 | ||
32 | namespace OpenSim.Region.Physics.BulletSPlugin | 32 | namespace OpenSim.Region.Physics.BulletSPlugin |
33 | { | 33 | { |
34 | 34 | ||
35 | class BSHingeConstraint : BSConstraint | 35 | class BSHingeConstraint : BSConstraint |
36 | { | 36 | { |
37 | public BSHingeConstraint(BulletSim world, BulletBody obj1, BulletBody obj2, | 37 | public BSHingeConstraint(BulletSim world, BulletBody obj1, BulletBody obj2, |
38 | Vector3 pivotInA, Vector3 pivotInB, | 38 | Vector3 pivotInA, Vector3 pivotInB, |
39 | Vector3 axisInA, Vector3 axisInB, | 39 | Vector3 axisInA, Vector3 axisInB, |
40 | bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) | 40 | bool useLinearReferenceFrameA, bool disableCollisionsBetweenLinkedBodies) |
41 | { | 41 | { |
42 | m_world = world; | 42 | m_world = world; |
43 | m_body1 = obj1; | 43 | m_body1 = obj1; |
44 | m_body2 = obj2; | 44 | m_body2 = obj2; |
45 | m_constraint = new BulletConstraint( | 45 | m_constraint = new BulletConstraint( |
46 | BulletSimAPI.CreateHingeConstraint2(m_world.Ptr, m_body1.Ptr, m_body2.Ptr, | 46 | BulletSimAPI.CreateHingeConstraint2(m_world.ptr, m_body1.ptr, m_body2.ptr, |
47 | pivotInA, pivotInB, | 47 | pivotInA, pivotInB, |
48 | axisInA, axisInB, | 48 | axisInA, axisInB, |
49 | useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); | 49 | useLinearReferenceFrameA, disableCollisionsBetweenLinkedBodies)); |
50 | m_enabled = true; | 50 | m_enabled = true; |
51 | } | 51 | } |
52 | 52 | ||
53 | } | 53 | } |
54 | 54 | ||
55 | } | 55 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 1e8fe52..84a7fac 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | |||
@@ -282,10 +282,10 @@ public class BSLinkset | |||
282 | { | 282 | { |
283 | // If this is a multiple object linkset, set everybody's center of mass to the set's center of mass | 283 | // If this is a multiple object linkset, set everybody's center of mass to the set's center of mass |
284 | OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass(); | 284 | OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass(); |
285 | BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.Ptr, centerOfMass, OMV.Quaternion.Identity); | 285 | BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity); |
286 | foreach (BSPhysObject child in m_children) | 286 | foreach (BSPhysObject child in m_children) |
287 | { | 287 | { |
288 | BulletSimAPI.SetCenterOfMassByPosRot2(child.BSBody.Ptr, centerOfMass, OMV.Quaternion.Identity); | 288 | BulletSimAPI.SetCenterOfMassByPosRot2(child.BSBody.ptr, centerOfMass, OMV.Quaternion.Identity); |
289 | } | 289 | } |
290 | /* | 290 | /* |
291 | // The root prim takes on the weight of the whole linkset | 291 | // The root prim takes on the weight of the whole linkset |
@@ -442,7 +442,7 @@ public class BSLinkset | |||
442 | PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody, childPrim.BSBody); | 442 | PhysicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody, childPrim.BSBody); |
443 | 443 | ||
444 | // Make the child refresh its location | 444 | // Make the child refresh its location |
445 | BulletSimAPI.PushUpdate2(childPrim.BSBody.Ptr); | 445 | BulletSimAPI.PushUpdate2(childPrim.BSBody.ptr); |
446 | } | 446 | } |
447 | 447 | ||
448 | // Remove linkage between myself and any possible children I might have | 448 | // Remove linkage between myself and any possible children I might have |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 70a10b1..6a9fe50 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
@@ -121,8 +121,8 @@ public abstract class BSPhysObject : PhysicsActor | |||
121 | // if someone has subscribed for collision events.... | 121 | // if someone has subscribed for collision events.... |
122 | if (SubscribedEvents()) { | 122 | if (SubscribedEvents()) { |
123 | CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); | 123 | CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); |
124 | // DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5}", | 124 | DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5}", |
125 | // LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth); | 125 | LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth); |
126 | ret = true; | 126 | ret = true; |
127 | } | 127 | } |
128 | return ret; | 128 | return ret; |
@@ -147,7 +147,7 @@ public abstract class BSPhysObject : PhysicsActor | |||
147 | if (CollisionCollection.Count == 0) | 147 | if (CollisionCollection.Count == 0) |
148 | PhysicsScene.ObjectsWithNoMoreCollisions.Add(this); | 148 | PhysicsScene.ObjectsWithNoMoreCollisions.Add(this); |
149 | 149 | ||
150 | // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); | 150 | DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count); |
151 | base.SendCollisionUpdate(CollisionCollection); | 151 | base.SendCollisionUpdate(CollisionCollection); |
152 | 152 | ||
153 | // The collisionCollection structure is passed around in the simulator. | 153 | // The collisionCollection structure is passed around in the simulator. |
@@ -158,7 +158,8 @@ public abstract class BSPhysObject : PhysicsActor | |||
158 | 158 | ||
159 | // Subscribe for collision events. | 159 | // Subscribe for collision events. |
160 | // Parameter is the millisecond rate the caller wishes collision events to occur. | 160 | // Parameter is the millisecond rate the caller wishes collision events to occur. |
161 | public override void SubscribeEvents(int ms) { | 161 | public override void SubscribeEvents(int ms) { |
162 | DetailLog("{0},BSScene.SubscribeEvents,subscribing,ms={1}", BSScene.DetailLogZero, ms); | ||
162 | SubscribedEventsMs = ms; | 163 | SubscribedEventsMs = ms; |
163 | if (ms > 0) | 164 | if (ms > 0) |
164 | { | 165 | { |
@@ -167,7 +168,7 @@ public abstract class BSPhysObject : PhysicsActor | |||
167 | 168 | ||
168 | PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate() | 169 | PhysicsScene.TaintedObject(TypeName+".SubscribeEvents", delegate() |
169 | { | 170 | { |
170 | CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); | 171 | CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); |
171 | }); | 172 | }); |
172 | } | 173 | } |
173 | else | 174 | else |
@@ -177,10 +178,11 @@ public abstract class BSPhysObject : PhysicsActor | |||
177 | } | 178 | } |
178 | } | 179 | } |
179 | public override void UnSubscribeEvents() { | 180 | public override void UnSubscribeEvents() { |
181 | DetailLog("{0},BSScene.UnSubscribeEvents,unsubscribing", BSScene.DetailLogZero); | ||
180 | SubscribedEventsMs = 0; | 182 | SubscribedEventsMs = 0; |
181 | PhysicsScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate() | 183 | PhysicsScene.TaintedObject(TypeName+".UnSubscribeEvents", delegate() |
182 | { | 184 | { |
183 | CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); | 185 | CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); |
184 | }); | 186 | }); |
185 | } | 187 | } |
186 | // Return 'true' if the simulator wants collision events | 188 | // Return 'true' if the simulator wants collision events |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index b764379..5be2b1b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -24,6 +24,11 @@ | |||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | |||
28 | // Uncomment this it enable code to do all shape an body memory management | ||
29 | // in the C# code. | ||
30 | #define CSHARP_BODY_MANAGEMENT | ||
31 | |||
27 | using System; | 32 | using System; |
28 | using System.Reflection; | 33 | using System.Reflection; |
29 | using System.Collections.Generic; | 34 | using System.Collections.Generic; |
@@ -36,6 +41,7 @@ using OpenSim.Region.Physics.ConvexDecompositionDotNet; | |||
36 | 41 | ||
37 | namespace OpenSim.Region.Physics.BulletSPlugin | 42 | namespace OpenSim.Region.Physics.BulletSPlugin |
38 | { | 43 | { |
44 | |||
39 | [Serializable] | 45 | [Serializable] |
40 | public sealed class BSPrim : BSPhysObject | 46 | public sealed class BSPrim : BSPhysObject |
41 | { | 47 | { |
@@ -126,7 +132,7 @@ public sealed class BSPrim : BSPhysObject | |||
126 | { | 132 | { |
127 | CreateGeomAndObject(true); | 133 | CreateGeomAndObject(true); |
128 | 134 | ||
129 | CurrentCollisionFlags = BulletSimAPI.GetCollisionFlags2(BSBody.Ptr); | 135 | CurrentCollisionFlags = BulletSimAPI.GetCollisionFlags2(BSBody.ptr); |
130 | }); | 136 | }); |
131 | } | 137 | } |
132 | 138 | ||
@@ -246,10 +252,10 @@ public sealed class BSPrim : BSPhysObject | |||
246 | _rotationalVelocity = OMV.Vector3.Zero; | 252 | _rotationalVelocity = OMV.Vector3.Zero; |
247 | 253 | ||
248 | // Zero some other properties directly into the physics engine | 254 | // Zero some other properties directly into the physics engine |
249 | BulletSimAPI.SetLinearVelocity2(BSBody.Ptr, OMV.Vector3.Zero); | 255 | BulletSimAPI.SetLinearVelocity2(BSBody.ptr, OMV.Vector3.Zero); |
250 | BulletSimAPI.SetAngularVelocity2(BSBody.Ptr, OMV.Vector3.Zero); | 256 | BulletSimAPI.SetAngularVelocity2(BSBody.ptr, OMV.Vector3.Zero); |
251 | BulletSimAPI.SetInterpolationVelocity2(BSBody.Ptr, OMV.Vector3.Zero, OMV.Vector3.Zero); | 257 | BulletSimAPI.SetInterpolationVelocity2(BSBody.ptr, OMV.Vector3.Zero, OMV.Vector3.Zero); |
252 | BulletSimAPI.ClearForces2(BSBody.Ptr); | 258 | BulletSimAPI.ClearForces2(BSBody.ptr); |
253 | } | 259 | } |
254 | 260 | ||
255 | public override void LockAngularMotion(OMV.Vector3 axis) | 261 | public override void LockAngularMotion(OMV.Vector3 axis) |
@@ -262,7 +268,7 @@ public sealed class BSPrim : BSPhysObject | |||
262 | get { | 268 | get { |
263 | if (!Linkset.IsRoot(this)) | 269 | if (!Linkset.IsRoot(this)) |
264 | // child prims move around based on their parent. Need to get the latest location | 270 | // child prims move around based on their parent. Need to get the latest location |
265 | _position = BulletSimAPI.GetPosition2(BSBody.Ptr); | 271 | _position = BulletSimAPI.GetPosition2(BSBody.ptr); |
266 | 272 | ||
267 | // don't do the GetObjectPosition for root elements because this function is called a zillion times | 273 | // don't do the GetObjectPosition for root elements because this function is called a zillion times |
268 | // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, LocalID); | 274 | // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, LocalID); |
@@ -274,7 +280,7 @@ public sealed class BSPrim : BSPhysObject | |||
274 | PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() | 280 | PhysicsScene.TaintedObject("BSPrim.setPosition", delegate() |
275 | { | 281 | { |
276 | DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); | 282 | DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); |
277 | BulletSimAPI.SetTranslation2(BSBody.Ptr, _position, _orientation); | 283 | BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); |
278 | }); | 284 | }); |
279 | } | 285 | } |
280 | } | 286 | } |
@@ -312,7 +318,7 @@ public sealed class BSPrim : BSPhysObject | |||
312 | PhysicsScene.TaintedObject("BSPrim.setForce", delegate() | 318 | PhysicsScene.TaintedObject("BSPrim.setForce", delegate() |
313 | { | 319 | { |
314 | DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force); | 320 | DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force); |
315 | BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force); | 321 | BulletSimAPI.SetObjectForce2(BSBody.ptr, _force); |
316 | }); | 322 | }); |
317 | } | 323 | } |
318 | } | 324 | } |
@@ -374,12 +380,15 @@ public sealed class BSPrim : BSPhysObject | |||
374 | // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more | 380 | // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more |
375 | public override void SetVolumeDetect(int param) { | 381 | public override void SetVolumeDetect(int param) { |
376 | bool newValue = (param != 0); | 382 | bool newValue = (param != 0); |
377 | _isVolumeDetect = newValue; | 383 | if (_isVolumeDetect != newValue) |
378 | PhysicsScene.TaintedObject("BSPrim.SetVolumeDetect", delegate() | ||
379 | { | 384 | { |
380 | DetailLog("{0},setVolumeDetect,taint,volDetect={1}", LocalID, _isVolumeDetect); | 385 | _isVolumeDetect = newValue; |
381 | SetObjectDynamic(true); | 386 | PhysicsScene.TaintedObject("BSPrim.SetVolumeDetect", delegate() |
382 | }); | 387 | { |
388 | DetailLog("{0},setVolumeDetect,taint,volDetect={1}", LocalID, _isVolumeDetect); | ||
389 | SetObjectDynamic(true); | ||
390 | }); | ||
391 | } | ||
383 | return; | 392 | return; |
384 | } | 393 | } |
385 | 394 | ||
@@ -390,7 +399,7 @@ public sealed class BSPrim : BSPhysObject | |||
390 | PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate() | 399 | PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate() |
391 | { | 400 | { |
392 | DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); | 401 | DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); |
393 | BulletSimAPI.SetLinearVelocity2(BSBody.Ptr, _velocity); | 402 | BulletSimAPI.SetLinearVelocity2(BSBody.ptr, _velocity); |
394 | }); | 403 | }); |
395 | } | 404 | } |
396 | } | 405 | } |
@@ -414,7 +423,7 @@ public sealed class BSPrim : BSPhysObject | |||
414 | if (!Linkset.IsRoot(this)) | 423 | if (!Linkset.IsRoot(this)) |
415 | { | 424 | { |
416 | // Children move around because tied to parent. Get a fresh value. | 425 | // Children move around because tied to parent. Get a fresh value. |
417 | _orientation = BulletSimAPI.GetOrientation2(BSBody.Ptr); | 426 | _orientation = BulletSimAPI.GetOrientation2(BSBody.ptr); |
418 | } | 427 | } |
419 | return _orientation; | 428 | return _orientation; |
420 | } | 429 | } |
@@ -425,7 +434,7 @@ public sealed class BSPrim : BSPhysObject | |||
425 | { | 434 | { |
426 | // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, LocalID); | 435 | // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, LocalID); |
427 | DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); | 436 | DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); |
428 | BulletSimAPI.SetTranslation2(BSBody.Ptr, _position, _orientation); | 437 | BulletSimAPI.SetTranslation2(BSBody.ptr, _position, _orientation); |
429 | }); | 438 | }); |
430 | } | 439 | } |
431 | } | 440 | } |
@@ -436,12 +445,15 @@ public sealed class BSPrim : BSPhysObject | |||
436 | public override bool IsPhysical { | 445 | public override bool IsPhysical { |
437 | get { return _isPhysical; } | 446 | get { return _isPhysical; } |
438 | set { | 447 | set { |
439 | _isPhysical = value; | 448 | if (_isPhysical != value) |
440 | PhysicsScene.TaintedObject("BSPrim.setIsPhysical", delegate() | ||
441 | { | 449 | { |
442 | DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical); | 450 | _isPhysical = value; |
443 | SetObjectDynamic(true); | 451 | PhysicsScene.TaintedObject("BSPrim.setIsPhysical", delegate() |
444 | }); | 452 | { |
453 | DetailLog("{0},setIsPhysical,taint,isPhys={1}", LocalID, _isPhysical); | ||
454 | SetObjectDynamic(true); | ||
455 | }); | ||
456 | } | ||
445 | } | 457 | } |
446 | } | 458 | } |
447 | 459 | ||
@@ -458,7 +470,7 @@ public sealed class BSPrim : BSPhysObject | |||
458 | } | 470 | } |
459 | 471 | ||
460 | // Make gravity work if the object is physical and not selected | 472 | // Make gravity work if the object is physical and not selected |
461 | // No locking here because only called when it is safe | 473 | // No locking here because only called when it is safe (called at taint-time). |
462 | // There are four flags we're interested in: | 474 | // There are four flags we're interested in: |
463 | // IsStatic: Object does not move, otherwise the object has mass and moves | 475 | // IsStatic: Object does not move, otherwise the object has mass and moves |
464 | // isSolid: other objects bounce off of this object | 476 | // isSolid: other objects bounce off of this object |
@@ -481,11 +493,13 @@ public sealed class BSPrim : BSPhysObject | |||
481 | DetailLog("{0},BSPrim.UpdatePhysicalParameters,entry,body={1},shape={2}", LocalID, BSBody, BSShape); | 493 | DetailLog("{0},BSPrim.UpdatePhysicalParameters,entry,body={1},shape={2}", LocalID, BSBody, BSShape); |
482 | 494 | ||
483 | // Mangling all the physical properties requires the object to be out of the physical world | 495 | // Mangling all the physical properties requires the object to be out of the physical world |
484 | BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.Ptr, BSBody.Ptr); | 496 | BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, BSBody.ptr); |
485 | 497 | ||
498 | #if !CSHARP_BODY_MANAGEMENT | ||
486 | // Make solid or not (do things bounce off or pass through this object) | 499 | // Make solid or not (do things bounce off or pass through this object) |
487 | // This is done first because it can change the collisionObject type. | 500 | // This is done first because it can change the collisionObject type. |
488 | MakeSolid(IsSolid); | 501 | MakeSolid(IsSolid); |
502 | #endif // !CSHARP_BODY_MANAGEMENT | ||
489 | 503 | ||
490 | // Set up the object physicalness (does gravity and collisions move this object) | 504 | // Set up the object physicalness (does gravity and collisions move this object) |
491 | MakeDynamic(IsStatic); | 505 | MakeDynamic(IsStatic); |
@@ -493,15 +507,23 @@ public sealed class BSPrim : BSPhysObject | |||
493 | // Arrange for collisions events if the simulator wants them | 507 | // Arrange for collisions events if the simulator wants them |
494 | EnableCollisions(SubscribedEvents()); | 508 | EnableCollisions(SubscribedEvents()); |
495 | 509 | ||
496 | BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.Ptr, BSBody.Ptr); | 510 | #if CSHARP_BODY_MANAGEMENT |
511 | // Make solid or not (do things bounce off or pass through this object). | ||
512 | MakeSolid(IsSolid); | ||
513 | #endif // CSHARP_BODY_MANAGEMENT | ||
514 | |||
515 | BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, BSBody.ptr); | ||
516 | |||
517 | // Rebuild its shape | ||
518 | BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, BSBody.ptr); | ||
497 | 519 | ||
498 | // Recompute any linkset parameters. | 520 | // Recompute any linkset parameters. |
499 | // When going from non-physical to physical, this re-enables the constraints that | 521 | // When going from non-physical to physical, this re-enables the constraints that |
500 | // had been automatically disabled when the mass was set to zero. | 522 | // had been automatically disabled when the mass was set to zero. |
501 | Linkset.Refresh(this); | 523 | Linkset.Refresh(this); |
502 | 524 | ||
503 | DetailLog("{0},BSPrim.UpdatePhysicalParameters,taint,static={1},solid={2},mass={3},collide={4},cf={5}", | 525 | DetailLog("{0},BSPrim.UpdatePhysicalParameters,exit,static={1},solid={2},mass={3},collide={4},cf={5:X},body={6},shape={7}", |
504 | LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags); | 526 | LocalID, IsStatic, IsSolid, _mass, SubscribedEvents(), CurrentCollisionFlags, BSBody, BSShape); |
505 | } | 527 | } |
506 | 528 | ||
507 | // "Making dynamic" means changing to and from static. | 529 | // "Making dynamic" means changing to and from static. |
@@ -514,52 +536,52 @@ public sealed class BSPrim : BSPhysObject | |||
514 | if (makeStatic) | 536 | if (makeStatic) |
515 | { | 537 | { |
516 | // Become a Bullet 'static' object type | 538 | // Become a Bullet 'static' object type |
517 | CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT); | 539 | CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.CF_STATIC_OBJECT); |
518 | // Stop all movement | 540 | // Stop all movement |
519 | BulletSimAPI.ClearAllForces2(BSBody.Ptr); | 541 | BulletSimAPI.ClearAllForces2(BSBody.ptr); |
520 | // Center of mass is at the center of the object | 542 | // Center of mass is at the center of the object |
521 | BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.BSBody.Ptr, _position, _orientation); | 543 | BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.BSBody.ptr, _position, _orientation); |
522 | // Mass is zero which disables a bunch of physics stuff in Bullet | 544 | // Mass is zero which disables a bunch of physics stuff in Bullet |
523 | BulletSimAPI.SetMassProps2(BSBody.Ptr, 0f, OMV.Vector3.Zero); | 545 | BulletSimAPI.SetMassProps2(BSBody.ptr, 0f, OMV.Vector3.Zero); |
524 | // There is no inertia in a static object | 546 | // There is no inertia in a static object |
525 | BulletSimAPI.UpdateInertiaTensor2(BSBody.Ptr); | 547 | BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); |
526 | // There can be special things needed for implementing linksets | 548 | // There can be special things needed for implementing linksets |
527 | Linkset.MakeStatic(this); | 549 | Linkset.MakeStatic(this); |
528 | // The activation state is 'sleeping' so Bullet will not try to act on it | 550 | // The activation state is 'sleeping' so Bullet will not try to act on it |
529 | BulletSimAPI.ForceActivationState2(BSBody.Ptr, ActivationState.ISLAND_SLEEPING); | 551 | BulletSimAPI.ForceActivationState2(BSBody.ptr, ActivationState.ISLAND_SLEEPING); |
530 | // BulletSimAPI.ForceActivationState2(BSBody.Ptr, ActivationState.DISABLE_SIMULATION); | 552 | // BulletSimAPI.ForceActivationState2(BSBody.Ptr, ActivationState.DISABLE_SIMULATION); |
531 | } | 553 | } |
532 | else | 554 | else |
533 | { | 555 | { |
534 | // Not a Bullet static object | 556 | // Not a Bullet static object |
535 | CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT); | 557 | CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.ptr, CollisionFlags.CF_STATIC_OBJECT); |
536 | 558 | ||
537 | // Set various physical properties so internal dynamic properties will get computed correctly as they are set | 559 | // Set various physical properties so internal dynamic properties will get computed correctly as they are set |
538 | BulletSimAPI.SetFriction2(BSBody.Ptr, PhysicsScene.Params.defaultFriction); | 560 | BulletSimAPI.SetFriction2(BSBody.ptr, PhysicsScene.Params.defaultFriction); |
539 | BulletSimAPI.SetRestitution2(BSBody.Ptr, PhysicsScene.Params.defaultRestitution); | 561 | BulletSimAPI.SetRestitution2(BSBody.ptr, PhysicsScene.Params.defaultRestitution); |
540 | // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382 | 562 | // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382 |
541 | BulletSimAPI.SetInterpolationLinearVelocity2(BSBody.Ptr, OMV.Vector3.Zero); | 563 | BulletSimAPI.SetInterpolationLinearVelocity2(BSBody.ptr, OMV.Vector3.Zero); |
542 | BulletSimAPI.SetInterpolationAngularVelocity2(BSBody.Ptr, OMV.Vector3.Zero); | 564 | BulletSimAPI.SetInterpolationAngularVelocity2(BSBody.ptr, OMV.Vector3.Zero); |
543 | BulletSimAPI.SetInterpolationVelocity2(BSBody.Ptr, OMV.Vector3.Zero, OMV.Vector3.Zero); | 565 | BulletSimAPI.SetInterpolationVelocity2(BSBody.ptr, OMV.Vector3.Zero, OMV.Vector3.Zero); |
544 | 566 | ||
545 | // A dynamic object has mass | 567 | // A dynamic object has mass |
546 | IntPtr collisionShapePtr = BulletSimAPI.GetCollisionShape2(BSBody.Ptr); | 568 | IntPtr collisionShapePtr = BulletSimAPI.GetCollisionShape2(BSBody.ptr); |
547 | OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, Linkset.LinksetMass); | 569 | OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, Linkset.LinksetMass); |
548 | BulletSimAPI.SetMassProps2(BSBody.Ptr, _mass, inertia); | 570 | BulletSimAPI.SetMassProps2(BSBody.ptr, _mass, inertia); |
549 | // Inertia is based on our new mass | 571 | // Inertia is based on our new mass |
550 | BulletSimAPI.UpdateInertiaTensor2(BSBody.Ptr); | 572 | BulletSimAPI.UpdateInertiaTensor2(BSBody.ptr); |
551 | 573 | ||
552 | // Various values for simulation limits | 574 | // Various values for simulation limits |
553 | BulletSimAPI.SetDamping2(BSBody.Ptr, PhysicsScene.Params.linearDamping, PhysicsScene.Params.angularDamping); | 575 | BulletSimAPI.SetDamping2(BSBody.ptr, PhysicsScene.Params.linearDamping, PhysicsScene.Params.angularDamping); |
554 | BulletSimAPI.SetDeactivationTime2(BSBody.Ptr, PhysicsScene.Params.deactivationTime); | 576 | BulletSimAPI.SetDeactivationTime2(BSBody.ptr, PhysicsScene.Params.deactivationTime); |
555 | BulletSimAPI.SetSleepingThresholds2(BSBody.Ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); | 577 | BulletSimAPI.SetSleepingThresholds2(BSBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); |
556 | BulletSimAPI.SetContactProcessingThreshold2(BSBody.Ptr, PhysicsScene.Params.contactProcessingThreshold); | 578 | BulletSimAPI.SetContactProcessingThreshold2(BSBody.ptr, PhysicsScene.Params.contactProcessingThreshold); |
557 | 579 | ||
558 | // There can be special things needed for implementing linksets | 580 | // There can be special things needed for implementing linksets |
559 | Linkset.MakeDynamic(this); | 581 | Linkset.MakeDynamic(this); |
560 | 582 | ||
561 | // Force activation of the object so Bullet will act on it. | 583 | // Force activation of the object so Bullet will act on it. |
562 | BulletSimAPI.Activate2(BSBody.Ptr, true); | 584 | BulletSimAPI.Activate2(BSBody.ptr, true); |
563 | } | 585 | } |
564 | } | 586 | } |
565 | 587 | ||
@@ -569,8 +591,28 @@ public sealed class BSPrim : BSPhysObject | |||
569 | // the functions after this one set up the state of a possibly newly created collision body. | 591 | // the functions after this one set up the state of a possibly newly created collision body. |
570 | private void MakeSolid(bool makeSolid) | 592 | private void MakeSolid(bool makeSolid) |
571 | { | 593 | { |
572 | #if !CSHARP_BODY_MANAGEMENT | 594 | #if CSHARP_BODY_MANAGEMENT |
573 | CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(BSBody.Ptr); | 595 | CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(BSBody.ptr); |
596 | if (makeSolid) | ||
597 | { | ||
598 | // Verify the previous code created the correct shape for this type of thing. | ||
599 | if ((bodyType & CollisionObjectTypes.CO_RIGID_BODY) == 0) | ||
600 | { | ||
601 | m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for solidity. id={1}, type={2}", LogHeader, LocalID, bodyType); | ||
602 | } | ||
603 | CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); | ||
604 | } | ||
605 | else | ||
606 | { | ||
607 | if ((bodyType & CollisionObjectTypes.CO_GHOST_OBJECT) == 0) | ||
608 | { | ||
609 | m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType); | ||
610 | } | ||
611 | CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); | ||
612 | } | ||
613 | #else | ||
614 | // If doing the body management in C#, all this logic is in CSShapeCollection.CreateObject(). | ||
615 | CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(BSBody.ptr); | ||
574 | if (makeSolid) | 616 | if (makeSolid) |
575 | { | 617 | { |
576 | if ((bodyType & CollisionObjectTypes.CO_RIGID_BODY) == 0) | 618 | if ((bodyType & CollisionObjectTypes.CO_RIGID_BODY) == 0) |
@@ -618,11 +660,11 @@ public sealed class BSPrim : BSPhysObject | |||
618 | { | 660 | { |
619 | if (wantsCollisionEvents) | 661 | if (wantsCollisionEvents) |
620 | { | 662 | { |
621 | CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); | 663 | CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); |
622 | } | 664 | } |
623 | else | 665 | else |
624 | { | 666 | { |
625 | CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); | 667 | CurrentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); |
626 | } | 668 | } |
627 | } | 669 | } |
628 | 670 | ||
@@ -683,7 +725,7 @@ public sealed class BSPrim : BSPhysObject | |||
683 | PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate() | 725 | PhysicsScene.TaintedObject("BSPrim.setRotationalVelocity", delegate() |
684 | { | 726 | { |
685 | DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); | 727 | DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); |
686 | BulletSimAPI.SetAngularVelocity2(BSBody.Ptr, _rotationalVelocity); | 728 | BulletSimAPI.SetAngularVelocity2(BSBody.ptr, _rotationalVelocity); |
687 | }); | 729 | }); |
688 | } | 730 | } |
689 | } | 731 | } |
@@ -702,7 +744,7 @@ public sealed class BSPrim : BSPhysObject | |||
702 | DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy); | 744 | DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy); |
703 | // Buoyancy is faked by changing the gravity applied to the object | 745 | // Buoyancy is faked by changing the gravity applied to the object |
704 | float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); | 746 | float grav = PhysicsScene.Params.gravity * (1f - _buoyancy); |
705 | BulletSimAPI.SetGravity2(BSBody.Ptr, new OMV.Vector3(0f, 0f, grav)); | 747 | BulletSimAPI.SetGravity2(BSBody.ptr, new OMV.Vector3(0f, 0f, grav)); |
706 | // BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy); | 748 | // BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy); |
707 | }); | 749 | }); |
708 | } | 750 | } |
@@ -767,7 +809,7 @@ public sealed class BSPrim : BSPhysObject | |||
767 | } | 809 | } |
768 | DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, fSum); | 810 | DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, fSum); |
769 | // For unknown reasons, "ApplyCentralForce" adds this force to the total force on the object. | 811 | // For unknown reasons, "ApplyCentralForce" adds this force to the total force on the object. |
770 | BulletSimAPI.ApplyCentralForce2(BSBody.Ptr, fSum); | 812 | BulletSimAPI.ApplyCentralForce2(BSBody.ptr, fSum); |
771 | }); | 813 | }); |
772 | } | 814 | } |
773 | 815 | ||
@@ -1394,7 +1436,7 @@ public sealed class BSPrim : BSPhysObject | |||
1394 | } | 1436 | } |
1395 | // Rebuild the geometry and object. | 1437 | // Rebuild the geometry and object. |
1396 | // This is called when the shape changes so we need to recreate the mesh/hull. | 1438 | // This is called when the shape changes so we need to recreate the mesh/hull. |
1397 | // No locking here because this is done when the physics engine is not simulating | 1439 | // No locking here because this is done when the physics engine is not simulating (taint-time). |
1398 | private void CreateGeomAndObject(bool forceRebuild) | 1440 | private void CreateGeomAndObject(bool forceRebuild) |
1399 | { | 1441 | { |
1400 | #if CSHARP_BODY_MANAGEMENT | 1442 | #if CSHARP_BODY_MANAGEMENT |
@@ -1403,11 +1445,10 @@ public sealed class BSPrim : BSPhysObject | |||
1403 | 1445 | ||
1404 | // Create the correct physical representation for this type of object. | 1446 | // Create the correct physical representation for this type of object. |
1405 | // Updates BSBody and BSShape with the new information. | 1447 | // Updates BSBody and BSShape with the new information. |
1406 | if (PhysicsScene.Shapes.GetBodyAndShape(forceRebuild, PhysicsScene.World, this, shapeData, _pbs)) | 1448 | PhysicsScene.Shapes.GetBodyAndShape(forceRebuild, PhysicsScene.World, this, shapeData, _pbs); |
1407 | { | 1449 | |
1408 | // Make sure the properties are set on the new object | 1450 | // Make sure the properties are set on the new object |
1409 | UpdatePhysicalParameters(); | 1451 | UpdatePhysicalParameters(); |
1410 | } | ||
1411 | #else | 1452 | #else |
1412 | // m_log.DebugFormat("{0}: CreateGeomAndObject. lID={1}, force={2}", LogHeader, LocalID, forceRebuild); | 1453 | // m_log.DebugFormat("{0}: CreateGeomAndObject. lID={1}, force={2}", LogHeader, LocalID, forceRebuild); |
1413 | // Create the geometry that will make up the object | 1454 | // Create the geometry that will make up the object |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 76da42d..87c7b1b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -589,6 +589,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
589 | { | 589 | { |
590 | if (localID <= TerrainManager.HighestTerrainID) | 590 | if (localID <= TerrainManager.HighestTerrainID) |
591 | { | 591 | { |
592 | DetailLog("{0},BSScene.SendCollision,collideWithTerrain,id={1},with={2}", DetailLogZero, localID, collidingWith); | ||
592 | return; // don't send collisions to the terrain | 593 | return; // don't send collisions to the terrain |
593 | } | 594 | } |
594 | 595 | ||
@@ -596,6 +597,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
596 | if (!PhysObjects.TryGetValue(localID, out collider)) | 597 | if (!PhysObjects.TryGetValue(localID, out collider)) |
597 | { | 598 | { |
598 | // If the object that is colliding cannot be found, just ignore the collision. | 599 | // If the object that is colliding cannot be found, just ignore the collision. |
600 | DetailLog("{0},BSScene.SendCollision,colliderNotInObjectList,id={1},with={2}", DetailLogZero, localID, collidingWith); | ||
599 | return; | 601 | return; |
600 | } | 602 | } |
601 | 603 | ||
@@ -604,7 +606,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
604 | BSPhysObject collidee = null; | 606 | BSPhysObject collidee = null; |
605 | PhysObjects.TryGetValue(collidingWith, out collidee); | 607 | PhysObjects.TryGetValue(collidingWith, out collidee); |
606 | 608 | ||
607 | // DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith); | 609 | DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith); |
608 | 610 | ||
609 | if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration)) | 611 | if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration)) |
610 | { | 612 | { |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 7470d23..6b90661 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | |||
@@ -38,8 +38,9 @@ public class BSShapeCollection : IDisposable | |||
38 | { | 38 | { |
39 | protected BSScene PhysicsScene { get; set; } | 39 | protected BSScene PhysicsScene { get; set; } |
40 | 40 | ||
41 | private Object m_shapeActivityLock = new Object(); | 41 | private Object m_collectionActivityLock = new Object(); |
42 | 42 | ||
43 | // Description of a Mesh | ||
43 | private struct MeshDesc | 44 | private struct MeshDesc |
44 | { | 45 | { |
45 | public IntPtr Ptr; | 46 | public IntPtr Ptr; |
@@ -48,6 +49,8 @@ public class BSShapeCollection : IDisposable | |||
48 | public IMesh meshData; | 49 | public IMesh meshData; |
49 | } | 50 | } |
50 | 51 | ||
52 | // Description of a hull. | ||
53 | // Meshes and hulls have the same shape hash key but we only need hulls for efficient physical objects | ||
51 | private struct HullDesc | 54 | private struct HullDesc |
52 | { | 55 | { |
53 | public IntPtr Ptr; | 56 | public IntPtr Ptr; |
@@ -55,8 +58,17 @@ public class BSShapeCollection : IDisposable | |||
55 | public DateTime lastReferenced; | 58 | public DateTime lastReferenced; |
56 | } | 59 | } |
57 | 60 | ||
61 | private struct BodyDesc | ||
62 | { | ||
63 | public IntPtr Ptr; | ||
64 | // Bodies are only used once so reference count is always either one or zero | ||
65 | public int referenceCount; | ||
66 | public DateTime lastReferenced; | ||
67 | } | ||
68 | |||
58 | private Dictionary<ulong, MeshDesc> Meshes = new Dictionary<ulong, MeshDesc>(); | 69 | private Dictionary<ulong, MeshDesc> Meshes = new Dictionary<ulong, MeshDesc>(); |
59 | private Dictionary<ulong, HullDesc> Hulls = new Dictionary<ulong, HullDesc>(); | 70 | private Dictionary<ulong, HullDesc> Hulls = new Dictionary<ulong, HullDesc>(); |
71 | private Dictionary<uint, BodyDesc> Bodies = new Dictionary<uint, BodyDesc>(); | ||
60 | 72 | ||
61 | public BSShapeCollection(BSScene physScene) | 73 | public BSShapeCollection(BSScene physScene) |
62 | { | 74 | { |
@@ -65,6 +77,7 @@ public class BSShapeCollection : IDisposable | |||
65 | 77 | ||
66 | public void Dispose() | 78 | public void Dispose() |
67 | { | 79 | { |
80 | // TODO!!!!!!!!! | ||
68 | } | 81 | } |
69 | 82 | ||
70 | // Called to update/change the body and shape for an object. | 83 | // Called to update/change the body and shape for an object. |
@@ -76,40 +89,104 @@ public class BSShapeCollection : IDisposable | |||
76 | { | 89 | { |
77 | bool ret = false; | 90 | bool ret = false; |
78 | 91 | ||
79 | // Do we have the correct geometry for this type of object? | 92 | // This lock could probably be pushed down lower but building shouldn't take long |
80 | if (CreateGeom(forceRebuild, prim, shapeData, pbs)) | 93 | lock (m_collectionActivityLock) |
81 | { | 94 | { |
95 | // Do we have the correct geometry for this type of object? | ||
96 | bool newGeom = CreateGeom(forceRebuild, prim, shapeData, pbs); | ||
82 | // If we had to select a new shape geometry for the object, | 97 | // If we had to select a new shape geometry for the object, |
83 | // rebuild the body around it. | 98 | // rebuild the body around it. |
84 | CreateObject(true, prim, PhysicsScene.World, prim.BSShape, shapeData); | 99 | bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World, prim.BSShape, shapeData); |
85 | ret = true; | 100 | ret = newGeom || newBody; |
86 | } | 101 | } |
102 | DetailLog("{0},BSShapeCollection.GetBodyAndShape,force-{1},ret={2},body={3},shape={4}", | ||
103 | prim.LocalID, forceRebuild, ret, prim.BSBody, prim.BSShape); | ||
87 | 104 | ||
88 | return ret; | 105 | return ret; |
89 | } | 106 | } |
90 | 107 | ||
91 | // Track another user of a body | 108 | // Track another user of a body |
92 | public void ReferenceBody(BulletBody shape) | 109 | // We presume the caller has allocated the body. |
110 | // Bodies only have one user so the reference count is either 1 or 0. | ||
111 | public void ReferenceBody(BulletBody shape, bool atTaintTime) | ||
93 | { | 112 | { |
94 | } | 113 | lock (m_collectionActivityLock) |
114 | { | ||
115 | BodyDesc bodyDesc; | ||
116 | if (Bodies.TryGetValue(shape.ID, out bodyDesc)) | ||
117 | { | ||
118 | bodyDesc.referenceCount++; | ||
119 | DetailLog("{0},BSShapeCollection.ReferenceBody,existingBody,ref={1}", shape.ID, bodyDesc.referenceCount); | ||
120 | } | ||
121 | else | ||
122 | { | ||
123 | bodyDesc.Ptr = shape.ptr; | ||
124 | bodyDesc.referenceCount = 1; | ||
125 | DetailLog("{0},BSShapeCollection.ReferenceBody,newBody,ref={1}", shape.ID, bodyDesc.referenceCount); | ||
126 | } | ||
127 | bodyDesc.lastReferenced = System.DateTime.Now; | ||
128 | Bodies[shape.ID] = bodyDesc; | ||
129 | } | ||
130 | } | ||
95 | 131 | ||
96 | // Release the usage of a body | 132 | // Release the usage of a body. |
97 | public void DereferenceBody(BulletBody shape) | 133 | // Not that this will also delete the body in BUllet if the body is now unused (reference count = 0). |
134 | public void DereferenceBody(BulletBody shape, bool inTaintTime) | ||
98 | { | 135 | { |
136 | if (shape.ptr == IntPtr.Zero) | ||
137 | return; | ||
138 | |||
139 | lock (m_collectionActivityLock) | ||
140 | { | ||
141 | BodyDesc bodyDesc; | ||
142 | if (Bodies.TryGetValue(shape.ID, out bodyDesc)) | ||
143 | { | ||
144 | bodyDesc.referenceCount--; | ||
145 | bodyDesc.lastReferenced = System.DateTime.Now; | ||
146 | Bodies[shape.ID] = bodyDesc; | ||
147 | DetailLog("{0},BSShapeCollection.DereferenceBody,ref={1}", shape.ID, bodyDesc.referenceCount); | ||
148 | |||
149 | if (bodyDesc.referenceCount == 0) | ||
150 | { | ||
151 | Bodies.Remove(shape.ID); | ||
152 | BSScene.TaintCallback removeOperation = delegate() | ||
153 | { | ||
154 | DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody. Ptr={1:X}", shape.ID, shape.ptr); | ||
155 | // zero any reference to the shape so it is not freed when the body is deleted | ||
156 | BulletSimAPI.SetCollisionShape2(PhysicsScene.World.ptr, shape.ptr, IntPtr.Zero); | ||
157 | // It may have already been removed from the world in which case the next is a NOOP | ||
158 | BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, shape.ptr); | ||
159 | BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, shape.ptr); | ||
160 | }; | ||
161 | // If already in taint-time, do the operations now. Otherwise queue for later. | ||
162 | if (inTaintTime) | ||
163 | removeOperation(); | ||
164 | else | ||
165 | PhysicsScene.TaintedObject("BSShapeCollection.DereferenceBody", removeOperation); | ||
166 | } | ||
167 | } | ||
168 | else | ||
169 | { | ||
170 | DetailLog("{0},BSShapeCollection.DereferenceBody,DID NOT FIND BODY", shape.ID, bodyDesc.referenceCount); | ||
171 | } | ||
172 | } | ||
99 | } | 173 | } |
100 | 174 | ||
101 | // Track another user of the shape | 175 | // Track another user of the shape |
102 | public void ReferenceShape(BulletShape shape) | 176 | private bool ReferenceShape(BulletShape shape) |
103 | { | 177 | { |
104 | ReferenceShape(shape, null); | 178 | return ReferenceShape(shape, null); |
105 | } | 179 | } |
106 | 180 | ||
107 | // Track the datastructures and use count for a shape. | 181 | // Track the datastructures and use count for a shape. |
108 | // When creating a hull, this is called first to reference the mesh | 182 | // When creating a hull, this is called first to reference the mesh |
109 | // and then again to reference the hull. | 183 | // and then again to reference the hull. |
110 | // Meshes and hulls for the same shape have the same hash key. | 184 | // Meshes and hulls for the same shape have the same hash key. |
111 | private void ReferenceShape(BulletShape shape, IMesh meshData) | 185 | // NOTE that native shapes are not added to the mesh list or removed. |
186 | // Returns 'true' if this is the initial reference to the shape. Otherwise reused. | ||
187 | private bool ReferenceShape(BulletShape shape, IMesh meshData) | ||
112 | { | 188 | { |
189 | bool ret = false; | ||
113 | switch (shape.type) | 190 | switch (shape.type) |
114 | { | 191 | { |
115 | case ShapeData.PhysicsShapeType.SHAPE_MESH: | 192 | case ShapeData.PhysicsShapeType.SHAPE_MESH: |
@@ -118,14 +195,18 @@ public class BSShapeCollection : IDisposable | |||
118 | { | 195 | { |
119 | // There is an existing instance of this mesh. | 196 | // There is an existing instance of this mesh. |
120 | meshDesc.referenceCount++; | 197 | meshDesc.referenceCount++; |
198 | DetailLog("{0},BSShapeColliction.ReferenceShape,existingMesh,key={1},cnt={2}", | ||
199 | BSScene.DetailLogZero, shape.shapeKey, meshDesc.referenceCount); | ||
121 | } | 200 | } |
122 | else | 201 | else |
123 | { | 202 | { |
124 | // This is a new reference to a mesh | 203 | // This is a new reference to a mesh |
125 | meshDesc.Ptr = shape.Ptr; | 204 | meshDesc.Ptr = shape.ptr; |
126 | meshDesc.meshData = meshData; | 205 | meshDesc.meshData = meshData; |
127 | meshDesc.referenceCount = 1; | 206 | meshDesc.referenceCount = 1; |
128 | 207 | DetailLog("{0},BSShapeColliction.ReferenceShape,newMesh,key={1},cnt={2}", | |
208 | BSScene.DetailLogZero, shape.shapeKey, meshDesc.referenceCount); | ||
209 | ret = true; | ||
129 | } | 210 | } |
130 | meshDesc.lastReferenced = System.DateTime.Now; | 211 | meshDesc.lastReferenced = System.DateTime.Now; |
131 | Meshes[shape.shapeKey] = meshDesc; | 212 | Meshes[shape.shapeKey] = meshDesc; |
@@ -136,41 +217,68 @@ public class BSShapeCollection : IDisposable | |||
136 | { | 217 | { |
137 | // There is an existing instance of this mesh. | 218 | // There is an existing instance of this mesh. |
138 | hullDesc.referenceCount++; | 219 | hullDesc.referenceCount++; |
220 | DetailLog("{0},BSShapeColliction.ReferenceShape,existingHull,key={1},cnt={2}", | ||
221 | BSScene.DetailLogZero, shape.shapeKey, hullDesc.referenceCount); | ||
139 | } | 222 | } |
140 | else | 223 | else |
141 | { | 224 | { |
142 | // This is a new reference to a mesh | 225 | // This is a new reference to a hull |
143 | hullDesc.Ptr = shape.Ptr; | 226 | hullDesc.Ptr = shape.ptr; |
144 | hullDesc.referenceCount = 1; | 227 | hullDesc.referenceCount = 1; |
228 | DetailLog("{0},BSShapeColliction.ReferenceShape,newHull,key={1},cnt={2}", | ||
229 | BSScene.DetailLogZero, shape.shapeKey, hullDesc.referenceCount); | ||
230 | ret = true; | ||
145 | 231 | ||
146 | } | 232 | } |
147 | hullDesc.lastReferenced = System.DateTime.Now; | 233 | hullDesc.lastReferenced = System.DateTime.Now; |
148 | Hulls[shape.shapeKey] = hullDesc; | 234 | Hulls[shape.shapeKey] = hullDesc; |
149 | break; | 235 | break; |
236 | case ShapeData.PhysicsShapeType.SHAPE_UNKNOWN: | ||
237 | break; | ||
150 | default: | 238 | default: |
239 | // Native shapes are not tracked and they don't go into any list | ||
151 | break; | 240 | break; |
152 | } | 241 | } |
242 | return ret; | ||
153 | } | 243 | } |
154 | 244 | ||
155 | // Release the usage of a shape | 245 | // Release the usage of a shape |
156 | public void DereferenceShape(BulletShape shape) | 246 | private void DereferenceShape(BulletShape shape, bool atTaintTime) |
157 | { | 247 | { |
158 | switch (shape.type) | 248 | if (shape.ptr == IntPtr.Zero) |
249 | return; | ||
250 | |||
251 | BSScene.TaintCallback dereferenceOperation = delegate() | ||
159 | { | 252 | { |
160 | case ShapeData.PhysicsShapeType.SHAPE_HULL: | 253 | switch (shape.type) |
161 | DereferenceHull(shape); | 254 | { |
162 | // Hulls also include a mesh | 255 | case ShapeData.PhysicsShapeType.SHAPE_HULL: |
163 | DereferenceMesh(shape); | 256 | DereferenceHull(shape); |
164 | break; | 257 | // Hulls also include a mesh |
165 | case ShapeData.PhysicsShapeType.SHAPE_MESH: | 258 | DereferenceMesh(shape); |
166 | DereferenceMesh(shape); | 259 | break; |
167 | break; | 260 | case ShapeData.PhysicsShapeType.SHAPE_MESH: |
168 | default: | 261 | DereferenceMesh(shape); |
169 | break; | 262 | break; |
170 | } | 263 | case ShapeData.PhysicsShapeType.SHAPE_UNKNOWN: |
264 | break; | ||
265 | default: | ||
266 | // Native shapes are not tracked and are released immediately | ||
267 | if (shape.ptr != IntPtr.Zero & shape.isNativeShape) | ||
268 | { | ||
269 | BulletSimAPI.DeleteCollisionShape2(PhysicsScene.World.ptr, shape.ptr); | ||
270 | } | ||
271 | break; | ||
272 | } | ||
273 | }; | ||
274 | if (atTaintTime) | ||
275 | dereferenceOperation(); | ||
276 | else | ||
277 | PhysicsScene.TaintedObject("BSShapeCollection.DereferenceShape", dereferenceOperation); | ||
171 | } | 278 | } |
172 | 279 | ||
173 | // Count down the reference count for a mesh shape | 280 | // Count down the reference count for a mesh shape |
281 | // Called at taint-time. | ||
174 | private void DereferenceMesh(BulletShape shape) | 282 | private void DereferenceMesh(BulletShape shape) |
175 | { | 283 | { |
176 | MeshDesc meshDesc; | 284 | MeshDesc meshDesc; |
@@ -180,10 +288,14 @@ public class BSShapeCollection : IDisposable | |||
180 | // TODO: release the Bullet storage | 288 | // TODO: release the Bullet storage |
181 | meshDesc.lastReferenced = System.DateTime.Now; | 289 | meshDesc.lastReferenced = System.DateTime.Now; |
182 | Meshes[shape.shapeKey] = meshDesc; | 290 | Meshes[shape.shapeKey] = meshDesc; |
291 | DetailLog("{0},BSShapeColliction.DereferenceMesh,key={1},cnt={2}", | ||
292 | BSScene.DetailLogZero, shape.shapeKey, meshDesc.referenceCount); | ||
293 | |||
183 | } | 294 | } |
184 | } | 295 | } |
185 | 296 | ||
186 | // Count down the reference count for a hull shape | 297 | // Count down the reference count for a hull shape |
298 | // Called at taint-time. | ||
187 | private void DereferenceHull(BulletShape shape) | 299 | private void DereferenceHull(BulletShape shape) |
188 | { | 300 | { |
189 | HullDesc hullDesc; | 301 | HullDesc hullDesc; |
@@ -193,6 +305,8 @@ public class BSShapeCollection : IDisposable | |||
193 | // TODO: release the Bullet storage (aging old entries?) | 305 | // TODO: release the Bullet storage (aging old entries?) |
194 | hullDesc.lastReferenced = System.DateTime.Now; | 306 | hullDesc.lastReferenced = System.DateTime.Now; |
195 | Hulls[shape.shapeKey] = hullDesc; | 307 | Hulls[shape.shapeKey] = hullDesc; |
308 | DetailLog("{0},BSShapeColliction.DereferenceHull,key={1},cnt={2}", | ||
309 | BSScene.DetailLogZero, shape.shapeKey, hullDesc.referenceCount); | ||
196 | } | 310 | } |
197 | } | 311 | } |
198 | 312 | ||
@@ -210,10 +324,6 @@ public class BSShapeCollection : IDisposable | |||
210 | 324 | ||
211 | BulletShape newShape = new BulletShape(IntPtr.Zero); | 325 | BulletShape newShape = new BulletShape(IntPtr.Zero); |
212 | 326 | ||
213 | // If the object is dynamic, it must have a hull shape | ||
214 | if (prim.IsPhysical) | ||
215 | nativeShapePossible = false; | ||
216 | |||
217 | // If the prim attributes are simple, this could be a simple Bullet native shape | 327 | // If the prim attributes are simple, this could be a simple Bullet native shape |
218 | if (nativeShapePossible | 328 | if (nativeShapePossible |
219 | && ((pbs.SculptEntry && !PhysicsScene.ShouldMeshSculptedPrim) | 329 | && ((pbs.SculptEntry && !PhysicsScene.ShouldMeshSculptedPrim) |
@@ -230,8 +340,10 @@ public class BSShapeCollection : IDisposable | |||
230 | haveShape = true; | 340 | haveShape = true; |
231 | if (forceRebuild || (prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE)) | 341 | if (forceRebuild || (prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE)) |
232 | { | 342 | { |
233 | DetailLog("{0},BSShapeCollection.CreateGeom,sphere (force={1}", prim.LocalID, forceRebuild); | 343 | newShape = AddNativeShapeToPrim( |
234 | newShape = AddNativeShapeToPrim(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_SPHERE); | 344 | prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_SPHERE, ShapeData.FixedShapeKey.KEY_SPHERE); |
345 | DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", | ||
346 | prim.LocalID, forceRebuild,prim.BSShape); | ||
235 | 347 | ||
236 | ret = true; | 348 | ret = true; |
237 | } | 349 | } |
@@ -242,71 +354,87 @@ public class BSShapeCollection : IDisposable | |||
242 | haveShape = true; | 354 | haveShape = true; |
243 | if (forceRebuild || (prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX)) | 355 | if (forceRebuild || (prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX)) |
244 | { | 356 | { |
245 | DetailLog("{0},BSShapeCollection.CreateGeom,box (force={1})", prim.LocalID, forceRebuild); | 357 | newShape = AddNativeShapeToPrim( |
246 | newShape = AddNativeShapeToPrim(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_BOX); | 358 | prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_BOX, ShapeData.FixedShapeKey.KEY_BOX); |
359 | DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", | ||
360 | prim.LocalID, forceRebuild,prim.BSShape); | ||
247 | 361 | ||
248 | ret = true; | 362 | ret = true; |
249 | } | 363 | } |
250 | } | 364 | } |
251 | } | 365 | } |
252 | // If a simple shape isn't happening, create a mesh and possibly a hull | 366 | // If a simple shape is not happening, create a mesh and possibly a hull |
367 | // Note that if it's a native shape, the check for physical/non-physical is not | ||
368 | // made. Native shapes are best used in either case. | ||
253 | if (!haveShape) | 369 | if (!haveShape) |
254 | { | 370 | { |
255 | if (prim.IsPhysical) | 371 | if (prim.IsPhysical) |
256 | { | 372 | { |
257 | if (forceRebuild || !Hulls.ContainsKey(prim.BSShape.shapeKey)) | 373 | if (forceRebuild || !Hulls.ContainsKey(shapeData.HullKey)) |
258 | { | 374 | { |
259 | // physical objects require a hull for interaction. | 375 | // physical objects require a hull for interaction. |
260 | // This also creates the mesh if it doesn't already exist | 376 | // This also creates the mesh if it doesn't already exist. |
261 | ret = CreateGeomHull(prim, shapeData, pbs); | 377 | ret = CreateGeomHull(prim, shapeData, pbs); |
262 | } | 378 | } |
379 | else | ||
380 | { | ||
381 | prim.BSShape = new BulletShape(Hulls[shapeData.HullKey].Ptr, | ||
382 | ShapeData.PhysicsShapeType.SHAPE_HULL); | ||
383 | prim.BSShape.shapeKey = shapeData.HullKey; | ||
384 | // Another user of this shape. | ||
385 | ReferenceShape(prim.BSShape); | ||
386 | ret = true; | ||
387 | } | ||
263 | } | 388 | } |
264 | else | 389 | else |
265 | { | 390 | { |
266 | if (forceRebuild || !Meshes.ContainsKey(prim.BSShape.shapeKey)) | 391 | if (forceRebuild || !Meshes.ContainsKey(prim.BSShape.shapeKey)) |
267 | { | 392 | { |
268 | // Static (non-physical) objects only need a mesh for bumping into | 393 | // Static (non-physical) objects only need a mesh for bumping into |
394 | // Returning 'true' means prim.BShape was changed. | ||
269 | ret = CreateGeomMesh(prim, shapeData, pbs); | 395 | ret = CreateGeomMesh(prim, shapeData, pbs); |
270 | } | 396 | } |
397 | else | ||
398 | { | ||
399 | prim.BSShape = new BulletShape(Hulls[shapeData.MeshKey].Ptr, | ||
400 | ShapeData.PhysicsShapeType.SHAPE_MESH); | ||
401 | prim.BSShape.shapeKey = shapeData.MeshKey; | ||
402 | ReferenceShape(prim.BSShape); | ||
403 | ret = true; | ||
404 | } | ||
271 | } | 405 | } |
272 | } | 406 | } |
273 | return ret; | 407 | return ret; |
274 | } | 408 | } |
275 | 409 | ||
276 | private BulletShape AddNativeShapeToPrim(BSPrim prim, ShapeData shapeData, ShapeData.PhysicsShapeType shapeType) | 410 | // Creates a native shape and assignes it to prim.BSShape |
411 | private BulletShape AddNativeShapeToPrim( | ||
412 | BSPrim prim, ShapeData shapeData, ShapeData.PhysicsShapeType shapeType, | ||
413 | ShapeData.FixedShapeKey shapeKey) | ||
277 | { | 414 | { |
278 | BulletShape newShape; | 415 | BulletShape newShape; |
279 | 416 | ||
280 | // Bullet native objects are scaled by the Bullet engine so pass the size in | 417 | // Bullet native objects are scaled by the Bullet engine so pass the size in |
281 | prim.Scale = shapeData.Size; | 418 | prim.Scale = shapeData.Size; |
419 | shapeData.Type = shapeType; | ||
420 | shapeData.Scale = prim.Scale; | ||
282 | 421 | ||
283 | // release any previous shape | 422 | // release any previous shape |
284 | DereferenceShape(prim.BSShape); | 423 | DereferenceShape(prim.BSShape, true); |
424 | |||
425 | // Shape of this discriptioin is not allocated. Create new. | ||
426 | newShape = new BulletShape( | ||
427 | BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, shapeData), shapeType); | ||
428 | newShape.shapeKey = (ulong)shapeKey; | ||
429 | newShape.isNativeShape = true; | ||
430 | |||
431 | // Don't to a 'ReferenceShape()' here because native shapes are not tracked. | ||
285 | 432 | ||
286 | MeshDesc existingShapeDesc; | ||
287 | if (Meshes.TryGetValue(shapeData.MeshKey, out existingShapeDesc)) | ||
288 | { | ||
289 | // If there is an existing allocated shape, use it | ||
290 | newShape = new BulletShape(existingShapeDesc.Ptr, shapeType); | ||
291 | } | ||
292 | else | ||
293 | { | ||
294 | // Shape of this discriptioin is not allocated. Create new. | ||
295 | newShape = new BulletShape( | ||
296 | BulletSimAPI.BuildNativeShape2(PhysicsScene.World.Ptr, | ||
297 | (float)shapeType, | ||
298 | PhysicsScene.Params.collisionMargin, | ||
299 | prim.Scale), | ||
300 | shapeType); | ||
301 | } | ||
302 | newShape.shapeKey = shapeData.MeshKey; | ||
303 | ReferenceShape(newShape); | ||
304 | prim.BSShape = newShape; | 433 | prim.BSShape = newShape; |
305 | return newShape; | 434 | return newShape; |
306 | } | 435 | } |
307 | 436 | ||
308 | // No locking here because this is done when we know physics is not simulating | 437 | // Returns 'true' of a mesh was actually rebuild. |
309 | // Returns 'true' of a mesh was actually rebuild (we could also have one of these specs). | ||
310 | // Called at taint-time! | 438 | // Called at taint-time! |
311 | private bool CreateGeomMesh(BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs) | 439 | private bool CreateGeomMesh(BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs) |
312 | { | 440 | { |
@@ -322,7 +450,6 @@ public class BSShapeCollection : IDisposable | |||
322 | lod = PhysicsScene.MeshMegaPrimLOD; | 450 | lod = PhysicsScene.MeshMegaPrimLOD; |
323 | 451 | ||
324 | ulong newMeshKey = (ulong)pbs.GetMeshKey(shapeData.Size, lod); | 452 | ulong newMeshKey = (ulong)pbs.GetMeshKey(shapeData.Size, lod); |
325 | // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, LocalID, _meshKey, newMeshKey); | ||
326 | 453 | ||
327 | // if this new shape is the same as last time, don't recreate the mesh | 454 | // if this new shape is the same as last time, don't recreate the mesh |
328 | if (prim.BSShape.shapeKey == newMeshKey) return false; | 455 | if (prim.BSShape.shapeKey == newMeshKey) return false; |
@@ -330,7 +457,7 @@ public class BSShapeCollection : IDisposable | |||
330 | DetailLog("{0},BSShapeCollection.CreateGeomMesh,create,key={1}", prim.LocalID, newMeshKey); | 457 | DetailLog("{0},BSShapeCollection.CreateGeomMesh,create,key={1}", prim.LocalID, newMeshKey); |
331 | 458 | ||
332 | // Since we're recreating new, get rid of the reference to the previous shape | 459 | // Since we're recreating new, get rid of the reference to the previous shape |
333 | DereferenceShape(prim.BSShape); | 460 | DereferenceShape(prim.BSShape, true); |
334 | 461 | ||
335 | IMesh meshData = null; | 462 | IMesh meshData = null; |
336 | IntPtr meshPtr; | 463 | IntPtr meshPtr; |
@@ -360,7 +487,7 @@ public class BSShapeCollection : IDisposable | |||
360 | // m_log.DebugFormat("{0}: CreateGeomMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}", | 487 | // m_log.DebugFormat("{0}: CreateGeomMesh: calling CreateMesh. lid={1}, key={2}, indices={3}, vertices={4}", |
361 | // LogHeader, prim.LocalID, newMeshKey, indices.Length, vertices.Count); | 488 | // LogHeader, prim.LocalID, newMeshKey, indices.Length, vertices.Count); |
362 | 489 | ||
363 | meshPtr = BulletSimAPI.CreateMeshShape2(PhysicsScene.World.Ptr, | 490 | meshPtr = BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, |
364 | indices.GetLength(0), indices, vertices.Count, verticesAsFloats); | 491 | indices.GetLength(0), indices, vertices.Count, verticesAsFloats); |
365 | } | 492 | } |
366 | newShape = new BulletShape(meshPtr, ShapeData.PhysicsShapeType.SHAPE_MESH); | 493 | newShape = new BulletShape(meshPtr, ShapeData.PhysicsShapeType.SHAPE_MESH); |
@@ -374,26 +501,29 @@ public class BSShapeCollection : IDisposable | |||
374 | return true; // 'true' means a new shape has been added to this prim | 501 | return true; // 'true' means a new shape has been added to this prim |
375 | } | 502 | } |
376 | 503 | ||
377 | // No locking here because this is done when we know physics is not simulating | ||
378 | // Returns 'true' of a mesh was actually rebuild (we could also have one of these specs). | 504 | // Returns 'true' of a mesh was actually rebuild (we could also have one of these specs). |
379 | List<ConvexResult> m_hulls; | 505 | List<ConvexResult> m_hulls; |
380 | private bool CreateGeomHull(BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs) | 506 | private bool CreateGeomHull(BSPrim prim, ShapeData shapeData, PrimitiveBaseShape pbs) |
381 | { | 507 | { |
382 | BulletShape newShape; | 508 | BulletShape newShape; |
383 | 509 | ||
510 | // Level of detail for the mesh can be different for sculpties and regular meshes. | ||
384 | float lod = pbs.SculptEntry ? PhysicsScene.SculptLOD : PhysicsScene.MeshLOD; | 511 | float lod = pbs.SculptEntry ? PhysicsScene.SculptLOD : PhysicsScene.MeshLOD; |
512 | |||
385 | ulong newHullKey = (ulong)pbs.GetMeshKey(shapeData.Size, lod); | 513 | ulong newHullKey = (ulong)pbs.GetMeshKey(shapeData.Size, lod); |
386 | // m_log.DebugFormat("{0}: CreateGeomHull: lID={1}, oldKey={2}, newKey={3}", LogHeader, LocalID, _hullKey, newHullKey); | ||
387 | 514 | ||
388 | // if the hull hasn't changed, don't rebuild it | 515 | // if the hull hasn't changed, don't rebuild it |
389 | if (newHullKey == prim.BSShape.shapeKey) return false; | 516 | if (newHullKey == prim.BSShape.shapeKey) return false; |
390 | 517 | ||
391 | DetailLog("{0},BSShapeCollection.CreateGeomHull,create,oldKey={1},newKey={2}", prim.LocalID, newHullKey, newHullKey); | 518 | DetailLog("{0},BSShapeCollection.CreateGeomHull,create,oldKey={1},newKey={2}", prim.LocalID, newHullKey, newHullKey); |
392 | 519 | ||
393 | // remove references to any previous shape | 520 | // Remove references to the previous shape. Also removes reference to underlying mesh. |
394 | DereferenceShape(prim.BSShape); | 521 | DereferenceShape(prim.BSShape, true); |
395 | 522 | ||
396 | // Make sure the underlying mesh exists and is correct | 523 | // Do not let the mesh dereference itself again. Was done in the above DerefereceShape(). |
524 | prim.BSShape.type = ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; | ||
525 | |||
526 | // Make sure the underlying mesh exists and is correct. | ||
397 | // Since we're in the hull code, we know CreateGeomMesh() will not create a native shape. | 527 | // Since we're in the hull code, we know CreateGeomMesh() will not create a native shape. |
398 | CreateGeomMesh(prim, shapeData, pbs); | 528 | CreateGeomMesh(prim, shapeData, pbs); |
399 | MeshDesc meshDesc = Meshes[newHullKey]; | 529 | MeshDesc meshDesc = Meshes[newHullKey]; |
@@ -402,10 +532,12 @@ public class BSShapeCollection : IDisposable | |||
402 | HullDesc hullDesc; | 532 | HullDesc hullDesc; |
403 | if (Hulls.TryGetValue(newHullKey, out hullDesc)) | 533 | if (Hulls.TryGetValue(newHullKey, out hullDesc)) |
404 | { | 534 | { |
535 | // If the hull shape already is created, just use it. | ||
405 | hullPtr = hullDesc.Ptr; | 536 | hullPtr = hullDesc.Ptr; |
406 | } | 537 | } |
407 | else | 538 | else |
408 | { | 539 | { |
540 | // Build a new hull in the physical world | ||
409 | int[] indices = meshDesc.meshData.getIndexListAsInt(); | 541 | int[] indices = meshDesc.meshData.getIndexListAsInt(); |
410 | List<OMV.Vector3> vertices = meshDesc.meshData.getVertexList(); | 542 | List<OMV.Vector3> vertices = meshDesc.meshData.getVertexList(); |
411 | 543 | ||
@@ -485,63 +617,85 @@ public class BSShapeCollection : IDisposable | |||
485 | } | 617 | } |
486 | // create the hull data structure in Bullet | 618 | // create the hull data structure in Bullet |
487 | // m_log.DebugFormat("{0}: CreateGeom: calling CreateHull. lid={1}, key={2}, hulls={3}", LogHeader, LocalID, _hullKey, hullCount); | 619 | // m_log.DebugFormat("{0}: CreateGeom: calling CreateHull. lid={1}, key={2}, hulls={3}", LogHeader, LocalID, _hullKey, hullCount); |
488 | hullPtr = BulletSimAPI.CreateHullShape2(PhysicsScene.World.Ptr, hullCount, convHulls); | 620 | hullPtr = BulletSimAPI.CreateHullShape2(PhysicsScene.World.ptr, hullCount, convHulls); |
489 | } | 621 | } |
622 | |||
490 | newShape = new BulletShape(hullPtr, ShapeData.PhysicsShapeType.SHAPE_HULL); | 623 | newShape = new BulletShape(hullPtr, ShapeData.PhysicsShapeType.SHAPE_HULL); |
491 | newShape.shapeKey = newHullKey; | 624 | newShape.shapeKey = newHullKey; |
625 | newShape.meshPtr = meshDesc.Ptr; | ||
492 | 626 | ||
493 | ReferenceShape(newShape); | 627 | ReferenceShape(newShape); |
494 | 628 | ||
495 | // meshes are already scaled by the meshmerizer | 629 | // meshes and hulls are already scaled by the meshmerizer |
496 | prim.Scale = new OMV.Vector3(1f, 1f, 1f); | 630 | prim.Scale = new OMV.Vector3(1f, 1f, 1f); |
497 | prim.BSShape = newShape; | 631 | prim.BSShape = newShape; |
498 | return true; // 'true' means a new shape has been added to this prim | 632 | return true; // 'true' means a new shape has been added to this prim |
499 | } | 633 | } |
500 | 634 | ||
501 | // Callback from convex hull creater with a newly created hull. | 635 | // Callback from convex hull creater with a newly created hull. |
502 | // Just add it to the collection of hulls for this shape. | 636 | // Just add it to our collection of hulls for this shape. |
503 | private void HullReturn(ConvexResult result) | 637 | private void HullReturn(ConvexResult result) |
504 | { | 638 | { |
505 | m_hulls.Add(result); | 639 | m_hulls.Add(result); |
506 | return; | 640 | return; |
507 | } | 641 | } |
508 | 642 | ||
509 | // Create an object in Bullet if it has not already been created | 643 | // Create an object in Bullet if it has not already been created. |
510 | // No locking here because this is done when the physics engine is not simulating | 644 | // Updates prim.BSBody with the information about the new body if one is created. |
511 | // Returns 'true' if an object was actually created. | 645 | // Returns 'true' if an object was actually created. |
512 | private bool CreateObject(bool forceRebuild, BSPrim prim, BulletSim sim, BulletShape shape, ShapeData shapeData) | 646 | // Called at taint-time. |
647 | private bool CreateBody(bool forceRebuild, BSPrim prim, BulletSim sim, BulletShape shape, ShapeData shapeData) | ||
513 | { | 648 | { |
514 | // the mesh or hull must have already been created in Bullet | 649 | bool ret = false; |
515 | // m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, LocalID, shape.Type); | ||
516 | 650 | ||
517 | DereferenceBody(prim.BSBody); | 651 | // the mesh, hull or native shape must have already been created in Bullet |
652 | bool mustRebuild = (prim.BSBody.ptr == IntPtr.Zero); | ||
518 | 653 | ||
519 | BulletBody aBody; | 654 | // If there is an existing body, verify it's of an acceptable type. |
520 | IntPtr bodyPtr = IntPtr.Zero; | 655 | // If not a solid object, body is a GhostObject. Otherwise a RigidBody. |
521 | if (prim.IsSolid) | 656 | if (!mustRebuild) |
522 | { | 657 | { |
523 | bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.Ptr, shape.Ptr, shapeData.Position, shapeData.Rotation); | 658 | CollisionObjectTypes bodyType = (CollisionObjectTypes)BulletSimAPI.GetBodyType2(prim.BSBody.ptr); |
659 | if (prim.IsSolid && bodyType != CollisionObjectTypes.CO_RIGID_BODY | ||
660 | || !prim.IsSolid && bodyType != CollisionObjectTypes.CO_GHOST_OBJECT) | ||
661 | { | ||
662 | // If the collisionObject is not the correct type for solidness, rebuild what's there | ||
663 | mustRebuild = true; | ||
664 | } | ||
665 | |||
524 | } | 666 | } |
525 | else | 667 | |
668 | if (mustRebuild) | ||
526 | { | 669 | { |
527 | bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.Ptr, shape.Ptr, shapeData.Position, shapeData.Rotation); | 670 | DereferenceBody(prim.BSBody, true); |
528 | } | 671 | |
529 | aBody = new BulletBody(shapeData.ID, bodyPtr); | 672 | BulletBody aBody; |
673 | IntPtr bodyPtr = IntPtr.Zero; | ||
674 | if (prim.IsSolid) | ||
675 | { | ||
676 | bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr, shapeData.Position, shapeData.Rotation); | ||
677 | DetailLog("{0},BSShapeCollection.CreateObject,mesh,ptr={1:X}", prim.LocalID, bodyPtr); | ||
678 | } | ||
679 | else | ||
680 | { | ||
681 | bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr, shapeData.Position, shapeData.Rotation); | ||
682 | DetailLog("{0},BSShapeCollection.CreateObject,ghost,ptr={1:X}", prim.LocalID, bodyPtr); | ||
683 | } | ||
684 | aBody = new BulletBody(shapeData.ID, bodyPtr); | ||
685 | |||
686 | ReferenceBody(aBody, true); | ||
687 | |||
688 | prim.BSBody = aBody; | ||
530 | 689 | ||
531 | ReferenceBody(aBody); | 690 | ret = true; |
691 | } | ||
532 | 692 | ||
533 | prim.BSBody = aBody; | 693 | return ret; |
534 | return true; | ||
535 | } | 694 | } |
536 | 695 | ||
537 | private void DetailLog(string msg, params Object[] args) | 696 | private void DetailLog(string msg, params Object[] args) |
538 | { | 697 | { |
539 | PhysicsScene.PhysicsLogging.Write(msg, args); | 698 | PhysicsScene.PhysicsLogging.Write(msg, args); |
540 | } | 699 | } |
541 | |||
542 | |||
543 | |||
544 | |||
545 | |||
546 | } | 700 | } |
547 | } | 701 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index fb802e4..093d2a4 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs | |||
@@ -111,8 +111,8 @@ public class BSTerrainManager | |||
111 | BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, TERRAIN_COLLISION_MARGIN), | 111 | BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, TERRAIN_COLLISION_MARGIN), |
112 | ShapeData.PhysicsShapeType.SHAPE_GROUNDPLANE); | 112 | ShapeData.PhysicsShapeType.SHAPE_GROUNDPLANE); |
113 | m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID, | 113 | m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID, |
114 | BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.Ptr, Vector3.Zero, Quaternion.Identity)); | 114 | BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, Vector3.Zero, Quaternion.Identity)); |
115 | BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.Ptr, m_groundPlane.Ptr); | 115 | BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr); |
116 | 116 | ||
117 | Vector3 minTerrainCoords = new Vector3(0f, 0f, HEIGHT_INITIALIZATION - HEIGHT_EQUAL_FUDGE); | 117 | Vector3 minTerrainCoords = new Vector3(0f, 0f, HEIGHT_INITIALIZATION - HEIGHT_EQUAL_FUDGE); |
118 | Vector3 maxTerrainCoords = new Vector3(DefaultRegionSize.X, DefaultRegionSize.Y, HEIGHT_INITIALIZATION); | 118 | Vector3 maxTerrainCoords = new Vector3(DefaultRegionSize.X, DefaultRegionSize.Y, HEIGHT_INITIALIZATION); |
@@ -128,13 +128,13 @@ public class BSTerrainManager | |||
128 | // Release all the terrain structures we might have allocated | 128 | // Release all the terrain structures we might have allocated |
129 | public void ReleaseGroundPlaneAndTerrain() | 129 | public void ReleaseGroundPlaneAndTerrain() |
130 | { | 130 | { |
131 | if (m_groundPlane.Ptr != IntPtr.Zero) | 131 | if (m_groundPlane.ptr != IntPtr.Zero) |
132 | { | 132 | { |
133 | if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.Ptr, m_groundPlane.Ptr)) | 133 | if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr)) |
134 | { | 134 | { |
135 | BulletSimAPI.DestroyObject2(PhysicsScene.World.Ptr, m_groundPlane.Ptr); | 135 | BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, m_groundPlane.ptr); |
136 | } | 136 | } |
137 | m_groundPlane.Ptr = IntPtr.Zero; | 137 | m_groundPlane.ptr = IntPtr.Zero; |
138 | } | 138 | } |
139 | 139 | ||
140 | ReleaseTerrain(); | 140 | ReleaseTerrain(); |
@@ -145,9 +145,9 @@ public class BSTerrainManager | |||
145 | { | 145 | { |
146 | foreach (KeyValuePair<Vector2, BulletHeightMapInfo> kvp in m_heightMaps) | 146 | foreach (KeyValuePair<Vector2, BulletHeightMapInfo> kvp in m_heightMaps) |
147 | { | 147 | { |
148 | if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.Ptr, kvp.Value.terrainBody.Ptr)) | 148 | if (BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, kvp.Value.terrainBody.ptr)) |
149 | { | 149 | { |
150 | BulletSimAPI.DestroyObject2(PhysicsScene.World.Ptr, kvp.Value.terrainBody.Ptr); | 150 | BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, kvp.Value.terrainBody.ptr); |
151 | BulletSimAPI.ReleaseHeightMapInfo2(kvp.Value.Ptr); | 151 | BulletSimAPI.ReleaseHeightMapInfo2(kvp.Value.Ptr); |
152 | } | 152 | } |
153 | } | 153 | } |
@@ -248,17 +248,17 @@ public class BSTerrainManager | |||
248 | return; | 248 | return; |
249 | } | 249 | } |
250 | 250 | ||
251 | if (mapInfo.terrainBody.Ptr != IntPtr.Zero) | 251 | if (mapInfo.terrainBody.ptr != IntPtr.Zero) |
252 | { | 252 | { |
253 | // Updating an existing terrain. | 253 | // Updating an existing terrain. |
254 | DetailLog("{0},UpdateOrCreateTerrain:UpdateExisting,taint,terrainBase={1},minC={2}, maxC={3}, szX={4}, szY={5}", | 254 | DetailLog("{0},UpdateOrCreateTerrain:UpdateExisting,taint,terrainBase={1},minC={2}, maxC={3}, szX={4}, szY={5}", |
255 | BSScene.DetailLogZero, terrainRegionBase, mapInfo.minCoords, mapInfo.maxCoords, mapInfo.sizeX, mapInfo.sizeY); | 255 | BSScene.DetailLogZero, terrainRegionBase, mapInfo.minCoords, mapInfo.maxCoords, mapInfo.sizeX, mapInfo.sizeY); |
256 | 256 | ||
257 | // Remove from the dynamics world because we're going to mangle this object | 257 | // Remove from the dynamics world because we're going to mangle this object |
258 | BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.Ptr, mapInfo.terrainBody.Ptr); | 258 | BulletSimAPI.RemoveObjectFromWorld2(PhysicsScene.World.ptr, mapInfo.terrainBody.ptr); |
259 | 259 | ||
260 | // Get rid of the old terrain | 260 | // Get rid of the old terrain |
261 | BulletSimAPI.DestroyObject2(PhysicsScene.World.Ptr, mapInfo.terrainBody.Ptr); | 261 | BulletSimAPI.DestroyObject2(PhysicsScene.World.ptr, mapInfo.terrainBody.ptr); |
262 | BulletSimAPI.ReleaseHeightMapInfo2(mapInfo.Ptr); | 262 | BulletSimAPI.ReleaseHeightMapInfo2(mapInfo.Ptr); |
263 | mapInfo.Ptr = IntPtr.Zero; | 263 | mapInfo.Ptr = IntPtr.Zero; |
264 | 264 | ||
@@ -289,7 +289,7 @@ public class BSTerrainManager | |||
289 | BSScene.DetailLogZero, mapInfo.minCoords.X, mapInfo.minCoords.Y, minZ, maxZ); | 289 | BSScene.DetailLogZero, mapInfo.minCoords.X, mapInfo.minCoords.Y, minZ, maxZ); |
290 | 290 | ||
291 | mapInfo.ID = id; | 291 | mapInfo.ID = id; |
292 | mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.Ptr, mapInfo.ID, | 292 | mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, mapInfo.ID, |
293 | mapInfo.minCoords, mapInfo.maxCoords, mapInfo.heightMap, TERRAIN_COLLISION_MARGIN); | 293 | mapInfo.minCoords, mapInfo.maxCoords, mapInfo.heightMap, TERRAIN_COLLISION_MARGIN); |
294 | 294 | ||
295 | // The terrain object initial position is at the center of the object | 295 | // The terrain object initial position is at the center of the object |
@@ -303,7 +303,7 @@ public class BSTerrainManager | |||
303 | ShapeData.PhysicsShapeType.SHAPE_TERRAIN); | 303 | ShapeData.PhysicsShapeType.SHAPE_TERRAIN); |
304 | 304 | ||
305 | mapInfo.terrainBody = new BulletBody(mapInfo.ID, | 305 | mapInfo.terrainBody = new BulletBody(mapInfo.ID, |
306 | BulletSimAPI.CreateBodyWithDefaultMotionState2(mapInfo.terrainShape.Ptr, | 306 | BulletSimAPI.CreateBodyWithDefaultMotionState2(mapInfo.terrainShape.ptr, |
307 | centerPos, Quaternion.Identity)); | 307 | centerPos, Quaternion.Identity)); |
308 | } | 308 | } |
309 | 309 | ||
@@ -311,22 +311,22 @@ public class BSTerrainManager | |||
311 | m_heightMaps[terrainRegionBase] = mapInfo; | 311 | m_heightMaps[terrainRegionBase] = mapInfo; |
312 | 312 | ||
313 | // Set current terrain attributes | 313 | // Set current terrain attributes |
314 | BulletSimAPI.SetFriction2(mapInfo.terrainBody.Ptr, PhysicsScene.Params.terrainFriction); | 314 | BulletSimAPI.SetFriction2(mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainFriction); |
315 | BulletSimAPI.SetHitFraction2(mapInfo.terrainBody.Ptr, PhysicsScene.Params.terrainHitFraction); | 315 | BulletSimAPI.SetHitFraction2(mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainHitFraction); |
316 | BulletSimAPI.SetRestitution2(mapInfo.terrainBody.Ptr, PhysicsScene.Params.terrainRestitution); | 316 | BulletSimAPI.SetRestitution2(mapInfo.terrainBody.ptr, PhysicsScene.Params.terrainRestitution); |
317 | BulletSimAPI.SetCollisionFlags2(mapInfo.terrainBody.Ptr, CollisionFlags.CF_STATIC_OBJECT); | 317 | BulletSimAPI.SetCollisionFlags2(mapInfo.terrainBody.ptr, CollisionFlags.CF_STATIC_OBJECT); |
318 | 318 | ||
319 | BulletSimAPI.SetMassProps2(mapInfo.terrainBody.Ptr, 0f, Vector3.Zero); | 319 | BulletSimAPI.SetMassProps2(mapInfo.terrainBody.ptr, 0f, Vector3.Zero); |
320 | BulletSimAPI.UpdateInertiaTensor2(mapInfo.terrainBody.Ptr); | 320 | BulletSimAPI.UpdateInertiaTensor2(mapInfo.terrainBody.ptr); |
321 | 321 | ||
322 | // Return the new terrain to the world of physical objects | 322 | // Return the new terrain to the world of physical objects |
323 | BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.Ptr, mapInfo.terrainBody.Ptr); | 323 | BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, mapInfo.terrainBody.ptr); |
324 | 324 | ||
325 | // redo its bounding box now that it is in the world | 325 | // redo its bounding box now that it is in the world |
326 | BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.Ptr, mapInfo.terrainBody.Ptr); | 326 | BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, mapInfo.terrainBody.ptr); |
327 | 327 | ||
328 | // Make sure the new shape is processed. | 328 | // Make sure the new shape is processed. |
329 | BulletSimAPI.Activate2(mapInfo.terrainBody.Ptr, true); | 329 | BulletSimAPI.Activate2(mapInfo.terrainBody.ptr, true); |
330 | 330 | ||
331 | m_terrainModified = true; | 331 | m_terrainModified = true; |
332 | }; | 332 | }; |
@@ -361,7 +361,7 @@ public class BSTerrainManager | |||
361 | DetailLog("{0},UpdateOrCreateTerrain:NewTerrain,taint,baseX={1},baseY={2}", BSScene.DetailLogZero, minCoords.X, minCoords.Y); | 361 | DetailLog("{0},UpdateOrCreateTerrain:NewTerrain,taint,baseX={1},baseY={2}", BSScene.DetailLogZero, minCoords.X, minCoords.Y); |
362 | // Create a new mapInfo that will be filled with the new info | 362 | // Create a new mapInfo that will be filled with the new info |
363 | mapInfo = new BulletHeightMapInfo(id, heightMapX, | 363 | mapInfo = new BulletHeightMapInfo(id, heightMapX, |
364 | BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.Ptr, newTerrainID, | 364 | BulletSimAPI.CreateHeightMapInfo2(PhysicsScene.World.ptr, newTerrainID, |
365 | minCoordsX, maxCoordsX, heightMapX, TERRAIN_COLLISION_MARGIN)); | 365 | minCoordsX, maxCoordsX, heightMapX, TERRAIN_COLLISION_MARGIN)); |
366 | // Put the unfilled heightmap info into the collection of same | 366 | // Put the unfilled heightmap info into the collection of same |
367 | m_heightMaps.Add(terrainRegionBase, mapInfo); | 367 | m_heightMaps.Add(terrainRegionBase, mapInfo); |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 47875b0..8480dd1 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs | |||
@@ -40,14 +40,14 @@ public struct BulletSim | |||
40 | { | 40 | { |
41 | public BulletSim(uint worldId, BSScene bss, IntPtr xx) | 41 | public BulletSim(uint worldId, BSScene bss, IntPtr xx) |
42 | { | 42 | { |
43 | ptr = xx; | ||
43 | worldID = worldId; | 44 | worldID = worldId; |
44 | scene = bss; | 45 | scene = bss; |
45 | Ptr = xx; | ||
46 | } | 46 | } |
47 | public IntPtr ptr; | ||
47 | public uint worldID; | 48 | public uint worldID; |
48 | // The scene is only in here so very low level routines have a handle to print debug/error messages | 49 | // The scene is only in here so very low level routines have a handle to print debug/error messages |
49 | public BSScene scene; | 50 | public BSScene scene; |
50 | public IntPtr Ptr; | ||
51 | } | 51 | } |
52 | 52 | ||
53 | // An allocated Bullet btRigidBody | 53 | // An allocated Bullet btRigidBody |
@@ -56,9 +56,9 @@ public struct BulletBody | |||
56 | public BulletBody(uint id, IntPtr xx) | 56 | public BulletBody(uint id, IntPtr xx) |
57 | { | 57 | { |
58 | ID = id; | 58 | ID = id; |
59 | Ptr = xx; | 59 | ptr = xx; |
60 | } | 60 | } |
61 | public IntPtr Ptr; | 61 | public IntPtr ptr; |
62 | public uint ID; | 62 | public uint ID; |
63 | public override string ToString() | 63 | public override string ToString() |
64 | { | 64 | { |
@@ -66,7 +66,7 @@ public struct BulletBody | |||
66 | buff.Append("<id="); | 66 | buff.Append("<id="); |
67 | buff.Append(ID.ToString()); | 67 | buff.Append(ID.ToString()); |
68 | buff.Append(",p="); | 68 | buff.Append(",p="); |
69 | buff.Append(Ptr.ToString("X")); | 69 | buff.Append(ptr.ToString("X")); |
70 | buff.Append(">"); | 70 | buff.Append(">"); |
71 | return buff.ToString(); | 71 | return buff.ToString(); |
72 | } | 72 | } |
@@ -76,28 +76,39 @@ public struct BulletShape | |||
76 | { | 76 | { |
77 | public BulletShape(IntPtr xx) | 77 | public BulletShape(IntPtr xx) |
78 | { | 78 | { |
79 | Ptr = xx; | 79 | ptr = xx; |
80 | type=ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; | 80 | type=ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; |
81 | shapeKey = 0; | 81 | shapeKey = 0; |
82 | isNativeShape = false; | ||
83 | meshPtr = IntPtr.Zero; | ||
82 | } | 84 | } |
83 | public BulletShape(IntPtr xx, ShapeData.PhysicsShapeType typ) | 85 | public BulletShape(IntPtr xx, ShapeData.PhysicsShapeType typ) |
84 | { | 86 | { |
85 | Ptr = xx; | 87 | ptr = xx; |
86 | type = typ; | 88 | type = typ; |
87 | shapeKey = 0; | 89 | shapeKey = 0; |
90 | isNativeShape = false; | ||
91 | meshPtr = IntPtr.Zero; | ||
88 | } | 92 | } |
89 | public IntPtr Ptr; | 93 | public IntPtr ptr; |
90 | public ShapeData.PhysicsShapeType type; | 94 | public ShapeData.PhysicsShapeType type; |
91 | public ulong shapeKey; | 95 | public ulong shapeKey; |
96 | public bool isNativeShape; | ||
97 | // Hulls have an underlying mesh. A pointer to it is hidden here. | ||
98 | public IntPtr meshPtr; | ||
92 | public override string ToString() | 99 | public override string ToString() |
93 | { | 100 | { |
94 | StringBuilder buff = new StringBuilder(); | 101 | StringBuilder buff = new StringBuilder(); |
95 | buff.Append("<p="); | 102 | buff.Append("<p="); |
96 | buff.Append(Ptr.ToString("X")); | 103 | buff.Append(ptr.ToString("X")); |
97 | buff.Append(",s="); | 104 | buff.Append(",s="); |
98 | buff.Append(type.ToString()); | 105 | buff.Append(type.ToString()); |
99 | buff.Append(",k="); | 106 | buff.Append(",k="); |
100 | buff.Append(shapeKey.ToString("X")); | 107 | buff.Append(shapeKey.ToString("X")); |
108 | buff.Append(",n="); | ||
109 | buff.Append(isNativeShape.ToString()); | ||
110 | buff.Append(",m="); | ||
111 | buff.Append(meshPtr.ToString("X")); | ||
101 | buff.Append(">"); | 112 | buff.Append(">"); |
102 | return buff.ToString(); | 113 | return buff.ToString(); |
103 | } | 114 | } |
@@ -314,10 +325,10 @@ public enum CollisionFlags : uint | |||
314 | CF_DISABLE_SPU_COLLISION_PROCESS = 1 << 6, | 325 | CF_DISABLE_SPU_COLLISION_PROCESS = 1 << 6, |
315 | // Following used by BulletSim to control collisions | 326 | // Following used by BulletSim to control collisions |
316 | BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10, | 327 | BS_SUBSCRIBE_COLLISION_EVENTS = 1 << 10, |
317 | BS_VOLUME_DETECT_OBJECT = 1 << 11, | 328 | // BS_VOLUME_DETECT_OBJECT = 1 << 11, |
318 | BS_PHANTOM_OBJECT = 1 << 12, | 329 | // BS_PHANTOM_OBJECT = 1 << 12, |
319 | BS_PHYSICAL_OBJECT = 1 << 13, | 330 | // BS_PHYSICAL_OBJECT = 1 << 13, |
320 | BS_TERRAIN_OBJECT = 1 << 14, | 331 | // BS_TERRAIN_OBJECT = 1 << 14, |
321 | BS_NONE = 0, | 332 | BS_NONE = 0, |
322 | BS_ALL = 0xFFFFFFFF, | 333 | BS_ALL = 0xFFFFFFFF, |
323 | 334 | ||
@@ -326,9 +337,9 @@ public enum CollisionFlags : uint | |||
326 | BS_ACTIVE = CF_STATIC_OBJECT | 337 | BS_ACTIVE = CF_STATIC_OBJECT |
327 | | CF_KINEMATIC_OBJECT | 338 | | CF_KINEMATIC_OBJECT |
328 | | CF_NO_CONTACT_RESPONSE | 339 | | CF_NO_CONTACT_RESPONSE |
329 | | BS_VOLUME_DETECT_OBJECT | 340 | // | BS_VOLUME_DETECT_OBJECT |
330 | | BS_PHANTOM_OBJECT | 341 | // | BS_PHANTOM_OBJECT |
331 | | BS_PHYSICAL_OBJECT, | 342 | // | BS_PHYSICAL_OBJECT, |
332 | }; | 343 | }; |
333 | 344 | ||
334 | // Values for collisions groups and masks | 345 | // Values for collisions groups and masks |
@@ -552,8 +563,7 @@ public static extern IntPtr CreateHullShape2(IntPtr world, | |||
552 | public static extern IntPtr BuildHullShape2(IntPtr world, IntPtr meshShape); | 563 | public static extern IntPtr BuildHullShape2(IntPtr world, IntPtr meshShape); |
553 | 564 | ||
554 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 565 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
555 | public static extern IntPtr BuildNativeShape2(IntPtr world, | 566 | public static extern IntPtr BuildNativeShape2(IntPtr world, ShapeData shapeData); |
556 | float shapeType, float collisionMargin, Vector3 scale); | ||
557 | 567 | ||
558 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 568 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
559 | public static extern bool IsNativeShape2(IntPtr shape); | 569 | public static extern bool IsNativeShape2(IntPtr shape); |
@@ -568,6 +578,9 @@ public static extern void AddChildToCompoundShape2(IntPtr cShape, IntPtr addShap | |||
568 | public static extern void RemoveChildFromCompoundShape2(IntPtr cShape, IntPtr removeShape); | 578 | public static extern void RemoveChildFromCompoundShape2(IntPtr cShape, IntPtr removeShape); |
569 | 579 | ||
570 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 580 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
581 | public static extern IntPtr DuplicateCollisionShape2(IntPtr sim, IntPtr srcShape, uint id); | ||
582 | |||
583 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||
571 | public static extern IntPtr CreateBodyFromShapeAndInfo2(IntPtr sim, IntPtr shape, IntPtr constructionInfo); | 584 | public static extern IntPtr CreateBodyFromShapeAndInfo2(IntPtr sim, IntPtr shape, IntPtr constructionInfo); |
572 | 585 | ||
573 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 586 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |