diff options
author | Justin Clark-Casey (justincc) | 2012-12-14 23:29:33 +0000 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2012-12-14 23:29:33 +0000 |
commit | 2816551215958d866fca03906df4058cf0e4b19b (patch) | |
tree | 26eeb122bb197ed89db22f7de0ef97ff4aedf025 /OpenSim/Region/Physics | |
parent | Fix issue where calling llVolumeDetect(FALSE) would not remove phantom flag, ... (diff) | |
parent | BulletSim: Add more to the TODO list. Clean up and improve some comments. (diff) | |
download | opensim-SC-2816551215958d866fca03906df4058cf0e4b19b.zip opensim-SC-2816551215958d866fca03906df4058cf0e4b19b.tar.gz opensim-SC-2816551215958d866fca03906df4058cf0e4b19b.tar.bz2 opensim-SC-2816551215958d866fca03906df4058cf0e4b19b.tar.xz |
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
Diffstat (limited to 'OpenSim/Region/Physics')
12 files changed, 433 insertions, 301 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index c8aad8d..0defb24 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -167,9 +167,8 @@ public sealed class BSCharacter : BSPhysObject | |||
167 | BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); | 167 | BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); |
168 | 168 | ||
169 | // Do this after the object has been added to the world | 169 | // Do this after the object has been added to the world |
170 | BulletSimAPI.SetCollisionGroupMask2(PhysBody.ptr, | 170 | PhysBody.collisionType = CollisionType.Avatar; |
171 | (uint)CollisionFilterGroups.AvatarGroup, | 171 | PhysBody.ApplyCollisionMask(); |
172 | (uint)CollisionFilterGroups.AvatarMask); | ||
173 | } | 172 | } |
174 | 173 | ||
175 | public override void RequestPhysicsterseUpdate() | 174 | public override void RequestPhysicsterseUpdate() |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 777c5cb..ce0fbe6 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | |||
@@ -124,7 +124,7 @@ public abstract class BSLinkset | |||
124 | get { return ComputeLinksetGeometricCenter(); } | 124 | get { return ComputeLinksetGeometricCenter(); } |
125 | } | 125 | } |
126 | 126 | ||
127 | protected void Initialize(BSScene scene, BSPhysObject parent) | 127 | protected BSLinkset(BSScene scene, BSPhysObject parent) |
128 | { | 128 | { |
129 | // A simple linkset of one (no children) | 129 | // A simple linkset of one (no children) |
130 | LinksetID = m_nextLinksetID++; | 130 | LinksetID = m_nextLinksetID++; |
@@ -135,6 +135,7 @@ public abstract class BSLinkset | |||
135 | LinksetRoot = parent; | 135 | LinksetRoot = parent; |
136 | m_children = new HashSet<BSPhysObject>(); | 136 | m_children = new HashSet<BSPhysObject>(); |
137 | m_mass = parent.RawMass; | 137 | m_mass = parent.RawMass; |
138 | Rebuilding = false; | ||
138 | } | 139 | } |
139 | 140 | ||
140 | // Link to a linkset where the child knows the parent. | 141 | // Link to a linkset where the child knows the parent. |
@@ -227,7 +228,7 @@ public abstract class BSLinkset | |||
227 | // I am the root of a linkset and a new child is being added | 228 | // I am the root of a linkset and a new child is being added |
228 | // Called while LinkActivity is locked. | 229 | // Called while LinkActivity is locked. |
229 | protected abstract void AddChildToLinkset(BSPhysObject child); | 230 | protected abstract void AddChildToLinkset(BSPhysObject child); |
230 | 231 | ||
231 | // I am the root of a linkset and one of my children is being removed. | 232 | // I am the root of a linkset and one of my children is being removed. |
232 | // Safe to call even if the child is not really in my linkset. | 233 | // Safe to call even if the child is not really in my linkset. |
233 | protected abstract void RemoveChildFromLinkset(BSPhysObject child); | 234 | protected abstract void RemoveChildFromLinkset(BSPhysObject child); |
@@ -237,6 +238,10 @@ public abstract class BSLinkset | |||
237 | // May be called at runtime or taint-time. | 238 | // May be called at runtime or taint-time. |
238 | public abstract void Refresh(BSPhysObject requestor); | 239 | public abstract void Refresh(BSPhysObject requestor); |
239 | 240 | ||
241 | // Flag denoting the linkset is in the process of being rebuilt. | ||
242 | // Used to know not the schedule a rebuild in the middle of a rebuild. | ||
243 | protected bool Rebuilding { get; set; } | ||
244 | |||
240 | // The object is going dynamic (physical). Do any setup necessary | 245 | // The object is going dynamic (physical). Do any setup necessary |
241 | // for a dynamic linkset. | 246 | // for a dynamic linkset. |
242 | // Only the state of the passed object can be modified. The rest of the linkset | 247 | // Only the state of the passed object can be modified. The rest of the linkset |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index d2abdb4..2189468 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | |||
@@ -61,9 +61,8 @@ public sealed class BSLinksetCompound : BSLinkset | |||
61 | { | 61 | { |
62 | private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]"; | 62 | private static string LogHeader = "[BULLETSIM LINKSET COMPOUND]"; |
63 | 63 | ||
64 | public BSLinksetCompound(BSScene scene, BSPhysObject parent) | 64 | public BSLinksetCompound(BSScene scene, BSPhysObject parent) : base(scene, parent) |
65 | { | 65 | { |
66 | base.Initialize(scene, parent); | ||
67 | } | 66 | } |
68 | 67 | ||
69 | // For compound implimented linksets, if there are children, use compound shape for the root. | 68 | // For compound implimented linksets, if there are children, use compound shape for the root. |
@@ -81,8 +80,6 @@ public sealed class BSLinksetCompound : BSLinkset | |||
81 | 80 | ||
82 | // When physical properties are changed the linkset needs to recalculate | 81 | // When physical properties are changed the linkset needs to recalculate |
83 | // its internal properties. | 82 | // its internal properties. |
84 | // This is queued in the 'post taint' queue so the | ||
85 | // refresh will happen once after all the other taints are applied. | ||
86 | public override void Refresh(BSPhysObject requestor) | 83 | public override void Refresh(BSPhysObject requestor) |
87 | { | 84 | { |
88 | // External request for Refresh (from BSPrim) doesn't need to do anything | 85 | // External request for Refresh (from BSPrim) doesn't need to do anything |
@@ -92,12 +89,18 @@ public sealed class BSLinksetCompound : BSLinkset | |||
92 | // Schedule a refresh to happen after all the other taint processing. | 89 | // Schedule a refresh to happen after all the other taint processing. |
93 | private void InternalRefresh(BSPhysObject requestor) | 90 | private void InternalRefresh(BSPhysObject requestor) |
94 | { | 91 | { |
95 | DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,requestor={1}", LinksetRoot.LocalID, requestor.LocalID); | 92 | DetailLog("{0},BSLinksetCompound.Refresh,schedulingRefresh,requestor={1},rebuilding={2}", |
96 | PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", requestor.LocalID, delegate() | 93 | LinksetRoot.LocalID, requestor.LocalID, Rebuilding); |
94 | // When rebuilding, it is possible to set properties that would normally require a rebuild. | ||
95 | // If already rebuilding, don't request another rebuild. | ||
96 | if (!Rebuilding) | ||
97 | { | 97 | { |
98 | if (IsRoot(requestor) && HasAnyChildren) | 98 | PhysicsScene.PostTaintObject("BSLinksetCompound.Refresh", requestor.LocalID, delegate() |
99 | RecomputeLinksetCompound(); | 99 | { |
100 | }); | 100 | if (IsRoot(requestor) && HasAnyChildren) |
101 | RecomputeLinksetCompound(); | ||
102 | }); | ||
103 | } | ||
101 | } | 104 | } |
102 | 105 | ||
103 | // The object is going dynamic (physical). Do any setup necessary | 106 | // The object is going dynamic (physical). Do any setup necessary |
@@ -114,6 +117,8 @@ public sealed class BSLinksetCompound : BSLinkset | |||
114 | { | 117 | { |
115 | // The root is going dynamic. Make sure mass is properly set. | 118 | // The root is going dynamic. Make sure mass is properly set. |
116 | m_mass = ComputeLinksetMass(); | 119 | m_mass = ComputeLinksetMass(); |
120 | if (HasAnyChildren) | ||
121 | InternalRefresh(LinksetRoot); | ||
117 | } | 122 | } |
118 | else | 123 | else |
119 | { | 124 | { |
@@ -123,6 +128,9 @@ public sealed class BSLinksetCompound : BSLinkset | |||
123 | BulletSimAPI.ForceActivationState2(child.PhysBody.ptr, ActivationState.DISABLE_SIMULATION); | 128 | BulletSimAPI.ForceActivationState2(child.PhysBody.ptr, ActivationState.DISABLE_SIMULATION); |
124 | // We don't want collisions from the old linkset children. | 129 | // We don't want collisions from the old linkset children. |
125 | BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); | 130 | BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); |
131 | |||
132 | child.PhysBody.collisionType = CollisionType.LinksetChild; | ||
133 | |||
126 | ret = true; | 134 | ret = true; |
127 | } | 135 | } |
128 | return ret; | 136 | return ret; |
@@ -137,10 +145,18 @@ public sealed class BSLinksetCompound : BSLinkset | |||
137 | { | 145 | { |
138 | bool ret = false; | 146 | bool ret = false; |
139 | DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child)); | 147 | DetailLog("{0},BSLinksetCompound.MakeStatic,call,IsRoot={1}", child.LocalID, IsRoot(child)); |
140 | if (!IsRoot(child)) | 148 | if (IsRoot(child)) |
149 | { | ||
150 | if (HasAnyChildren) | ||
151 | InternalRefresh(LinksetRoot); | ||
152 | } | ||
153 | else | ||
141 | { | 154 | { |
142 | // The non-physical children can come back to life. | 155 | // The non-physical children can come back to life. |
143 | BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); | 156 | BulletSimAPI.RemoveFromCollisionFlags2(child.PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); |
157 | |||
158 | child.PhysBody.collisionType = CollisionType.LinksetChild; | ||
159 | |||
144 | // Don't force activation so setting of DISABLE_SIMULATION can stay if used. | 160 | // Don't force activation so setting of DISABLE_SIMULATION can stay if used. |
145 | BulletSimAPI.Activate2(child.PhysBody.ptr, false); | 161 | BulletSimAPI.Activate2(child.PhysBody.ptr, false); |
146 | ret = true; | 162 | ret = true; |
@@ -182,19 +198,25 @@ public sealed class BSLinksetCompound : BSLinkset | |||
182 | // Because it is a convenient time, recompute child world position and rotation based on | 198 | // Because it is a convenient time, recompute child world position and rotation based on |
183 | // its position in the linkset. | 199 | // its position in the linkset. |
184 | RecomputeChildWorldPosition(child, true); | 200 | RecomputeChildWorldPosition(child, true); |
185 | |||
186 | // Cause the current shape to be freed and the new one to be built. | ||
187 | InternalRefresh(LinksetRoot); | ||
188 | ret = true; | ||
189 | } | 201 | } |
190 | 202 | ||
203 | // Cannot schedule a refresh/rebuild here because this routine is called when | ||
204 | // the linkset is being rebuilt. | ||
205 | // InternalRefresh(LinksetRoot); | ||
206 | |||
191 | return ret; | 207 | return ret; |
192 | } | 208 | } |
193 | 209 | ||
194 | // When the linkset is built, the child shape is added | 210 | // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', |
195 | // to the compound shape relative to the root shape. The linkset then moves around but | 211 | // this routine will restore the removed constraints. |
196 | // this does not move the actual child prim. The child prim's location must be recomputed | 212 | // Called at taint-time!! |
197 | // based on the location of the root shape. | 213 | public override void RestoreBodyDependencies(BSPrim child) |
214 | { | ||
215 | } | ||
216 | |||
217 | // When the linkset is built, the child shape is added to the compound shape relative to the | ||
218 | // root shape. The linkset then moves around but this does not move the actual child | ||
219 | // prim. The child prim's location must be recomputed based on the location of the root shape. | ||
198 | private void RecomputeChildWorldPosition(BSPhysObject child, bool inTaintTime) | 220 | private void RecomputeChildWorldPosition(BSPhysObject child, bool inTaintTime) |
199 | { | 221 | { |
200 | BSLinksetCompoundInfo lci = child.LinksetInfo as BSLinksetCompoundInfo; | 222 | BSLinksetCompoundInfo lci = child.LinksetInfo as BSLinksetCompoundInfo; |
@@ -227,14 +249,6 @@ public sealed class BSLinksetCompound : BSLinkset | |||
227 | } | 249 | } |
228 | } | 250 | } |
229 | 251 | ||
230 | // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', | ||
231 | // this routine will restore the removed constraints. | ||
232 | // Called at taint-time!! | ||
233 | public override void RestoreBodyDependencies(BSPrim child) | ||
234 | { | ||
235 | // The Refresh operation queued by RemoveBodyDependencies() will build any missing constraints. | ||
236 | } | ||
237 | |||
238 | // ================================================================ | 252 | // ================================================================ |
239 | 253 | ||
240 | // Add a new child to the linkset. | 254 | // Add a new child to the linkset. |
@@ -254,7 +268,7 @@ public sealed class BSLinksetCompound : BSLinkset | |||
254 | } | 268 | } |
255 | 269 | ||
256 | // Remove the specified child from the linkset. | 270 | // Remove the specified child from the linkset. |
257 | // Safe to call even if the child is not really in my linkset. | 271 | // Safe to call even if the child is not really in the linkset. |
258 | protected override void RemoveChildFromLinkset(BSPhysObject child) | 272 | protected override void RemoveChildFromLinkset(BSPhysObject child) |
259 | { | 273 | { |
260 | if (m_children.Remove(child)) | 274 | if (m_children.Remove(child)) |
@@ -289,74 +303,83 @@ public sealed class BSLinksetCompound : BSLinkset | |||
289 | // Called at taint time!! | 303 | // Called at taint time!! |
290 | private void RecomputeLinksetCompound() | 304 | private void RecomputeLinksetCompound() |
291 | { | 305 | { |
292 | // Cause the root shape to be rebuilt as a compound object with just the root in it | 306 | try |
293 | LinksetRoot.ForceBodyShapeRebuild(true); | 307 | { |
308 | // Suppress rebuilding while rebuilding | ||
309 | Rebuilding = true; | ||
294 | 310 | ||
295 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", | 311 | // Cause the root shape to be rebuilt as a compound object with just the root in it |
296 | LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); | 312 | LinksetRoot.ForceBodyShapeRebuild(true); |
297 | 313 | ||
298 | // Add a shape for each of the other children in the linkset | 314 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,start,rBody={1},rShape={2},numChildren={3}", |
299 | ForEachMember(delegate(BSPhysObject cPrim) | 315 | LinksetRoot.LocalID, LinksetRoot.PhysBody, LinksetRoot.PhysShape, NumberOfChildren); |
300 | { | 316 | |
301 | if (!IsRoot(cPrim)) | 317 | // Add a shape for each of the other children in the linkset |
318 | ForEachMember(delegate(BSPhysObject cPrim) | ||
302 | { | 319 | { |
303 | // Compute the displacement of the child from the root of the linkset. | 320 | if (!IsRoot(cPrim)) |
304 | // This info is saved in the child prim so the relationship does not | ||
305 | // change over time and the new child position can be computed | ||
306 | // when the linkset is being disassembled (the linkset may have moved). | ||
307 | BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; | ||
308 | if (lci == null) | ||
309 | { | 321 | { |
310 | // Each child position and rotation is given relative to the root. | 322 | // Compute the displacement of the child from the root of the linkset. |
311 | OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); | 323 | // This info is saved in the child prim so the relationship does not |
312 | OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; | 324 | // change over time and the new child position can be computed |
313 | OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; | 325 | // when the linkset is being disassembled (the linkset may have moved). |
314 | 326 | BSLinksetCompoundInfo lci = cPrim.LinksetInfo as BSLinksetCompoundInfo; | |
315 | // Save relative position for recomputing child's world position after moving linkset. | 327 | if (lci == null) |
316 | lci = new BSLinksetCompoundInfo(displacementPos, displacementRot); | 328 | { |
317 | cPrim.LinksetInfo = lci; | 329 | // Each child position and rotation is given relative to the root. |
318 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); | 330 | OMV.Quaternion invRootOrientation = OMV.Quaternion.Inverse(LinksetRoot.RawOrientation); |
319 | } | 331 | OMV.Vector3 displacementPos = (cPrim.RawPosition - LinksetRoot.RawPosition) * invRootOrientation; |
332 | OMV.Quaternion displacementRot = cPrim.RawOrientation * invRootOrientation; | ||
333 | |||
334 | // Save relative position for recomputing child's world position after moving linkset. | ||
335 | lci = new BSLinksetCompoundInfo(displacementPos, displacementRot); | ||
336 | cPrim.LinksetInfo = lci; | ||
337 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,creatingRelPos,lci={1}", cPrim.LocalID, lci); | ||
338 | } | ||
320 | 339 | ||
321 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", | 340 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addMemberToShape,mID={1},mShape={2},dispPos={3},dispRot={4}", |
322 | LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); | 341 | LinksetRoot.LocalID, cPrim.LocalID, cPrim.PhysShape, lci.OffsetPos, lci.OffsetRot); |
323 | 342 | ||
324 | if (cPrim.PhysShape.isNativeShape) | 343 | if (cPrim.PhysShape.isNativeShape) |
325 | { | 344 | { |
326 | // A native shape is turning into a hull collision shape because native | 345 | // A native shape is turning into a hull collision shape because native |
327 | // shapes are not shared so we have to hullify it so it will be tracked | 346 | // shapes are not shared so we have to hullify it so it will be tracked |
328 | // and freed at the correct time. This also solves the scaling problem | 347 | // and freed at the correct time. This also solves the scaling problem |
329 | // (native shapes scaled but hull/meshes are assumed to not be). | 348 | // (native shapes scaled but hull/meshes are assumed to not be). |
330 | // TODO: decide of the native shape can just be used in the compound shape. | 349 | // TODO: decide of the native shape can just be used in the compound shape. |
331 | // Use call to CreateGeomNonSpecial(). | 350 | // Use call to CreateGeomNonSpecial(). |
332 | BulletShape saveShape = cPrim.PhysShape; | 351 | BulletShape saveShape = cPrim.PhysShape; |
333 | cPrim.PhysShape.Clear(); // Don't let the create free the child's shape | 352 | cPrim.PhysShape.Clear(); // Don't let the create free the child's shape |
334 | // PhysicsScene.Shapes.CreateGeomNonSpecial(true, cPrim, null); | 353 | // PhysicsScene.Shapes.CreateGeomNonSpecial(true, cPrim, null); |
335 | PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); | 354 | PhysicsScene.Shapes.CreateGeomMeshOrHull(cPrim, null); |
336 | BulletShape newShape = cPrim.PhysShape; | 355 | BulletShape newShape = cPrim.PhysShape; |
337 | cPrim.PhysShape = saveShape; | 356 | cPrim.PhysShape = saveShape; |
338 | BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, newShape.ptr, lci.OffsetPos , lci.OffsetRot); | 357 | BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, newShape.ptr, lci.OffsetPos, lci.OffsetRot); |
339 | } | 358 | } |
340 | else | 359 | else |
341 | { | ||
342 | // For the shared shapes (meshes and hulls), just use the shape in the child. | ||
343 | // The reference count added here will be decremented when the compound shape | ||
344 | // is destroyed in BSShapeCollection (the child shapes are looped over and dereferenced). | ||
345 | if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape)) | ||
346 | { | 360 | { |
347 | PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", | 361 | // For the shared shapes (meshes and hulls), just use the shape in the child. |
348 | LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); | 362 | // The reference count added here will be decremented when the compound shape |
363 | // is destroyed in BSShapeCollection (the child shapes are looped over and dereferenced). | ||
364 | if (PhysicsScene.Shapes.ReferenceShape(cPrim.PhysShape)) | ||
365 | { | ||
366 | PhysicsScene.Logger.ErrorFormat("{0} Rebuilt sharable shape when building linkset! Region={1}, primID={2}, shape={3}", | ||
367 | LogHeader, PhysicsScene.RegionName, cPrim.LocalID, cPrim.PhysShape); | ||
368 | } | ||
369 | BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, lci.OffsetPos, lci.OffsetRot); | ||
349 | } | 370 | } |
350 | BulletSimAPI.AddChildShapeToCompoundShape2(LinksetRoot.PhysShape.ptr, cPrim.PhysShape.ptr, lci.OffsetPos , lci.OffsetRot); | ||
351 | } | 371 | } |
352 | } | 372 | return false; // 'false' says to move onto the next child in the list |
353 | 373 | }); | |
354 | return false; // 'false' says to move onto the next child in the list | ||
355 | }); | ||
356 | 374 | ||
357 | // With all of the linkset packed into the root prim, it has the mass of everyone. | 375 | // With all of the linkset packed into the root prim, it has the mass of everyone. |
358 | float linksetMass = LinksetMass; | 376 | float linksetMass = LinksetMass; |
359 | LinksetRoot.UpdatePhysicalMassProperties(linksetMass); | 377 | LinksetRoot.UpdatePhysicalMassProperties(linksetMass); |
378 | } | ||
379 | finally | ||
380 | { | ||
381 | Rebuilding = false; | ||
382 | } | ||
360 | 383 | ||
361 | BulletSimAPI.RecalculateCompoundShapeLocalAabb2(LinksetRoot.PhysShape.ptr); | 384 | BulletSimAPI.RecalculateCompoundShapeLocalAabb2(LinksetRoot.PhysShape.ptr); |
362 | 385 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs index c855fda..732c084 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetConstraints.cs | |||
@@ -36,9 +36,8 @@ public sealed class BSLinksetConstraints : BSLinkset | |||
36 | { | 36 | { |
37 | // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; | 37 | // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; |
38 | 38 | ||
39 | public BSLinksetConstraints(BSScene scene, BSPhysObject parent) | 39 | public BSLinksetConstraints(BSScene scene, BSPhysObject parent) : base(scene, parent) |
40 | { | 40 | { |
41 | base.Initialize(scene, parent); | ||
42 | } | 41 | } |
43 | 42 | ||
44 | // When physical properties are changed the linkset needs to recalculate | 43 | // When physical properties are changed the linkset needs to recalculate |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 19c29cc..c9c9c2c 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -661,14 +661,7 @@ public sealed class BSPrim : BSPhysObject | |||
661 | BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); | 661 | BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, PhysBody.ptr); |
662 | 662 | ||
663 | // Collision filter can be set only when the object is in the world | 663 | // Collision filter can be set only when the object is in the world |
664 | if (PhysBody.collisionGroup != 0 || PhysBody.collisionMask != 0) | 664 | PhysBody.ApplyCollisionMask(); |
665 | { | ||
666 | if (!BulletSimAPI.SetCollisionGroupMask2(PhysBody.ptr, (uint)PhysBody.collisionGroup, (uint)PhysBody.collisionMask)) | ||
667 | { | ||
668 | PhysicsScene.Logger.ErrorFormat("{0} Failure setting prim collision mask. localID={1}, grp={2:X}, mask={3:X}", | ||
669 | LogHeader, LocalID, PhysBody.collisionGroup, PhysBody.collisionMask); | ||
670 | } | ||
671 | } | ||
672 | 665 | ||
673 | // Recompute any linkset parameters. | 666 | // Recompute any linkset parameters. |
674 | // When going from non-physical to physical, this re-enables the constraints that | 667 | // When going from non-physical to physical, this re-enables the constraints that |
@@ -713,11 +706,11 @@ public sealed class BSPrim : BSPhysObject | |||
713 | // Start it out sleeping and physical actions could wake it up. | 706 | // Start it out sleeping and physical actions could wake it up. |
714 | BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ISLAND_SLEEPING); | 707 | BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ISLAND_SLEEPING); |
715 | 708 | ||
709 | // This collides like a static object | ||
710 | PhysBody.collisionType = CollisionType.Static; | ||
711 | |||
716 | // There can be special things needed for implementing linksets | 712 | // There can be special things needed for implementing linksets |
717 | Linkset.MakeStatic(this); | 713 | Linkset.MakeStatic(this); |
718 | |||
719 | PhysBody.collisionGroup = CollisionFilterGroups.StaticObjectGroup; | ||
720 | PhysBody.collisionMask = CollisionFilterGroups.StaticObjectMask; | ||
721 | } | 714 | } |
722 | else | 715 | else |
723 | { | 716 | { |
@@ -755,16 +748,15 @@ public sealed class BSPrim : BSPhysObject | |||
755 | BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); | 748 | BulletSimAPI.SetSleepingThresholds2(PhysBody.ptr, PhysicsScene.Params.linearSleepingThreshold, PhysicsScene.Params.angularSleepingThreshold); |
756 | BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, PhysicsScene.Params.contactProcessingThreshold); | 749 | BulletSimAPI.SetContactProcessingThreshold2(PhysBody.ptr, PhysicsScene.Params.contactProcessingThreshold); |
757 | 750 | ||
758 | // There might be special things needed for implementing linksets. | 751 | // This collides like an object. |
759 | Linkset.MakeDynamic(this); | 752 | PhysBody.collisionType = CollisionType.Dynamic; |
760 | 753 | ||
761 | // Force activation of the object so Bullet will act on it. | 754 | // Force activation of the object so Bullet will act on it. |
762 | // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects. | 755 | // Must do the ForceActivationState2() to overcome the DISABLE_SIMULATION from static objects. |
763 | BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ACTIVE_TAG); | 756 | BulletSimAPI.ForceActivationState2(PhysBody.ptr, ActivationState.ACTIVE_TAG); |
764 | // BulletSimAPI.Activate2(BSBody.ptr, true); | ||
765 | 757 | ||
766 | PhysBody.collisionGroup = CollisionFilterGroups.ObjectGroup; | 758 | // There might be special things needed for implementing linksets. |
767 | PhysBody.collisionMask = CollisionFilterGroups.ObjectMask; | 759 | Linkset.MakeDynamic(this); |
768 | } | 760 | } |
769 | } | 761 | } |
770 | 762 | ||
@@ -791,8 +783,9 @@ public sealed class BSPrim : BSPhysObject | |||
791 | m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType); | 783 | m_log.ErrorFormat("{0} MakeSolid: physical body of wrong type for non-solidness. id={1}, type={2}", LogHeader, LocalID, bodyType); |
792 | } | 784 | } |
793 | CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); | 785 | CurrentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(PhysBody.ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE); |
794 | PhysBody.collisionGroup = CollisionFilterGroups.VolumeDetectGroup; | 786 | |
795 | PhysBody.collisionMask = CollisionFilterGroups.VolumeDetectMask; | 787 | // Change collision info from a static object to a ghosty collision object |
788 | PhysBody.collisionType = CollisionType.VolumeDetect; | ||
796 | } | 789 | } |
797 | } | 790 | } |
798 | 791 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs index 2d379bb..2b120d6 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainHeightmap.cs | |||
@@ -121,9 +121,8 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys | |||
121 | // redo its bounding box now that it is in the world | 121 | // redo its bounding box now that it is in the world |
122 | BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); | 122 | BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_mapInfo.terrainBody.ptr); |
123 | 123 | ||
124 | BulletSimAPI.SetCollisionGroupMask2(m_mapInfo.terrainBody.ptr, | 124 | m_mapInfo.terrainBody.collisionType = CollisionType.Terrain; |
125 | (uint)CollisionFilterGroups.TerrainGroup, | 125 | m_mapInfo.terrainBody.ApplyCollisionMask(); |
126 | (uint)CollisionFilterGroups.TerrainMask); | ||
127 | 126 | ||
128 | // Make it so the terrain will not move or be considered for movement. | 127 | // Make it so the terrain will not move or be considered for movement. |
129 | BulletSimAPI.ForceActivationState2(m_mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION); | 128 | BulletSimAPI.ForceActivationState2(m_mapInfo.terrainBody.ptr, ActivationState.DISABLE_SIMULATION); |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index c28d69d..5dbd8ce 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs | |||
@@ -140,8 +140,8 @@ public sealed class BSTerrainManager | |||
140 | // Ground plane does not move | 140 | // Ground plane does not move |
141 | BulletSimAPI.ForceActivationState2(m_groundPlane.ptr, ActivationState.DISABLE_SIMULATION); | 141 | BulletSimAPI.ForceActivationState2(m_groundPlane.ptr, ActivationState.DISABLE_SIMULATION); |
142 | // Everything collides with the ground plane. | 142 | // Everything collides with the ground plane. |
143 | BulletSimAPI.SetCollisionGroupMask2(m_groundPlane.ptr, | 143 | m_groundPlane.collisionType = CollisionType.Groundplane; |
144 | (uint)CollisionFilterGroups.GroundPlaneGroup, (uint)CollisionFilterGroups.GroundPlaneMask); | 144 | m_groundPlane.ApplyCollisionMask(); |
145 | 145 | ||
146 | // Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain. | 146 | // Build an initial terrain and put it in the world. This quickly gets replaced by the real region terrain. |
147 | BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize); | 147 | BSTerrainPhys initialTerrain = new BSTerrainHeightmap(PhysicsScene, Vector3.Zero, BSScene.TERRAIN_ID, DefaultRegionSize); |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index 3473006..6dc0d92 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs | |||
@@ -130,9 +130,8 @@ public sealed class BSTerrainMesh : BSTerrainPhys | |||
130 | // Redo its bounding box now that it is in the world | 130 | // Redo its bounding box now that it is in the world |
131 | BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr); | 131 | BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr); |
132 | 132 | ||
133 | BulletSimAPI.SetCollisionGroupMask2(m_terrainBody.ptr, | 133 | m_terrainBody.collisionType = CollisionType.Terrain; |
134 | (uint)CollisionFilterGroups.TerrainGroup, | 134 | m_terrainBody.ApplyCollisionMask(); |
135 | (uint)CollisionFilterGroups.TerrainMask); | ||
136 | 135 | ||
137 | // Make it so the terrain will not move or be considered for movement. | 136 | // Make it so the terrain will not move or be considered for movement. |
138 | BulletSimAPI.ForceActivationState2(m_terrainBody.ptr, ActivationState.DISABLE_SIMULATION); | 137 | BulletSimAPI.ForceActivationState2(m_terrainBody.ptr, ActivationState.DISABLE_SIMULATION); |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 1559025..962b540 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs | |||
@@ -25,6 +25,7 @@ | |||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | using System; | 27 | using System; |
28 | using System.Collections.Generic; | ||
28 | using System.Runtime.InteropServices; | 29 | using System.Runtime.InteropServices; |
29 | using System.Security; | 30 | using System.Security; |
30 | using System.Text; | 31 | using System.Text; |
@@ -32,110 +33,6 @@ using OpenMetaverse; | |||
32 | 33 | ||
33 | namespace OpenSim.Region.Physics.BulletSPlugin { | 34 | namespace OpenSim.Region.Physics.BulletSPlugin { |
34 | 35 | ||
35 | // Classes to allow some type checking for the API | ||
36 | // These hold pointers to allocated objects in the unmanaged space. | ||
37 | |||
38 | // The physics engine controller class created at initialization | ||
39 | public struct BulletSim | ||
40 | { | ||
41 | public BulletSim(uint worldId, BSScene bss, IntPtr xx) | ||
42 | { | ||
43 | ptr = xx; | ||
44 | worldID = worldId; | ||
45 | physicsScene = bss; | ||
46 | } | ||
47 | public IntPtr ptr; | ||
48 | public uint worldID; | ||
49 | // The scene is only in here so very low level routines have a handle to print debug/error messages | ||
50 | public BSScene physicsScene; | ||
51 | } | ||
52 | |||
53 | // An allocated Bullet btRigidBody | ||
54 | public struct BulletBody | ||
55 | { | ||
56 | public BulletBody(uint id) : this(id, IntPtr.Zero) | ||
57 | { | ||
58 | } | ||
59 | public BulletBody(uint id, IntPtr xx) | ||
60 | { | ||
61 | ID = id; | ||
62 | ptr = xx; | ||
63 | collisionGroup = 0; | ||
64 | collisionMask = 0; | ||
65 | } | ||
66 | public IntPtr ptr; | ||
67 | public uint ID; | ||
68 | public CollisionFilterGroups collisionGroup; | ||
69 | public CollisionFilterGroups collisionMask; | ||
70 | |||
71 | public void Clear() | ||
72 | { | ||
73 | ptr = IntPtr.Zero; | ||
74 | } | ||
75 | public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } } | ||
76 | |||
77 | public override string ToString() | ||
78 | { | ||
79 | StringBuilder buff = new StringBuilder(); | ||
80 | buff.Append("<id="); | ||
81 | buff.Append(ID.ToString()); | ||
82 | buff.Append(",p="); | ||
83 | buff.Append(ptr.ToString("X")); | ||
84 | if (collisionGroup != 0 || collisionMask != 0) | ||
85 | { | ||
86 | buff.Append(",g="); | ||
87 | buff.Append(collisionGroup.ToString("X")); | ||
88 | buff.Append(",m="); | ||
89 | buff.Append(collisionMask.ToString("X")); | ||
90 | } | ||
91 | buff.Append(">"); | ||
92 | return buff.ToString(); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | public struct BulletShape | ||
97 | { | ||
98 | public BulletShape(IntPtr xx) | ||
99 | { | ||
100 | ptr = xx; | ||
101 | type=BSPhysicsShapeType.SHAPE_UNKNOWN; | ||
102 | shapeKey = (System.UInt64)FixedShapeKey.KEY_NONE; | ||
103 | isNativeShape = false; | ||
104 | } | ||
105 | public BulletShape(IntPtr xx, BSPhysicsShapeType typ) | ||
106 | { | ||
107 | ptr = xx; | ||
108 | type = typ; | ||
109 | shapeKey = 0; | ||
110 | isNativeShape = false; | ||
111 | } | ||
112 | public IntPtr ptr; | ||
113 | public BSPhysicsShapeType type; | ||
114 | public System.UInt64 shapeKey; | ||
115 | public bool isNativeShape; | ||
116 | |||
117 | public void Clear() | ||
118 | { | ||
119 | ptr = IntPtr.Zero; | ||
120 | } | ||
121 | public bool HasPhysicalShape { get { return ptr != IntPtr.Zero; } } | ||
122 | |||
123 | public override string ToString() | ||
124 | { | ||
125 | StringBuilder buff = new StringBuilder(); | ||
126 | buff.Append("<p="); | ||
127 | buff.Append(ptr.ToString("X")); | ||
128 | buff.Append(",s="); | ||
129 | buff.Append(type.ToString()); | ||
130 | buff.Append(",k="); | ||
131 | buff.Append(shapeKey.ToString("X")); | ||
132 | buff.Append(",n="); | ||
133 | buff.Append(isNativeShape.ToString()); | ||
134 | buff.Append(">"); | ||
135 | return buff.ToString(); | ||
136 | } | ||
137 | } | ||
138 | |||
139 | // Constraint type values as defined by Bullet | 36 | // Constraint type values as defined by Bullet |
140 | public enum ConstraintType : int | 37 | public enum ConstraintType : int |
141 | { | 38 | { |
@@ -149,50 +46,6 @@ public enum ConstraintType : int | |||
149 | MAX_CONSTRAINT_TYPE | 46 | MAX_CONSTRAINT_TYPE |
150 | } | 47 | } |
151 | 48 | ||
152 | // An allocated Bullet btConstraint | ||
153 | public struct BulletConstraint | ||
154 | { | ||
155 | public BulletConstraint(IntPtr xx) | ||
156 | { | ||
157 | ptr = xx; | ||
158 | } | ||
159 | public IntPtr ptr; | ||
160 | |||
161 | public void Clear() | ||
162 | { | ||
163 | ptr = IntPtr.Zero; | ||
164 | } | ||
165 | public bool HasPhysicalConstraint { get { return ptr != IntPtr.Zero; } } | ||
166 | } | ||
167 | |||
168 | // An allocated HeightMapThing which holds various heightmap info. | ||
169 | // Made a class rather than a struct so there would be only one | ||
170 | // instance of this and C# will pass around pointers rather | ||
171 | // than making copies. | ||
172 | public class BulletHeightMapInfo | ||
173 | { | ||
174 | public BulletHeightMapInfo(uint id, float[] hm, IntPtr xx) { | ||
175 | ID = id; | ||
176 | Ptr = xx; | ||
177 | heightMap = hm; | ||
178 | terrainRegionBase = Vector3.Zero; | ||
179 | minCoords = new Vector3(100f, 100f, 25f); | ||
180 | maxCoords = new Vector3(101f, 101f, 26f); | ||
181 | minZ = maxZ = 0f; | ||
182 | sizeX = sizeY = 256f; | ||
183 | } | ||
184 | public uint ID; | ||
185 | public IntPtr Ptr; | ||
186 | public float[] heightMap; | ||
187 | public Vector3 terrainRegionBase; | ||
188 | public Vector3 minCoords; | ||
189 | public Vector3 maxCoords; | ||
190 | public float sizeX, sizeY; | ||
191 | public float minZ, maxZ; | ||
192 | public BulletShape terrainShape; | ||
193 | public BulletBody terrainBody; | ||
194 | } | ||
195 | |||
196 | // =============================================================================== | 49 | // =============================================================================== |
197 | [StructLayout(LayoutKind.Sequential)] | 50 | [StructLayout(LayoutKind.Sequential)] |
198 | public struct ConvexHull | 51 | public struct ConvexHull |
@@ -385,21 +238,15 @@ public enum CollisionFlags : uint | |||
385 | BS_FLOATS_ON_WATER = 1 << 11, | 238 | BS_FLOATS_ON_WATER = 1 << 11, |
386 | BS_VEHICLE_COLLISIONS = 1 << 12, | 239 | BS_VEHICLE_COLLISIONS = 1 << 12, |
387 | BS_NONE = 0, | 240 | BS_NONE = 0, |
388 | BS_ALL = 0xFFFFFFFF, | 241 | BS_ALL = 0xFFFFFFFF |
389 | |||
390 | // These are the collision flags switched depending on physical state. | ||
391 | // The other flags are used for other things and should not be fooled with. | ||
392 | BS_ACTIVE = CF_STATIC_OBJECT | ||
393 | | CF_KINEMATIC_OBJECT | ||
394 | | CF_NO_CONTACT_RESPONSE | ||
395 | }; | 242 | }; |
396 | 243 | ||
397 | // Values for collisions groups and masks | 244 | // Values f collisions groups and masks |
398 | public enum CollisionFilterGroups : uint | 245 | public enum CollisionFilterGroups : uint |
399 | { | 246 | { |
400 | // Don't use the bit definitions!! Define the use in a | 247 | // Don't use the bit definitions!! Define the use in a |
401 | // filter/mask definition below. This way collision interactions | 248 | // filter/mask definition below. This way collision interactions |
402 | // are more easily debugged. | 249 | // are more easily found and debugged. |
403 | BNoneGroup = 0, | 250 | BNoneGroup = 0, |
404 | BDefaultGroup = 1 << 0, | 251 | BDefaultGroup = 1 << 0, |
405 | BStaticGroup = 1 << 1, | 252 | BStaticGroup = 1 << 1, |
@@ -413,24 +260,8 @@ public enum CollisionFilterGroups : uint | |||
413 | BTerrainGroup = 1 << 11, | 260 | BTerrainGroup = 1 << 11, |
414 | BRaycastGroup = 1 << 12, | 261 | BRaycastGroup = 1 << 12, |
415 | BSolidGroup = 1 << 13, | 262 | BSolidGroup = 1 << 13, |
416 | BLinksetGroup = 1 << 14, | 263 | // BLinksetGroup = xx // a linkset proper is either static or dynamic |
417 | 264 | BLinksetChildGroup = 1 << 14, | |
418 | // The collsion filters and masked are defined in one place -- don't want them scattered | ||
419 | AvatarGroup = BCharacterGroup, | ||
420 | AvatarMask = BAllGroup, | ||
421 | ObjectGroup = BSolidGroup, | ||
422 | ObjectMask = BAllGroup, | ||
423 | StaticObjectGroup = BStaticGroup, | ||
424 | StaticObjectMask = AvatarGroup | ObjectGroup, // static things don't interact with much | ||
425 | LinksetGroup = BLinksetGroup, | ||
426 | LinksetMask = BAllGroup & ~BLinksetGroup, // linkset objects don't collide with each other | ||
427 | VolumeDetectGroup = BSensorTrigger, | ||
428 | VolumeDetectMask = ~BSensorTrigger, | ||
429 | TerrainGroup = BTerrainGroup, | ||
430 | TerrainMask = BAllGroup & ~BStaticGroup, // static objects on the ground don't collide | ||
431 | GroundPlaneGroup = BGroundPlaneGroup, | ||
432 | GroundPlaneMask = BAllGroup | ||
433 | |||
434 | }; | 265 | }; |
435 | 266 | ||
436 | // CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0 | 267 | // CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0 |
@@ -457,7 +288,7 @@ public enum ConstraintParamAxis : int | |||
457 | 288 | ||
458 | // =============================================================================== | 289 | // =============================================================================== |
459 | static class BulletSimAPI { | 290 | static class BulletSimAPI { |
460 | 291 | // =============================================================================== | |
461 | // Link back to the managed code for outputting log messages | 292 | // Link back to the managed code for outputting log messages |
462 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)] | 293 | [UnmanagedFunctionPointer(CallingConvention.Cdecl)] |
463 | public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg); | 294 | public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg); |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs new file mode 100755 index 0000000..662177f --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimData.cs | |||
@@ -0,0 +1,278 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyrightD | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | using System; | ||
28 | using System.Collections.Generic; | ||
29 | using System.Text; | ||
30 | using OMV = OpenMetaverse; | ||
31 | |||
32 | namespace OpenSim.Region.Physics.BulletSPlugin | ||
33 | { | ||
34 | // Classes to allow some type checking for the API | ||
35 | // These hold pointers to allocated objects in the unmanaged space. | ||
36 | |||
37 | // The physics engine controller class created at initialization | ||
38 | public struct BulletSim | ||
39 | { | ||
40 | public BulletSim(uint worldId, BSScene bss, IntPtr xx) | ||
41 | { | ||
42 | ptr = xx; | ||
43 | worldID = worldId; | ||
44 | physicsScene = bss; | ||
45 | } | ||
46 | public IntPtr ptr; | ||
47 | public uint worldID; | ||
48 | // The scene is only in here so very low level routines have a handle to print debug/error messages | ||
49 | public BSScene physicsScene; | ||
50 | } | ||
51 | |||
52 | // An allocated Bullet btRigidBody | ||
53 | public struct BulletBody | ||
54 | { | ||
55 | public BulletBody(uint id) : this(id, IntPtr.Zero) | ||
56 | { | ||
57 | } | ||
58 | public BulletBody(uint id, IntPtr xx) | ||
59 | { | ||
60 | ID = id; | ||
61 | ptr = xx; | ||
62 | collisionType = CollisionType.Static; | ||
63 | } | ||
64 | public IntPtr ptr; | ||
65 | public uint ID; | ||
66 | public CollisionType collisionType; | ||
67 | |||
68 | public void Clear() | ||
69 | { | ||
70 | ptr = IntPtr.Zero; | ||
71 | } | ||
72 | public bool HasPhysicalBody { get { return ptr != IntPtr.Zero; } } | ||
73 | |||
74 | // Apply the specificed collision mask into the physical world | ||
75 | public void ApplyCollisionMask() | ||
76 | { | ||
77 | // Should assert the body has been added to the physical world. | ||
78 | // (The collision masks are stored in the collision proxy cache which only exists for | ||
79 | // a collision body that is in the world.) | ||
80 | BulletSimAPI.SetCollisionGroupMask2(ptr, | ||
81 | BulletSimData.CollisionTypeMasks[collisionType].group, | ||
82 | BulletSimData.CollisionTypeMasks[collisionType].mask); | ||
83 | } | ||
84 | |||
85 | public override string ToString() | ||
86 | { | ||
87 | StringBuilder buff = new StringBuilder(); | ||
88 | buff.Append("<id="); | ||
89 | buff.Append(ID.ToString()); | ||
90 | buff.Append(",p="); | ||
91 | buff.Append(ptr.ToString("X")); | ||
92 | buff.Append(",c="); | ||
93 | buff.Append(collisionType); | ||
94 | buff.Append(">"); | ||
95 | return buff.ToString(); | ||
96 | } | ||
97 | } | ||
98 | |||
99 | public struct BulletShape | ||
100 | { | ||
101 | public BulletShape(IntPtr xx) : this(xx, BSPhysicsShapeType.SHAPE_UNKNOWN) | ||
102 | { | ||
103 | } | ||
104 | public BulletShape(IntPtr xx, BSPhysicsShapeType typ) | ||
105 | { | ||
106 | ptr = xx; | ||
107 | type = typ; | ||
108 | shapeKey = (System.UInt64)FixedShapeKey.KEY_NONE; | ||
109 | isNativeShape = false; | ||
110 | } | ||
111 | public IntPtr ptr; | ||
112 | public BSPhysicsShapeType type; | ||
113 | public System.UInt64 shapeKey; | ||
114 | public bool isNativeShape; | ||
115 | |||
116 | public void Clear() | ||
117 | { | ||
118 | ptr = IntPtr.Zero; | ||
119 | } | ||
120 | public bool HasPhysicalShape { get { return ptr != IntPtr.Zero; } } | ||
121 | |||
122 | public override string ToString() | ||
123 | { | ||
124 | StringBuilder buff = new StringBuilder(); | ||
125 | buff.Append("<p="); | ||
126 | buff.Append(ptr.ToString("X")); | ||
127 | buff.Append(",s="); | ||
128 | buff.Append(type.ToString()); | ||
129 | buff.Append(",k="); | ||
130 | buff.Append(shapeKey.ToString("X")); | ||
131 | buff.Append(",n="); | ||
132 | buff.Append(isNativeShape.ToString()); | ||
133 | buff.Append(">"); | ||
134 | return buff.ToString(); | ||
135 | } | ||
136 | } | ||
137 | |||
138 | // An allocated Bullet btConstraint | ||
139 | public struct BulletConstraint | ||
140 | { | ||
141 | public BulletConstraint(IntPtr xx) | ||
142 | { | ||
143 | ptr = xx; | ||
144 | } | ||
145 | public IntPtr ptr; | ||
146 | |||
147 | public void Clear() | ||
148 | { | ||
149 | ptr = IntPtr.Zero; | ||
150 | } | ||
151 | public bool HasPhysicalConstraint { get { return ptr != IntPtr.Zero; } } | ||
152 | } | ||
153 | |||
154 | // An allocated HeightMapThing which holds various heightmap info. | ||
155 | // Made a class rather than a struct so there would be only one | ||
156 | // instance of this and C# will pass around pointers rather | ||
157 | // than making copies. | ||
158 | public class BulletHeightMapInfo | ||
159 | { | ||
160 | public BulletHeightMapInfo(uint id, float[] hm, IntPtr xx) { | ||
161 | ID = id; | ||
162 | Ptr = xx; | ||
163 | heightMap = hm; | ||
164 | terrainRegionBase = OMV.Vector3.Zero; | ||
165 | minCoords = new OMV.Vector3(100f, 100f, 25f); | ||
166 | maxCoords = new OMV.Vector3(101f, 101f, 26f); | ||
167 | minZ = maxZ = 0f; | ||
168 | sizeX = sizeY = 256f; | ||
169 | } | ||
170 | public uint ID; | ||
171 | public IntPtr Ptr; | ||
172 | public float[] heightMap; | ||
173 | public OMV.Vector3 terrainRegionBase; | ||
174 | public OMV.Vector3 minCoords; | ||
175 | public OMV.Vector3 maxCoords; | ||
176 | public float sizeX, sizeY; | ||
177 | public float minZ, maxZ; | ||
178 | public BulletShape terrainShape; | ||
179 | public BulletBody terrainBody; | ||
180 | } | ||
181 | |||
182 | // The general class of collsion object. | ||
183 | public enum CollisionType | ||
184 | { | ||
185 | Avatar, | ||
186 | Groundplane, | ||
187 | Terrain, | ||
188 | Static, | ||
189 | Dynamic, | ||
190 | VolumeDetect, | ||
191 | // Linkset, // A linkset should be either Static or Dynamic | ||
192 | LinksetChild, | ||
193 | Unknown | ||
194 | }; | ||
195 | |||
196 | // Hold specification of group and mask collision flags for a CollisionType | ||
197 | public struct CollisionTypeFilterGroup | ||
198 | { | ||
199 | public CollisionTypeFilterGroup(CollisionType t, uint g, uint m) | ||
200 | { | ||
201 | type = t; | ||
202 | group = g; | ||
203 | mask = m; | ||
204 | } | ||
205 | public CollisionType type; | ||
206 | public uint group; | ||
207 | public uint mask; | ||
208 | }; | ||
209 | |||
210 | /* NOTE: old definitions kept for reference. Delete when things are working. | ||
211 | // The collsion filters and masked are defined in one place -- don't want them scattered | ||
212 | AvatarGroup = BCharacterGroup, | ||
213 | AvatarMask = BAllGroup, | ||
214 | ObjectGroup = BSolidGroup, | ||
215 | ObjectMask = BAllGroup, | ||
216 | StaticObjectGroup = BStaticGroup, | ||
217 | StaticObjectMask = AvatarGroup | ObjectGroup, // static things don't interact with much | ||
218 | LinksetGroup = BLinksetGroup, | ||
219 | LinksetMask = BAllGroup, | ||
220 | LinksetChildGroup = BLinksetChildGroup, | ||
221 | LinksetChildMask = BNoneGroup, // Linkset children disappear from the world | ||
222 | VolumeDetectGroup = BSensorTrigger, | ||
223 | VolumeDetectMask = ~BSensorTrigger, | ||
224 | TerrainGroup = BTerrainGroup, | ||
225 | TerrainMask = BAllGroup & ~BStaticGroup, // static objects on the ground don't collide | ||
226 | GroundPlaneGroup = BGroundPlaneGroup, | ||
227 | GroundPlaneMask = BAllGroup | ||
228 | */ | ||
229 | |||
230 | public static class BulletSimData | ||
231 | { | ||
232 | |||
233 | // Map of collisionTypes to flags for collision groups and masks. | ||
234 | // As mentioned above, don't use the CollisionFilterGroups definitions directly in the code | ||
235 | // but, instead, use references to this dictionary. Finding and debugging | ||
236 | // collision flag problems will be made easier. | ||
237 | public static Dictionary<CollisionType, CollisionTypeFilterGroup> CollisionTypeMasks | ||
238 | = new Dictionary<CollisionType, CollisionTypeFilterGroup>() | ||
239 | { | ||
240 | { CollisionType.Avatar, | ||
241 | new CollisionTypeFilterGroup(CollisionType.Avatar, | ||
242 | (uint)CollisionFilterGroups.BCharacterGroup, | ||
243 | (uint)CollisionFilterGroups.BAllGroup) | ||
244 | }, | ||
245 | { CollisionType.Groundplane, | ||
246 | new CollisionTypeFilterGroup(CollisionType.Groundplane, | ||
247 | (uint)CollisionFilterGroups.BGroundPlaneGroup, | ||
248 | (uint)CollisionFilterGroups.BAllGroup) | ||
249 | }, | ||
250 | { CollisionType.Terrain, | ||
251 | new CollisionTypeFilterGroup(CollisionType.Terrain, | ||
252 | (uint)CollisionFilterGroups.BTerrainGroup, | ||
253 | (uint)(CollisionFilterGroups.BAllGroup & ~CollisionFilterGroups.BStaticGroup)) | ||
254 | }, | ||
255 | { CollisionType.Static, | ||
256 | new CollisionTypeFilterGroup(CollisionType.Static, | ||
257 | (uint)CollisionFilterGroups.BStaticGroup, | ||
258 | (uint)(CollisionFilterGroups.BCharacterGroup | CollisionFilterGroups.BSolidGroup)) | ||
259 | }, | ||
260 | { CollisionType.Dynamic, | ||
261 | new CollisionTypeFilterGroup(CollisionType.Dynamic, | ||
262 | (uint)CollisionFilterGroups.BSolidGroup, | ||
263 | (uint)(CollisionFilterGroups.BAllGroup)) | ||
264 | }, | ||
265 | { CollisionType.VolumeDetect, | ||
266 | new CollisionTypeFilterGroup(CollisionType.VolumeDetect, | ||
267 | (uint)CollisionFilterGroups.BSensorTrigger, | ||
268 | (uint)(~CollisionFilterGroups.BSensorTrigger)) | ||
269 | }, | ||
270 | { CollisionType.LinksetChild, | ||
271 | new CollisionTypeFilterGroup(CollisionType.LinksetChild, | ||
272 | (uint)CollisionFilterGroups.BTerrainGroup, | ||
273 | (uint)(CollisionFilterGroups.BNoneGroup)) | ||
274 | }, | ||
275 | }; | ||
276 | |||
277 | } | ||
278 | } | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 11c1387..7d6ace8 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | |||
@@ -19,6 +19,7 @@ Some vehicles should not be able to turn if no speed or off ground. | |||
19 | Neb car jiggling left and right | 19 | Neb car jiggling left and right |
20 | Happens on terrain and any other mesh object. Flat cubes are much smoother. | 20 | Happens on terrain and any other mesh object. Flat cubes are much smoother. |
21 | This has been reduced but not eliminated. | 21 | This has been reduced but not eliminated. |
22 | Light cycle falling over when driving | ||
22 | For limitMotorUp, use raycast down to find if vehicle is in the air. | 23 | For limitMotorUp, use raycast down to find if vehicle is in the air. |
23 | Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE. | 24 | Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE. |
24 | Verify that angular motion specified around Z moves in the vehicle coordinates. | 25 | Verify that angular motion specified around Z moves in the vehicle coordinates. |
@@ -121,6 +122,9 @@ Remove unused fields from ShapeData (not used in API2) | |||
121 | Breakout code for mesh/hull/compound/native into separate BSShape* classes | 122 | Breakout code for mesh/hull/compound/native into separate BSShape* classes |
122 | Standardize access to building and reference code. | 123 | Standardize access to building and reference code. |
123 | The skeleton classes are in the sources but are not complete or linked in. | 124 | The skeleton classes are in the sources but are not complete or linked in. |
125 | Make BSBody and BSShape real classes to centralize creation/changin/destruction | ||
126 | Convert state and parameter calls from BulletSimAPI direct calls to | ||
127 | calls on BSBody and BSShape | ||
124 | Generalize Dynamics and PID with standardized motors. | 128 | Generalize Dynamics and PID with standardized motors. |
125 | Generalize Linkset and vehicles into PropertyManagers | 129 | Generalize Linkset and vehicles into PropertyManagers |
126 | Methods for Refresh, RemoveBodyDependencies, RestoreBodyDependencies | 130 | Methods for Refresh, RemoveBodyDependencies, RestoreBodyDependencies |
@@ -132,7 +136,7 @@ Implement linkset by setting position of children when root updated. (LinksetMan | |||
132 | Linkset implementation using manual prim movement. | 136 | Linkset implementation using manual prim movement. |
133 | LinkablePrim class? Would that simplify/centralize the linkset logic? | 137 | LinkablePrim class? Would that simplify/centralize the linkset logic? |
134 | BSScene.UpdateParameterSet() is broken. How to set params on objects? | 138 | BSScene.UpdateParameterSet() is broken. How to set params on objects? |
135 | Remove HeightmapInfo from terrain specification. | 139 | Remove HeightmapInfo from terrain specification |
136 | Since C++ code does not need terrain height, this structure et al are not needed. | 140 | Since C++ code does not need terrain height, this structure et al are not needed. |
137 | Add floating motor for BS_FLOATS_ON_WATER so prim and avatar will | 141 | Add floating motor for BS_FLOATS_ON_WATER so prim and avatar will |
138 | bob at the water level. BSPrim.PositionSanityCheck(). | 142 | bob at the water level. BSPrim.PositionSanityCheck(). |
@@ -164,7 +168,6 @@ Do prim hash codes work for sculpties and meshes? (Resolution: yes) | |||
164 | Linkset implementation using compound shapes. (Resolution: implemented LinksetCompound) | 168 | Linkset implementation using compound shapes. (Resolution: implemented LinksetCompound) |
165 | Compound shapes will need the LocalID in the shapes and collision | 169 | Compound shapes will need the LocalID in the shapes and collision |
166 | processing to get it from there. | 170 | processing to get it from there. |
167 | Light cycle falling over when driving (Resolution: implemented VerticalAttractor) | ||
168 | Light cycle not banking (Resolution: It doesn't. Banking is roll adding yaw.) | 171 | Light cycle not banking (Resolution: It doesn't. Banking is roll adding yaw.) |
169 | Package Bullet source mods for Bullet internal stats output | 172 | Package Bullet source mods for Bullet internal stats output |
170 | (Resolution: move code into WorldData.h rather than relying on patches) | 173 | (Resolution: move code into WorldData.h rather than relying on patches) |
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index 34413e5..d119791 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs | |||
@@ -250,17 +250,20 @@ namespace OpenSim.Region.Physics.Manager | |||
250 | public abstract Vector3 CenterOfMass { get; } | 250 | public abstract Vector3 CenterOfMass { get; } |
251 | 251 | ||
252 | /// <summary> | 252 | /// <summary> |
253 | /// Velocity of this actor. | 253 | /// The desired velocity of this actor. |
254 | /// </summary> | 254 | /// </summary> |
255 | /// <remarks> | 255 | /// <remarks> |
256 | /// Setting this provides a target velocity for physics scene updates. | 256 | /// Setting this provides a target velocity for physics scene updates. |
257 | /// Getting this returns the velocity calculated by physics scene updates, using factors such as target velocity, | 257 | /// Getting this returns the last set target. Fetch Velocity to get the current velocity. |
258 | /// time to accelerate and collisions. | ||
259 | /// </remarks> | 258 | /// </remarks> |
259 | protected Vector3 m_targetVelocity; | ||
260 | public virtual Vector3 TargetVelocity | 260 | public virtual Vector3 TargetVelocity |
261 | { | 261 | { |
262 | get { return Velocity; } | 262 | get { return m_targetVelocity; } |
263 | set { Velocity = value; } | 263 | set { |
264 | m_targetVelocity = value; | ||
265 | Velocity = m_targetVelocity; | ||
266 | } | ||
264 | } | 267 | } |
265 | 268 | ||
266 | public abstract Vector3 Velocity { get; set; } | 269 | public abstract Vector3 Velocity { get; set; } |