aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs75
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs12
-rw-r--r--OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs8
-rw-r--r--OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs645
-rw-r--r--OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs8
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsActor.cs9
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs13
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs80
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs563
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs261
10 files changed, 871 insertions, 803 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index c9ea8e4..8809cd0 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -957,12 +957,12 @@ namespace OpenSim.Region.Framework.Scenes
957 /// <returns></returns> 957 /// <returns></returns>
958 public void GetAxisAlignedBoundingBoxRaw(out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ) 958 public void GetAxisAlignedBoundingBoxRaw(out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ)
959 { 959 {
960 maxX = -256f; 960 maxX = float.MinValue;
961 maxY = -256f; 961 maxY = float.MinValue;
962 maxZ = -256f; 962 maxZ = float.MinValue;
963 minX = 256f; 963 minX = float.MaxValue;
964 minY = 256f; 964 minY = float.MaxValue;
965 minZ = 8192f; 965 minZ = float.MaxValue;
966 966
967 SceneObjectPart[] parts = m_parts.GetArray(); 967 SceneObjectPart[] parts = m_parts.GetArray();
968 foreach (SceneObjectPart part in parts) 968 foreach (SceneObjectPart part in parts)
@@ -1988,7 +1988,12 @@ namespace OpenSim.Region.Framework.Scenes
1988 /// <param name="cGroupID"></param> 1988 /// <param name="cGroupID"></param>
1989 public void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) 1989 public void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed)
1990 { 1990 {
1991 SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed)); 1991 // SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed));
1992 // give newpart a new local ID lettng old part keep same
1993 SceneObjectPart newpart = part.Copy(part.LocalId, OwnerID, GroupID, 0, userExposed);
1994 newpart.LocalId = m_scene.AllocateLocalId();
1995
1996 SetRootPart(newpart);
1992 if (userExposed) 1997 if (userExposed)
1993 RootPart.Velocity = Vector3.Zero; // In case source is moving 1998 RootPart.Velocity = Vector3.Zero; // In case source is moving
1994 } 1999 }
@@ -2191,7 +2196,10 @@ namespace OpenSim.Region.Framework.Scenes
2191 /// <param name="cGroupID"></param> 2196 /// <param name="cGroupID"></param>
2192 public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) 2197 public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed)
2193 { 2198 {
2194 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); 2199 // give new ID to the new part, letting old keep original
2200 // SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
2201 SceneObjectPart newPart = part.Copy(part.LocalId, OwnerID, GroupID, m_parts.Count, userExposed);
2202 newPart.LocalId = m_scene.AllocateLocalId();
2195 newPart.SetParent(this); 2203 newPart.SetParent(this);
2196 2204
2197 AddPart(newPart); 2205 AddPart(newPart);
@@ -2485,6 +2493,11 @@ namespace OpenSim.Region.Framework.Scenes
2485 2493
2486 SceneObjectPart linkPart = objectGroup.m_rootPart; 2494 SceneObjectPart linkPart = objectGroup.m_rootPart;
2487 2495
2496 if (m_rootPart.PhysActor != null)
2497 m_rootPart.PhysActor.Building = true;
2498 if (linkPart.PhysActor != null)
2499 linkPart.PhysActor.Building = true;
2500
2488 Vector3 oldGroupPosition = linkPart.GroupPosition; 2501 Vector3 oldGroupPosition = linkPart.GroupPosition;
2489 Quaternion oldRootRotation = linkPart.RotationOffset; 2502 Quaternion oldRootRotation = linkPart.RotationOffset;
2490 2503
@@ -2528,6 +2541,13 @@ namespace OpenSim.Region.Framework.Scenes
2528 linkPart.SetParent(this); 2541 linkPart.SetParent(this);
2529 linkPart.CreateSelected = true; 2542 linkPart.CreateSelected = true;
2530 2543
2544 // let physics know
2545 if (linkPart.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical)
2546 {
2547 linkPart.PhysActor.link(m_rootPart.PhysActor);
2548 this.Scene.PhysicsScene.AddPhysicsActorTaint(linkPart.PhysActor);
2549 }
2550
2531 linkPart.LinkNum = linkNum++; 2551 linkPart.LinkNum = linkNum++;
2532 2552
2533 SceneObjectPart[] ogParts = objectGroup.Parts; 2553 SceneObjectPart[] ogParts = objectGroup.Parts;
@@ -2540,7 +2560,15 @@ namespace OpenSim.Region.Framework.Scenes
2540 { 2560 {
2541 SceneObjectPart part = ogParts[i]; 2561 SceneObjectPart part = ogParts[i];
2542 if (part.UUID != objectGroup.m_rootPart.UUID) 2562 if (part.UUID != objectGroup.m_rootPart.UUID)
2563 {
2543 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); 2564 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2565 // let physics know
2566 if (part.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical)
2567 {
2568 part.PhysActor.link(m_rootPart.PhysActor);
2569 this.Scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2570 }
2571 }
2544 part.ClearUndoState(); 2572 part.ClearUndoState();
2545 } 2573 }
2546 } 2574 }
@@ -2560,6 +2588,9 @@ namespace OpenSim.Region.Framework.Scenes
2560 // unmoved prims! 2588 // unmoved prims!
2561 ResetChildPrimPhysicsPositions(); 2589 ResetChildPrimPhysicsPositions();
2562 2590
2591 if (m_rootPart.PhysActor != null)
2592 m_rootPart.PhysActor.Building = false;
2593
2563 //HasGroupChanged = true; 2594 //HasGroupChanged = true;
2564 //ScheduleGroupForFullUpdate(); 2595 //ScheduleGroupForFullUpdate();
2565 } 2596 }
@@ -2612,7 +2643,10 @@ namespace OpenSim.Region.Framework.Scenes
2612// m_log.DebugFormat( 2643// m_log.DebugFormat(
2613// "[SCENE OBJECT GROUP]: Delinking part {0}, {1} from group with root part {2}, {3}", 2644// "[SCENE OBJECT GROUP]: Delinking part {0}, {1} from group with root part {2}, {3}",
2614// linkPart.Name, linkPart.UUID, RootPart.Name, RootPart.UUID); 2645// linkPart.Name, linkPart.UUID, RootPart.Name, RootPart.UUID);
2615 2646
2647 if (m_rootPart.PhysActor != null)
2648 m_rootPart.PhysActor.Building = true;
2649
2616 linkPart.ClearUndoState(); 2650 linkPart.ClearUndoState();
2617 2651
2618 Quaternion worldRot = linkPart.GetWorldRotation(); 2652 Quaternion worldRot = linkPart.GetWorldRotation();
@@ -2672,6 +2706,10 @@ namespace OpenSim.Region.Framework.Scenes
2672 2706
2673 // When we delete a group, we currently have to force persist to the database if the object id has changed 2707 // When we delete a group, we currently have to force persist to the database if the object id has changed
2674 // (since delete works by deleting all rows which have a given object id) 2708 // (since delete works by deleting all rows which have a given object id)
2709
2710 if (m_rootPart.PhysActor != null)
2711 m_rootPart.PhysActor.Building = false;
2712
2675 objectGroup.HasGroupChangedDueToDelink = true; 2713 objectGroup.HasGroupChangedDueToDelink = true;
2676 2714
2677 return objectGroup; 2715 return objectGroup;
@@ -3284,6 +3322,10 @@ namespace OpenSim.Region.Framework.Scenes
3284 part.StoreUndoState(false); 3322 part.StoreUndoState(false);
3285 part.IgnoreUndoUpdate = true; 3323 part.IgnoreUndoUpdate = true;
3286 3324
3325// unlock parts position change
3326 if (m_rootPart.PhysActor != null)
3327 m_rootPart.PhysActor.Building = true;
3328
3287 if (part.UUID == m_rootPart.UUID) 3329 if (part.UUID == m_rootPart.UUID)
3288 { 3330 {
3289 UpdateRootPosition(pos); 3331 UpdateRootPosition(pos);
@@ -3293,6 +3335,9 @@ namespace OpenSim.Region.Framework.Scenes
3293 part.UpdateOffSet(pos); 3335 part.UpdateOffSet(pos);
3294 } 3336 }
3295 3337
3338 if (m_rootPart.PhysActor != null)
3339 m_rootPart.PhysActor.Building = false;
3340
3296 HasGroupChanged = true; 3341 HasGroupChanged = true;
3297 part.IgnoreUndoUpdate = false; 3342 part.IgnoreUndoUpdate = false;
3298 } 3343 }
@@ -3434,6 +3479,9 @@ namespace OpenSim.Region.Framework.Scenes
3434// m_log.DebugFormat( 3479// m_log.DebugFormat(
3435// "[SCENE OBJECT GROUP]: Updating single rotation of {0} {1} to {2}", part.Name, part.LocalId, rot); 3480// "[SCENE OBJECT GROUP]: Updating single rotation of {0} {1} to {2}", part.Name, part.LocalId, rot);
3436 3481
3482 if (m_rootPart.PhysActor != null)
3483 m_rootPart.PhysActor.Building = true;
3484
3437 if (part.UUID == m_rootPart.UUID) 3485 if (part.UUID == m_rootPart.UUID)
3438 { 3486 {
3439 UpdateRootRotation(rot); 3487 UpdateRootRotation(rot);
@@ -3442,6 +3490,9 @@ namespace OpenSim.Region.Framework.Scenes
3442 { 3490 {
3443 part.UpdateRotation(rot); 3491 part.UpdateRotation(rot);
3444 } 3492 }
3493
3494 if (m_rootPart.PhysActor != null)
3495 m_rootPart.PhysActor.Building = false;
3445 } 3496 }
3446 } 3497 }
3447 3498
@@ -3462,6 +3513,9 @@ namespace OpenSim.Region.Framework.Scenes
3462 part.StoreUndoState(); 3513 part.StoreUndoState();
3463 part.IgnoreUndoUpdate = true; 3514 part.IgnoreUndoUpdate = true;
3464 3515
3516 if (m_rootPart.PhysActor != null)
3517 m_rootPart.PhysActor.Building = true;
3518
3465 if (part.UUID == m_rootPart.UUID) 3519 if (part.UUID == m_rootPart.UUID)
3466 { 3520 {
3467 UpdateRootRotation(rot); 3521 UpdateRootRotation(rot);
@@ -3482,6 +3536,9 @@ namespace OpenSim.Region.Framework.Scenes
3482 part.OffsetPosition = pos; 3536 part.OffsetPosition = pos;
3483 } 3537 }
3484 3538
3539 if (m_rootPart.PhysActor != null)
3540 m_rootPart.PhysActor.Building = false;
3541
3485 part.IgnoreUndoUpdate = false; 3542 part.IgnoreUndoUpdate = false;
3486 } 3543 }
3487 } 3544 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 1c72b10..9c06786 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1691,10 +1691,9 @@ namespace OpenSim.Region.Framework.Scenes
1691 if (userExposed) 1691 if (userExposed)
1692 dupe.UUID = UUID.Random(); 1692 dupe.UUID = UUID.Random();
1693 1693
1694 //memberwiseclone means it also clones the physics actor reference 1694 // The PhysActor cannot be valid on a copy because the copy is not in the scene yet.
1695 // This will make physical prim 'bounce' if not set to null. 1695 // Null it, the caller has to create a new one once the object is added to a scene
1696 if (!userExposed) 1696 dupe.PhysActor = null;
1697 dupe.PhysActor = null;
1698 1697
1699 dupe.OwnerID = AgentID; 1698 dupe.OwnerID = AgentID;
1700 dupe.GroupID = GroupID; 1699 dupe.GroupID = GroupID;
@@ -1727,8 +1726,6 @@ namespace OpenSim.Region.Framework.Scenes
1727 1726
1728 // Move afterwards ResetIDs as it clears the localID 1727 // Move afterwards ResetIDs as it clears the localID
1729 dupe.LocalId = localID; 1728 dupe.LocalId = localID;
1730 if(dupe.PhysActor != null)
1731 dupe.PhysActor.LocalID = localID;
1732 1729
1733 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. 1730 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
1734 dupe.LastOwnerID = OwnerID; 1731 dupe.LastOwnerID = OwnerID;
@@ -1749,6 +1746,9 @@ namespace OpenSim.Region.Framework.Scenes
1749 dupe.DoPhysicsPropertyUpdate(UsePhysics, true); 1746 dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
1750 } 1747 }
1751 1748
1749 if (dupe.PhysActor != null)
1750 dupe.PhysActor.LocalID = localID;
1751
1752 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); 1752 ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
1753 1753
1754// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); 1754// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID);
diff --git a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs
index c1957e2..59ff9b8 100644
--- a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs
+++ b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs
@@ -121,12 +121,18 @@ namespace OpenSim.Region.OptionalModules
121 121
122 private bool CanObjectEnter(UUID objectID, bool enteringRegion, Vector3 newPoint, Scene scene) 122 private bool CanObjectEnter(UUID objectID, bool enteringRegion, Vector3 newPoint, Scene scene)
123 { 123 {
124 if ((newPoint.X > 257f || newPoint.X < -1f || newPoint.Y > 257f || newPoint.Y < -1f))
125 return true;
126
124 SceneObjectPart obj = scene.GetSceneObjectPart(objectID); 127 SceneObjectPart obj = scene.GetSceneObjectPart(objectID);
125 Vector3 oldPoint = obj.GroupPosition; 128 Vector3 oldPoint = obj.GroupPosition;
126 int objectCount = obj.ParentGroup.PrimCount; 129 int objectCount = obj.ParentGroup.PrimCount;
127 ILandObject oldParcel = scene.LandChannel.GetLandObject(oldPoint.X, oldPoint.Y); 130 ILandObject oldParcel = scene.LandChannel.GetLandObject(oldPoint.X, oldPoint.Y);
128 ILandObject newParcel = scene.LandChannel.GetLandObject(newPoint.X, newPoint.Y); 131 ILandObject newParcel = scene.LandChannel.GetLandObject(newPoint.X, newPoint.Y);
129 132
133 if (newParcel == null)
134 return true;
135
130 int usedPrims = newParcel.PrimCounts.Total; 136 int usedPrims = newParcel.PrimCounts.Total;
131 int simulatorCapacity = newParcel.GetSimulatorMaxPrimCount(); 137 int simulatorCapacity = newParcel.GetSimulatorMaxPrimCount();
132 138
@@ -171,4 +177,4 @@ namespace OpenSim.Region.OptionalModules
171 return true; 177 return true;
172 } 178 }
173 } 179 }
174} \ No newline at end of file 180}
diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
index 0a4ebe4..3ed3b5a 100644
--- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
@@ -163,6 +163,8 @@ namespace OpenSim.Region.Physics.OdePlugin
163 private bool m_isphysical; 163 private bool m_isphysical;
164 private bool m_isSelected; 164 private bool m_isSelected;
165 165
166 private bool m_NoColide; // for now only for internal use for bad meshs
167
166 internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively 168 internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively
167 169
168 private bool m_throttleUpdates; 170 private bool m_throttleUpdates;
@@ -253,7 +255,7 @@ namespace OpenSim.Region.Physics.OdePlugin
253 private float m_verticalAttractionEfficiency = 1.0f; // damped 255 private float m_verticalAttractionEfficiency = 1.0f; // damped
254 private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. 256 private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor.
255 257
256 SerialControl m_taintserial = null; 258// SerialControl m_taintserial = null;
257 object m_taintvehicledata = null; 259 object m_taintvehicledata = null;
258 260
259 public void DoSetVehicle() 261 public void DoSetVehicle()
@@ -309,410 +311,6 @@ namespace OpenSim.Region.Physics.OdePlugin
309 m_taintvehicledata = vdata; 311 m_taintvehicledata = vdata;
310 _parent_scene.AddPhysicsActorTaint(this); 312 _parent_scene.AddPhysicsActorTaint(this);
311 } 313 }
312
313 public override byte[] Serialize(bool PhysIsRunning)
314 {
315 SerialControl sc = new SerialControl();
316
317 lock (sc.alock)
318 {
319 if (PhysIsRunning)
320 {
321 m_taintserial = sc;
322
323 if (!Monitor.Wait(sc.alock, 1000))
324 {
325 m_log.Error("[chOde] prim data serialization timed out");
326 m_taintserial = null;
327 return new byte[0];
328 }
329 }
330 else
331 DoSerialize(sc);
332 }
333
334 return sc.data;
335 }
336
337 public void DoSerialize(SerialControl sc)
338 {
339 wstreamer st = new wstreamer();
340 Vector3 vtmp;
341
342 ushort version = 2;
343 if (!BitConverter.IsLittleEndian)
344 version |= 1;
345 st.Wushort(version); //version lower bit codes endian type for future use
346
347 // compact booleans in a ushort
348 ushort flags = 0;
349
350 if (m_isphysical) // this should be true for now
351 flags |= 1;
352 if (m_isSelected)
353 flags |= 2;
354 if (m_isVolumeDetect)
355 flags |= 4;
356 if (m_disabled)
357 flags |= 8;
358 if (m_collidesWater)
359 flags |= 16;
360 if (m_collidesLand)
361 flags |= 32;
362 if (m_usePID)
363 flags |= 64;
364 if (m_useAPID)
365 flags |= 128;
366 if (m_useHoverPID)
367 flags |= 256;
368 if (m_throttleUpdates)
369 flags |= 512;
370
371 st.Wushort(flags);
372
373 st.Wvector3(_size);
374 st.Wint(m_material);
375 st.Wfloat(m_density);
376 st.Wfloat(0); // future gravity mod V3
377 st.Wfloat(0); // future friction V3
378 st.Wfloat(0); // future bounce V3
379
380// st.Wuint((uint)m_collisionCategories);
381// st.Wuint((uint)m_collisionFlags);
382
383 if (_parent == null)
384 {
385 st.Wvector3(_position); // ??
386 st.Wquat(_orientation);
387 }
388 else // for childs save offsets
389 {
390 Quaternion to;
391 Quaternion ipo = Quaternion.Inverse(_parent.Orientation);
392
393 if (m_isphysical && prim_geom != IntPtr.Zero)
394 {
395 d.Vector3 dvt;
396 d.GeomCopyPosition(prim_geom, out dvt);
397
398 vtmp.X = dvt.X;
399 vtmp.Y = dvt.Y;
400 vtmp.Z = dvt.Z;
401
402 d.Quaternion dqt;
403 d.GeomCopyQuaternion(prim_geom, out dqt);
404
405 to.X = dqt.X;
406 to.Y = dqt.Y;
407 to.Z = dqt.Z;
408 to.W = dqt.W; // rotation in world
409 }
410 else
411 {
412 vtmp = _position;
413 to = _orientation;
414 }
415
416 vtmp -= _parent.Position; // offset in world
417 vtmp *= ipo; // offset in local
418 st.Wvector3(vtmp);
419
420 ipo *= to; // own rotation
421 st.Wquat(ipo);
422 }
423
424 st.Wvector3(_velocity);
425 st.Wvector3(m_rotationalVelocity);
426 st.Wvector3(_acceleration);
427 st.Wvector3(m_rotateEnable);
428
429 vtmp = Vector3.Zero;
430 for (int i = 0; i < m_forcelist.Count; i++)
431 {
432
433 vtmp += (m_forcelist[i] * 100);
434 }
435
436 st.Wvector3(vtmp); // force acc
437
438 vtmp = Vector3.Zero;
439 for (int i = 0; i < m_angularforcelist.Count; i++)
440 {
441 vtmp += (m_angularforcelist[i] * 100);
442 }
443
444 st.Wvector3(vtmp); // angular force acc
445
446 st.Wvector3(m_PIDTarget);
447 st.Wfloat(m_PIDTau);
448 st.Wfloat(PID_D);
449 st.Wfloat(PID_G);
450 st.Wquat(m_APIDTarget);
451 st.Wfloat(m_APIDStrength);
452 st.Wfloat(m_APIDDamping);
453 st.Wfloat(m_APIDdamper);
454
455 st.Wint((int)m_PIDHoverType);
456 st.Wfloat(m_PIDHoverHeight);
457 st.Wfloat(m_PIDHoverTau);
458 st.Wfloat(m_targetHoverHeight);
459
460 st.Wfloat(m_groundHeight);
461 st.Wfloat(m_waterHeight);
462
463 st.Wfloat(m_buoyancy);
464
465 // this must be last since type none ends stream
466 if (m_type == Vehicle.TYPE_NONE)
467 st.Wint((int)Vehicle.TYPE_NONE);
468 else
469 {
470 st.Wint((int)m_type);
471
472 st.Wquat(Quaternion.Identity); //m_referenceFrame
473
474 st.Wint((int)m_flags);
475
476 st.Wvector3(m_linearMotorDirection);
477 st.Wfloat(
478 (float)Math.Sqrt(m_lLinMotorDVel.LengthSquared() / m_linearMotorDirection.LengthSquared()));
479
480 st.Wvector3(m_linearFrictionTimescale);
481 st.Wfloat(m_linearMotorDecayTimescale);
482 st.Wfloat(m_linearMotorTimescale);
483 st.Wvector3(new Vector3(0, 0, 0)); //m_linearMotorOffset);
484
485 st.Wvector3(m_angularMotorDirection);
486 st.Wfloat((float)Math.Sqrt(m_angularMotorDVel.LengthSquared() / m_angularMotorDirection.LengthSquared()));
487
488 st.Wvector3(m_angularFrictionTimescale);
489 st.Wfloat(m_angularMotorDecayTimescale);
490 st.Wfloat(m_angularMotorTimescale);
491
492 st.Wfloat(0); //m_linearDeflectionEfficiency);
493 st.Wfloat(1000); //m_linearDeflectionTimescale);
494
495 st.Wfloat(0); //m_angularDeflectionEfficiency);
496 st.Wfloat(120); //m_angularDeflectionTimescale);
497
498 st.Wfloat(0); // m_bankingEfficiency);
499 st.Wfloat(0); //m_bankingMix);
500 st.Wfloat(1000); //m_bankingTimescale);
501
502 st.Wfloat(m_VhoverHeight);
503 st.Wfloat(0.5f); //m_VhoverEfficiency);
504 st.Wfloat(m_VhoverTimescale);
505
506 st.Wfloat(m_VehicleBuoyancy);
507
508 st.Wfloat(m_verticalAttractionEfficiency);
509 st.Wfloat(m_verticalAttractionTimescale);
510 }
511 sc.data = st.close();
512 m_taintserial = null;
513 Monitor.PulseAll(sc.alock);
514 }
515
516 public bool DeSerialize(byte[] data)
517 {
518 rstreamer st = new rstreamer(data);
519
520 int version =st.Rushort(); //version
521
522 // merge booleans in a ushort
523 ushort flags = st.Rushort();
524 if ((flags & 1) != 0)
525 m_isphysical = true;
526 if ((flags & 2) != 0)
527 m_taintselected = true;
528 if ((flags & 4) != 0)
529 m_isVolumeDetect = true;
530 if ((flags & 8) != 0)
531 m_taintdisable = true;
532 if ((flags & 16) != 0)
533 m_taintCollidesWater = true;
534 if ((flags & 32) != 0)
535 m_collidesLand = true;
536 if ((flags & 64) != 0)
537 m_usePID = true;
538 if ((flags & 128) != 0)
539 m_useAPID = true;
540 if ((flags & 256) != 0)
541 m_useHoverPID = true;
542 if ((flags & 512) != 0)
543 m_throttleUpdates = true;
544
545 _size = st.Rvector3();
546 m_taintsize = _size;
547
548 m_material= st.Rint();
549 m_density = st.Rfloat();
550 st.Rfloat(); // future gravity mod V3
551 st.Rfloat(); // future friction V3
552 st.Rfloat(); // future bounce V3
553
554// m_collisionCategories = (CollisionCategories)st.Ruint();
555// m_collisionFlags = (CollisionCategories) st.Ruint();
556
557 if (m_taintparent == null)
558 {
559 st.Rvector3(); // ignore old position sop/sog as to tell the new one
560 m_taintrot = st.Rquat(); //
561 _orientation = m_taintrot;
562 }
563 else
564 {
565 m_taintrot = _parent.Orientation;
566 m_taintposition = st.Rvector3(); // ??
567 _position = m_taintposition;
568
569 m_taintposition *= m_taintrot;
570 m_taintposition += _parent.Position;
571
572 m_taintrot *= st.Rquat(); //
573 _orientation = m_taintrot;
574 }
575
576 m_taintVelocity = st.Rvector3();
577 m_rotationalVelocity = st.Rvector3();
578
579 _acceleration = st.Rvector3();
580 m_rotateEnableRequest = st.Rvector3();
581 m_rotateEnableUpdate = true;
582
583 Vector3 vtmp;
584
585 vtmp = st.Rvector3(); // forces acc
586 m_forcelist.Add(vtmp);
587 m_taintforce = true;
588
589 vtmp = st.Rvector3(); // angular forces acc
590 m_angularforcelist.Add(vtmp);
591 m_taintaddangularforce = true;
592
593 m_PIDTarget = st.Rvector3();
594 m_PIDTau = st.Rfloat();
595 PID_D = st.Rfloat();
596 PID_G = st.Rfloat();
597
598 m_APIDTarget = st.Rquat();
599 m_APIDStrength = st.Rfloat();
600 m_APIDDamping = st.Rfloat();
601 m_APIDdamper = st.Rfloat();
602
603 m_PIDHoverType = (PIDHoverType) st.Rint();
604 m_PIDHoverHeight = st.Rfloat();
605 m_PIDHoverTau = st.Rfloat();
606 m_targetHoverHeight = st.Rfloat();
607
608 m_groundHeight = st.Rfloat();
609 m_waterHeight = st.Rfloat();
610
611 m_buoyancy = st.Rfloat();
612
613
614 // this must be last since type none ends stream
615
616 m_type = (Vehicle) st.Rint();
617
618 if (m_type != Vehicle.TYPE_NONE)
619 {
620 float ftmp;
621
622 st.Rquat(); //m_referenceFrame
623
624 m_flags = (VehicleFlag) st.Rint();
625
626 m_linearMotorDirection = st.Rvector3();
627
628 ftmp = st.Rfloat();
629 m_lLinMotorDVel = m_linearMotorDirection * ftmp;
630
631 m_linearFrictionTimescale = st.Rvector3();
632 m_linearMotorDecayTimescale = st.Rfloat();
633 m_linearMotorTimescale = st.Rfloat();
634 st.Rvector3(); //m_linearMotorOffset);
635
636 m_angularMotorDirection = st.Rvector3();
637 ftmp = st.Rfloat();
638 m_angularMotorDVel = m_angularMotorDirection * ftmp;
639
640 m_angularFrictionTimescale = st.Rvector3();
641 m_angularMotorDecayTimescale = st.Rfloat();
642 m_angularMotorTimescale = st.Rfloat();
643
644 st.Rfloat(); //m_linearDeflectionEfficiency);
645 st.Rfloat(); //m_linearDeflectionTimescale);
646
647 st.Rfloat(); //m_angularDeflectionEfficiency);
648 st.Rfloat(); //m_angularDeflectionTimescale);
649
650 st.Rfloat(); // m_bankingEfficiency);
651 st.Rfloat(); //m_bankingMix);
652 st.Rfloat(); //m_bankingTimescale);
653
654 m_VhoverHeight = st.Rfloat();
655 st.Rfloat(); //m_VhoverEfficiency);
656 m_VhoverTimescale = st.Rfloat();
657
658 m_VehicleBuoyancy = st.Rfloat();
659
660 m_verticalAttractionEfficiency = st.Rfloat();
661 m_verticalAttractionTimescale = st.Rfloat();
662 }
663 st.close();
664 return true;
665 }
666
667 public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, PhysicsActor parent,
668 PrimitiveBaseShape pbs, CollisionLocker dode, uint localid, byte[] sdata)
669 {
670 m_localID = localid;
671 ode = dode;
672
673 if (parent == null)
674 {
675 m_taintparent = null;
676
677 if (!pos.IsFinite())
678 {
679 pos = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f),
680 parent_scene.GetTerrainHeightAtXY(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f)) + 0.5f);
681 m_log.Warn("[PHYSICS]: Got nonFinite Object create Position");
682 }
683
684 _position = pos;
685 m_taintposition = pos;
686 }
687 else
688 m_taintparent = parent;
689
690 body_autodisable_frames = parent_scene.bodyFramesAutoDisable;
691
692 prim_geom = IntPtr.Zero;
693
694 _mesh = null;
695 m_meshfailed = false;
696 _pbs = pbs;
697
698 _parent_scene = parent_scene;
699 m_targetSpace = (IntPtr)0;
700
701 if(sdata != null && sdata.Length > 1)
702 DeSerialize(sdata);
703
704 if (m_isphysical)
705 m_targetSpace = _parent_scene.space;
706
707 _triMeshData = IntPtr.Zero;
708
709 m_primName = primName;
710 m_taintserial = null;
711 m_taintadd = true;
712 _parent_scene.AddPhysicsActorTaint(this);
713 // don't do .add() here; old geoms get recycled with the same hash
714 }
715
716 public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size, 314 public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size,
717 Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode, uint localid) 315 Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode, uint localid)
718 { 316 {
@@ -776,8 +374,9 @@ namespace OpenSim.Region.Physics.OdePlugin
776 } 374 }
777 375
778 _triMeshData = IntPtr.Zero; 376 _triMeshData = IntPtr.Zero;
377 m_NoColide = false;
779 378
780 m_taintserial = null; 379// m_taintserial = null;
781 m_primName = primName; 380 m_primName = primName;
782 m_taintadd = true; 381 m_taintadd = true;
783 _parent_scene.AddPhysicsActorTaint(this); 382 _parent_scene.AddPhysicsActorTaint(this);
@@ -814,7 +413,6 @@ namespace OpenSim.Region.Physics.OdePlugin
814 { 413 {
815 set 414 set
816 { 415 {
817
818 //Console.WriteLine("Sel {0} {1} {2}", m_primName, value, m_isphysical); 416 //Console.WriteLine("Sel {0} {1} {2}", m_primName, value, m_isphysical);
819 // This only makes the object not collidable if the object 417 // This only makes the object not collidable if the object
820 // is physical or the object is modified somehow *IN THE FUTURE* 418 // is physical or the object is modified somehow *IN THE FUTURE*
@@ -1077,7 +675,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1077 } 675 }
1078 } 676 }
1079 677
1080
1081 public override bool FloatOnWater 678 public override bool FloatOnWater
1082 { 679 {
1083 set 680 set
@@ -1270,7 +867,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1270 } 867 }
1271 } 868 }
1272 869
1273
1274 public void SetGeom(IntPtr geom) 870 public void SetGeom(IntPtr geom)
1275 { 871 {
1276 if (prim_geom != IntPtr.Zero) 872 if (prim_geom != IntPtr.Zero)
@@ -1290,9 +886,25 @@ namespace OpenSim.Region.Physics.OdePlugin
1290 { 886 {
1291 _parent_scene.geom_name_map[prim_geom] = this.m_primName; 887 _parent_scene.geom_name_map[prim_geom] = this.m_primName;
1292 _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this; 888 _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this;
1293 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1294 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1295 //Console.WriteLine("**** Create {2} Dicts: actor={0} name={1}", _parent_scene.actor_name_map.Count, _parent_scene.geom_name_map.Count, this.m_primName); 889 //Console.WriteLine("**** Create {2} Dicts: actor={0} name={1}", _parent_scene.actor_name_map.Count, _parent_scene.geom_name_map.Count, this.m_primName);
890 if (m_NoColide)
891 {
892 d.GeomSetCategoryBits(prim_geom, 0);
893 if (m_isphysical)
894 {
895 d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
896 }
897 else
898 {
899 d.GeomSetCollideBits(prim_geom, 0);
900 d.GeomDisable(prim_geom);
901 }
902 }
903 else
904 {
905 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
906 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
907 }
1296 } 908 }
1297 909
1298 if (childPrim) 910 if (childPrim)
@@ -1351,11 +963,20 @@ namespace OpenSim.Region.Physics.OdePlugin
1351 myrot.W = _orientation.W; 963 myrot.W = _orientation.W;
1352 d.BodySetQuaternion(Body, ref myrot); 964 d.BodySetQuaternion(Body, ref myrot);
1353 d.GeomSetBody(prim_geom, Body); 965 d.GeomSetBody(prim_geom, Body);
966
1354 m_collisionCategories |= CollisionCategories.Body; 967 m_collisionCategories |= CollisionCategories.Body;
1355 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); 968 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1356 969
1357 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 970 if (m_NoColide)
1358 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 971 {
972 d.GeomSetCategoryBits(prim_geom, 0);
973 d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
974 }
975 else
976 {
977 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
978 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
979 }
1359 980
1360 d.BodySetAutoDisableFlag(Body, true); 981 d.BodySetAutoDisableFlag(Body, true);
1361 d.BodySetAutoDisableSteps(Body, body_autodisable_frames); 982 d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
@@ -1723,11 +1344,19 @@ namespace OpenSim.Region.Physics.OdePlugin
1723 1344
1724 if (prim_geom != IntPtr.Zero) 1345 if (prim_geom != IntPtr.Zero)
1725 { 1346 {
1726 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 1347 if (m_NoColide)
1727 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1348 {
1349 d.GeomSetCategoryBits(prim_geom, 0);
1350 d.GeomSetCollideBits(prim_geom, 0);
1351 d.GeomDisable(prim_geom);
1352 }
1353 else
1354 {
1355 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1356 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1357 }
1728 } 1358 }
1729 1359
1730
1731 d.BodyDestroy(Body); 1360 d.BodyDestroy(Body);
1732 lock (childrenPrim) 1361 lock (childrenPrim)
1733 { 1362 {
@@ -1735,6 +1364,13 @@ namespace OpenSim.Region.Physics.OdePlugin
1735 { 1364 {
1736 foreach (OdePrim prm in childrenPrim) 1365 foreach (OdePrim prm in childrenPrim)
1737 { 1366 {
1367 if (prm.m_NoColide && prm.prim_geom != IntPtr.Zero)
1368 {
1369 d.GeomSetCategoryBits(prm.prim_geom, 0);
1370 d.GeomSetCollideBits(prm.prim_geom, 0);
1371 d.GeomDisable(prm.prim_geom);
1372 }
1373
1738 _parent_scene.remActivePrim(prm); 1374 _parent_scene.remActivePrim(prm);
1739 prm.Body = IntPtr.Zero; 1375 prm.Body = IntPtr.Zero;
1740 } 1376 }
@@ -1752,8 +1388,18 @@ namespace OpenSim.Region.Physics.OdePlugin
1752 1388
1753 if (prim_geom != IntPtr.Zero) 1389 if (prim_geom != IntPtr.Zero)
1754 { 1390 {
1755 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 1391 if (m_NoColide)
1756 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1392 {
1393 d.GeomSetCategoryBits(prim_geom, 0);
1394 d.GeomSetCollideBits(prim_geom, 0);
1395 d.GeomDisable(prim_geom);
1396 }
1397 else
1398 {
1399 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1400 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1401 }
1402
1757 } 1403 }
1758 1404
1759 1405
@@ -1768,11 +1414,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1768 1414
1769 public bool setMesh(OdeScene parent_scene, IMesh mesh) 1415 public bool setMesh(OdeScene parent_scene, IMesh mesh)
1770 { 1416 {
1771 // This sleeper is there to moderate how long it takes between
1772 // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object
1773
1774 //Thread.Sleep(10);
1775
1776 //Kill Body so that mesh can re-make the geom 1417 //Kill Body so that mesh can re-make the geom
1777 if (IsPhysical && Body != IntPtr.Zero) 1418 if (IsPhysical && Body != IntPtr.Zero)
1778 { 1419 {
@@ -1790,14 +1431,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1790 } 1431 }
1791 } 1432 }
1792 1433
1793// do it on caller instead
1794/*
1795 if (_triMeshData != IntPtr.Zero)
1796 {
1797 d.GeomTriMeshDataDestroy(_triMeshData);
1798 _triMeshData = IntPtr.Zero;
1799 }
1800*/
1801 IntPtr vertices, indices; 1434 IntPtr vertices, indices;
1802 int vertexCount, indexCount; 1435 int vertexCount, indexCount;
1803 int vertexStride, triStride; 1436 int vertexStride, triStride;
@@ -1809,38 +1442,20 @@ namespace OpenSim.Region.Physics.OdePlugin
1809 1442
1810 if (vertexCount == 0 || indexCount == 0) 1443 if (vertexCount == 0 || indexCount == 0)
1811 { 1444 {
1812 m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. It can be a sculp with alpha channel in map. Replacing it by a small box.", Name, _position.X, _position.Y, _position.Z); 1445 m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. mesh UUID {4}", Name, _position.X, _position.Y, _position.Z, _pbs.SculptTexture.ToString());
1813 _size.X = 0.05f;
1814 _size.Y = 0.05f;
1815 _size.Z = 0.05f;
1816 return false; 1446 return false;
1817 } 1447 }
1818 1448
1819/* 1449 IntPtr geo = IntPtr.Zero;
1820 if (m_MeshToTriMeshMap.ContainsKey(mesh)) 1450 try
1821 {
1822 _triMeshData = m_MeshToTriMeshMap[mesh];
1823 }
1824 else
1825*/
1826
1827
1828 { 1451 {
1829 _triMeshData = d.GeomTriMeshDataCreate(); 1452 _triMeshData = d.GeomTriMeshDataCreate();
1830
1831 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); 1453 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
1832 d.GeomTriMeshDataPreprocess(_triMeshData); 1454 d.GeomTriMeshDataPreprocess(_triMeshData);
1833// m_MeshToTriMeshMap[mesh] = _triMeshData;
1834 }
1835 1455
1836 _parent_scene.waitForSpaceUnlock(m_targetSpace); 1456 _parent_scene.waitForSpaceUnlock(m_targetSpace);
1837 try 1457
1838 { 1458 geo = d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null);
1839 // if (prim_geom == IntPtr.Zero) // setGeom takes care of phys engine recreate and prim_geom pointer
1840 // {
1841 // SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null));
1842 SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null));
1843 // }
1844 } 1459 }
1845 catch (Exception e) 1460 catch (Exception e)
1846 { 1461 {
@@ -1851,21 +1466,11 @@ namespace OpenSim.Region.Physics.OdePlugin
1851 d.GeomTriMeshDataDestroy(_triMeshData); 1466 d.GeomTriMeshDataDestroy(_triMeshData);
1852 _triMeshData = IntPtr.Zero; 1467 _triMeshData = IntPtr.Zero;
1853 } 1468 }
1854 _size.X = 0.05f;
1855 _size.Y = 0.05f;
1856 _size.Z = 0.05f;
1857 return false; 1469 return false;
1858 } 1470 }
1859 1471
1472 SetGeom(geo);
1860 1473
1861 // if (IsPhysical && Body == (IntPtr) 0)
1862 // {
1863 // Recreate the body
1864 // m_interpenetrationcount = 0;
1865 // m_collisionscore = 0;
1866
1867 // enableBody();
1868 // }
1869 return true; 1474 return true;
1870 } 1475 }
1871 1476
@@ -1943,18 +1548,21 @@ namespace OpenSim.Region.Physics.OdePlugin
1943 if (m_taintvehicledata != null) 1548 if (m_taintvehicledata != null)
1944 DoSetVehicle(); 1549 DoSetVehicle();
1945 1550
1946 if (m_taintserial != null)
1947 DoSerialize(m_taintserial);
1948
1949 /* obsolete 1551 /* obsolete
1950 if (!m_angularLock.ApproxEquals(m_taintAngularLock,0f)) 1552 if (!m_angularLock.ApproxEquals(m_taintAngularLock,0f))
1951 changeAngularLock(timestep); 1553 changeAngularLock(timestep);
1952 */ 1554 */
1953 } 1555 }
1556
1954 else 1557 else
1955 { 1558 {
1956 m_log.Error("[PHYSICS]: The scene reused a disposed PhysActor! *waves finger*, Don't be evil. A couple of things can cause this. An improper prim breakdown(be sure to set prim_geom to zero after d.GeomDestroy! An improper buildup (creating the geom failed). Or, the Scene Reused a physics actor after disposing it.)"); 1559 m_log.Error("[PHYSICS]: prim {0} at <{1},{2},{3}> as invalid geom");
1560
1561 // not sure this will not flame...
1562 m_taintremove = true;
1563 _parent_scene.AddPhysicsActorTaint(this);
1957 } 1564 }
1565
1958 } 1566 }
1959 1567
1960 /* obsolete 1568 /* obsolete
@@ -2058,7 +1666,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2058 } 1666 }
2059 foreach (OdePrim prm in childrenPrim) 1667 foreach (OdePrim prm in childrenPrim)
2060 { 1668 {
2061
2062 prm.m_collisionCategories |= CollisionCategories.Body; 1669 prm.m_collisionCategories |= CollisionCategories.Body;
2063 prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); 1670 prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
2064 1671
@@ -2067,9 +1674,17 @@ namespace OpenSim.Region.Physics.OdePlugin
2067 m_log.Warn("[PHYSICS]: Unable to link one of the linkset elements. No geom yet"); 1674 m_log.Warn("[PHYSICS]: Unable to link one of the linkset elements. No geom yet");
2068 continue; 1675 continue;
2069 } 1676 }
2070 d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories);
2071 d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags);
2072 1677
1678 if (prm.m_NoColide)
1679 {
1680 d.GeomSetCategoryBits(prm.prim_geom, 0);
1681 d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
1682 }
1683 else
1684 {
1685 d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories);
1686 d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags);
1687 }
2073 1688
2074 d.Quaternion quat = new d.Quaternion(); 1689 d.Quaternion quat = new d.Quaternion();
2075 quat.W = prm._orientation.W; 1690 quat.W = prm._orientation.W;
@@ -2098,20 +1713,28 @@ namespace OpenSim.Region.Physics.OdePlugin
2098 m_log.Debug("[PHYSICS]:I ain't got no boooooooooddy, no body"); 1713 m_log.Debug("[PHYSICS]:I ain't got no boooooooooddy, no body");
2099 } 1714 }
2100 1715
2101
2102 prm.m_interpenetrationcount = 0; 1716 prm.m_interpenetrationcount = 0;
2103 prm.m_collisionscore = 0; 1717 prm.m_collisionscore = 0;
2104 prm.m_disabled = false; 1718 prm.m_disabled = false;
2105 1719
2106 prm.Body = Body; 1720 prm.Body = Body;
2107 _parent_scene.addActivePrim(prm); 1721
1722 _parent_scene.addActivePrim(prm);
2108 } 1723 }
1724
2109 m_collisionCategories |= CollisionCategories.Body; 1725 m_collisionCategories |= CollisionCategories.Body;
2110 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); 1726 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
2111 1727
2112 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 1728 if (m_NoColide)
2113 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1729 {
2114 1730 d.GeomSetCategoryBits(prim_geom, 0);
1731 d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
1732 }
1733 else
1734 {
1735 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1736 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1737 }
2115 1738
2116 d.Quaternion quat2 = new d.Quaternion(); 1739 d.Quaternion quat2 = new d.Quaternion();
2117 quat2.W = _orientation.W; 1740 quat2.W = _orientation.W;
@@ -2134,19 +1757,18 @@ namespace OpenSim.Region.Physics.OdePlugin
2134 d.BodySetAutoDisableFlag(Body, true); 1757 d.BodySetAutoDisableFlag(Body, true);
2135 d.BodySetAutoDisableSteps(Body, body_autodisable_frames); 1758 d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
2136 1759
2137
2138 m_interpenetrationcount = 0; 1760 m_interpenetrationcount = 0;
2139 m_collisionscore = 0; 1761 m_collisionscore = 0;
2140 m_disabled = false; 1762 m_disabled = false;
2141 1763
2142 d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); 1764 d.BodySetPosition(Body, Position.X, Position.Y, Position.Z);
2143 if (m_type != Vehicle.TYPE_NONE) Enable(Body, _parent_scene); 1765 if (m_type != Vehicle.TYPE_NONE) Enable(Body, _parent_scene);
1766
2144 _parent_scene.addActivePrim(this); 1767 _parent_scene.addActivePrim(this);
2145 } 1768 }
2146 } 1769 }
2147 } 1770 }
2148 } 1771 }
2149
2150 } 1772 }
2151 1773
2152 private void ChildSetGeom(OdePrim odePrim) 1774 private void ChildSetGeom(OdePrim odePrim)
@@ -2258,6 +1880,8 @@ namespace OpenSim.Region.Physics.OdePlugin
2258 { 1880 {
2259 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 1881 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
2260 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1882 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1883 if (m_NoColide)
1884 d.GeomDisable(prim_geom);
2261 } 1885 }
2262 1886
2263 if (m_isphysical) 1887 if (m_isphysical)
@@ -2275,22 +1899,35 @@ namespace OpenSim.Region.Physics.OdePlugin
2275 } 1899 }
2276 else 1900 else
2277 { 1901 {
2278 m_collisionCategories = CollisionCategories.Geom; 1902 m_collisionCategories = CollisionCategories.Geom;
2279 1903 if (m_isphysical)
2280 if (m_isphysical) 1904 m_collisionCategories |= CollisionCategories.Body;
2281 m_collisionCategories |= CollisionCategories.Body;
2282 1905
2283 m_collisionFlags = m_default_collisionFlags; 1906 m_collisionFlags = m_default_collisionFlags;
2284 1907
2285 if (m_collidesLand) 1908 if (m_collidesLand)
2286 m_collisionFlags |= CollisionCategories.Land; 1909 m_collisionFlags |= CollisionCategories.Land;
2287 if (m_collidesWater) 1910 if (m_collidesWater)
2288 m_collisionFlags |= CollisionCategories.Water; 1911 m_collisionFlags |= CollisionCategories.Water;
2289 1912
2290 if (prim_geom != IntPtr.Zero) 1913 if (prim_geom != IntPtr.Zero)
2291 { 1914 {
2292 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 1915 if (m_NoColide)
2293 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1916 {
1917 d.GeomSetCategoryBits(prim_geom, 0);
1918 if (m_isphysical)
1919 d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
1920 else
1921 {
1922 d.GeomSetCollideBits(prim_geom, 0);
1923 d.GeomDisable(prim_geom);
1924 }
1925 }
1926 else
1927 {
1928 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1929 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1930 }
2294 } 1931 }
2295 if (Body != IntPtr.Zero) 1932 if (Body != IntPtr.Zero)
2296 { 1933 {
@@ -2330,19 +1967,29 @@ namespace OpenSim.Region.Physics.OdePlugin
2330 { 1967 {
2331 bool gottrimesh = false; 1968 bool gottrimesh = false;
2332 1969
1970 m_NoColide = false; // assume all will go well
1971
2333 if (_triMeshData != IntPtr.Zero) 1972 if (_triMeshData != IntPtr.Zero)
2334 { 1973 {
2335 d.GeomTriMeshDataDestroy(_triMeshData); 1974 d.GeomTriMeshDataDestroy(_triMeshData);
2336 _triMeshData = IntPtr.Zero; 1975 _triMeshData = IntPtr.Zero;
2337 } 1976 }
2338 1977
2339 if (_mesh != null) // Special - make mesh 1978 if (_mesh != null)
2340 { 1979 {
2341 gottrimesh = setMesh(_parent_scene, _mesh); 1980 gottrimesh = setMesh(_parent_scene, _mesh);
1981 if (!gottrimesh)
1982 {
1983 // getting a mesh failed,
1984 // lets go on having a basic box or sphere, with prim size but not coliding
1985 // physical colides with land, non with nothing
1986
1987 m_NoColide = true;
1988 }
2342 } 1989 }
2343 1990
2344 if (!gottrimesh) // not a mesh 1991 if (!gottrimesh)
2345 { 1992 { // we will have a basic box or sphere
2346 IntPtr geo = IntPtr.Zero; 1993 IntPtr geo = IntPtr.Zero;
2347 1994
2348 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1 1995 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1
@@ -2376,14 +2023,17 @@ namespace OpenSim.Region.Physics.OdePlugin
2376 } 2023 }
2377 } 2024 }
2378 2025
2379 if (geo == IntPtr.Zero) 2026 if (geo == IntPtr.Zero) // if this happens it must be fixed
2380 { 2027 {
2028 // if it does lets stop what we can
2029 // not sure this will not flame...
2030
2381 m_taintremove = true; 2031 m_taintremove = true;
2382 _parent_scene.AddPhysicsActorTaint(this); 2032 _parent_scene.AddPhysicsActorTaint(this);
2383 return; 2033 return;
2384 } 2034 }
2385 2035
2386 SetGeom(geo); 2036 SetGeom(geo); // this processes the m_NoColide
2387 } 2037 }
2388 } 2038 }
2389 2039
@@ -2415,7 +2065,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2415 } 2065 }
2416 } 2066 }
2417 2067
2418
2419 lock (_parent_scene.OdeLock) 2068 lock (_parent_scene.OdeLock)
2420 { 2069 {
2421 CreateGeom(m_targetSpace, _mesh); 2070 CreateGeom(m_targetSpace, _mesh);
@@ -2518,8 +2167,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2518 m_taintposition = _position; 2167 m_taintposition = _position;
2519 } 2168 }
2520 2169
2521
2522
2523 public void rotate(float timestep) 2170 public void rotate(float timestep)
2524 { 2171 {
2525 d.Quaternion myrot = new d.Quaternion(); 2172 d.Quaternion myrot = new d.Quaternion();
diff --git a/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs
index 7a1e671..5f5d547 100644
--- a/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs
@@ -1735,7 +1735,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1735 1735
1736 return newPrim; 1736 return newPrim;
1737 } 1737 }
1738 1738/*
1739 private PhysicsActor AddPrim(String name, Vector3 position, PhysicsActor parent, 1739 private PhysicsActor AddPrim(String name, Vector3 position, PhysicsActor parent,
1740 PrimitiveBaseShape pbs, uint localid, byte[] sdata) 1740 PrimitiveBaseShape pbs, uint localid, byte[] sdata)
1741 { 1741 {
@@ -1751,7 +1751,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1751 1751
1752 return newPrim; 1752 return newPrim;
1753 } 1753 }
1754 1754*/
1755 1755
1756 public void addActivePrim(OdePrim activatePrim) 1756 public void addActivePrim(OdePrim activatePrim)
1757 { 1757 {
@@ -1778,7 +1778,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1778 1778
1779 return result; 1779 return result;
1780 } 1780 }
1781 1781/*
1782 public override PhysicsActor AddPrimShape(string primName, PhysicsActor parent, PrimitiveBaseShape pbs, Vector3 position, 1782 public override PhysicsActor AddPrimShape(string primName, PhysicsActor parent, PrimitiveBaseShape pbs, Vector3 position,
1783 uint localid, byte[] sdata) 1783 uint localid, byte[] sdata)
1784 { 1784 {
@@ -1789,7 +1789,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1789 1789
1790 return result; 1790 return result;
1791 } 1791 }
1792 1792*/
1793 public override float TimeDilation 1793 public override float TimeDilation
1794 { 1794 {
1795 get { return m_timeDilation; } 1795 get { return m_timeDilation; }
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
index f525e9e..1a0c2a7 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
@@ -72,11 +72,13 @@ namespace OpenSim.Region.Physics.Manager
72 { 72 {
73 public float mu; 73 public float mu;
74 public float bounce; 74 public float bounce;
75 public bool softcolide;
75 76
76 public ContactData(float _mu, float _bounce) 77 public ContactData(float _mu, float _bounce, bool _softcolide)
77 { 78 {
78 mu = _mu; 79 mu = _mu;
79 bounce = _bounce; 80 bounce = _bounce;
81 softcolide = _softcolide;
80 } 82 }
81 } 83 }
82 /// <summary> 84 /// <summary>
@@ -158,9 +160,10 @@ namespace OpenSim.Region.Physics.Manager
158 160
159 public virtual bool Building { get; set; } 161 public virtual bool Building { get; set; }
160 162
161 public virtual ContactData ContactData 163 public virtual void getContactData(ref ContactData cdata)
162 { 164 {
163 get { return new ContactData(0, 0); } 165 cdata.mu = 0;
166 cdata.bounce = 0;
164 } 167 }
165 168
166 public abstract bool Stopped { get; } 169 public abstract bool Stopped { get; }
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
index 793e281..9a22331 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
@@ -136,7 +136,8 @@ namespace OpenSim.Region.Physics.OdePlugin
136 public UUID m_uuid; 136 public UUID m_uuid;
137 public bool bad = false; 137 public bool bad = false;
138 138
139 public ContactData AvatarContactData = new ContactData(10f, 0.3f); 139 float mu;
140 float bounce;
140 141
141 public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, Vector3 size, float pid_d, float pid_p, float capsule_radius, float density, float walk_divisor, float rundivisor) 142 public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, Vector3 size, float pid_d, float pid_p, float capsule_radius, float density, float walk_divisor, float rundivisor)
142 { 143 {
@@ -168,8 +169,8 @@ namespace OpenSim.Region.Physics.OdePlugin
168 m_density = density; 169 m_density = density;
169 m_mass = 80f; // sure we have a default 170 m_mass = 80f; // sure we have a default
170 171
171 AvatarContactData.mu = parent_scene.AvatarFriction; 172 mu = parent_scene.AvatarFriction;
172 AvatarContactData.bounce = parent_scene.AvatarBounce; 173 bounce = parent_scene.AvatarBounce;
173 174
174 walkDivisor = walk_divisor; 175 walkDivisor = walk_divisor;
175 runDivisor = rundivisor; 176 runDivisor = rundivisor;
@@ -190,9 +191,11 @@ namespace OpenSim.Region.Physics.OdePlugin
190 set { return; } 191 set { return; }
191 } 192 }
192 193
193 public override ContactData ContactData 194 public override void getContactData(ref ContactData cdata)
194 { 195 {
195 get { return AvatarContactData; } 196 cdata.mu = mu;
197 cdata.bounce = bounce;
198 cdata.softcolide = false;
196 } 199 }
197 200
198 public override bool Building { get; set; } 201 public override bool Building { get; set; }
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs
index c9d0909..d0b4546 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs
@@ -38,7 +38,7 @@
38 * settings use. 38 * settings use.
39 */ 39 */
40 40
41// Ubit 2012 41// Extensive change Ubit 2012
42 42
43using System; 43using System;
44using System.Collections.Generic; 44using System.Collections.Generic;
@@ -119,7 +119,15 @@ namespace OpenSim.Region.Physics.OdePlugin
119 // auxiliar 119 // auxiliar
120 private float m_lmEfect = 0; // current linear motor eficiency 120 private float m_lmEfect = 0; // current linear motor eficiency
121 private float m_amEfect = 0; // current angular motor eficiency 121 private float m_amEfect = 0; // current angular motor eficiency
122 private float m_ffactor = 1.0f;
122 123
124 public float FrictionFactor
125 {
126 get
127 {
128 return m_ffactor;
129 }
130 }
123 131
124 public ODEDynamics(OdePrim rootp) 132 public ODEDynamics(OdePrim rootp)
125 { 133 {
@@ -127,7 +135,6 @@ namespace OpenSim.Region.Physics.OdePlugin
127 _pParentScene = rootPrim._parent_scene; 135 _pParentScene = rootPrim._parent_scene;
128 } 136 }
129 137
130
131 public void DoSetVehicle(VehicleData vd) 138 public void DoSetVehicle(VehicleData vd)
132 { 139 {
133 140
@@ -152,6 +159,7 @@ namespace OpenSim.Region.Physics.OdePlugin
152 m_linearMotorTimescale = vd.m_linearMotorTimescale; 159 m_linearMotorTimescale = vd.m_linearMotorTimescale;
153 if (m_linearMotorTimescale < timestep) m_linearMotorTimescale = timestep; 160 if (m_linearMotorTimescale < timestep) m_linearMotorTimescale = timestep;
154 161
162
155 m_linearMotorOffset = vd.m_linearMotorOffset; 163 m_linearMotorOffset = vd.m_linearMotorOffset;
156 164
157 //Angular properties 165 //Angular properties
@@ -201,6 +209,7 @@ namespace OpenSim.Region.Physics.OdePlugin
201 209
202 m_lmEfect = 0; 210 m_lmEfect = 0;
203 m_amEfect = 0; 211 m_amEfect = 0;
212 m_ffactor = 1.0f;
204 } 213 }
205 214
206 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) 215 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
@@ -318,6 +327,7 @@ namespace OpenSim.Region.Physics.OdePlugin
318 if (len > 30.0f) 327 if (len > 30.0f)
319 m_linearMotorDirection *= (30.0f / len); 328 m_linearMotorDirection *= (30.0f / len);
320 m_lmEfect = 1.0f; // turn it on 329 m_lmEfect = 1.0f; // turn it on
330 m_ffactor = 0.01f;
321 if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) 331 if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
322 && !rootPrim.m_isSelected && !rootPrim.m_disabled) 332 && !rootPrim.m_isSelected && !rootPrim.m_disabled)
323 d.BodyEnable(rootPrim.Body); 333 d.BodyEnable(rootPrim.Body);
@@ -368,6 +378,7 @@ namespace OpenSim.Region.Physics.OdePlugin
368 if (len > 30.0f) 378 if (len > 30.0f)
369 m_linearMotorDirection *= (30.0f / len); 379 m_linearMotorDirection *= (30.0f / len);
370 m_lmEfect = 1.0f; // turn it on 380 m_lmEfect = 1.0f; // turn it on
381 m_ffactor = 0.01f;
371 if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) 382 if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
372 && !rootPrim.m_isSelected && !rootPrim.m_disabled) 383 && !rootPrim.m_isSelected && !rootPrim.m_disabled)
373 d.BodyEnable(rootPrim.Body); 384 d.BodyEnable(rootPrim.Body);
@@ -414,6 +425,7 @@ namespace OpenSim.Region.Physics.OdePlugin
414 float invtimestep = _pParentScene.ODE_STEPSIZE; 425 float invtimestep = _pParentScene.ODE_STEPSIZE;
415 m_lmEfect = 0; 426 m_lmEfect = 0;
416 m_amEfect = 0; 427 m_amEfect = 0;
428 m_ffactor = 1f;
417 429
418 m_linearMotorDirection = Vector3.Zero; 430 m_linearMotorDirection = Vector3.Zero;
419 m_angularMotorDirection = Vector3.Zero; 431 m_angularMotorDirection = Vector3.Zero;
@@ -591,6 +603,7 @@ namespace OpenSim.Region.Physics.OdePlugin
591 { 603 {
592 m_lmEfect = 0; 604 m_lmEfect = 0;
593 m_amEfect = 0; 605 m_amEfect = 0;
606 m_ffactor = 1f;
594 } 607 }
595 608
596 public static Vector3 Xrot(Quaternion rot) 609 public static Vector3 Xrot(Quaternion rot)
@@ -614,6 +627,7 @@ namespace OpenSim.Region.Physics.OdePlugin
614 return vec; 627 return vec;
615 } 628 }
616 629
630 private const float pi = (float)Math.PI;
617 private const float halfpi = 0.5f * (float)Math.PI; 631 private const float halfpi = 0.5f * (float)Math.PI;
618 632
619 public static Vector3 ubitRot2Euler(Quaternion rot) 633 public static Vector3 ubitRot2Euler(Quaternion rot)
@@ -740,9 +754,14 @@ namespace OpenSim.Region.Physics.OdePlugin
740 force.Z += tmpV.Z; 754 force.Z += tmpV.Z;
741 } 755 }
742 m_lmEfect *= (1.0f - 1.0f / m_linearMotorDecayTimescale); 756 m_lmEfect *= (1.0f - 1.0f / m_linearMotorDecayTimescale);
757
758 m_ffactor = 0.01f + 1e-4f * curVel.LengthSquared();
743 } 759 }
744 else 760 else
761 {
745 m_lmEfect = 0; 762 m_lmEfect = 0;
763 m_ffactor = 1f;
764 }
746 765
747 // friction 766 // friction
748 if (curLocalVel.X != 0 || curLocalVel.Y != 0 || curLocalVel.Z != 0) 767 if (curLocalVel.X != 0 || curLocalVel.Y != 0 || curLocalVel.Z != 0)
@@ -884,35 +903,64 @@ namespace OpenSim.Region.Physics.OdePlugin
884 float ftmp = 1.0f / m_verticalAttractionTimescale / m_verticalAttractionTimescale / _pParentScene.ODE_STEPSIZE; 903 float ftmp = 1.0f / m_verticalAttractionTimescale / m_verticalAttractionTimescale / _pParentScene.ODE_STEPSIZE;
885 float ftmp2 = m_verticalAttractionEfficiency / _pParentScene.ODE_STEPSIZE; 904 float ftmp2 = m_verticalAttractionEfficiency / _pParentScene.ODE_STEPSIZE;
886 905
887 if (Math.Abs(roll) > 0.01) // roll 906 if (roll > halfpi)
907 roll = pi - roll;
908 else if (roll < -halfpi)
909 roll = -pi - roll;
910
911 float effroll = pitch / halfpi;
912 effroll *= effroll;
913 effroll = 1 - effroll;
914 effroll *= roll;
915
916 if (Math.Abs(effroll) > 0.01) // roll
888 { 917 {
889 torque.X -= -roll * ftmp + curLocalAngVel.X * ftmp2; 918 torque.X -= -effroll * ftmp + curLocalAngVel.X * ftmp2;
890 } 919 }
891 920
892 if (Math.Abs(pitch) > 0.01 && ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) == 0)) // pitch 921 if ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) == 0)
893 { 922 {
894 torque.Y -= -pitch * ftmp + curLocalAngVel.Y * ftmp2; 923 float effpitch = roll / halfpi;
924 effpitch *= effpitch;
925 effpitch = 1 - effpitch;
926 effpitch *= pitch;
927
928 if (Math.Abs(effpitch) > 0.01) // pitch
929 {
930 torque.Y -= -effpitch * ftmp + curLocalAngVel.Y * ftmp2;
931 }
895 } 932 }
896 933
897 if (m_bankingEfficiency != 0 && Math.Abs(roll) > 0.01) 934 if (m_bankingEfficiency != 0 && Math.Abs(effroll) > 0.01)
898 { 935 {
899 float broll = roll * m_bankingEfficiency; ; 936
937 float broll = effroll;
938/*
939 if (broll > halfpi)
940 broll = pi - broll;
941 else if (broll < -halfpi)
942 broll = -pi - broll;
943*/
944 broll *= m_bankingEfficiency;
900 if (m_bankingMix != 0) 945 if (m_bankingMix != 0)
901 { 946 {
902 float vfact = Math.Abs(curLocalVel.X) / 10.0f; 947 float vfact = Math.Abs(curLocalVel.X) / 10.0f;
903 if (vfact > 1.0f) vfact = 1.0f; 948 if (vfact > 1.0f) vfact = 1.0f;
949
904 if (curLocalVel.X >= 0) 950 if (curLocalVel.X >= 0)
905 broll *= ((1 - m_bankingMix) + vfact); 951 broll *= (1 + (vfact - 1) * m_bankingMix);
906 else 952 else
907 broll *= -((1 - m_bankingMix) + vfact); 953 broll *= -(1 + (vfact - 1) * m_bankingMix);
908 } 954 }
909 broll = (broll - curLocalAngVel.Z) / m_bankingTimescale;
910 // torque.Z += broll;
911
912 // make z rot be in world Z not local as seems to be in sl 955 // make z rot be in world Z not local as seems to be in sl
913 tmpV.X = 0; 956
914 tmpV.Y = 0; 957 broll = broll / m_bankingTimescale;
915 tmpV.Z = broll; 958
959 ftmp = -Math.Abs(m_bankingEfficiency) / m_bankingTimescale;
960
961 tmpV.X = ftmp * curAngVel.X;
962 tmpV.Y = ftmp * curAngVel.Y;
963 tmpV.Z = broll + ftmp * curAngVel.Z;
916 tmpV *= irotq; 964 tmpV *= irotq;
917 965
918 torque.X += tmpV.X; 966 torque.X += tmpV.X;
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index 0ccdbc0..b105f77 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
@@ -114,6 +114,9 @@ namespace OpenSim.Region.Physics.OdePlugin
114// private bool m_collidesLand = true; 114// private bool m_collidesLand = true;
115 private bool m_collidesWater; 115 private bool m_collidesWater;
116 public bool m_returnCollisions; 116 public bool m_returnCollisions;
117 private bool m_softcolide;
118
119 private bool m_NoColide; // for now only for internal use for bad meshs
117 120
118 // Default we're a Geometry 121 // Default we're a Geometry
119 private CollisionCategories m_collisionCategories = (CollisionCategories.Geom); 122 private CollisionCategories m_collisionCategories = (CollisionCategories.Geom);
@@ -155,6 +158,8 @@ namespace OpenSim.Region.Physics.OdePlugin
155 public float m_collisionscore; 158 public float m_collisionscore;
156 int m_colliderfilter = 0; 159 int m_colliderfilter = 0;
157 160
161 public IntPtr collide_geom; // for objects: geom if single prim space it linkset
162
158 private float m_density = 10.000006836f; // Aluminum g/cm3; 163 private float m_density = 10.000006836f; // Aluminum g/cm3;
159 164
160 public bool _zeroFlag; 165 public bool _zeroFlag;
@@ -185,7 +190,8 @@ namespace OpenSim.Region.Physics.OdePlugin
185 public ODEDynamics m_vehicle; 190 public ODEDynamics m_vehicle;
186 191
187 internal int m_material = (int)Material.Wood; 192 internal int m_material = (int)Material.Wood;
188 protected ContactData primContactData = new ContactData { mu = 0f, bounce = 0.1f }; 193 private float mu;
194 private float bounce;
189 195
190 /// <summary> 196 /// <summary>
191 /// Is this prim subject to physics? Even if not, it's still solid for collision purposes. 197 /// Is this prim subject to physics? Even if not, it's still solid for collision purposes.
@@ -216,13 +222,26 @@ namespace OpenSim.Region.Physics.OdePlugin
216 } 222 }
217 } 223 }
218 224
219 public override ContactData ContactData 225 public override void getContactData(ref ContactData cdata)
220 { 226 {
221 get 227 cdata.mu = mu;
228 cdata.bounce = bounce;
229
230 // cdata.softcolide = m_softcolide;
231 cdata.softcolide = false;
232
233 if (m_isphysical)
222 { 234 {
223 return primContactData; 235 ODEDynamics veh;
236 if (_parent != null)
237 veh = ((OdePrim)_parent).m_vehicle;
238 else
239 veh = m_vehicle;
240
241 if (veh != null && veh.Type != Vehicle.TYPE_NONE)
242 cdata.mu *= veh.FrictionFactor;
224 } 243 }
225 } 244 }
226 245
227 public override int PhysicsActorType 246 public override int PhysicsActorType
228 { 247 {
@@ -290,7 +309,10 @@ namespace OpenSim.Region.Physics.OdePlugin
290 } 309 }
291 310
292 if (m_colliderfilter == 0) 311 if (m_colliderfilter == 0)
312 {
313 m_softcolide = false;
293 m_iscolliding = false; 314 m_iscolliding = false;
315 }
294 else 316 else
295 m_iscolliding = true; 317 m_iscolliding = true;
296 } 318 }
@@ -453,8 +475,6 @@ namespace OpenSim.Region.Physics.OdePlugin
453 { 475 {
454 get 476 get
455 { 477 {
456 // Averate previous velocity with the new one so
457 // client object interpolation works a 'little' better
458 if (_zeroFlag) 478 if (_zeroFlag)
459 return Vector3.Zero; 479 return Vector3.Zero;
460 return _velocity; 480 return _velocity;
@@ -733,8 +753,8 @@ namespace OpenSim.Region.Physics.OdePlugin
733 public override void SetMaterial(int pMaterial) 753 public override void SetMaterial(int pMaterial)
734 { 754 {
735 m_material = pMaterial; 755 m_material = pMaterial;
736 primContactData.mu = _parent_scene.m_materialContactsData[pMaterial].mu; 756 mu = _parent_scene.m_materialContactsData[pMaterial].mu;
737 primContactData.bounce = _parent_scene.m_materialContactsData[pMaterial].bounce; 757 bounce = _parent_scene.m_materialContactsData[pMaterial].bounce;
738 } 758 }
739 759
740 public void setPrimForRemoval() 760 public void setPrimForRemoval()
@@ -833,6 +853,7 @@ namespace OpenSim.Region.Physics.OdePlugin
833 body_autodisable_frames = parent_scene.bodyFramesAutoDisable; 853 body_autodisable_frames = parent_scene.bodyFramesAutoDisable;
834 854
835 prim_geom = IntPtr.Zero; 855 prim_geom = IntPtr.Zero;
856 collide_geom = IntPtr.Zero;
836 Body = IntPtr.Zero; 857 Body = IntPtr.Zero;
837 858
838 if (!size.IsFinite()) 859 if (!size.IsFinite())
@@ -847,7 +868,6 @@ namespace OpenSim.Region.Physics.OdePlugin
847 868
848 _size = size; 869 _size = size;
849 870
850
851 if (!QuaternionIsFinite(rotation)) 871 if (!QuaternionIsFinite(rotation))
852 { 872 {
853 rotation = Quaternion.Identity; 873 rotation = Quaternion.Identity;
@@ -878,6 +898,8 @@ namespace OpenSim.Region.Physics.OdePlugin
878 898
879 m_iscolliding = false; 899 m_iscolliding = false;
880 m_colliderfilter = 0; 900 m_colliderfilter = 0;
901 m_softcolide = true;
902 m_NoColide = false;
881 903
882 hasOOBoffsetFromMesh = false; 904 hasOOBoffsetFromMesh = false;
883 _triMeshData = IntPtr.Zero; 905 _triMeshData = IntPtr.Zero;
@@ -886,8 +908,8 @@ namespace OpenSim.Region.Physics.OdePlugin
886 m_isSelected = false; 908 m_isSelected = false;
887 m_delaySelect = false; 909 m_delaySelect = false;
888 910
889 primContactData.mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu; 911 mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu;
890 primContactData.bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce; 912 bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce;
891 913
892 CalcPrimBodyData(); 914 CalcPrimBodyData();
893 915
@@ -1025,34 +1047,42 @@ namespace OpenSim.Region.Physics.OdePlugin
1025 1047
1026 if (vertexCount == 0 || indexCount == 0) 1048 if (vertexCount == 0 || indexCount == 0)
1027 { 1049 {
1028 m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. It can be a sculp with alpha channel in map. Replacing it by a small box.", Name, _position.X, _position.Y, _position.Z); 1050 m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. mesh UUID {4}",
1029 _size.X = 0.01f; 1051 Name, _position.X, _position.Y, _position.Z, _pbs.SculptTexture.ToString());
1030 _size.Y = 0.01f; 1052 mesh.releaseSourceMeshData();
1031 _size.Z = 0.01f;
1032 return false; 1053 return false;
1033 } 1054 }
1034 1055
1035 primOOBoffset = mesh.GetCentroid(); 1056 primOOBoffset = mesh.GetCentroid();
1036 hasOOBoffsetFromMesh = true; 1057 hasOOBoffsetFromMesh = true;
1037 1058
1038 _triMeshData = d.GeomTriMeshDataCreate();
1039
1040 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
1041 d.GeomTriMeshDataPreprocess(_triMeshData);
1042
1043 mesh.releaseSourceMeshData(); 1059 mesh.releaseSourceMeshData();
1044 1060
1045 _parent_scene.waitForSpaceUnlock(m_targetSpace); 1061 IntPtr geo = IntPtr.Zero;
1062
1046 try 1063 try
1047 { 1064 {
1048 SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null)); 1065 _triMeshData = d.GeomTriMeshDataCreate();
1066
1067 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
1068 d.GeomTriMeshDataPreprocess(_triMeshData);
1069
1070 _parent_scene.waitForSpaceUnlock(m_targetSpace);
1071 geo = d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null);
1049 } 1072 }
1050 1073
1051 catch (Exception e) 1074 catch (Exception e)
1052 { 1075 {
1053 m_log.ErrorFormat("[PHYSICS]: SetGeom Mesh failed for {0} exception: {1}", Name, e); 1076 m_log.ErrorFormat("[PHYSICS]: SetGeom Mesh failed for {0} exception: {1}", Name, e);
1077 if (_triMeshData != IntPtr.Zero)
1078 {
1079 d.GeomTriMeshDataDestroy(_triMeshData);
1080 _triMeshData = IntPtr.Zero;
1081 }
1054 return false; 1082 return false;
1055 } 1083 }
1084
1085 SetGeom(geo);
1056 return true; 1086 return true;
1057 } 1087 }
1058 1088
@@ -1062,25 +1092,30 @@ namespace OpenSim.Region.Physics.OdePlugin
1062 //Console.WriteLine("SetGeom to " + prim_geom + " for " + Name); 1092 //Console.WriteLine("SetGeom to " + prim_geom + " for " + Name);
1063 if (prim_geom != IntPtr.Zero) 1093 if (prim_geom != IntPtr.Zero)
1064 { 1094 {
1065 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 1095 if (m_NoColide)
1066 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1096 {
1097 d.GeomSetCategoryBits(prim_geom, 0);
1098 if (m_isphysical)
1099 {
1100 d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
1101 }
1102 else
1103 {
1104 d.GeomSetCollideBits(prim_geom, 0);
1105 d.GeomDisable(prim_geom);
1106 }
1107 }
1108 else
1109 {
1110 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1111 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1112 }
1067 1113
1068 CalcPrimBodyData(); 1114 CalcPrimBodyData();
1069 1115
1070 _parent_scene.geom_name_map[prim_geom] = Name; 1116 _parent_scene.geom_name_map[prim_geom] = Name;
1071 _parent_scene.actor_name_map[prim_geom] = this; 1117 _parent_scene.actor_name_map[prim_geom] = this;
1072 1118
1073 /*
1074 if (childPrim)
1075 {
1076 if (_parent != null && _parent is OdePrim)
1077 {
1078 OdePrim parent = (OdePrim)_parent;
1079 //Console.WriteLine("SetGeom calls ChildSetGeom");
1080 parent.ChildSetGeom(this);
1081 }
1082 }
1083 */
1084 } 1119 }
1085 else 1120 else
1086 m_log.Warn("Setting bad Geom"); 1121 m_log.Warn("Setting bad Geom");
@@ -1102,10 +1137,13 @@ namespace OpenSim.Region.Physics.OdePlugin
1102 1137
1103 bool haveMesh = false; 1138 bool haveMesh = false;
1104 hasOOBoffsetFromMesh = false; 1139 hasOOBoffsetFromMesh = false;
1140 m_NoColide = false;
1105 1141
1106 if (_parent_scene.needsMeshing(_pbs)) 1142 if (_parent_scene.needsMeshing(_pbs))
1107 { 1143 {
1108 haveMesh = setMesh(_parent_scene); // this will give a mesh to non trivial known prims 1144 haveMesh = setMesh(_parent_scene); // this will give a mesh to non trivial known prims
1145 if (!haveMesh)
1146 m_NoColide = true;
1109 } 1147 }
1110 1148
1111 if (!haveMesh) 1149 if (!haveMesh)
@@ -1197,12 +1235,46 @@ namespace OpenSim.Region.Physics.OdePlugin
1197 { 1235 {
1198 if (!childPrim && !m_isSelected) 1236 if (!childPrim && !m_isSelected)
1199 { 1237 {
1200 if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero) 1238 if (m_isphysical && Body != IntPtr.Zero)
1201 { 1239 {
1202 d.GeomEnable(prim_geom); 1240 m_collisionCategories |= CollisionCategories.Body;
1241 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1242
1203 foreach (OdePrim prm in childrenPrim) 1243 foreach (OdePrim prm in childrenPrim)
1204 d.GeomEnable(prm.prim_geom); 1244 {
1245 prm.m_collisionCategories = m_collisionCategories;
1246 prm.m_collisionFlags = m_collisionFlags;
1205 1247
1248 if (prm.prim_geom != IntPtr.Zero)
1249 {
1250 if (prm.m_NoColide)
1251 {
1252 d.GeomSetCategoryBits(prm.prim_geom, 0);
1253 d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
1254 }
1255 else
1256 {
1257 d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
1258 d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
1259 }
1260 d.GeomEnable(prm.prim_geom);
1261 }
1262 }
1263
1264 if (prim_geom != IntPtr.Zero)
1265 {
1266 if (m_NoColide)
1267 {
1268 d.GeomSetCategoryBits(prim_geom, 0);
1269 d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
1270 }
1271 else
1272 {
1273 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1274 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1275 }
1276 d.GeomEnable(prim_geom);
1277 }
1206 d.BodyEnable(Body); 1278 d.BodyEnable(Body);
1207 } 1279 }
1208 } 1280 }
@@ -1215,11 +1287,47 @@ namespace OpenSim.Region.Physics.OdePlugin
1215 m_disabled = true; 1287 m_disabled = true;
1216 if (!childPrim) 1288 if (!childPrim)
1217 { 1289 {
1218 if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero) 1290 if (m_isphysical && Body != IntPtr.Zero)
1219 { 1291 {
1220 d.GeomDisable(prim_geom); 1292 m_collisionCategories &= ~CollisionCategories.Body;
1293 m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
1294
1221 foreach (OdePrim prm in childrenPrim) 1295 foreach (OdePrim prm in childrenPrim)
1222 d.GeomDisable(prm.prim_geom); 1296 {
1297 prm.m_collisionCategories = m_collisionCategories;
1298 prm.m_collisionFlags = m_collisionFlags;
1299
1300 if (prm.prim_geom != IntPtr.Zero)
1301 {
1302 if (prm.m_NoColide)
1303 {
1304 d.GeomSetCategoryBits(prm.prim_geom, 0);
1305 d.GeomSetCollideBits(prm.prim_geom, 0);
1306 }
1307 else
1308 {
1309 d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
1310 d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
1311 }
1312 d.GeomDisable(prm.prim_geom);
1313 }
1314 }
1315
1316 if (prim_geom != IntPtr.Zero)
1317 {
1318 if (m_NoColide)
1319 {
1320 d.GeomSetCategoryBits(prim_geom, 0);
1321 d.GeomSetCollideBits(prim_geom, 0);
1322 }
1323 else
1324 {
1325 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1326 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1327 }
1328 d.GeomDisable(prim_geom);
1329 }
1330
1223 d.BodyDisable(Body); 1331 d.BodyDisable(Body);
1224 } 1332 }
1225 } 1333 }
@@ -1298,8 +1406,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1298 continue; 1406 continue;
1299 } 1407 }
1300 1408
1301
1302
1303 DMassCopy(ref prm.primdMass, ref tmpdmass); 1409 DMassCopy(ref prm.primdMass, ref tmpdmass);
1304 1410
1305 // apply prim current rotation to inertia 1411 // apply prim current rotation to inertia
@@ -1361,14 +1467,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1361 // d.BodySetAngularDampingThreshold(Body, 0.001f); 1467 // d.BodySetAngularDampingThreshold(Body, 0.001f);
1362 d.BodySetDamping(Body, .002f, .002f); 1468 d.BodySetDamping(Body, .002f, .002f);
1363 1469
1364 m_collisionCategories |= CollisionCategories.Body;
1365 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1366 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1367 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1368 m_collisionscore = 0;
1369 1470
1370 if (m_targetSpace != _parent_scene.ActiveSpace)
1371 {
1372 if (m_targetSpace != IntPtr.Zero) 1471 if (m_targetSpace != IntPtr.Zero)
1373 { 1472 {
1374 _parent_scene.waitForSpaceUnlock(m_targetSpace); 1473 _parent_scene.waitForSpaceUnlock(m_targetSpace);
@@ -1376,9 +1475,22 @@ namespace OpenSim.Region.Physics.OdePlugin
1376 d.SpaceRemove(m_targetSpace, prim_geom); 1475 d.SpaceRemove(m_targetSpace, prim_geom);
1377 } 1476 }
1378 1477
1478
1479 if (childrenPrim.Count == 0)
1480 {
1481 collide_geom = prim_geom;
1379 m_targetSpace = _parent_scene.ActiveSpace; 1482 m_targetSpace = _parent_scene.ActiveSpace;
1380 d.SpaceAdd(m_targetSpace, prim_geom); 1483 d.SpaceAdd(m_targetSpace, prim_geom);
1381 } 1484 }
1485 else
1486 {
1487 m_targetSpace = d.HashSpaceCreate(_parent_scene.ActiveSpace);
1488 d.HashSpaceSetLevels(m_targetSpace, -2, 8);
1489 d.SpaceSetSublevel(m_targetSpace, 3);
1490 d.SpaceSetCleanup(m_targetSpace, false);
1491 d.SpaceAdd(m_targetSpace, prim_geom);
1492 collide_geom = m_targetSpace;
1493 }
1382 1494
1383 lock (childrenPrim) 1495 lock (childrenPrim)
1384 { 1496 {
@@ -1390,28 +1502,45 @@ namespace OpenSim.Region.Physics.OdePlugin
1390 Vector3 ppos = prm._position; 1502 Vector3 ppos = prm._position;
1391 d.GeomSetOffsetWorldPosition(prm.prim_geom, ppos.X, ppos.Y, ppos.Z); // set relative position 1503 d.GeomSetOffsetWorldPosition(prm.prim_geom, ppos.X, ppos.Y, ppos.Z); // set relative position
1392 1504
1393 prm.m_collisionCategories |= CollisionCategories.Body; 1505 if (prm.m_targetSpace != m_targetSpace)
1394 prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1395 d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories);
1396 d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags);
1397 prm.m_collisionscore = 0;
1398
1399 if (prm.m_targetSpace != _parent_scene.ActiveSpace)
1400 { 1506 {
1401 if (prm.m_targetSpace != IntPtr.Zero) 1507 if (prm.m_targetSpace != IntPtr.Zero)
1402 { 1508 {
1403 _parent_scene.waitForSpaceUnlock(m_targetSpace); 1509 _parent_scene.waitForSpaceUnlock(prm.m_targetSpace);
1404 if (d.SpaceQuery(prm.m_targetSpace, prm.prim_geom)) 1510 if (d.SpaceQuery(prm.m_targetSpace, prm.prim_geom))
1405 d.SpaceRemove(prm.m_targetSpace, prm.prim_geom); 1511 d.SpaceRemove(prm.m_targetSpace, prm.prim_geom);
1406 } 1512 }
1407 prm.m_targetSpace = _parent_scene.ActiveSpace; 1513 prm.m_targetSpace = m_targetSpace;
1408 d.SpaceAdd(m_targetSpace, prm.prim_geom); 1514 d.SpaceAdd(m_targetSpace, prm.prim_geom);
1409 } 1515 }
1410 1516
1411 if (m_isSelected || m_disabled) 1517 if (m_isSelected || m_disabled)
1518 {
1519 prm.m_collisionCategories &= ~CollisionCategories.Body;
1520 prm.m_collisionFlags &= ~(CollisionCategories.Land | CollisionCategories.Wind);
1412 d.GeomDisable(prm.prim_geom); 1521 d.GeomDisable(prm.prim_geom);
1522 }
1523 else
1524 {
1525 prm.m_collisionCategories |= CollisionCategories.Body;
1526 prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1527 }
1528
1529 if (prm.m_NoColide)
1530 {
1531 d.GeomSetCategoryBits(prm.prim_geom, 0);
1532 d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
1533 }
1534 else
1535 {
1536 d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
1537 d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
1538 }
1539 prm.m_collisionscore = 0;
1540
1541 if(!m_disabled)
1542 prm.m_disabled = false;
1413 1543
1414 prm.m_disabled = false;
1415 _parent_scene.addActivePrim(prm); 1544 _parent_scene.addActivePrim(prm);
1416 } 1545 }
1417 } 1546 }
@@ -1424,11 +1553,37 @@ namespace OpenSim.Region.Physics.OdePlugin
1424 1553
1425 if (m_isSelected || m_disabled) 1554 if (m_isSelected || m_disabled)
1426 { 1555 {
1556 m_collisionCategories &= ~CollisionCategories.Body;
1557 m_collisionFlags &= ~(CollisionCategories.Land | CollisionCategories.Wind);
1558
1427 d.GeomDisable(prim_geom); 1559 d.GeomDisable(prim_geom);
1428 d.BodyDisable(Body); 1560 d.BodyDisable(Body);
1429 } 1561 }
1562 else
1563 {
1564 m_collisionCategories |= CollisionCategories.Body;
1565 m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
1566
1567 d.BodySetAngularVel(Body, m_rotationalVelocity.X, m_rotationalVelocity.Y, m_rotationalVelocity.Z);
1568 d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z);
1569 }
1430 1570
1571 if (m_NoColide)
1572 {
1573 d.GeomSetCategoryBits(prim_geom, 0);
1574 d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
1575 }
1576 else
1577 {
1578 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1579 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1580 }
1581
1582 m_collisionscore = 0;
1583
1584 m_softcolide = true;
1431 _parent_scene.addActivePrim(this); 1585 _parent_scene.addActivePrim(this);
1586 _parent_scene.addActiveGroups(this);
1432 } 1587 }
1433 1588
1434 private void DestroyBody() 1589 private void DestroyBody()
@@ -1440,8 +1595,16 @@ namespace OpenSim.Region.Physics.OdePlugin
1440 m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); 1595 m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
1441 if (prim_geom != IntPtr.Zero) 1596 if (prim_geom != IntPtr.Zero)
1442 { 1597 {
1443 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); 1598 if (m_NoColide)
1444 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); 1599 {
1600 d.GeomSetCategoryBits(prim_geom, 0);
1601 d.GeomSetCollideBits(prim_geom, 0);
1602 }
1603 else
1604 {
1605 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
1606 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
1607 }
1445 UpdateDataFromGeom(); 1608 UpdateDataFromGeom();
1446 d.GeomSetBody(prim_geom, IntPtr.Zero); 1609 d.GeomSetBody(prim_geom, IntPtr.Zero);
1447 SetInStaticSpace(this); 1610 SetInStaticSpace(this);
@@ -1454,12 +1617,20 @@ namespace OpenSim.Region.Physics.OdePlugin
1454 foreach (OdePrim prm in childrenPrim) 1617 foreach (OdePrim prm in childrenPrim)
1455 { 1618 {
1456 _parent_scene.remActivePrim(prm); 1619 _parent_scene.remActivePrim(prm);
1457 prm.m_collisionCategories &= ~CollisionCategories.Body; 1620 prm.m_collisionCategories = m_collisionCategories;
1458 prm.m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); 1621 prm.m_collisionFlags = m_collisionFlags;
1459 if (prm.prim_geom != IntPtr.Zero) 1622 if (prm.prim_geom != IntPtr.Zero)
1460 { 1623 {
1461 d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); 1624 if (prm.m_NoColide)
1462 d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); 1625 {
1626 d.GeomSetCategoryBits(prm.prim_geom, 0);
1627 d.GeomSetCollideBits(prm.prim_geom, 0);
1628 }
1629 else
1630 {
1631 d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
1632 d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
1633 }
1463 prm.UpdateDataFromGeom(); 1634 prm.UpdateDataFromGeom();
1464 SetInStaticSpace(prm); 1635 SetInStaticSpace(prm);
1465 } 1636 }
@@ -1473,6 +1644,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1473 d.JointDestroy(Amotor); 1644 d.JointDestroy(Amotor);
1474 Amotor = IntPtr.Zero; 1645 Amotor = IntPtr.Zero;
1475 } 1646 }
1647 _parent_scene.remActiveGroup(this);
1476 d.BodyDestroy(Body); 1648 d.BodyDestroy(Body);
1477 } 1649 }
1478 Body = IntPtr.Zero; 1650 Body = IntPtr.Zero;
@@ -2008,23 +2180,14 @@ namespace OpenSim.Region.Physics.OdePlugin
2008 myrot.Z = _orientation.Z; 2180 myrot.Z = _orientation.Z;
2009 myrot.W = _orientation.W; 2181 myrot.W = _orientation.W;
2010 d.GeomSetQuaternion(prim_geom, ref myrot); 2182 d.GeomSetQuaternion(prim_geom, ref myrot);
2011 // _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this; 2183
2012 if (!m_isphysical) 2184 if (!m_isphysical)
2013 SetInStaticSpace(this); 2185 SetInStaticSpace(this);
2014 } 2186 }
2015 2187
2016 if (m_isphysical && Body == IntPtr.Zero) 2188 if (m_isphysical && Body == IntPtr.Zero)
2017 { 2189 {
2018 /*
2019 if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
2020 {
2021 changeShape(_pbs);
2022 }
2023 else
2024 {
2025 */
2026 MakeBody(); 2190 MakeBody();
2027 // }
2028 } 2191 }
2029 } 2192 }
2030 2193
@@ -2133,17 +2296,52 @@ namespace OpenSim.Region.Physics.OdePlugin
2133 if (!childPrim && Body != IntPtr.Zero) 2296 if (!childPrim && Body != IntPtr.Zero)
2134 d.BodyDisable(Body); 2297 d.BodyDisable(Body);
2135 2298
2136 if (m_delaySelect) 2299 if (m_delaySelect || m_isphysical)
2137 { 2300 {
2301 m_collisionCategories = CollisionCategories.Selected;
2302 m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space);
2303
2138 if (!childPrim) 2304 if (!childPrim)
2139 { 2305 {
2140 foreach (OdePrim prm in childrenPrim) 2306 foreach (OdePrim prm in childrenPrim)
2141 { 2307 {
2142 d.GeomDisable(prm.prim_geom); 2308 prm.m_collisionCategories = m_collisionCategories;
2309 prm.m_collisionFlags = m_collisionFlags;
2310
2311 if (prm.prim_geom != null)
2312 {
2313
2314 if (prm.m_NoColide)
2315 {
2316 d.GeomSetCategoryBits(prm.prim_geom, 0);
2317 d.GeomSetCollideBits(prm.prim_geom, 0);
2318 }
2319 else
2320 {
2321 d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
2322 d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
2323 }
2324 d.GeomDisable(prm.prim_geom);
2325 }
2143 prm.m_delaySelect = false; 2326 prm.m_delaySelect = false;
2144 } 2327 }
2145 } 2328 }
2146 d.GeomDisable(prim_geom); 2329
2330 if (prim_geom != null)
2331 {
2332 if (m_NoColide)
2333 {
2334 d.GeomSetCategoryBits(prim_geom, 0);
2335 d.GeomSetCollideBits(prim_geom, 0);
2336 }
2337 else
2338 {
2339 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
2340 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
2341 }
2342 d.GeomDisable(prim_geom);
2343 }
2344
2147 m_delaySelect = false; 2345 m_delaySelect = false;
2148 } 2346 }
2149 else 2347 else
@@ -2156,19 +2354,64 @@ namespace OpenSim.Region.Physics.OdePlugin
2156 if (!childPrim && Body != IntPtr.Zero && !m_disabled) 2354 if (!childPrim && Body != IntPtr.Zero && !m_disabled)
2157 d.BodyEnable(Body); 2355 d.BodyEnable(Body);
2158 2356
2357 m_collisionCategories = CollisionCategories.Geom;
2358 if (m_isphysical)
2359 m_collisionCategories |= CollisionCategories.Body;
2360
2361 m_collisionFlags = m_default_collisionFlags | CollisionCategories.Land;
2362
2363 if (m_collidesWater)
2364 m_collisionFlags |= CollisionCategories.Water;
2365
2159 if (!childPrim) 2366 if (!childPrim)
2160 { 2367 {
2161 foreach (OdePrim prm in childrenPrim) 2368 foreach (OdePrim prm in childrenPrim)
2162 { 2369 {
2163 if(!prm.m_disabled) 2370 prm.m_collisionCategories = m_collisionCategories;
2371 prm.m_collisionFlags = m_collisionFlags;
2372
2373 if (!prm.m_disabled && prm.prim_geom != IntPtr.Zero)
2374 {
2375 if (prm.m_NoColide)
2376 {
2377 d.GeomSetCategoryBits(prm.prim_geom, 0);
2378 if (m_isphysical)
2379 d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
2380 else
2381 d.GeomSetCollideBits(prm.prim_geom, 0);
2382 }
2383 else
2384 {
2385 d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
2386 d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
2387 }
2164 d.GeomEnable(prm.prim_geom); 2388 d.GeomEnable(prm.prim_geom);
2389 }
2165 prm.m_delaySelect = false; 2390 prm.m_delaySelect = false;
2391 prm.m_softcolide = true;
2166 } 2392 }
2167 } 2393 }
2168 if(!m_disabled) 2394
2395 if (!m_disabled && prim_geom != IntPtr.Zero)
2396 {
2397 if (m_NoColide)
2398 {
2399 d.GeomSetCategoryBits(prim_geom, 0);
2400 if (m_isphysical)
2401 d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
2402 else
2403 d.GeomSetCollideBits(prim_geom, 0);
2404 }
2405 else
2406 {
2407 d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
2408 d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
2409 }
2169 d.GeomEnable(prim_geom); 2410 d.GeomEnable(prim_geom);
2411 }
2170 2412
2171 m_delaySelect = false; 2413 m_delaySelect = false;
2414 m_softcolide = true;
2172 } 2415 }
2173 2416
2174 resetCollisionAccounting(); 2417 resetCollisionAccounting();
@@ -2214,6 +2457,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2214 if (givefakepos < 0) 2457 if (givefakepos < 0)
2215 givefakepos = 0; 2458 givefakepos = 0;
2216 // changeSelectedStatus(); 2459 // changeSelectedStatus();
2460 m_softcolide = true;
2217 resetCollisionAccounting(); 2461 resetCollisionAccounting();
2218 } 2462 }
2219 2463
@@ -2266,6 +2510,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2266 givefakeori--; 2510 givefakeori--;
2267 if (givefakeori < 0) 2511 if (givefakeori < 0)
2268 givefakeori = 0; 2512 givefakeori = 0;
2513 m_softcolide = true;
2269 resetCollisionAccounting(); 2514 resetCollisionAccounting();
2270 } 2515 }
2271 2516
@@ -2336,6 +2581,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2336 if (givefakeori < 0) 2581 if (givefakeori < 0)
2337 givefakeori = 0; 2582 givefakeori = 0;
2338 2583
2584 m_softcolide = true;
2339 resetCollisionAccounting(); 2585 resetCollisionAccounting();
2340 } 2586 }
2341 2587
@@ -2390,8 +2636,8 @@ namespace OpenSim.Region.Physics.OdePlugin
2390 else 2636 else
2391 */ 2637 */
2392 DestroyBody(); 2638 DestroyBody();
2393 Stop();
2394 } 2639 }
2640 Stop();
2395 } 2641 }
2396 } 2642 }
2397 2643
@@ -2452,6 +2698,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2452 else 2698 else
2453 MakeBody(); 2699 MakeBody();
2454 2700
2701 m_softcolide = true;
2455 resetCollisionAccounting(); 2702 resetCollisionAccounting();
2456 } 2703 }
2457 2704
@@ -2576,7 +2823,8 @@ namespace OpenSim.Region.Physics.OdePlugin
2576 if ((bool)newbuilding) 2823 if ((bool)newbuilding)
2577 { 2824 {
2578 m_building = true; 2825 m_building = true;
2579 DestroyBody(); 2826 if (!childPrim)
2827 DestroyBody();
2580 } 2828 }
2581 else 2829 else
2582 { 2830 {
@@ -2648,12 +2896,95 @@ namespace OpenSim.Region.Physics.OdePlugin
2648 public void Move() 2896 public void Move()
2649 { 2897 {
2650 if (!childPrim && m_isphysical && Body != IntPtr.Zero && 2898 if (!childPrim && m_isphysical && Body != IntPtr.Zero &&
2651 !m_disabled && !m_isSelected && d.BodyIsEnabled(Body) && !m_building) // KF: Only move root prims. 2899 !m_disabled && !m_isSelected && d.BodyIsEnabled(Body) && !m_building && !m_outbounds)
2900 // !m_disabled && !m_isSelected && !m_building && !m_outbounds)
2652 { 2901 {
2653 // if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); // KF add 161009 2902// if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); // KF add 161009
2654 2903
2655 float timestep = _parent_scene.ODE_STEPSIZE; 2904 float timestep = _parent_scene.ODE_STEPSIZE;
2656 2905
2906 // check outside region
2907 d.Vector3 lpos;
2908 d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator
2909
2910 if (lpos.Z < -100 || lpos.Z > 100000f)
2911 {
2912 m_outbounds = true;
2913
2914 lpos.Z = Util.Clip(lpos.Z, -100f, 100000f);
2915 _acceleration.X = 0;
2916 _acceleration.Y = 0;
2917 _acceleration.Z = 0;
2918
2919 _velocity.X = 0;
2920 _velocity.Y = 0;
2921 _velocity.Z = 0;
2922 m_rotationalVelocity.X = 0;
2923 m_rotationalVelocity.Y = 0;
2924 m_rotationalVelocity.Z = 0;
2925
2926 d.BodySetLinearVel(Body, 0, 0, 0); // stop it
2927 d.BodySetAngularVel(Body, 0, 0, 0); // stop it
2928 d.BodySetPosition(Body, lpos.X, lpos.Y, lpos.Z); // put it somewhere
2929 m_lastposition = _position;
2930 m_lastorientation = _orientation;
2931
2932 base.RequestPhysicsterseUpdate();
2933
2934 m_throttleUpdates = false;
2935 throttleCounter = 0;
2936 _zeroFlag = true;
2937
2938 disableBodySoft(); // disable it and colisions
2939 base.RaiseOutOfBounds(_position);
2940 return;
2941 }
2942
2943 if (lpos.X < 0f)
2944 {
2945 _position.X = Util.Clip(lpos.X, -2f, -0.1f);
2946 m_outbounds = true;
2947 }
2948 else if(lpos.X > _parent_scene.WorldExtents.X)
2949 {
2950 _position.X = Util.Clip(lpos.X, _parent_scene.WorldExtents.X + 0.1f, _parent_scene.WorldExtents.X + 2f);
2951 m_outbounds = true;
2952 }
2953 if (lpos.Y < 0f)
2954 {
2955 _position.Y = Util.Clip(lpos.Y, -2f, -0.1f);
2956 m_outbounds = true;
2957 }
2958 else if(lpos.Y > _parent_scene.WorldExtents.Y)
2959 {
2960 _position.Y = Util.Clip(lpos.Y, _parent_scene.WorldExtents.Y + 0.1f, _parent_scene.WorldExtents.Y + 2f);
2961 m_outbounds = true;
2962 }
2963
2964 if(m_outbounds)
2965 {
2966 m_lastposition = _position;
2967 m_lastorientation = _orientation;
2968
2969 d.Vector3 dtmp = d.BodyGetAngularVel(Body);
2970 m_rotationalVelocity.X = dtmp.X;
2971 m_rotationalVelocity.Y = dtmp.Y;
2972 m_rotationalVelocity.Z = dtmp.Z;
2973
2974 dtmp = d.BodyGetLinearVel(Body);
2975 _velocity.X = dtmp.X;
2976 _velocity.Y = dtmp.Y;
2977 _velocity.Z = dtmp.Z;
2978
2979 d.BodySetLinearVel(Body, 0, 0, 0); // stop it
2980 d.BodySetAngularVel(Body, 0, 0, 0);
2981 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
2982 disableBodySoft(); // stop collisions
2983 base.RequestPhysicsterseUpdate();
2984 return;
2985 }
2986
2987
2657 float fx = 0; 2988 float fx = 0;
2658 float fy = 0; 2989 float fy = 0;
2659 float fz = 0; 2990 float fz = 0;
@@ -2862,7 +3193,7 @@ namespace OpenSim.Region.Physics.OdePlugin
2862 public void UpdatePositionAndVelocity(float simulatedtime) 3193 public void UpdatePositionAndVelocity(float simulatedtime)
2863 { 3194 {
2864 // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! 3195 // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
2865 if (_parent == null && !m_disabled && !m_building) 3196 if (_parent == null && !m_disabled && !m_building && !m_outbounds)
2866 { 3197 {
2867 if (Body != IntPtr.Zero) 3198 if (Body != IntPtr.Zero)
2868 { 3199 {
@@ -2872,64 +3203,6 @@ namespace OpenSim.Region.Physics.OdePlugin
2872 d.Vector3 lpos; 3203 d.Vector3 lpos;
2873 d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator 3204 d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator
2874 3205
2875 // we need to use root position since that's all the rest of scene uses
2876 if (lpos.X < 0f || lpos.X > _parent_scene.WorldExtents.X
2877 || lpos.Y < 0f || lpos.Y > _parent_scene.WorldExtents.Y
2878 )
2879 {
2880 // we are outside current region
2881 // we can't let it keeping moving and having colisions
2882 // since it can be stucked between something like terrain and edge
2883 // so lets stop and disable it until something else kicks it
2884
2885 _position.X = Util.Clip(lpos.X, -0.2f, _parent_scene.WorldExtents.X + 0.2f);
2886 _position.Y = Util.Clip(lpos.Y, -0.2f, _parent_scene.WorldExtents.Y + 0.2f);
2887 _position.Z = Util.Clip(lpos.Z, -100f, 50000f);
2888
2889 m_lastposition = _position;
2890// m_lastorientation = _orientation;
2891
2892 d.BodySetLinearVel(Body, 0, 0, 0); // stop it
2893// d.BodySetAngularVel(Body, 0, 0, 0);
2894 d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
2895 disableBodySoft(); // stop collisions
2896 m_outbounds = true;
2897 base.RequestPhysicsterseUpdate();
2898 return;
2899 }
2900
2901 if (lpos.Z < -100 || lpos.Z > 100000f)
2902 {
2903 lpos.Z = Util.Clip(lpos.Z, -100f, 50000f);
2904
2905 _acceleration.X = 0;
2906 _acceleration.Y = 0;
2907 _acceleration.Z = 0;
2908
2909 _velocity.X = 0;
2910 _velocity.Y = 0;
2911 _velocity.Z = 0;
2912 m_rotationalVelocity.X = 0;
2913 m_rotationalVelocity.Y = 0;
2914 m_rotationalVelocity.Z = 0;
2915
2916 d.BodySetLinearVel(Body, 0, 0, 0); // stop it
2917 d.BodySetAngularVel(Body, 0, 0, 0); // stop it
2918 d.BodySetPosition(Body, lpos.X, lpos.Y, lpos.Z); // put it somewhere
2919 m_lastposition = _position;
2920 m_lastorientation = _orientation;
2921
2922 base.RequestPhysicsterseUpdate();
2923
2924 m_throttleUpdates = false;
2925 throttleCounter = 0;
2926 _zeroFlag = true;
2927
2928 disableBodySoft(); // disable it and colisions
2929 base.RaiseOutOfBounds(_position);
2930
2931 return;
2932 }
2933 3206
2934 d.Quaternion ori; 3207 d.Quaternion ori;
2935 d.GeomCopyQuaternion(prim_geom, out ori); 3208 d.GeomCopyQuaternion(prim_geom, out ori);
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index 6e4c373..14516f9 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -155,7 +155,7 @@ namespace OpenSim.Region.Physics.OdePlugin
155 private readonly ILog m_log; 155 private readonly ILog m_log;
156 // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>(); 156 // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>();
157 157
158 private int threadid = 0; 158// private int threadid = 0;
159 private Random fluidRandomizer = new Random(Environment.TickCount); 159 private Random fluidRandomizer = new Random(Environment.TickCount);
160 160
161 const d.ContactFlags comumContactFlags = d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM |d.ContactFlags.Approx1 | d.ContactFlags.Bounce; 161 const d.ContactFlags comumContactFlags = d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM |d.ContactFlags.Approx1 | d.ContactFlags.Bounce;
@@ -163,12 +163,10 @@ namespace OpenSim.Region.Physics.OdePlugin
163 const float comumSoftContactERP = 0.1f; 163 const float comumSoftContactERP = 0.1f;
164 const float comumContactCFM = 0.0001f; 164 const float comumContactCFM = 0.0001f;
165 165
166 float frictionScale = 1.0f;
167
168 float frictionMovementMult = 0.3f; 166 float frictionMovementMult = 0.3f;
169 167
170 float TerrainBounce = 0.1f; 168 float TerrainBounce = 0.1f;
171 float TerrainFriction = 0.1f; 169 float TerrainFriction = 0.3f;
172 170
173 public float AvatarBounce = 0.3f; 171 public float AvatarBounce = 0.3f;
174 public float AvatarFriction = 0;// 0.9f * 0.5f; 172 public float AvatarFriction = 0;// 0.9f * 0.5f;
@@ -189,8 +187,8 @@ namespace OpenSim.Region.Physics.OdePlugin
189 187
190 internal IntPtr WaterGeom; 188 internal IntPtr WaterGeom;
191 189
192 public float avPIDD = 3200f; // make it visible 190 public float avPIDD = 2200f; // make it visible
193 public float avPIDP = 1400f; // make it visible 191 public float avPIDP = 900f; // make it visible
194 private float avCapRadius = 0.37f; 192 private float avCapRadius = 0.37f;
195 private float avDensity = 3f; 193 private float avDensity = 3f;
196 private float avMovementDivisorWalk = 1.3f; 194 private float avMovementDivisorWalk = 1.3f;
@@ -202,7 +200,7 @@ namespace OpenSim.Region.Physics.OdePlugin
202 public bool forceSimplePrimMeshing = false; 200 public bool forceSimplePrimMeshing = false;
203 201
204 public float meshSculptLOD = 32; 202 public float meshSculptLOD = 32;
205 public float MeshSculptphysicalLOD = 16; 203 public float MeshSculptphysicalLOD = 32;
206 204
207 public float geomDefaultDensity = 10.000006836f; 205 public float geomDefaultDensity = 10.000006836f;
208 206
@@ -212,18 +210,18 @@ namespace OpenSim.Region.Physics.OdePlugin
212 public float bodyPIDD = 35f; 210 public float bodyPIDD = 35f;
213 public float bodyPIDG = 25; 211 public float bodyPIDG = 25;
214 212
215 public int geomCrossingFailuresBeforeOutofbounds = 6; 213// public int geomCrossingFailuresBeforeOutofbounds = 6;
216 214
217 public int bodyFramesAutoDisable = 20; 215 public int bodyFramesAutoDisable = 20;
218 216
219 private float[] _watermap; 217 private float[] _watermap;
220 private bool m_filterCollisions = true;
221 218
222 private d.NearCallback nearCallback; 219 private d.NearCallback nearCallback;
223 220
224 private readonly HashSet<OdeCharacter> _characters = new HashSet<OdeCharacter>(); 221 private readonly HashSet<OdeCharacter> _characters = new HashSet<OdeCharacter>();
225 private readonly HashSet<OdePrim> _prims = new HashSet<OdePrim>(); 222 private readonly HashSet<OdePrim> _prims = new HashSet<OdePrim>();
226 private readonly HashSet<OdePrim> _activeprims = new HashSet<OdePrim>(); 223 private readonly HashSet<OdePrim> _activeprims = new HashSet<OdePrim>();
224 private readonly HashSet<OdePrim> _activegroups = new HashSet<OdePrim>();
227 225
228 public OpenSim.Framework.LocklessQueue<ODEchangeitem> ChangesQueue = new OpenSim.Framework.LocklessQueue<ODEchangeitem>(); 226 public OpenSim.Framework.LocklessQueue<ODEchangeitem> ChangesQueue = new OpenSim.Framework.LocklessQueue<ODEchangeitem>();
229 227
@@ -387,9 +385,6 @@ namespace OpenSim.Region.Physics.OdePlugin
387 385
388 // Defaults 386 // Defaults
389 387
390 avPIDD = 2200.0f;
391 avPIDP = 900.0f;
392
393 int contactsPerCollision = 80; 388 int contactsPerCollision = 80;
394 389
395 if (m_config != null) 390 if (m_config != null)
@@ -397,90 +392,86 @@ namespace OpenSim.Region.Physics.OdePlugin
397 IConfig physicsconfig = m_config.Configs["ODEPhysicsSettings"]; 392 IConfig physicsconfig = m_config.Configs["ODEPhysicsSettings"];
398 if (physicsconfig != null) 393 if (physicsconfig != null)
399 { 394 {
400 gravityx = physicsconfig.GetFloat("world_gravityx", 0f); 395 gravityx = physicsconfig.GetFloat("world_gravityx", gravityx);
401 gravityy = physicsconfig.GetFloat("world_gravityy", 0f); 396 gravityy = physicsconfig.GetFloat("world_gravityy", gravityy);
402 gravityz = physicsconfig.GetFloat("world_gravityz", -9.8f); 397 gravityz = physicsconfig.GetFloat("world_gravityz", gravityz);
403 398
404 metersInSpace = physicsconfig.GetFloat("meters_in_small_space", 29.9f); 399 metersInSpace = physicsconfig.GetFloat("meters_in_small_space", metersInSpace);
405 400
406 contactsurfacelayer = physicsconfig.GetFloat("world_contact_surface_layer", contactsurfacelayer); 401 contactsurfacelayer = physicsconfig.GetFloat("world_contact_surface_layer", contactsurfacelayer);
407 402
408 ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", 0.020f); 403 ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", ODE_STEPSIZE);
409 m_physicsiterations = physicsconfig.GetInt("world_internal_steps_without_collisions", 10); 404 m_physicsiterations = physicsconfig.GetInt("world_internal_steps_without_collisions", m_physicsiterations);
410 405
411 avDensity = physicsconfig.GetFloat("av_density", avDensity); 406 avDensity = physicsconfig.GetFloat("av_density", avDensity);
412 avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", 1.3f); 407 avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", avMovementDivisorWalk);
413 avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", 0.8f); 408 avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", avMovementDivisorRun);
414 avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f); 409 avCapRadius = physicsconfig.GetFloat("av_capsule_radius", avCapRadius);
415 410
416 contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80); 411 contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", contactsPerCollision);
417 412
418 geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 3); 413 geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 3);
419 geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15); 414 geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15);
420 geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5); 415// geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5);
421 416
422 geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", 10.000006836f); 417 geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity);
423 bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", 20); 418 bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable);
424 419
425 bodyPIDD = physicsconfig.GetFloat("body_pid_derivative", 35f); 420 bodyPIDD = physicsconfig.GetFloat("body_pid_derivative", bodyPIDD);
426 bodyPIDG = physicsconfig.GetFloat("body_pid_gain", 25f); 421 bodyPIDG = physicsconfig.GetFloat("body_pid_gain", bodyPIDG);
427 422
428 forceSimplePrimMeshing = physicsconfig.GetBoolean("force_simple_prim_meshing", forceSimplePrimMeshing); 423 forceSimplePrimMeshing = physicsconfig.GetBoolean("force_simple_prim_meshing", forceSimplePrimMeshing);
429 meshSculptedPrim = physicsconfig.GetBoolean("mesh_sculpted_prim", true); 424 meshSculptedPrim = physicsconfig.GetBoolean("mesh_sculpted_prim", meshSculptedPrim);
430 meshSculptLOD = physicsconfig.GetFloat("mesh_lod", 32f); 425 meshSculptLOD = physicsconfig.GetFloat("mesh_lod", meshSculptLOD);
431 MeshSculptphysicalLOD = physicsconfig.GetFloat("mesh_physical_lod", 16f); 426 MeshSculptphysicalLOD = physicsconfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD);
432 m_filterCollisions = physicsconfig.GetBoolean("filter_collisions", false);
433 427
434 if (Environment.OSVersion.Platform == PlatformID.Unix) 428 if (Environment.OSVersion.Platform == PlatformID.Unix)
435 { 429 {
436 avPIDD = physicsconfig.GetFloat("av_pid_derivative_linux", 2200.0f); 430 avPIDD = physicsconfig.GetFloat("av_pid_derivative_linux", avPIDD);
437 avPIDP = physicsconfig.GetFloat("av_pid_proportional_linux", 900.0f); 431 avPIDP = physicsconfig.GetFloat("av_pid_proportional_linux", avPIDP);
438 } 432 }
439 else 433 else
440 { 434 {
441 avPIDD = physicsconfig.GetFloat("av_pid_derivative_win", 2200.0f); 435 avPIDD = physicsconfig.GetFloat("av_pid_derivative_win", avPIDD);
442 avPIDP = physicsconfig.GetFloat("av_pid_proportional_win", 900.0f); 436 avPIDP = physicsconfig.GetFloat("av_pid_proportional_win", avPIDP);
443 } 437 }
444 438
445 physics_logging = physicsconfig.GetBoolean("physics_logging", false); 439 physics_logging = physicsconfig.GetBoolean("physics_logging", false);
446 physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0); 440 physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0);
447 physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false); 441 physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false);
448 442
449 minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", 3f); 443 minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", minimumGroundFlightOffset);
450 maximumMassObject = physicsconfig.GetFloat("maximum_mass_object", 10000.01f); 444 maximumMassObject = physicsconfig.GetFloat("maximum_mass_object", maximumMassObject);
451 } 445 }
452 } 446 }
453 447
454 ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf); 448 ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf);
455 GlobalContactsArray = GlobalContactsArray = Marshal.AllocHGlobal(maxContactsbeforedeath * d.Contact.unmanagedSizeOf); 449 GlobalContactsArray = GlobalContactsArray = Marshal.AllocHGlobal(maxContactsbeforedeath * d.Contact.unmanagedSizeOf);
456 450
457 m_materialContactsData[(int)Material.Stone].mu = frictionScale * 0.8f; 451 m_materialContactsData[(int)Material.Stone].mu = 0.8f;
458 m_materialContactsData[(int)Material.Stone].bounce = 0.4f; 452 m_materialContactsData[(int)Material.Stone].bounce = 0.4f;
459 453
460 m_materialContactsData[(int)Material.Metal].mu = frictionScale * 0.3f; 454 m_materialContactsData[(int)Material.Metal].mu = 0.3f;
461 m_materialContactsData[(int)Material.Metal].bounce = 0.4f; 455 m_materialContactsData[(int)Material.Metal].bounce = 0.4f;
462 456
463 m_materialContactsData[(int)Material.Glass].mu = frictionScale * 0.2f; 457 m_materialContactsData[(int)Material.Glass].mu = 0.2f;
464 m_materialContactsData[(int)Material.Glass].bounce = 0.7f; 458 m_materialContactsData[(int)Material.Glass].bounce = 0.7f;
465 459
466 m_materialContactsData[(int)Material.Wood].mu = frictionScale * 0.6f; 460 m_materialContactsData[(int)Material.Wood].mu = 0.6f;
467 m_materialContactsData[(int)Material.Wood].bounce = 0.5f; 461 m_materialContactsData[(int)Material.Wood].bounce = 0.5f;
468 462
469 m_materialContactsData[(int)Material.Flesh].mu = frictionScale * 0.9f; 463 m_materialContactsData[(int)Material.Flesh].mu = 0.9f;
470 m_materialContactsData[(int)Material.Flesh].bounce = 0.3f; 464 m_materialContactsData[(int)Material.Flesh].bounce = 0.3f;
471 465
472 m_materialContactsData[(int)Material.Plastic].mu = frictionScale * 0.4f; 466 m_materialContactsData[(int)Material.Plastic].mu = 0.4f;
473 m_materialContactsData[(int)Material.Plastic].bounce = 0.7f; 467 m_materialContactsData[(int)Material.Plastic].bounce = 0.7f;
474 468
475 m_materialContactsData[(int)Material.Rubber].mu = frictionScale * 0.9f; 469 m_materialContactsData[(int)Material.Rubber].mu = 0.9f;
476 m_materialContactsData[(int)Material.Rubber].bounce = 0.95f; 470 m_materialContactsData[(int)Material.Rubber].bounce = 0.95f;
477 471
478 m_materialContactsData[(int)Material.light].mu = 0.0f; 472 m_materialContactsData[(int)Material.light].mu = 0.0f;
479 m_materialContactsData[(int)Material.light].bounce = 0.0f; 473 m_materialContactsData[(int)Material.light].bounce = 0.0f;
480 474
481 TerrainFriction *= frictionScale;
482// AvatarFriction *= frictionScale;
483
484 // Set the gravity,, don't disable things automatically (we set it explicitly on some things) 475 // Set the gravity,, don't disable things automatically (we set it explicitly on some things)
485 476
486 d.WorldSetGravity(world, gravityx, gravityy, gravityz); 477 d.WorldSetGravity(world, gravityx, gravityy, gravityz);
@@ -566,13 +557,6 @@ namespace OpenSim.Region.Physics.OdePlugin
566 } 557 }
567 558
568 559
569 /// <summary>
570 /// This is our near callback. A geometry is near a body
571 /// </summary>
572 /// <param name="space">The space that contains the geoms. Remember, spaces are also geoms</param>
573 /// <param name="g1">a geometry or space</param>
574 /// <param name="g2">another geometry or space</param>
575 ///
576 560
577 private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom) 561 private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom)
578 { 562 {
@@ -584,7 +568,13 @@ namespace OpenSim.Region.Physics.OdePlugin
584 return true; 568 return true;
585 } 569 }
586 570
587 571 /// <summary>
572 /// This is our near callback. A geometry is near a body
573 /// </summary>
574 /// <param name="space">The space that contains the geoms. Remember, spaces are also geoms</param>
575 /// <param name="g1">a geometry or space</param>
576 /// <param name="g2">another geometry or space</param>
577 ///
588 578
589 private void near(IntPtr space, IntPtr g1, IntPtr g2) 579 private void near(IntPtr space, IntPtr g1, IntPtr g2)
590 { 580 {
@@ -703,8 +693,8 @@ namespace OpenSim.Region.Physics.OdePlugin
703 // big messy collision analises 693 // big messy collision analises
704 float mu = 0; 694 float mu = 0;
705 float bounce = 0; 695 float bounce = 0;
706 ContactData contactdata1; 696 ContactData contactdata1 = new ContactData(0, 0, false);
707 ContactData contactdata2; 697 ContactData contactdata2 = new ContactData(0, 0, false);
708 bool erpSoft = false; 698 bool erpSoft = false;
709 699
710 String name = null; 700 String name = null;
@@ -718,8 +708,9 @@ namespace OpenSim.Region.Physics.OdePlugin
718 switch (p2.PhysicsActorType) 708 switch (p2.PhysicsActorType)
719 { 709 {
720 case (int)ActorTypes.Agent: 710 case (int)ActorTypes.Agent:
721 contactdata1 = p1.ContactData; 711 p1.getContactData(ref contactdata1);
722 contactdata2 = p2.ContactData; 712 p2.getContactData(ref contactdata2);
713
723 bounce = contactdata1.bounce * contactdata2.bounce; 714 bounce = contactdata1.bounce * contactdata2.bounce;
724 715
725 mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); 716 mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu);
@@ -727,12 +718,13 @@ namespace OpenSim.Region.Physics.OdePlugin
727 if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f)) 718 if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f))
728 mu *= frictionMovementMult; 719 mu *= frictionMovementMult;
729 720
721 erpSoft = contactdata1.softcolide | contactdata2.softcolide;
730 p1.CollidingObj = true; 722 p1.CollidingObj = true;
731 p2.CollidingObj = true; 723 p2.CollidingObj = true;
732 break; 724 break;
733 case (int)ActorTypes.Prim: 725 case (int)ActorTypes.Prim:
734 contactdata1 = p1.ContactData; 726 p1.getContactData(ref contactdata1);
735 contactdata2 = p2.ContactData; 727 p2.getContactData(ref contactdata2);
736 bounce = contactdata1.bounce * contactdata2.bounce; 728 bounce = contactdata1.bounce * contactdata2.bounce;
737 729
738 mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); 730 mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu);
@@ -741,6 +733,9 @@ namespace OpenSim.Region.Physics.OdePlugin
741 mu *= frictionMovementMult; 733 mu *= frictionMovementMult;
742 if (p2.Velocity.LengthSquared() > 0.0f) 734 if (p2.Velocity.LengthSquared() > 0.0f)
743 p2.CollidingObj = true; 735 p2.CollidingObj = true;
736
737 erpSoft = contactdata1.softcolide | contactdata2.softcolide;
738
744 dop1foot = true; 739 dop1foot = true;
745 break; 740 break;
746 default: 741 default:
@@ -753,8 +748,8 @@ namespace OpenSim.Region.Physics.OdePlugin
753 switch (p2.PhysicsActorType) 748 switch (p2.PhysicsActorType)
754 { 749 {
755 case (int)ActorTypes.Agent: 750 case (int)ActorTypes.Agent:
756 contactdata1 = p1.ContactData; 751 p1.getContactData(ref contactdata1);
757 contactdata2 = p2.ContactData; 752 p2.getContactData(ref contactdata2);
758 bounce = contactdata1.bounce * contactdata2.bounce; 753 bounce = contactdata1.bounce * contactdata2.bounce;
759 754
760 mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); 755 mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu);
@@ -762,6 +757,7 @@ namespace OpenSim.Region.Physics.OdePlugin
762 if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f)) 757 if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f))
763 mu *= frictionMovementMult; 758 mu *= frictionMovementMult;
764 759
760 erpSoft = contactdata1.softcolide | contactdata2.softcolide;
765 dop2foot = true; 761 dop2foot = true;
766 if (p1.Velocity.LengthSquared() > 0.0f) 762 if (p1.Velocity.LengthSquared() > 0.0f)
767 p1.CollidingObj = true; 763 p1.CollidingObj = true;
@@ -772,10 +768,10 @@ namespace OpenSim.Region.Physics.OdePlugin
772 p1.CollidingObj = true; 768 p1.CollidingObj = true;
773 p2.CollidingObj = true; 769 p2.CollidingObj = true;
774 } 770 }
775 contactdata1 = p1.ContactData; 771 p1.getContactData(ref contactdata1);
776 contactdata2 = p2.ContactData; 772 p2.getContactData(ref contactdata2);
777 bounce = contactdata1.bounce * contactdata2.bounce; 773 bounce = contactdata1.bounce * contactdata2.bounce;
778 erpSoft = true; 774 erpSoft = contactdata1.softcolide | contactdata2.softcolide;
779 mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); 775 mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu);
780 776
781 if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f)) 777 if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f))
@@ -787,12 +783,12 @@ namespace OpenSim.Region.Physics.OdePlugin
787 { 783 {
788 if (name == "Terrain") 784 if (name == "Terrain")
789 { 785 {
790 erpSoft = true; 786 p1.getContactData(ref contactdata1);
791 contactdata1 = p1.ContactData;
792 bounce = contactdata1.bounce * TerrainBounce; 787 bounce = contactdata1.bounce * TerrainBounce;
793 mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction); 788 mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction);
794 if (Math.Abs(p1.Velocity.X) > 0.1f || Math.Abs(p1.Velocity.Y) > 0.1f) 789 if (Math.Abs(p1.Velocity.X) > 0.1f || Math.Abs(p1.Velocity.Y) > 0.1f)
795 mu *= frictionMovementMult; 790 mu *= frictionMovementMult;
791 erpSoft = contactdata1.softcolide;
796 p1.CollidingGround = true; 792 p1.CollidingGround = true;
797 } 793 }
798 else if (name == "Water") 794 else if (name == "Water")
@@ -813,11 +809,11 @@ namespace OpenSim.Region.Physics.OdePlugin
813 { 809 {
814 if (p2.PhysicsActorType == (int)ActorTypes.Prim) 810 if (p2.PhysicsActorType == (int)ActorTypes.Prim)
815 { 811 {
816 erpSoft = true;
817 p2.CollidingGround = true; 812 p2.CollidingGround = true;
818 contactdata2 = p2.ContactData; 813 p2.getContactData(ref contactdata2);
819 bounce = contactdata2.bounce * TerrainBounce; 814 bounce = contactdata2.bounce * TerrainBounce;
820 mu = (float)Math.Sqrt(contactdata2.mu * TerrainFriction); 815 mu = (float)Math.Sqrt(contactdata2.mu * TerrainFriction);
816 erpSoft = contactdata2.softcolide;
821 817
822 if (Math.Abs(p2.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y) > 0.1f) 818 if (Math.Abs(p2.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y) > 0.1f)
823 mu *= frictionMovementMult; 819 mu *= frictionMovementMult;
@@ -1013,15 +1009,24 @@ namespace OpenSim.Region.Physics.OdePlugin
1013 1009
1014 } 1010 }
1015 1011
1016 // collide active prims with static enviroment
1017 lock (_activeprims) 1012 lock (_activeprims)
1018 { 1013 {
1014 foreach (OdePrim aprim in _activeprims)
1015 {
1016 aprim.CollisionScore = 0;
1017 aprim.IsColliding = false;
1018 }
1019 }
1020
1021 // collide active prims with static enviroment
1022 lock (_activegroups)
1023 {
1019 try 1024 try
1020 { 1025 {
1021 foreach (OdePrim prm in _activeprims) 1026 foreach (OdePrim prm in _activegroups)
1022 { 1027 {
1023 if (d.BodyIsEnabled(prm.Body)) 1028 if (d.BodyIsEnabled(prm.Body) && !prm.m_outbounds)
1024 d.SpaceCollide2(StaticSpace, prm.prim_geom, IntPtr.Zero, nearCallback); 1029 d.SpaceCollide2(StaticSpace, prm.collide_geom, IntPtr.Zero, nearCallback);
1025 } 1030 }
1026 } 1031 }
1027 catch (AccessViolationException) 1032 catch (AccessViolationException)
@@ -1029,7 +1034,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1029 m_log.Warn("[PHYSICS]: Unable to collide Active prim to static space"); 1034 m_log.Warn("[PHYSICS]: Unable to collide Active prim to static space");
1030 } 1035 }
1031 } 1036 }
1032
1033 // finally colide active things amoung them 1037 // finally colide active things amoung them
1034 try 1038 try
1035 { 1039 {
@@ -1039,7 +1043,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1039 { 1043 {
1040 m_log.Warn("[PHYSICS]: Unable to collide in Active space"); 1044 m_log.Warn("[PHYSICS]: Unable to collide in Active space");
1041 } 1045 }
1042
1043// _perloopContact.Clear(); 1046// _perloopContact.Clear();
1044 } 1047 }
1045 1048
@@ -1148,13 +1151,20 @@ namespace OpenSim.Region.Physics.OdePlugin
1148 1151
1149 public void addActivePrim(OdePrim activatePrim) 1152 public void addActivePrim(OdePrim activatePrim)
1150 { 1153 {
1151 // adds active prim.. (ones that should be iterated over in collisions_optimized 1154 // adds active prim..
1152 lock (_activeprims) 1155 lock (_activeprims)
1153 { 1156 {
1154 if (!_activeprims.Contains(activatePrim)) 1157 if (!_activeprims.Contains(activatePrim))
1155 _activeprims.Add(activatePrim); 1158 _activeprims.Add(activatePrim);
1156 //else 1159 }
1157 // m_log.Warn("[PHYSICS]: Double Entry in _activeprims detected, potential crash immenent"); 1160 }
1161
1162 public void addActiveGroups(OdePrim activatePrim)
1163 {
1164 lock (_activegroups)
1165 {
1166 if (!_activegroups.Contains(activatePrim))
1167 _activegroups.Add(activatePrim);
1158 } 1168 }
1159 } 1169 }
1160 1170
@@ -1186,6 +1196,13 @@ namespace OpenSim.Region.Physics.OdePlugin
1186 _activeprims.Remove(deactivatePrim); 1196 _activeprims.Remove(deactivatePrim);
1187 } 1197 }
1188 } 1198 }
1199 public void remActiveGroup(OdePrim deactivatePrim)
1200 {
1201 lock (_activegroups)
1202 {
1203 _activegroups.Remove(deactivatePrim);
1204 }
1205 }
1189 1206
1190 public override void RemovePrim(PhysicsActor prim) 1207 public override void RemovePrim(PhysicsActor prim)
1191 { 1208 {
@@ -1258,6 +1275,11 @@ namespace OpenSim.Region.Physics.OdePlugin
1258 { 1275 {
1259 waitForSpaceUnlock(currentspace); 1276 waitForSpaceUnlock(currentspace);
1260 d.SpaceRemove(currentspace, geom); 1277 d.SpaceRemove(currentspace, geom);
1278
1279 if (d.SpaceGetSublevel(currentspace) > 2 && d.SpaceGetNumGeoms(currentspace) == 0)
1280 {
1281 d.SpaceDestroy(currentspace);
1282 }
1261 } 1283 }
1262 else 1284 else
1263 { 1285 {
@@ -1274,6 +1296,12 @@ namespace OpenSim.Region.Physics.OdePlugin
1274 { 1296 {
1275 waitForSpaceUnlock(currentspace); 1297 waitForSpaceUnlock(currentspace);
1276 d.SpaceRemove(currentspace, geom); 1298 d.SpaceRemove(currentspace, geom);
1299
1300 if (d.SpaceGetSublevel(currentspace) > 2 && d.SpaceGetNumGeoms(currentspace) == 0)
1301 {
1302 d.SpaceDestroy(currentspace);
1303 }
1304
1277 } 1305 }
1278 } 1306 }
1279 } 1307 }
@@ -1577,42 +1605,14 @@ namespace OpenSim.Region.Physics.OdePlugin
1577 1605
1578 statchanges += Util.EnvironmentTickCountSubtract(statstart); 1606 statchanges += Util.EnvironmentTickCountSubtract(statstart);
1579 1607
1580 // Move characters
1581 lock (_characters)
1582 {
1583 List<OdeCharacter> defects = new List<OdeCharacter>();
1584 foreach (OdeCharacter actor in _characters)
1585 {
1586 if (actor != null)
1587 actor.Move(ODE_STEPSIZE, defects);
1588 }
1589 if (defects.Count != 0)
1590 {
1591 foreach (OdeCharacter defect in defects)
1592 {
1593 RemoveCharacter(defect);
1594 }
1595 }
1596 }
1597 statchmove += Util.EnvironmentTickCountSubtract(statstart);
1598
1599 // Move other active objects
1600 lock (_activeprims)
1601 {
1602 foreach (OdePrim aprim in _activeprims)
1603 {
1604 aprim.CollisionScore = 0;
1605 aprim.IsColliding = false;
1606 aprim.Move();
1607 }
1608 }
1609
1610 statactmove += Util.EnvironmentTickCountSubtract(statstart); 1608 statactmove += Util.EnvironmentTickCountSubtract(statstart);
1611 //if ((framecount % m_randomizeWater) == 0) 1609 //if ((framecount % m_randomizeWater) == 0)
1612 // randomizeWater(waterlevel); 1610 // randomizeWater(waterlevel);
1613 1611
1614 m_rayCastManager.ProcessQueuedRequests(); 1612 m_rayCastManager.ProcessQueuedRequests();
1615 1613
1614
1615
1616 statray += Util.EnvironmentTickCountSubtract(statstart); 1616 statray += Util.EnvironmentTickCountSubtract(statstart);
1617 collision_optimized(); 1617 collision_optimized();
1618 statcol += Util.EnvironmentTickCountSubtract(statstart); 1618 statcol += Util.EnvironmentTickCountSubtract(statstart);
@@ -1642,8 +1642,35 @@ namespace OpenSim.Region.Physics.OdePlugin
1642 1642
1643 d.WorldQuickStep(world, ODE_STEPSIZE); 1643 d.WorldQuickStep(world, ODE_STEPSIZE);
1644 statstep += Util.EnvironmentTickCountSubtract(statstart); 1644 statstep += Util.EnvironmentTickCountSubtract(statstart);
1645 d.JointGroupEmpty(contactgroup); 1645
1646 totjcontact += m_global_contactcount; 1646 // Move characters
1647 lock (_characters)
1648 {
1649 List<OdeCharacter> defects = new List<OdeCharacter>();
1650 foreach (OdeCharacter actor in _characters)
1651 {
1652 if (actor != null)
1653 actor.Move(ODE_STEPSIZE, defects);
1654 }
1655 if (defects.Count != 0)
1656 {
1657 foreach (OdeCharacter defect in defects)
1658 {
1659 RemoveCharacter(defect);
1660 }
1661 }
1662 }
1663 statchmove += Util.EnvironmentTickCountSubtract(statstart);
1664
1665 // Move other active objects
1666 lock (_activegroups)
1667 {
1668 foreach (OdePrim aprim in _activegroups)
1669 {
1670 aprim.Move();
1671 }
1672 }
1673
1647 //ode.dunlock(world); 1674 //ode.dunlock(world);
1648 } 1675 }
1649 catch (Exception e) 1676 catch (Exception e)
@@ -1652,6 +1679,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1652// ode.dunlock(world); 1679// ode.dunlock(world);
1653 } 1680 }
1654 1681
1682 d.JointGroupEmpty(contactgroup);
1683 totjcontact += m_global_contactcount;
1684
1655 step_time -= ODE_STEPSIZE; 1685 step_time -= ODE_STEPSIZE;
1656 nodeframes++; 1686 nodeframes++;
1657 } 1687 }
@@ -1686,10 +1716,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1686 } 1716 }
1687 statmovchar = Util.EnvironmentTickCountSubtract(statstart); 1717 statmovchar = Util.EnvironmentTickCountSubtract(statstart);
1688 1718
1689 lock (_activeprims) 1719 lock (_activegroups)
1690 { 1720 {
1691 { 1721 {
1692 foreach (OdePrim actor in _activeprims) 1722 foreach (OdePrim actor in _activegroups)
1693 { 1723 {
1694 if (actor.IsPhysical) 1724 if (actor.IsPhysical)
1695 { 1725 {
@@ -1906,13 +1936,14 @@ namespace OpenSim.Region.Physics.OdePlugin
1906 yy += regionsize; 1936 yy += regionsize;
1907 1937
1908 val = heightMap[yy + xx]; 1938 val = heightMap[yy + xx];
1939 if (val < 0.0f)
1940 val = 0.0f; // no neg terrain as in chode
1909 _heightmap[xt + y] = val; 1941 _heightmap[xt + y] = val;
1910 1942
1911 if (hfmin > val) 1943 if (hfmin > val)
1912 hfmin = val; 1944 hfmin = val;
1913 if (hfmax < val) 1945 if (hfmax < val)
1914 hfmax = val; 1946 hfmax = val;
1915
1916 } 1947 }
1917 xt += heightmapHeightSamples; 1948 xt += heightmapHeightSamples;
1918 } 1949 }
@@ -1966,7 +1997,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1966 1997
1967 d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); 1998 d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
1968 d.GeomSetRotation(GroundGeom, ref R); 1999 d.GeomSetRotation(GroundGeom, ref R);
1969 d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f - 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f - 0.5f, 0); 2000 d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f, 0);
1970 RegionTerrain.Add(pOffset, GroundGeom, GroundGeom); 2001 RegionTerrain.Add(pOffset, GroundGeom, GroundGeom);
1971// TerrainHeightFieldHeights.Add(GroundGeom, ODElandMap); 2002// TerrainHeightFieldHeights.Add(GroundGeom, ODElandMap);
1972 TerrainHeightFieldHeights.Add(GroundGeom, _heightmap); 2003 TerrainHeightFieldHeights.Add(GroundGeom, _heightmap);