aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
authorRobert Adams2012-08-24 12:58:42 -0700
committerRobert Adams2012-08-31 11:41:12 -0700
commit7b6987ce83d16871f6070f3cc7d56280ad3d5dbe (patch)
treed996f2e9871d0d8bba505d9f581c7f42a8f040b3 /OpenSim/Region/Physics
parentBulletSim: add new interface for mesh, hull and terrain creation that will mo... (diff)
downloadopensim-SC-7b6987ce83d16871f6070f3cc7d56280ad3d5dbe.zip
opensim-SC-7b6987ce83d16871f6070f3cc7d56280ad3d5dbe.tar.gz
opensim-SC-7b6987ce83d16871f6070f3cc7d56280ad3d5dbe.tar.bz2
opensim-SC-7b6987ce83d16871f6070f3cc7d56280ad3d5dbe.tar.xz
BulletSim: unify physical objects under BSPhysObjects. Now BSScene and BSLinkset only know of BSPhysObject's and there is only one list to search in BSScene.
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs31
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs50
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs58
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs84
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs137
5 files changed, 200 insertions, 160 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index 1b23a36..784076d 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -34,7 +34,7 @@ using OpenSim.Region.Physics.Manager;
34 34
35namespace OpenSim.Region.Physics.BulletSPlugin 35namespace OpenSim.Region.Physics.BulletSPlugin
36{ 36{
37public class BSCharacter : PhysicsActor 37public class BSCharacter : BSPhysObject
38{ 38{
39 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 39 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
40 private static readonly string LogHeader = "[BULLETS CHAR]"; 40 private static readonly string LogHeader = "[BULLETS CHAR]";
@@ -74,11 +74,8 @@ public class BSCharacter : PhysicsActor
74 private bool _kinematic; 74 private bool _kinematic;
75 private float _buoyancy; 75 private float _buoyancy;
76 76
77 private BulletBody m_body; 77 public override BulletBody Body { get; set; }
78 public BulletBody Body { 78 public override BSLinkset Linkset { get; set; }
79 get { return m_body; }
80 set { m_body = value; }
81 }
82 79
83 private int _subscribedEventsMs = 0; 80 private int _subscribedEventsMs = 0;
84 private int _nextCollisionOkTime = 0; 81 private int _nextCollisionOkTime = 0;
@@ -108,6 +105,8 @@ public class BSCharacter : PhysicsActor
108 _density = _scene.Params.avatarDensity; 105 _density = _scene.Params.avatarDensity;
109 ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale 106 ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale
110 107
108 Linkset = new BSLinkset(_scene, this);
109
111 ShapeData shapeData = new ShapeData(); 110 ShapeData shapeData = new ShapeData();
112 shapeData.ID = _localID; 111 shapeData.ID = _localID;
113 shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR; 112 shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR;
@@ -130,7 +129,7 @@ public class BSCharacter : PhysicsActor
130 // Set the buoyancy for flying. This will be refactored when all the settings happen in C# 129 // Set the buoyancy for flying. This will be refactored when all the settings happen in C#
131 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy); 130 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy);
132 131
133 m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); 132 Body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
134 // avatars get all collisions no matter what (makes walking on ground and such work) 133 // avatars get all collisions no matter what (makes walking on ground and such work)
135 BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 134 BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
136 }); 135 });
@@ -139,7 +138,7 @@ public class BSCharacter : PhysicsActor
139 } 138 }
140 139
141 // called when this character is being destroyed and the resources should be released 140 // called when this character is being destroyed and the resources should be released
142 public void Destroy() 141 public override void Destroy()
143 { 142 {
144 DetailLog("{0},BSCharacter.Destroy", LocalID); 143 DetailLog("{0},BSCharacter.Destroy", LocalID);
145 _scene.TaintedObject("BSCharacter.destroy", delegate() 144 _scene.TaintedObject("BSCharacter.destroy", delegate()
@@ -245,6 +244,10 @@ public class BSCharacter : PhysicsActor
245 return _mass; 244 return _mass;
246 } 245 }
247 } 246 }
247
248 // used when we only want this prim's mass and not the linkset thing
249 public override float MassRaw { get {return _mass; } }
250
248 public override Vector3 Force { 251 public override Vector3 Force {
249 get { return _force; } 252 get { return _force; }
250 set { 253 set {
@@ -448,6 +451,12 @@ public class BSCharacter : PhysicsActor
448 }); 451 });
449 } 452 }
450 } 453 }
454
455 public override void ZeroMotion()
456 {
457 return;
458 }
459
451 // Stop collision events 460 // Stop collision events
452 public override void UnSubscribeEvents() { 461 public override void UnSubscribeEvents() {
453 _subscribedEventsMs = 0; 462 _subscribedEventsMs = 0;
@@ -481,7 +490,7 @@ public class BSCharacter : PhysicsActor
481 490
482 // The physics engine says that properties have updated. Update same and inform 491 // The physics engine says that properties have updated. Update same and inform
483 // the world that things have changed. 492 // the world that things have changed.
484 public void UpdateProperties(EntityProperties entprop) 493 public override void UpdateProperties(EntityProperties entprop)
485 { 494 {
486 _position = entprop.Position; 495 _position = entprop.Position;
487 _orientation = entprop.Rotation; 496 _orientation = entprop.Rotation;
@@ -500,7 +509,7 @@ public class BSCharacter : PhysicsActor
500 // The collision, if it should be reported to the character, is placed in a collection 509 // The collision, if it should be reported to the character, is placed in a collection
501 // that will later be sent to the simulator when SendCollisions() is called. 510 // that will later be sent to the simulator when SendCollisions() is called.
502 CollisionEventUpdate collisionCollection = null; 511 CollisionEventUpdate collisionCollection = null;
503 public void Collide(uint collidingWith, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth) 512 public override void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
504 { 513 {
505 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); 514 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
506 515
@@ -525,7 +534,7 @@ public class BSCharacter : PhysicsActor
525 } 534 }
526 } 535 }
527 536
528 public void SendCollisions() 537 public override void SendCollisions()
529 { 538 {
530 /* 539 /*
531 if (collisionCollection != null && collisionCollection.Count > 0) 540 if (collisionCollection != null && collisionCollection.Count > 0)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 9e3f0db..b04e1b6 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -36,8 +36,8 @@ public class BSLinkset
36{ 36{
37 private static string LogHeader = "[BULLETSIM LINKSET]"; 37 private static string LogHeader = "[BULLETSIM LINKSET]";
38 38
39 private BSPrim m_linksetRoot; 39 private BSPhysObject m_linksetRoot;
40 public BSPrim LinksetRoot { get { return m_linksetRoot; } } 40 public BSPhysObject LinksetRoot { get { return m_linksetRoot; } }
41 41
42 private BSScene m_physicsScene; 42 private BSScene m_physicsScene;
43 public BSScene PhysicsScene { get { return m_physicsScene; } } 43 public BSScene PhysicsScene { get { return m_physicsScene; } }
@@ -46,7 +46,7 @@ public class BSLinkset
46 public int LinksetID { get; private set; } 46 public int LinksetID { get; private set; }
47 47
48 // The children under the root in this linkset 48 // The children under the root in this linkset
49 private List<BSPrim> m_children; 49 private List<BSPhysObject> m_children;
50 50
51 // We lock the diddling of linkset classes to prevent any badness. 51 // We lock the diddling of linkset classes to prevent any badness.
52 // This locks the modification of the instances of this class. Changes 52 // This locks the modification of the instances of this class. Changes
@@ -74,7 +74,7 @@ public class BSLinkset
74 get { return ComputeLinksetGeometricCenter(); } 74 get { return ComputeLinksetGeometricCenter(); }
75 } 75 }
76 76
77 public BSLinkset(BSScene scene, BSPrim parent) 77 public BSLinkset(BSScene scene, BSPhysObject parent)
78 { 78 {
79 // A simple linkset of one (no children) 79 // A simple linkset of one (no children)
80 LinksetID = m_nextLinksetID++; 80 LinksetID = m_nextLinksetID++;
@@ -83,14 +83,14 @@ public class BSLinkset
83 m_nextLinksetID = 1; 83 m_nextLinksetID = 1;
84 m_physicsScene = scene; 84 m_physicsScene = scene;
85 m_linksetRoot = parent; 85 m_linksetRoot = parent;
86 m_children = new List<BSPrim>(); 86 m_children = new List<BSPhysObject>();
87 m_mass = parent.MassRaw; 87 m_mass = parent.MassRaw;
88 } 88 }
89 89
90 // Link to a linkset where the child knows the parent. 90 // Link to a linkset where the child knows the parent.
91 // Parent changing should not happen so do some sanity checking. 91 // Parent changing should not happen so do some sanity checking.
92 // We return the parent's linkset so the child can track its membership. 92 // We return the parent's linkset so the child can track its membership.
93 public BSLinkset AddMeToLinkset(BSPrim child) 93 public BSLinkset AddMeToLinkset(BSPhysObject child)
94 { 94 {
95 lock (m_linksetActivityLock) 95 lock (m_linksetActivityLock)
96 { 96 {
@@ -102,7 +102,7 @@ public class BSLinkset
102 // Remove a child from a linkset. 102 // Remove a child from a linkset.
103 // Returns a new linkset for the child which is a linkset of one (just the 103 // Returns a new linkset for the child which is a linkset of one (just the
104 // orphened child). 104 // orphened child).
105 public BSLinkset RemoveMeFromLinkset(BSPrim child) 105 public BSLinkset RemoveMeFromLinkset(BSPhysObject child)
106 { 106 {
107 lock (m_linksetActivityLock) 107 lock (m_linksetActivityLock)
108 { 108 {
@@ -129,7 +129,7 @@ public class BSLinkset
129 } 129 }
130 130
131 // Return 'true' if the passed object is the root object of this linkset 131 // Return 'true' if the passed object is the root object of this linkset
132 public bool IsRoot(BSPrim requestor) 132 public bool IsRoot(BSPhysObject requestor)
133 { 133 {
134 return (requestor.LocalID == m_linksetRoot.LocalID); 134 return (requestor.LocalID == m_linksetRoot.LocalID);
135 } 135 }
@@ -140,12 +140,12 @@ public class BSLinkset
140 public bool HasAnyChildren { get { return (m_children.Count > 0); } } 140 public bool HasAnyChildren { get { return (m_children.Count > 0); } }
141 141
142 // Return 'true' if this child is in this linkset 142 // Return 'true' if this child is in this linkset
143 public bool HasChild(BSPrim child) 143 public bool HasChild(BSPhysObject child)
144 { 144 {
145 bool ret = false; 145 bool ret = false;
146 lock (m_linksetActivityLock) 146 lock (m_linksetActivityLock)
147 { 147 {
148 foreach (BSPrim bp in m_children) 148 foreach (BSPhysObject bp in m_children)
149 { 149 {
150 if (child.LocalID == bp.LocalID) 150 if (child.LocalID == bp.LocalID)
151 { 151 {
@@ -160,7 +160,7 @@ public class BSLinkset
160 private float ComputeLinksetMass() 160 private float ComputeLinksetMass()
161 { 161 {
162 float mass = m_linksetRoot.MassRaw; 162 float mass = m_linksetRoot.MassRaw;
163 foreach (BSPrim bp in m_children) 163 foreach (BSPhysObject bp in m_children)
164 { 164 {
165 mass += bp.MassRaw; 165 mass += bp.MassRaw;
166 } 166 }
@@ -174,7 +174,7 @@ public class BSLinkset
174 174
175 lock (m_linksetActivityLock) 175 lock (m_linksetActivityLock)
176 { 176 {
177 foreach (BSPrim bp in m_children) 177 foreach (BSPhysObject bp in m_children)
178 { 178 {
179 com += bp.Position * bp.MassRaw; 179 com += bp.Position * bp.MassRaw;
180 totalMass += bp.MassRaw; 180 totalMass += bp.MassRaw;
@@ -192,7 +192,7 @@ public class BSLinkset
192 192
193 lock (m_linksetActivityLock) 193 lock (m_linksetActivityLock)
194 { 194 {
195 foreach (BSPrim bp in m_children) 195 foreach (BSPhysObject bp in m_children)
196 { 196 {
197 com += bp.Position * bp.MassRaw; 197 com += bp.Position * bp.MassRaw;
198 } 198 }
@@ -204,7 +204,7 @@ public class BSLinkset
204 204
205 // When physical properties are changed the linkset needs to recalculate 205 // When physical properties are changed the linkset needs to recalculate
206 // its internal properties. 206 // its internal properties.
207 public void Refresh(BSPrim requestor) 207 public void Refresh(BSPhysObject requestor)
208 { 208 {
209 // If there are no children, there aren't any constraints to recompute 209 // If there are no children, there aren't any constraints to recompute
210 if (!HasAnyChildren) 210 if (!HasAnyChildren)
@@ -230,7 +230,7 @@ public class BSLinkset
230 float linksetMass = LinksetMass; 230 float linksetMass = LinksetMass;
231 lock (m_linksetActivityLock) 231 lock (m_linksetActivityLock)
232 { 232 {
233 foreach (BSPrim child in m_children) 233 foreach (BSPhysObject child in m_children)
234 { 234 {
235 BSConstraint constrain; 235 BSConstraint constrain;
236 if (m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.Body, child.Body, out constrain)) 236 if (m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.Body, child.Body, out constrain))
@@ -255,14 +255,14 @@ public class BSLinkset
255 255
256 // I am the root of a linkset and a new child is being added 256 // I am the root of a linkset and a new child is being added
257 // Called while LinkActivity is locked. 257 // Called while LinkActivity is locked.
258 private void AddChildToLinkset(BSPrim child) 258 private void AddChildToLinkset(BSPhysObject child)
259 { 259 {
260 if (!HasChild(child)) 260 if (!HasChild(child))
261 { 261 {
262 m_children.Add(child); 262 m_children.Add(child);
263 263
264 BSPrim rootx = LinksetRoot; // capture the root as of now 264 BSPhysObject rootx = LinksetRoot; // capture the root as of now
265 BSPrim childx = child; 265 BSPhysObject childx = child;
266 m_physicsScene.TaintedObject("AddChildToLinkset", delegate() 266 m_physicsScene.TaintedObject("AddChildToLinkset", delegate()
267 { 267 {
268 DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID); 268 DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
@@ -277,7 +277,7 @@ public class BSLinkset
277 // it's still connected to the linkset. 277 // it's still connected to the linkset.
278 // Normal OpenSimulator operation will never do this because other SceneObjectPart information 278 // Normal OpenSimulator operation will never do this because other SceneObjectPart information
279 // has to be updated also (like pointer to prim's parent). 279 // has to be updated also (like pointer to prim's parent).
280 private void RemoveChildFromOtherLinkset(BSPrim pchild) 280 private void RemoveChildFromOtherLinkset(BSPhysObject pchild)
281 { 281 {
282 pchild.Linkset = new BSLinkset(m_physicsScene, pchild); 282 pchild.Linkset = new BSLinkset(m_physicsScene, pchild);
283 RemoveChildFromLinkset(pchild); 283 RemoveChildFromLinkset(pchild);
@@ -285,12 +285,12 @@ public class BSLinkset
285 285
286 // I am the root of a linkset and one of my children is being removed. 286 // I am the root of a linkset and one of my children is being removed.
287 // Safe to call even if the child is not really in my linkset. 287 // Safe to call even if the child is not really in my linkset.
288 private void RemoveChildFromLinkset(BSPrim child) 288 private void RemoveChildFromLinkset(BSPhysObject child)
289 { 289 {
290 if (m_children.Remove(child)) 290 if (m_children.Remove(child))
291 { 291 {
292 BSPrim rootx = LinksetRoot; // capture the root as of now 292 BSPhysObject rootx = LinksetRoot; // capture the root as of now
293 BSPrim childx = child; 293 BSPhysObject childx = child;
294 m_physicsScene.TaintedObject("RemoveChildFromLinkset", delegate() 294 m_physicsScene.TaintedObject("RemoveChildFromLinkset", delegate()
295 { 295 {
296 DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID); 296 DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
@@ -310,7 +310,7 @@ public class BSLinkset
310 310
311 // Create a constraint between me (root of linkset) and the passed prim (the child). 311 // Create a constraint between me (root of linkset) and the passed prim (the child).
312 // Called at taint time! 312 // Called at taint time!
313 private void PhysicallyLinkAChildToRoot(BSPrim rootPrim, BSPrim childPrim) 313 private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim)
314 { 314 {
315 // Zero motion for children so they don't interpolate 315 // Zero motion for children so they don't interpolate
316 childPrim.ZeroMotion(); 316 childPrim.ZeroMotion();
@@ -383,7 +383,7 @@ public class BSLinkset
383 383
384 // Remove linkage between myself and a particular child 384 // Remove linkage between myself and a particular child
385 // Called at taint time! 385 // Called at taint time!
386 private void PhysicallyUnlinkAChildFromRoot(BSPrim rootPrim, BSPrim childPrim) 386 private void PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim)
387 { 387 {
388 DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); 388 DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
389 389
@@ -396,7 +396,7 @@ public class BSLinkset
396 396
397 // Remove linkage between myself and any possible children I might have 397 // Remove linkage between myself and any possible children I might have
398 // Called at taint time! 398 // Called at taint time!
399 private void PhysicallyUnlinkAllChildrenFromRoot(BSPrim rootPrim) 399 private void PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim)
400 { 400 {
401 DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); 401 DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
402 402
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
new file mode 100755
index 0000000..6e205a9
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyrightD
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections.Generic;
29using System.Text;
30
31using OMV = OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Region.Physics.Manager;
34
35namespace OpenSim.Region.Physics.BulletSPlugin
36{
37// Class to wrap all objects.
38// The rest of BulletSim doesn't need to keep checking for avatars or prims
39// unless the difference is significant.
40public abstract class BSPhysObject : PhysicsActor
41{
42 public abstract BSLinkset Linkset { get; set; }
43
44 public abstract void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type,
45 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth);
46 public abstract void SendCollisions();
47
48 // Return the object mass without calculating it or side effects
49 public abstract float MassRaw { get; }
50
51 public abstract BulletBody Body { get; set; }
52 public abstract void ZeroMotion();
53
54 public abstract void UpdateProperties(EntityProperties entprop);
55
56 public abstract void Destroy();
57}
58}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index d3f1e9c..036fd4f 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -37,7 +37,7 @@ using OpenSim.Region.Physics.ConvexDecompositionDotNet;
37namespace OpenSim.Region.Physics.BulletSPlugin 37namespace OpenSim.Region.Physics.BulletSPlugin
38{ 38{
39 [Serializable] 39 [Serializable]
40public sealed class BSPrim : PhysicsActor 40public sealed class BSPrim : BSPhysObject
41{ 41{
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43 private static readonly string LogHeader = "[BULLETS PRIM]"; 43 private static readonly string LogHeader = "[BULLETS PRIM]";
@@ -88,23 +88,14 @@ public sealed class BSPrim : PhysicsActor
88 private float _buoyancy; 88 private float _buoyancy;
89 89
90 // Membership in a linkset is controlled by this class. 90 // Membership in a linkset is controlled by this class.
91 private BSLinkset _linkset; 91 public override BSLinkset Linkset { get; set; }
92 public BSLinkset Linkset
93 {
94 get { return _linkset; }
95 set { _linkset = value; }
96 }
97 92
98 private int _subscribedEventsMs = 0; 93 private int _subscribedEventsMs = 0;
99 private int _nextCollisionOkTime = 0; 94 private int _nextCollisionOkTime = 0;
100 long _collidingStep; 95 long _collidingStep;
101 long _collidingGroundStep; 96 long _collidingGroundStep;
102 97
103 private BulletBody m_body; 98 public override BulletBody Body { get; set; }
104 public BulletBody Body {
105 get { return m_body; }
106 set { m_body = value; }
107 }
108 99
109 private BSDynamics _vehicle; 100 private BSDynamics _vehicle;
110 101
@@ -139,7 +130,7 @@ public sealed class BSPrim : PhysicsActor
139 _friction = _scene.Params.defaultFriction; // TODO: compute based on object material 130 _friction = _scene.Params.defaultFriction; // TODO: compute based on object material
140 _density = _scene.Params.defaultDensity; // TODO: compute based on object material 131 _density = _scene.Params.defaultDensity; // TODO: compute based on object material
141 _restitution = _scene.Params.defaultRestitution; 132 _restitution = _scene.Params.defaultRestitution;
142 _linkset = new BSLinkset(Scene, this); // a linkset of one 133 Linkset = new BSLinkset(Scene, this); // a linkset of one
143 _vehicle = new BSDynamics(Scene, this); // add vehicleness 134 _vehicle = new BSDynamics(Scene, this); // add vehicleness
144 _mass = CalculateMass(); 135 _mass = CalculateMass();
145 // do the actual object creation at taint time 136 // do the actual object creation at taint time
@@ -151,23 +142,23 @@ public sealed class BSPrim : PhysicsActor
151 // Get the pointer to the physical body for this object. 142 // Get the pointer to the physical body for this object.
152 // At the moment, we're still letting BulletSim manage the creation and destruction 143 // At the moment, we're still letting BulletSim manage the creation and destruction
153 // of the object. Someday we'll move that into the C# code. 144 // of the object. Someday we'll move that into the C# code.
154 m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); 145 Body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
155 }); 146 });
156 } 147 }
157 148
158 // called when this prim is being destroyed and we should free all the resources 149 // called when this prim is being destroyed and we should free all the resources
159 public void Destroy() 150 public override void Destroy()
160 { 151 {
161 // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); 152 // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID);
162 153
163 // Undo any links between me and any other object 154 // Undo any links between me and any other object
164 BSPrim parentBefore = _linkset.LinksetRoot; 155 BSPhysObject parentBefore = Linkset.LinksetRoot;
165 int childrenBefore = _linkset.NumberOfChildren; 156 int childrenBefore = Linkset.NumberOfChildren;
166 157
167 _linkset = _linkset.RemoveMeFromLinkset(this); 158 Linkset = Linkset.RemoveMeFromLinkset(this);
168 159
169 DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}", 160 DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}",
170 LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren); 161 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
171 162
172 // Undo any vehicle properties 163 // Undo any vehicle properties
173 this.VehicleType = (int)Vehicle.TYPE_NONE; 164 this.VehicleType = (int)Vehicle.TYPE_NONE;
@@ -230,13 +221,13 @@ public sealed class BSPrim : PhysicsActor
230 BSPrim parent = obj as BSPrim; 221 BSPrim parent = obj as BSPrim;
231 if (parent != null) 222 if (parent != null)
232 { 223 {
233 BSPrim parentBefore = _linkset.LinksetRoot; 224 BSPhysObject parentBefore = Linkset.LinksetRoot;
234 int childrenBefore = _linkset.NumberOfChildren; 225 int childrenBefore = Linkset.NumberOfChildren;
235 226
236 _linkset = parent.Linkset.AddMeToLinkset(this); 227 Linkset = parent.Linkset.AddMeToLinkset(this);
237 228
238 DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}", 229 DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}",
239 LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren); 230 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
240 } 231 }
241 return; 232 return;
242 } 233 }
@@ -246,13 +237,13 @@ public sealed class BSPrim : PhysicsActor
246 // TODO: decide if this parent checking needs to happen at taint time 237 // TODO: decide if this parent checking needs to happen at taint time
247 // Race condition here: if link() and delink() in same simulation tick, the delink will not happen 238 // Race condition here: if link() and delink() in same simulation tick, the delink will not happen
248 239
249 BSPrim parentBefore = _linkset.LinksetRoot; 240 BSPhysObject parentBefore = Linkset.LinksetRoot;
250 int childrenBefore = _linkset.NumberOfChildren; 241 int childrenBefore = Linkset.NumberOfChildren;
251 242
252 _linkset = _linkset.RemoveMeFromLinkset(this); 243 Linkset = Linkset.RemoveMeFromLinkset(this);
253 244
254 DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ", 245 DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",
255 LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren); 246 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
256 return; 247 return;
257 } 248 }
258 249
@@ -260,7 +251,7 @@ public sealed class BSPrim : PhysicsActor
260 // Do it to the properties so the values get set in the physics engine. 251 // Do it to the properties so the values get set in the physics engine.
261 // Push the setting of the values to the viewer. 252 // Push the setting of the values to the viewer.
262 // Called at taint time! 253 // Called at taint time!
263 public void ZeroMotion() 254 public override void ZeroMotion()
264 { 255 {
265 _velocity = OMV.Vector3.Zero; 256 _velocity = OMV.Vector3.Zero;
266 _acceleration = OMV.Vector3.Zero; 257 _acceleration = OMV.Vector3.Zero;
@@ -281,7 +272,7 @@ public sealed class BSPrim : PhysicsActor
281 272
282 public override OMV.Vector3 Position { 273 public override OMV.Vector3 Position {
283 get { 274 get {
284 if (!_linkset.IsRoot(this)) 275 if (!Linkset.IsRoot(this))
285 // child prims move around based on their parent. Need to get the latest location 276 // child prims move around based on their parent. Need to get the latest location
286 _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 277 _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
287 278
@@ -306,23 +297,23 @@ public sealed class BSPrim : PhysicsActor
306 { 297 {
307 get 298 get
308 { 299 {
309 return _linkset.LinksetMass; 300 return Linkset.LinksetMass;
310 } 301 }
311 } 302 }
312 303
313 // used when we only want this prim's mass and not the linkset thing 304 // used when we only want this prim's mass and not the linkset thing
314 public float MassRaw { get { return _mass; } } 305 public override float MassRaw { get { return _mass; } }
315 306
316 // Is this used? 307 // Is this used?
317 public override OMV.Vector3 CenterOfMass 308 public override OMV.Vector3 CenterOfMass
318 { 309 {
319 get { return _linkset.CenterOfMass; } 310 get { return Linkset.CenterOfMass; }
320 } 311 }
321 312
322 // Is this used? 313 // Is this used?
323 public override OMV.Vector3 GeometricCenter 314 public override OMV.Vector3 GeometricCenter
324 { 315 {
325 get { return _linkset.GeometricCenter; } 316 get { return Linkset.GeometricCenter; }
326 } 317 }
327 318
328 public override OMV.Vector3 Force { 319 public override OMV.Vector3 Force {
@@ -431,7 +422,7 @@ public sealed class BSPrim : PhysicsActor
431 } 422 }
432 public override OMV.Quaternion Orientation { 423 public override OMV.Quaternion Orientation {
433 get { 424 get {
434 if (!_linkset.IsRoot(this)) 425 if (!Linkset.IsRoot(this))
435 { 426 {
436 // Children move around because tied to parent. Get a fresh value. 427 // Children move around because tied to parent. Get a fresh value.
437 _orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID); 428 _orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID);
@@ -490,7 +481,7 @@ public sealed class BSPrim : PhysicsActor
490 BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass); 481 BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass);
491 482
492 // recompute any linkset parameters 483 // recompute any linkset parameters
493 _linkset.Refresh(this); 484 Linkset.Refresh(this);
494 485
495 CollisionFlags cf = BulletSimAPI.GetCollisionFlags2(Body.Ptr); 486 CollisionFlags cf = BulletSimAPI.GetCollisionFlags2(Body.Ptr);
496 DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, cf); 487 DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, cf);
@@ -1299,7 +1290,7 @@ public sealed class BSPrim : PhysicsActor
1299 const float ACCELERATION_TOLERANCE = 0.01f; 1290 const float ACCELERATION_TOLERANCE = 0.01f;
1300 const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f; 1291 const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f;
1301 1292
1302 public void UpdateProperties(EntityProperties entprop) 1293 public override void UpdateProperties(EntityProperties entprop)
1303 { 1294 {
1304 /* 1295 /*
1305 UpdatedProperties changed = 0; 1296 UpdatedProperties changed = 0;
@@ -1347,7 +1338,7 @@ public sealed class BSPrim : PhysicsActor
1347 // Don't check for damping here -- it's done in BulletSim and SceneObjectPart. 1338 // Don't check for damping here -- it's done in BulletSim and SceneObjectPart.
1348 1339
1349 // Updates only for individual prims and for the root object of a linkset. 1340 // Updates only for individual prims and for the root object of a linkset.
1350 if (_linkset.IsRoot(this)) 1341 if (Linkset.IsRoot(this))
1351 { 1342 {
1352 // Assign to the local variables so the normal set action does not happen 1343 // Assign to the local variables so the normal set action does not happen
1353 _position = entprop.Position; 1344 _position = entprop.Position;
@@ -1375,7 +1366,7 @@ public sealed class BSPrim : PhysicsActor
1375 // I've collided with something 1366 // I've collided with something
1376 // Called at taint time from within the Step() function 1367 // Called at taint time from within the Step() function
1377 CollisionEventUpdate collisionCollection; 1368 CollisionEventUpdate collisionCollection;
1378 public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) 1369 public override void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
1379 { 1370 {
1380 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); 1371 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
1381 1372
@@ -1387,18 +1378,15 @@ public sealed class BSPrim : PhysicsActor
1387 } 1378 }
1388 1379
1389 // DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith); 1380 // DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith);
1390 BSPrim collidingWithPrim; 1381
1391 if (_scene.Prims.TryGetValue(collidingWith, out collidingWithPrim)) 1382 // prims in the same linkset cannot collide with each other
1383 if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID))
1392 { 1384 {
1393 // prims in the same linkset cannot collide with each other 1385 return;
1394 if (this.Linkset.LinksetID == collidingWithPrim.Linkset.LinksetID)
1395 {
1396 return;
1397 }
1398 } 1386 }
1399 1387
1400 // if someone is subscribed to collision events.... 1388 // if someone has subscribed for collision events....
1401 if (_subscribedEventsMs != 0) { 1389 if (SubscribedEvents()) {
1402 // throttle the collisions to the number of milliseconds specified in the subscription 1390 // throttle the collisions to the number of milliseconds specified in the subscription
1403 int nowTime = _scene.SimulationNowTime; 1391 int nowTime = _scene.SimulationNowTime;
1404 if (nowTime >= _nextCollisionOkTime) { 1392 if (nowTime >= _nextCollisionOkTime) {
@@ -1412,7 +1400,7 @@ public sealed class BSPrim : PhysicsActor
1412 } 1400 }
1413 1401
1414 // The scene is telling us it's time to pass our collected collisions into the simulator 1402 // The scene is telling us it's time to pass our collected collisions into the simulator
1415 public void SendCollisions() 1403 public override void SendCollisions()
1416 { 1404 {
1417 if (collisionCollection != null && collisionCollection.Count > 0) 1405 if (collisionCollection != null && collisionCollection.Count > 0)
1418 { 1406 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 56924aa..ce64b9b 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -78,14 +78,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
78 78
79 public string BulletSimVersion = "?"; 79 public string BulletSimVersion = "?";
80 80
81 private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>(); 81 public Dictionary<uint, BSPhysObject> PhysObjects = new Dictionary<uint, BSPhysObject>();
82 public Dictionary<uint, BSCharacter> Characters { get { return m_avatars; } }
83
84 private Dictionary<uint, BSPrim> m_prims = new Dictionary<uint, BSPrim>();
85 public Dictionary<uint, BSPrim> Prims { get { return m_prims; } }
86 82
83 private HashSet<BSPhysObject> m_objectsWithCollisions = new HashSet<BSPhysObject>();
84 // Following is a kludge and can be removed when avatar animation updating is
85 // moved to a better place.
87 private HashSet<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>(); 86 private HashSet<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>();
88 private HashSet<BSPrim> m_primsWithCollisions = new HashSet<BSPrim>();
89 87
90 private List<BSPrim> m_vehicles = new List<BSPrim>(); 88 private List<BSPrim> m_vehicles = new List<BSPrim>();
91 89
@@ -235,7 +233,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
235 // BulletSimVersion = BulletSimAPI.GetVersion(); 233 // BulletSimVersion = BulletSimAPI.GetVersion();
236 // m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion); 234 // m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion);
237 235
238 // if Debug, enable logging from the unmanaged code 236 // If Debug logging level, enable logging from the unmanaged code
239 if (m_log.IsDebugEnabled || PhysicsLogging.Enabled) 237 if (m_log.IsDebugEnabled || PhysicsLogging.Enabled)
240 { 238 {
241 m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader); 239 m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader);
@@ -243,13 +241,14 @@ public class BSScene : PhysicsScene, IPhysicsParameters
243 m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLoggerPhysLog); 241 m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLoggerPhysLog);
244 else 242 else
245 m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger); 243 m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger);
246 // the handle is saved in a variable to make sure it doesn't get freed after this call 244 // The handle is saved in a variable to make sure it doesn't get freed after this call
247 BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle); 245 BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle);
248 } 246 }
249 247
250 _taintedObjects = new List<TaintCallbackEntry>(); 248 _taintedObjects = new List<TaintCallbackEntry>();
251 249
252 mesher = meshmerizer; 250 mesher = meshmerizer;
251
253 // The bounding box for the simulated world 252 // The bounding box for the simulated world
254 Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 8192f); 253 Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 8192f);
255 254
@@ -337,7 +336,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
337 if (!m_initialized) return null; 336 if (!m_initialized) return null;
338 337
339 BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying); 338 BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying);
340 lock (m_avatars) m_avatars.Add(localID, actor); 339 lock (PhysObjects) PhysObjects.Add(localID, actor);
340
341 // Remove kludge someday
342 lock (m_avatarsWithCollisions) m_avatarsWithCollisions.Add(actor);
343
341 return actor; 344 return actor;
342 } 345 }
343 346
@@ -352,7 +355,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
352 { 355 {
353 try 356 try
354 { 357 {
355 lock (m_avatars) m_avatars.Remove(actor.LocalID); 358 lock (PhysObjects) PhysObjects.Remove(actor.LocalID);
359 // Remove kludge someday
360 lock (m_avatarsWithCollisions) m_avatarsWithCollisions.Remove(bsactor);
356 } 361 }
357 catch (Exception e) 362 catch (Exception e)
358 { 363 {
@@ -374,7 +379,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
374 // m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID); 379 // m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID);
375 try 380 try
376 { 381 {
377 lock (m_prims) m_prims.Remove(bsprim.LocalID); 382 lock (PhysObjects) PhysObjects.Remove(bsprim.LocalID);
378 } 383 }
379 catch (Exception e) 384 catch (Exception e)
380 { 385 {
@@ -399,7 +404,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
399 DetailLog("{0},AddPrimShape,call", localID); 404 DetailLog("{0},AddPrimShape,call", localID);
400 405
401 BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical); 406 BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical);
402 lock (m_prims) m_prims.Add(localID, prim); 407 lock (PhysObjects) PhysObjects.Add(localID, prim);
403 return prim; 408 return prim;
404 } 409 }
405 410
@@ -470,19 +475,16 @@ public class BSScene : PhysicsScene, IPhysicsParameters
470 475
471 // The above SendCollision's batch up the collisions on the objects. 476 // The above SendCollision's batch up the collisions on the objects.
472 // Now push the collisions into the simulator. 477 // Now push the collisions into the simulator.
473 foreach (BSPrim bsp in m_primsWithCollisions) 478 foreach (BSPhysObject bsp in m_objectsWithCollisions)
474 bsp.SendCollisions(); 479 bsp.SendCollisions();
475 m_primsWithCollisions.Clear(); 480 m_objectsWithCollisions.Clear();
476 481
477 // This is a kludge to get avatar movement updated. 482 // This is a kludge to get avatar movement updated.
478 // Don't send collisions only if there were collisions -- send everytime.
479 // ODE sends collisions even if there are none and this is used to update 483 // ODE sends collisions even if there are none and this is used to update
480 // avatar animations and stuff. 484 // avatar animations and stuff.
481 // foreach (BSCharacter bsc in m_avatarsWithCollisions) 485 foreach (BSPhysObject bpo in m_avatarsWithCollisions)
482 // bsc.SendCollisions(); 486 bpo.SendCollisions();
483 foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars) 487 // m_avatarsWithCollisions.Clear();
484 kvp.Value.SendCollisions();
485 m_avatarsWithCollisions.Clear();
486 488
487 // If any of the objects had updated properties, tell the object it has been changed by the physics engine 489 // If any of the objects had updated properties, tell the object it has been changed by the physics engine
488 if (updatedEntityCount > 0) 490 if (updatedEntityCount > 0)
@@ -490,16 +492,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
490 for (int ii = 0; ii < updatedEntityCount; ii++) 492 for (int ii = 0; ii < updatedEntityCount; ii++)
491 { 493 {
492 EntityProperties entprop = m_updateArray[ii]; 494 EntityProperties entprop = m_updateArray[ii];
493 BSPrim prim; 495 BSPhysObject pobj;
494 if (m_prims.TryGetValue(entprop.ID, out prim)) 496 if (PhysObjects.TryGetValue(entprop.ID, out pobj))
495 {
496 prim.UpdateProperties(entprop);
497 continue;
498 }
499 BSCharacter actor;
500 if (m_avatars.TryGetValue(entprop.ID, out actor))
501 { 497 {
502 actor.UpdateProperties(entprop); 498 pobj.UpdateProperties(entprop);
503 continue; 499 continue;
504 } 500 }
505 } 501 }
@@ -529,33 +525,36 @@ public class BSScene : PhysicsScene, IPhysicsParameters
529 } 525 }
530 526
531 // Something has collided 527 // Something has collided
532 private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal, float penitration) 528 private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal, float penetration)
533 { 529 {
534 if (localID == TERRAIN_ID || localID == GROUNDPLANE_ID) 530 if (localID == TERRAIN_ID || localID == GROUNDPLANE_ID)
535 { 531 {
536 return; // don't send collisions to the terrain 532 return; // don't send collisions to the terrain
537 } 533 }
538 534
535 BSPhysObject collider = PhysObjects[localID];
536 // TODO: as of this code, terrain was not in the physical object list.
537 // When BSTerrain is created and it will be in the list, we can remove
538 // the possibility that it's not there and just fetch the collidee.
539 BSPhysObject collidee = null;
540
539 ActorTypes type = ActorTypes.Prim; 541 ActorTypes type = ActorTypes.Prim;
540 if (collidingWith == TERRAIN_ID || collidingWith == GROUNDPLANE_ID) 542 if (collidingWith == TERRAIN_ID || collidingWith == GROUNDPLANE_ID)
543 {
541 type = ActorTypes.Ground; 544 type = ActorTypes.Ground;
542 else if (m_avatars.ContainsKey(collidingWith)) 545 }
543 type = ActorTypes.Agent; 546 else
547 {
548 collidee = PhysObjects[collidingWith];
549 if (collidee is BSCharacter)
550 type = ActorTypes.Agent;
551 }
544 552
545 // DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith); 553 // DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith);
546 554
547 BSPrim prim; 555 collider.Collide(collidingWith, collidee, type, collidePoint, collideNormal, penetration);
548 if (m_prims.TryGetValue(localID, out prim)) { 556 m_objectsWithCollisions.Add(collider);
549 prim.Collide(collidingWith, type, collidePoint, collideNormal, penitration); 557
550 m_primsWithCollisions.Add(prim);
551 return;
552 }
553 BSCharacter actor;
554 if (m_avatars.TryGetValue(localID, out actor)) {
555 actor.Collide(collidingWith, type, collidePoint, collideNormal, penitration);
556 m_avatarsWithCollisions.Add(actor);
557 return;
558 }
559 return; 558 return;
560 } 559 }
561 560
@@ -605,17 +604,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
605 // make sure no stepping happens while we're deleting stuff 604 // make sure no stepping happens while we're deleting stuff
606 m_initialized = false; 605 m_initialized = false;
607 606
608 foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars) 607 foreach (KeyValuePair<uint, BSPhysObject> kvp in PhysObjects)
609 {
610 kvp.Value.Destroy();
611 }
612 m_avatars.Clear();
613
614 foreach (KeyValuePair<uint, BSPrim> kvp in m_prims)
615 { 608 {
616 kvp.Value.Destroy(); 609 kvp.Value.Destroy();
617 } 610 }
618 m_prims.Clear(); 611 PhysObjects.Clear();
619 612
620 // Now that the prims are all cleaned up, there should be no constraints left 613 // Now that the prims are all cleaned up, there should be no constraints left
621 if (m_constraintCollection != null) 614 if (m_constraintCollection != null)
@@ -996,42 +989,42 @@ public class BSScene : PhysicsScene, IPhysicsParameters
996 0f, 989 0f,
997 (s,cf,p,v) => { s.m_params[0].linearDamping = cf.GetFloat(p, v); }, 990 (s,cf,p,v) => { s.m_params[0].linearDamping = cf.GetFloat(p, v); },
998 (s) => { return s.m_params[0].linearDamping; }, 991 (s) => { return s.m_params[0].linearDamping; },
999 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].linearDamping, p, l, v); } ), 992 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearDamping, p, l, v); } ),
1000 new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)", 993 new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)",
1001 0f, 994 0f,
1002 (s,cf,p,v) => { s.m_params[0].angularDamping = cf.GetFloat(p, v); }, 995 (s,cf,p,v) => { s.m_params[0].angularDamping = cf.GetFloat(p, v); },
1003 (s) => { return s.m_params[0].angularDamping; }, 996 (s) => { return s.m_params[0].angularDamping; },
1004 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].angularDamping, p, l, v); } ), 997 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularDamping, p, l, v); } ),
1005 new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static", 998 new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static",
1006 0.2f, 999 0.2f,
1007 (s,cf,p,v) => { s.m_params[0].deactivationTime = cf.GetFloat(p, v); }, 1000 (s,cf,p,v) => { s.m_params[0].deactivationTime = cf.GetFloat(p, v); },
1008 (s) => { return s.m_params[0].deactivationTime; }, 1001 (s) => { return s.m_params[0].deactivationTime; },
1009 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].deactivationTime, p, l, v); } ), 1002 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].deactivationTime, p, l, v); } ),
1010 new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static", 1003 new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static",
1011 0.8f, 1004 0.8f,
1012 (s,cf,p,v) => { s.m_params[0].linearSleepingThreshold = cf.GetFloat(p, v); }, 1005 (s,cf,p,v) => { s.m_params[0].linearSleepingThreshold = cf.GetFloat(p, v); },
1013 (s) => { return s.m_params[0].linearSleepingThreshold; }, 1006 (s) => { return s.m_params[0].linearSleepingThreshold; },
1014 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].linearSleepingThreshold, p, l, v); } ), 1007 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearSleepingThreshold, p, l, v); } ),
1015 new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static", 1008 new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static",
1016 1.0f, 1009 1.0f,
1017 (s,cf,p,v) => { s.m_params[0].angularSleepingThreshold = cf.GetFloat(p, v); }, 1010 (s,cf,p,v) => { s.m_params[0].angularSleepingThreshold = cf.GetFloat(p, v); },
1018 (s) => { return s.m_params[0].angularSleepingThreshold; }, 1011 (s) => { return s.m_params[0].angularSleepingThreshold; },
1019 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].angularSleepingThreshold, p, l, v); } ), 1012 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularSleepingThreshold, p, l, v); } ),
1020 new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , 1013 new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ,
1021 0f, // set to zero to disable 1014 0f, // set to zero to disable
1022 (s,cf,p,v) => { s.m_params[0].ccdMotionThreshold = cf.GetFloat(p, v); }, 1015 (s,cf,p,v) => { s.m_params[0].ccdMotionThreshold = cf.GetFloat(p, v); },
1023 (s) => { return s.m_params[0].ccdMotionThreshold; }, 1016 (s) => { return s.m_params[0].ccdMotionThreshold; },
1024 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].ccdMotionThreshold, p, l, v); } ), 1017 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdMotionThreshold, p, l, v); } ),
1025 new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , 1018 new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" ,
1026 0f, 1019 0f,
1027 (s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); }, 1020 (s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); },
1028 (s) => { return s.m_params[0].ccdSweptSphereRadius; }, 1021 (s) => { return s.m_params[0].ccdSweptSphereRadius; },
1029 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); } ), 1022 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); } ),
1030 new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" , 1023 new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" ,
1031 0.1f, 1024 0.1f,
1032 (s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); }, 1025 (s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); },
1033 (s) => { return s.m_params[0].contactProcessingThreshold; }, 1026 (s) => { return s.m_params[0].contactProcessingThreshold; },
1034 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].contactProcessingThreshold, p, l, v); } ), 1027 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].contactProcessingThreshold, p, l, v); } ),
1035 1028
1036 new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , 1029 new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" ,
1037 0.5f, 1030 0.5f,
@@ -1052,32 +1045,32 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1052 0.5f, 1045 0.5f,
1053 (s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); }, 1046 (s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); },
1054 (s) => { return s.m_params[0].avatarFriction; }, 1047 (s) => { return s.m_params[0].avatarFriction; },
1055 (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarFriction, p, l, v); } ), 1048 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarFriction, p, l, v); } ),
1056 new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.", 1049 new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.",
1057 60f, 1050 60f,
1058 (s,cf,p,v) => { s.m_params[0].avatarDensity = cf.GetFloat(p, v); }, 1051 (s,cf,p,v) => { s.m_params[0].avatarDensity = cf.GetFloat(p, v); },
1059 (s) => { return s.m_params[0].avatarDensity; }, 1052 (s) => { return s.m_params[0].avatarDensity; },
1060 (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarDensity, p, l, v); } ), 1053 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarDensity, p, l, v); } ),
1061 new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.", 1054 new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.",
1062 0f, 1055 0f,
1063 (s,cf,p,v) => { s.m_params[0].avatarRestitution = cf.GetFloat(p, v); }, 1056 (s,cf,p,v) => { s.m_params[0].avatarRestitution = cf.GetFloat(p, v); },
1064 (s) => { return s.m_params[0].avatarRestitution; }, 1057 (s) => { return s.m_params[0].avatarRestitution; },
1065 (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarRestitution, p, l, v); } ), 1058 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarRestitution, p, l, v); } ),
1066 new ParameterDefn("AvatarCapsuleRadius", "Radius of space around an avatar", 1059 new ParameterDefn("AvatarCapsuleRadius", "Radius of space around an avatar",
1067 0.37f, 1060 0.37f,
1068 (s,cf,p,v) => { s.m_params[0].avatarCapsuleRadius = cf.GetFloat(p, v); }, 1061 (s,cf,p,v) => { s.m_params[0].avatarCapsuleRadius = cf.GetFloat(p, v); },
1069 (s) => { return s.m_params[0].avatarCapsuleRadius; }, 1062 (s) => { return s.m_params[0].avatarCapsuleRadius; },
1070 (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarCapsuleRadius, p, l, v); } ), 1063 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleRadius, p, l, v); } ),
1071 new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar", 1064 new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar",
1072 1.5f, 1065 1.5f,
1073 (s,cf,p,v) => { s.m_params[0].avatarCapsuleHeight = cf.GetFloat(p, v); }, 1066 (s,cf,p,v) => { s.m_params[0].avatarCapsuleHeight = cf.GetFloat(p, v); },
1074 (s) => { return s.m_params[0].avatarCapsuleHeight; }, 1067 (s) => { return s.m_params[0].avatarCapsuleHeight; },
1075 (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarCapsuleHeight, p, l, v); } ), 1068 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleHeight, p, l, v); } ),
1076 new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", 1069 new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
1077 0.1f, 1070 0.1f,
1078 (s,cf,p,v) => { s.m_params[0].avatarContactProcessingThreshold = cf.GetFloat(p, v); }, 1071 (s,cf,p,v) => { s.m_params[0].avatarContactProcessingThreshold = cf.GetFloat(p, v); },
1079 (s) => { return s.m_params[0].avatarContactProcessingThreshold; }, 1072 (s) => { return s.m_params[0].avatarContactProcessingThreshold; },
1080 (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ), 1073 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ),
1081 1074
1082 1075
1083 new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", 1076 new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
@@ -1264,18 +1257,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1264 } 1257 }
1265 1258
1266 // check to see if we are updating a parameter for a particular or all of the prims 1259 // check to see if we are updating a parameter for a particular or all of the prims
1267 protected void UpdateParameterPrims(ref float loc, string parm, uint localID, float val) 1260 protected void UpdateParameterObject(ref float loc, string parm, uint localID, float val)
1268 {
1269 List<uint> operateOn;
1270 lock (m_prims) operateOn = new List<uint>(m_prims.Keys);
1271 UpdateParameterSet(operateOn, ref loc, parm, localID, val);
1272 }
1273
1274 // check to see if we are updating a parameter for a particular or all of the avatars
1275 protected void UpdateParameterAvatars(ref float loc, string parm, uint localID, float val)
1276 { 1261 {
1277 List<uint> operateOn; 1262 List<uint> operateOn;
1278 lock (m_avatars) operateOn = new List<uint>(m_avatars.Keys); 1263 lock (PhysObjects) operateOn = new List<uint>(PhysObjects.Keys);
1279 UpdateParameterSet(operateOn, ref loc, parm, localID, val); 1264 UpdateParameterSet(operateOn, ref loc, parm, localID, val);
1280 } 1265 }
1281 1266