diff options
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] |