aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorRobert Adams2012-09-23 18:39:46 -0700
committerRobert Adams2012-09-27 22:01:37 -0700
commitd016051fa028a485b09fac47b3fa3d8fd08e207a (patch)
tree8f483976bb64b1328439b76754675126b09943b0 /OpenSim/Region
parentBulletSim: fix regression that caused cylindar shapes to have a box collision... (diff)
downloadopensim-SC-d016051fa028a485b09fac47b3fa3d8fd08e207a.zip
opensim-SC-d016051fa028a485b09fac47b3fa3d8fd08e207a.tar.gz
opensim-SC-d016051fa028a485b09fac47b3fa3d8fd08e207a.tar.bz2
opensim-SC-d016051fa028a485b09fac47b3fa3d8fd08e207a.tar.xz
BulletSim: renamed members of BulletShape, BulletSim and BulletBody
so the members case is consistant. Caused modifications everywhere. New logic in BSShapeCollection to track use and sharing of shapes. I just reslized, though, that shapes cannot be shared because the shape's UserPointer is the localID of the prim and is required for tracking collisions. More changes coming. Added DuplicateCollisionShape2() to API and changed BuildNativeShape2 to take a ShapeData structure so don't have to pass so many parameters. This matches the latest version of BulletSim.dll. Additions and removal of DetailLog() statements for debugging.
Diffstat (limited to 'OpenSim/Region')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BS6DofConstraint.cs4
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs12
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSHingeConstraint.cs110
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs6
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs16
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs159
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs4
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs344
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs46
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs49
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 */
27using System; 27using System;
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Text; 29using System.Text;
30using OpenMetaverse; 30using OpenMetaverse;
31 31
32namespace OpenSim.Region.Physics.BulletSPlugin 32namespace OpenSim.Region.Physics.BulletSPlugin
33{ 33{
34 34
35class BSHingeConstraint : BSConstraint 35class 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
27using System; 32using System;
28using System.Reflection; 33using System.Reflection;
29using System.Collections.Generic; 34using System.Collections.Generic;
@@ -36,6 +41,7 @@ using OpenSim.Region.Physics.ConvexDecompositionDotNet;
36 41
37namespace OpenSim.Region.Physics.BulletSPlugin 42namespace OpenSim.Region.Physics.BulletSPlugin
38{ 43{
44
39 [Serializable] 45 [Serializable]
40public sealed class BSPrim : BSPhysObject 46public 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,
552public static extern IntPtr BuildHullShape2(IntPtr world, IntPtr meshShape); 563public static extern IntPtr BuildHullShape2(IntPtr world, IntPtr meshShape);
553 564
554[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 565[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
555public static extern IntPtr BuildNativeShape2(IntPtr world, 566public 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]
559public static extern bool IsNativeShape2(IntPtr shape); 569public static extern bool IsNativeShape2(IntPtr shape);
@@ -568,6 +578,9 @@ public static extern void AddChildToCompoundShape2(IntPtr cShape, IntPtr addShap
568public static extern void RemoveChildFromCompoundShape2(IntPtr cShape, IntPtr removeShape); 578public static extern void RemoveChildFromCompoundShape2(IntPtr cShape, IntPtr removeShape);
569 579
570[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 580[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
581public static extern IntPtr DuplicateCollisionShape2(IntPtr sim, IntPtr srcShape, uint id);
582
583[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
571public static extern IntPtr CreateBodyFromShapeAndInfo2(IntPtr sim, IntPtr shape, IntPtr constructionInfo); 584public 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]