diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index c9ea8e49c5..8809cd04a0 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -957,12 +957,12 @@ namespace OpenSim.Region.Framework.Scenes
///
public void GetAxisAlignedBoundingBoxRaw(out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ)
{
- maxX = -256f;
- maxY = -256f;
- maxZ = -256f;
- minX = 256f;
- minY = 256f;
- minZ = 8192f;
+ maxX = float.MinValue;
+ maxY = float.MinValue;
+ maxZ = float.MinValue;
+ minX = float.MaxValue;
+ minY = float.MaxValue;
+ minZ = float.MaxValue;
SceneObjectPart[] parts = m_parts.GetArray();
foreach (SceneObjectPart part in parts)
@@ -1988,7 +1988,12 @@ namespace OpenSim.Region.Framework.Scenes
///
public void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed)
{
- SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed));
+ // SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed));
+ // give newpart a new local ID lettng old part keep same
+ SceneObjectPart newpart = part.Copy(part.LocalId, OwnerID, GroupID, 0, userExposed);
+ newpart.LocalId = m_scene.AllocateLocalId();
+
+ SetRootPart(newpart);
if (userExposed)
RootPart.Velocity = Vector3.Zero; // In case source is moving
}
@@ -2191,7 +2196,10 @@ namespace OpenSim.Region.Framework.Scenes
///
public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed)
{
- SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
+ // give new ID to the new part, letting old keep original
+ // SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
+ SceneObjectPart newPart = part.Copy(part.LocalId, OwnerID, GroupID, m_parts.Count, userExposed);
+ newPart.LocalId = m_scene.AllocateLocalId();
newPart.SetParent(this);
AddPart(newPart);
@@ -2485,6 +2493,11 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectPart linkPart = objectGroup.m_rootPart;
+ if (m_rootPart.PhysActor != null)
+ m_rootPart.PhysActor.Building = true;
+ if (linkPart.PhysActor != null)
+ linkPart.PhysActor.Building = true;
+
Vector3 oldGroupPosition = linkPart.GroupPosition;
Quaternion oldRootRotation = linkPart.RotationOffset;
@@ -2528,6 +2541,13 @@ namespace OpenSim.Region.Framework.Scenes
linkPart.SetParent(this);
linkPart.CreateSelected = true;
+ // let physics know
+ if (linkPart.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical)
+ {
+ linkPart.PhysActor.link(m_rootPart.PhysActor);
+ this.Scene.PhysicsScene.AddPhysicsActorTaint(linkPart.PhysActor);
+ }
+
linkPart.LinkNum = linkNum++;
SceneObjectPart[] ogParts = objectGroup.Parts;
@@ -2540,7 +2560,15 @@ namespace OpenSim.Region.Framework.Scenes
{
SceneObjectPart part = ogParts[i];
if (part.UUID != objectGroup.m_rootPart.UUID)
+ {
LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
+ // let physics know
+ if (part.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical)
+ {
+ part.PhysActor.link(m_rootPart.PhysActor);
+ this.Scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
+ }
+ }
part.ClearUndoState();
}
}
@@ -2560,6 +2588,9 @@ namespace OpenSim.Region.Framework.Scenes
// unmoved prims!
ResetChildPrimPhysicsPositions();
+ if (m_rootPart.PhysActor != null)
+ m_rootPart.PhysActor.Building = false;
+
//HasGroupChanged = true;
//ScheduleGroupForFullUpdate();
}
@@ -2612,7 +2643,10 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.DebugFormat(
// "[SCENE OBJECT GROUP]: Delinking part {0}, {1} from group with root part {2}, {3}",
// linkPart.Name, linkPart.UUID, RootPart.Name, RootPart.UUID);
-
+
+ if (m_rootPart.PhysActor != null)
+ m_rootPart.PhysActor.Building = true;
+
linkPart.ClearUndoState();
Quaternion worldRot = linkPart.GetWorldRotation();
@@ -2672,6 +2706,10 @@ namespace OpenSim.Region.Framework.Scenes
// When we delete a group, we currently have to force persist to the database if the object id has changed
// (since delete works by deleting all rows which have a given object id)
+
+ if (m_rootPart.PhysActor != null)
+ m_rootPart.PhysActor.Building = false;
+
objectGroup.HasGroupChangedDueToDelink = true;
return objectGroup;
@@ -3284,6 +3322,10 @@ namespace OpenSim.Region.Framework.Scenes
part.StoreUndoState(false);
part.IgnoreUndoUpdate = true;
+// unlock parts position change
+ if (m_rootPart.PhysActor != null)
+ m_rootPart.PhysActor.Building = true;
+
if (part.UUID == m_rootPart.UUID)
{
UpdateRootPosition(pos);
@@ -3293,6 +3335,9 @@ namespace OpenSim.Region.Framework.Scenes
part.UpdateOffSet(pos);
}
+ if (m_rootPart.PhysActor != null)
+ m_rootPart.PhysActor.Building = false;
+
HasGroupChanged = true;
part.IgnoreUndoUpdate = false;
}
@@ -3434,6 +3479,9 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.DebugFormat(
// "[SCENE OBJECT GROUP]: Updating single rotation of {0} {1} to {2}", part.Name, part.LocalId, rot);
+ if (m_rootPart.PhysActor != null)
+ m_rootPart.PhysActor.Building = true;
+
if (part.UUID == m_rootPart.UUID)
{
UpdateRootRotation(rot);
@@ -3442,6 +3490,9 @@ namespace OpenSim.Region.Framework.Scenes
{
part.UpdateRotation(rot);
}
+
+ if (m_rootPart.PhysActor != null)
+ m_rootPart.PhysActor.Building = false;
}
}
@@ -3462,6 +3513,9 @@ namespace OpenSim.Region.Framework.Scenes
part.StoreUndoState();
part.IgnoreUndoUpdate = true;
+ if (m_rootPart.PhysActor != null)
+ m_rootPart.PhysActor.Building = true;
+
if (part.UUID == m_rootPart.UUID)
{
UpdateRootRotation(rot);
@@ -3482,6 +3536,9 @@ namespace OpenSim.Region.Framework.Scenes
part.OffsetPosition = pos;
}
+ if (m_rootPart.PhysActor != null)
+ m_rootPart.PhysActor.Building = false;
+
part.IgnoreUndoUpdate = false;
}
}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 1c72b10646..9c06786b8b 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -1691,10 +1691,9 @@ namespace OpenSim.Region.Framework.Scenes
if (userExposed)
dupe.UUID = UUID.Random();
- //memberwiseclone means it also clones the physics actor reference
- // This will make physical prim 'bounce' if not set to null.
- if (!userExposed)
- dupe.PhysActor = null;
+ // The PhysActor cannot be valid on a copy because the copy is not in the scene yet.
+ // Null it, the caller has to create a new one once the object is added to a scene
+ dupe.PhysActor = null;
dupe.OwnerID = AgentID;
dupe.GroupID = GroupID;
@@ -1727,8 +1726,6 @@ namespace OpenSim.Region.Framework.Scenes
// Move afterwards ResetIDs as it clears the localID
dupe.LocalId = localID;
- if(dupe.PhysActor != null)
- dupe.PhysActor.LocalID = localID;
// This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
dupe.LastOwnerID = OwnerID;
@@ -1749,6 +1746,9 @@ namespace OpenSim.Region.Framework.Scenes
dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
}
+ if (dupe.PhysActor != null)
+ dupe.PhysActor.LocalID = localID;
+
ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
// 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 c1957e2cb8..59ff9b8a19 100644
--- a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs
+++ b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs
@@ -121,12 +121,18 @@ namespace OpenSim.Region.OptionalModules
private bool CanObjectEnter(UUID objectID, bool enteringRegion, Vector3 newPoint, Scene scene)
{
+ if ((newPoint.X > 257f || newPoint.X < -1f || newPoint.Y > 257f || newPoint.Y < -1f))
+ return true;
+
SceneObjectPart obj = scene.GetSceneObjectPart(objectID);
Vector3 oldPoint = obj.GroupPosition;
int objectCount = obj.ParentGroup.PrimCount;
ILandObject oldParcel = scene.LandChannel.GetLandObject(oldPoint.X, oldPoint.Y);
ILandObject newParcel = scene.LandChannel.GetLandObject(newPoint.X, newPoint.Y);
+ if (newParcel == null)
+ return true;
+
int usedPrims = newParcel.PrimCounts.Total;
int simulatorCapacity = newParcel.GetSimulatorMaxPrimCount();
@@ -171,4 +177,4 @@ namespace OpenSim.Region.OptionalModules
return true;
}
}
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
index 0a4ebe4db5..3ed3b5a3c8 100644
--- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs
@@ -163,6 +163,8 @@ namespace OpenSim.Region.Physics.OdePlugin
private bool m_isphysical;
private bool m_isSelected;
+ private bool m_NoColide; // for now only for internal use for bad meshs
+
internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively
private bool m_throttleUpdates;
@@ -253,7 +255,7 @@ namespace OpenSim.Region.Physics.OdePlugin
private float m_verticalAttractionEfficiency = 1.0f; // damped
private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor.
- SerialControl m_taintserial = null;
+// SerialControl m_taintserial = null;
object m_taintvehicledata = null;
public void DoSetVehicle()
@@ -309,410 +311,6 @@ namespace OpenSim.Region.Physics.OdePlugin
m_taintvehicledata = vdata;
_parent_scene.AddPhysicsActorTaint(this);
}
-
- public override byte[] Serialize(bool PhysIsRunning)
- {
- SerialControl sc = new SerialControl();
-
- lock (sc.alock)
- {
- if (PhysIsRunning)
- {
- m_taintserial = sc;
-
- if (!Monitor.Wait(sc.alock, 1000))
- {
- m_log.Error("[chOde] prim data serialization timed out");
- m_taintserial = null;
- return new byte[0];
- }
- }
- else
- DoSerialize(sc);
- }
-
- return sc.data;
- }
-
- public void DoSerialize(SerialControl sc)
- {
- wstreamer st = new wstreamer();
- Vector3 vtmp;
-
- ushort version = 2;
- if (!BitConverter.IsLittleEndian)
- version |= 1;
- st.Wushort(version); //version lower bit codes endian type for future use
-
- // compact booleans in a ushort
- ushort flags = 0;
-
- if (m_isphysical) // this should be true for now
- flags |= 1;
- if (m_isSelected)
- flags |= 2;
- if (m_isVolumeDetect)
- flags |= 4;
- if (m_disabled)
- flags |= 8;
- if (m_collidesWater)
- flags |= 16;
- if (m_collidesLand)
- flags |= 32;
- if (m_usePID)
- flags |= 64;
- if (m_useAPID)
- flags |= 128;
- if (m_useHoverPID)
- flags |= 256;
- if (m_throttleUpdates)
- flags |= 512;
-
- st.Wushort(flags);
-
- st.Wvector3(_size);
- st.Wint(m_material);
- st.Wfloat(m_density);
- st.Wfloat(0); // future gravity mod V3
- st.Wfloat(0); // future friction V3
- st.Wfloat(0); // future bounce V3
-
-// st.Wuint((uint)m_collisionCategories);
-// st.Wuint((uint)m_collisionFlags);
-
- if (_parent == null)
- {
- st.Wvector3(_position); // ??
- st.Wquat(_orientation);
- }
- else // for childs save offsets
- {
- Quaternion to;
- Quaternion ipo = Quaternion.Inverse(_parent.Orientation);
-
- if (m_isphysical && prim_geom != IntPtr.Zero)
- {
- d.Vector3 dvt;
- d.GeomCopyPosition(prim_geom, out dvt);
-
- vtmp.X = dvt.X;
- vtmp.Y = dvt.Y;
- vtmp.Z = dvt.Z;
-
- d.Quaternion dqt;
- d.GeomCopyQuaternion(prim_geom, out dqt);
-
- to.X = dqt.X;
- to.Y = dqt.Y;
- to.Z = dqt.Z;
- to.W = dqt.W; // rotation in world
- }
- else
- {
- vtmp = _position;
- to = _orientation;
- }
-
- vtmp -= _parent.Position; // offset in world
- vtmp *= ipo; // offset in local
- st.Wvector3(vtmp);
-
- ipo *= to; // own rotation
- st.Wquat(ipo);
- }
-
- st.Wvector3(_velocity);
- st.Wvector3(m_rotationalVelocity);
- st.Wvector3(_acceleration);
- st.Wvector3(m_rotateEnable);
-
- vtmp = Vector3.Zero;
- for (int i = 0; i < m_forcelist.Count; i++)
- {
-
- vtmp += (m_forcelist[i] * 100);
- }
-
- st.Wvector3(vtmp); // force acc
-
- vtmp = Vector3.Zero;
- for (int i = 0; i < m_angularforcelist.Count; i++)
- {
- vtmp += (m_angularforcelist[i] * 100);
- }
-
- st.Wvector3(vtmp); // angular force acc
-
- st.Wvector3(m_PIDTarget);
- st.Wfloat(m_PIDTau);
- st.Wfloat(PID_D);
- st.Wfloat(PID_G);
- st.Wquat(m_APIDTarget);
- st.Wfloat(m_APIDStrength);
- st.Wfloat(m_APIDDamping);
- st.Wfloat(m_APIDdamper);
-
- st.Wint((int)m_PIDHoverType);
- st.Wfloat(m_PIDHoverHeight);
- st.Wfloat(m_PIDHoverTau);
- st.Wfloat(m_targetHoverHeight);
-
- st.Wfloat(m_groundHeight);
- st.Wfloat(m_waterHeight);
-
- st.Wfloat(m_buoyancy);
-
- // this must be last since type none ends stream
- if (m_type == Vehicle.TYPE_NONE)
- st.Wint((int)Vehicle.TYPE_NONE);
- else
- {
- st.Wint((int)m_type);
-
- st.Wquat(Quaternion.Identity); //m_referenceFrame
-
- st.Wint((int)m_flags);
-
- st.Wvector3(m_linearMotorDirection);
- st.Wfloat(
- (float)Math.Sqrt(m_lLinMotorDVel.LengthSquared() / m_linearMotorDirection.LengthSquared()));
-
- st.Wvector3(m_linearFrictionTimescale);
- st.Wfloat(m_linearMotorDecayTimescale);
- st.Wfloat(m_linearMotorTimescale);
- st.Wvector3(new Vector3(0, 0, 0)); //m_linearMotorOffset);
-
- st.Wvector3(m_angularMotorDirection);
- st.Wfloat((float)Math.Sqrt(m_angularMotorDVel.LengthSquared() / m_angularMotorDirection.LengthSquared()));
-
- st.Wvector3(m_angularFrictionTimescale);
- st.Wfloat(m_angularMotorDecayTimescale);
- st.Wfloat(m_angularMotorTimescale);
-
- st.Wfloat(0); //m_linearDeflectionEfficiency);
- st.Wfloat(1000); //m_linearDeflectionTimescale);
-
- st.Wfloat(0); //m_angularDeflectionEfficiency);
- st.Wfloat(120); //m_angularDeflectionTimescale);
-
- st.Wfloat(0); // m_bankingEfficiency);
- st.Wfloat(0); //m_bankingMix);
- st.Wfloat(1000); //m_bankingTimescale);
-
- st.Wfloat(m_VhoverHeight);
- st.Wfloat(0.5f); //m_VhoverEfficiency);
- st.Wfloat(m_VhoverTimescale);
-
- st.Wfloat(m_VehicleBuoyancy);
-
- st.Wfloat(m_verticalAttractionEfficiency);
- st.Wfloat(m_verticalAttractionTimescale);
- }
- sc.data = st.close();
- m_taintserial = null;
- Monitor.PulseAll(sc.alock);
- }
-
- public bool DeSerialize(byte[] data)
- {
- rstreamer st = new rstreamer(data);
-
- int version =st.Rushort(); //version
-
- // merge booleans in a ushort
- ushort flags = st.Rushort();
- if ((flags & 1) != 0)
- m_isphysical = true;
- if ((flags & 2) != 0)
- m_taintselected = true;
- if ((flags & 4) != 0)
- m_isVolumeDetect = true;
- if ((flags & 8) != 0)
- m_taintdisable = true;
- if ((flags & 16) != 0)
- m_taintCollidesWater = true;
- if ((flags & 32) != 0)
- m_collidesLand = true;
- if ((flags & 64) != 0)
- m_usePID = true;
- if ((flags & 128) != 0)
- m_useAPID = true;
- if ((flags & 256) != 0)
- m_useHoverPID = true;
- if ((flags & 512) != 0)
- m_throttleUpdates = true;
-
- _size = st.Rvector3();
- m_taintsize = _size;
-
- m_material= st.Rint();
- m_density = st.Rfloat();
- st.Rfloat(); // future gravity mod V3
- st.Rfloat(); // future friction V3
- st.Rfloat(); // future bounce V3
-
-// m_collisionCategories = (CollisionCategories)st.Ruint();
-// m_collisionFlags = (CollisionCategories) st.Ruint();
-
- if (m_taintparent == null)
- {
- st.Rvector3(); // ignore old position sop/sog as to tell the new one
- m_taintrot = st.Rquat(); //
- _orientation = m_taintrot;
- }
- else
- {
- m_taintrot = _parent.Orientation;
- m_taintposition = st.Rvector3(); // ??
- _position = m_taintposition;
-
- m_taintposition *= m_taintrot;
- m_taintposition += _parent.Position;
-
- m_taintrot *= st.Rquat(); //
- _orientation = m_taintrot;
- }
-
- m_taintVelocity = st.Rvector3();
- m_rotationalVelocity = st.Rvector3();
-
- _acceleration = st.Rvector3();
- m_rotateEnableRequest = st.Rvector3();
- m_rotateEnableUpdate = true;
-
- Vector3 vtmp;
-
- vtmp = st.Rvector3(); // forces acc
- m_forcelist.Add(vtmp);
- m_taintforce = true;
-
- vtmp = st.Rvector3(); // angular forces acc
- m_angularforcelist.Add(vtmp);
- m_taintaddangularforce = true;
-
- m_PIDTarget = st.Rvector3();
- m_PIDTau = st.Rfloat();
- PID_D = st.Rfloat();
- PID_G = st.Rfloat();
-
- m_APIDTarget = st.Rquat();
- m_APIDStrength = st.Rfloat();
- m_APIDDamping = st.Rfloat();
- m_APIDdamper = st.Rfloat();
-
- m_PIDHoverType = (PIDHoverType) st.Rint();
- m_PIDHoverHeight = st.Rfloat();
- m_PIDHoverTau = st.Rfloat();
- m_targetHoverHeight = st.Rfloat();
-
- m_groundHeight = st.Rfloat();
- m_waterHeight = st.Rfloat();
-
- m_buoyancy = st.Rfloat();
-
-
- // this must be last since type none ends stream
-
- m_type = (Vehicle) st.Rint();
-
- if (m_type != Vehicle.TYPE_NONE)
- {
- float ftmp;
-
- st.Rquat(); //m_referenceFrame
-
- m_flags = (VehicleFlag) st.Rint();
-
- m_linearMotorDirection = st.Rvector3();
-
- ftmp = st.Rfloat();
- m_lLinMotorDVel = m_linearMotorDirection * ftmp;
-
- m_linearFrictionTimescale = st.Rvector3();
- m_linearMotorDecayTimescale = st.Rfloat();
- m_linearMotorTimescale = st.Rfloat();
- st.Rvector3(); //m_linearMotorOffset);
-
- m_angularMotorDirection = st.Rvector3();
- ftmp = st.Rfloat();
- m_angularMotorDVel = m_angularMotorDirection * ftmp;
-
- m_angularFrictionTimescale = st.Rvector3();
- m_angularMotorDecayTimescale = st.Rfloat();
- m_angularMotorTimescale = st.Rfloat();
-
- st.Rfloat(); //m_linearDeflectionEfficiency);
- st.Rfloat(); //m_linearDeflectionTimescale);
-
- st.Rfloat(); //m_angularDeflectionEfficiency);
- st.Rfloat(); //m_angularDeflectionTimescale);
-
- st.Rfloat(); // m_bankingEfficiency);
- st.Rfloat(); //m_bankingMix);
- st.Rfloat(); //m_bankingTimescale);
-
- m_VhoverHeight = st.Rfloat();
- st.Rfloat(); //m_VhoverEfficiency);
- m_VhoverTimescale = st.Rfloat();
-
- m_VehicleBuoyancy = st.Rfloat();
-
- m_verticalAttractionEfficiency = st.Rfloat();
- m_verticalAttractionTimescale = st.Rfloat();
- }
- st.close();
- return true;
- }
-
- public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, PhysicsActor parent,
- PrimitiveBaseShape pbs, CollisionLocker dode, uint localid, byte[] sdata)
- {
- m_localID = localid;
- ode = dode;
-
- if (parent == null)
- {
- m_taintparent = null;
-
- if (!pos.IsFinite())
- {
- pos = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f),
- parent_scene.GetTerrainHeightAtXY(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f)) + 0.5f);
- m_log.Warn("[PHYSICS]: Got nonFinite Object create Position");
- }
-
- _position = pos;
- m_taintposition = pos;
- }
- else
- m_taintparent = parent;
-
- body_autodisable_frames = parent_scene.bodyFramesAutoDisable;
-
- prim_geom = IntPtr.Zero;
-
- _mesh = null;
- m_meshfailed = false;
- _pbs = pbs;
-
- _parent_scene = parent_scene;
- m_targetSpace = (IntPtr)0;
-
- if(sdata != null && sdata.Length > 1)
- DeSerialize(sdata);
-
- if (m_isphysical)
- m_targetSpace = _parent_scene.space;
-
- _triMeshData = IntPtr.Zero;
-
- m_primName = primName;
- m_taintserial = null;
- m_taintadd = true;
- _parent_scene.AddPhysicsActorTaint(this);
- // don't do .add() here; old geoms get recycled with the same hash
- }
-
public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size,
Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode, uint localid)
{
@@ -776,8 +374,9 @@ namespace OpenSim.Region.Physics.OdePlugin
}
_triMeshData = IntPtr.Zero;
+ m_NoColide = false;
- m_taintserial = null;
+// m_taintserial = null;
m_primName = primName;
m_taintadd = true;
_parent_scene.AddPhysicsActorTaint(this);
@@ -814,7 +413,6 @@ namespace OpenSim.Region.Physics.OdePlugin
{
set
{
-
//Console.WriteLine("Sel {0} {1} {2}", m_primName, value, m_isphysical);
// This only makes the object not collidable if the object
// is physical or the object is modified somehow *IN THE FUTURE*
@@ -1077,7 +675,6 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
-
public override bool FloatOnWater
{
set
@@ -1270,7 +867,6 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
-
public void SetGeom(IntPtr geom)
{
if (prim_geom != IntPtr.Zero)
@@ -1290,9 +886,25 @@ namespace OpenSim.Region.Physics.OdePlugin
{
_parent_scene.geom_name_map[prim_geom] = this.m_primName;
_parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this;
- d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
//Console.WriteLine("**** Create {2} Dicts: actor={0} name={1}", _parent_scene.actor_name_map.Count, _parent_scene.geom_name_map.Count, this.m_primName);
+ if (m_NoColide)
+ {
+ d.GeomSetCategoryBits(prim_geom, 0);
+ if (m_isphysical)
+ {
+ d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
+ }
+ else
+ {
+ d.GeomSetCollideBits(prim_geom, 0);
+ d.GeomDisable(prim_geom);
+ }
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
+ d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ }
}
if (childPrim)
@@ -1351,11 +963,20 @@ namespace OpenSim.Region.Physics.OdePlugin
myrot.W = _orientation.W;
d.BodySetQuaternion(Body, ref myrot);
d.GeomSetBody(prim_geom, Body);
+
m_collisionCategories |= CollisionCategories.Body;
m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
- d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ if (m_NoColide)
+ {
+ d.GeomSetCategoryBits(prim_geom, 0);
+ d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
+ d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ }
d.BodySetAutoDisableFlag(Body, true);
d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
@@ -1723,11 +1344,19 @@ namespace OpenSim.Region.Physics.OdePlugin
if (prim_geom != IntPtr.Zero)
{
- d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ if (m_NoColide)
+ {
+ d.GeomSetCategoryBits(prim_geom, 0);
+ d.GeomSetCollideBits(prim_geom, 0);
+ d.GeomDisable(prim_geom);
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
+ d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ }
}
-
d.BodyDestroy(Body);
lock (childrenPrim)
{
@@ -1735,6 +1364,13 @@ namespace OpenSim.Region.Physics.OdePlugin
{
foreach (OdePrim prm in childrenPrim)
{
+ if (prm.m_NoColide && prm.prim_geom != IntPtr.Zero)
+ {
+ d.GeomSetCategoryBits(prm.prim_geom, 0);
+ d.GeomSetCollideBits(prm.prim_geom, 0);
+ d.GeomDisable(prm.prim_geom);
+ }
+
_parent_scene.remActivePrim(prm);
prm.Body = IntPtr.Zero;
}
@@ -1752,8 +1388,18 @@ namespace OpenSim.Region.Physics.OdePlugin
if (prim_geom != IntPtr.Zero)
{
- d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ if (m_NoColide)
+ {
+ d.GeomSetCategoryBits(prim_geom, 0);
+ d.GeomSetCollideBits(prim_geom, 0);
+ d.GeomDisable(prim_geom);
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
+ d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ }
+
}
@@ -1768,11 +1414,6 @@ namespace OpenSim.Region.Physics.OdePlugin
public bool setMesh(OdeScene parent_scene, IMesh mesh)
{
- // This sleeper is there to moderate how long it takes between
- // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object
-
- //Thread.Sleep(10);
-
//Kill Body so that mesh can re-make the geom
if (IsPhysical && Body != IntPtr.Zero)
{
@@ -1790,14 +1431,6 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
-// do it on caller instead
-/*
- if (_triMeshData != IntPtr.Zero)
- {
- d.GeomTriMeshDataDestroy(_triMeshData);
- _triMeshData = IntPtr.Zero;
- }
-*/
IntPtr vertices, indices;
int vertexCount, indexCount;
int vertexStride, triStride;
@@ -1809,38 +1442,20 @@ namespace OpenSim.Region.Physics.OdePlugin
if (vertexCount == 0 || indexCount == 0)
{
- 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);
- _size.X = 0.05f;
- _size.Y = 0.05f;
- _size.Z = 0.05f;
+ 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());
return false;
}
-/*
- if (m_MeshToTriMeshMap.ContainsKey(mesh))
- {
- _triMeshData = m_MeshToTriMeshMap[mesh];
- }
- else
-*/
-
-
- {
- _triMeshData = d.GeomTriMeshDataCreate();
-
- d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
- d.GeomTriMeshDataPreprocess(_triMeshData);
-// m_MeshToTriMeshMap[mesh] = _triMeshData;
- }
-
- _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ IntPtr geo = IntPtr.Zero;
try
{
- // if (prim_geom == IntPtr.Zero) // setGeom takes care of phys engine recreate and prim_geom pointer
- // {
- // SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null));
- SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null));
- // }
+ _triMeshData = d.GeomTriMeshDataCreate();
+ d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
+ d.GeomTriMeshDataPreprocess(_triMeshData);
+
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+
+ geo = d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null);
}
catch (Exception e)
{
@@ -1851,21 +1466,11 @@ namespace OpenSim.Region.Physics.OdePlugin
d.GeomTriMeshDataDestroy(_triMeshData);
_triMeshData = IntPtr.Zero;
}
- _size.X = 0.05f;
- _size.Y = 0.05f;
- _size.Z = 0.05f;
return false;
}
+ SetGeom(geo);
- // if (IsPhysical && Body == (IntPtr) 0)
- // {
- // Recreate the body
- // m_interpenetrationcount = 0;
- // m_collisionscore = 0;
-
- // enableBody();
- // }
return true;
}
@@ -1943,18 +1548,21 @@ namespace OpenSim.Region.Physics.OdePlugin
if (m_taintvehicledata != null)
DoSetVehicle();
- if (m_taintserial != null)
- DoSerialize(m_taintserial);
-
/* obsolete
if (!m_angularLock.ApproxEquals(m_taintAngularLock,0f))
changeAngularLock(timestep);
*/
}
+
else
{
- 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.)");
+ m_log.Error("[PHYSICS]: prim {0} at <{1},{2},{3}> as invalid geom");
+
+ // not sure this will not flame...
+ m_taintremove = true;
+ _parent_scene.AddPhysicsActorTaint(this);
}
+
}
/* obsolete
@@ -2058,7 +1666,6 @@ namespace OpenSim.Region.Physics.OdePlugin
}
foreach (OdePrim prm in childrenPrim)
{
-
prm.m_collisionCategories |= CollisionCategories.Body;
prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
@@ -2067,9 +1674,17 @@ namespace OpenSim.Region.Physics.OdePlugin
m_log.Warn("[PHYSICS]: Unable to link one of the linkset elements. No geom yet");
continue;
}
- d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories);
- d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags);
+ if (prm.m_NoColide)
+ {
+ d.GeomSetCategoryBits(prm.prim_geom, 0);
+ d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories);
+ d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags);
+ }
d.Quaternion quat = new d.Quaternion();
quat.W = prm._orientation.W;
@@ -2098,20 +1713,28 @@ namespace OpenSim.Region.Physics.OdePlugin
m_log.Debug("[PHYSICS]:I ain't got no boooooooooddy, no body");
}
-
prm.m_interpenetrationcount = 0;
prm.m_collisionscore = 0;
prm.m_disabled = false;
prm.Body = Body;
- _parent_scene.addActivePrim(prm);
+
+ _parent_scene.addActivePrim(prm);
}
+
m_collisionCategories |= CollisionCategories.Body;
m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
- d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
-
+ if (m_NoColide)
+ {
+ d.GeomSetCategoryBits(prim_geom, 0);
+ d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
+ d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ }
d.Quaternion quat2 = new d.Quaternion();
quat2.W = _orientation.W;
@@ -2134,19 +1757,18 @@ namespace OpenSim.Region.Physics.OdePlugin
d.BodySetAutoDisableFlag(Body, true);
d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
-
m_interpenetrationcount = 0;
m_collisionscore = 0;
m_disabled = false;
d.BodySetPosition(Body, Position.X, Position.Y, Position.Z);
if (m_type != Vehicle.TYPE_NONE) Enable(Body, _parent_scene);
+
_parent_scene.addActivePrim(this);
}
}
}
}
-
}
private void ChildSetGeom(OdePrim odePrim)
@@ -2258,6 +1880,8 @@ namespace OpenSim.Region.Physics.OdePlugin
{
d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ if (m_NoColide)
+ d.GeomDisable(prim_geom);
}
if (m_isphysical)
@@ -2275,22 +1899,35 @@ namespace OpenSim.Region.Physics.OdePlugin
}
else
{
- m_collisionCategories = CollisionCategories.Geom;
+ m_collisionCategories = CollisionCategories.Geom;
+ if (m_isphysical)
+ m_collisionCategories |= CollisionCategories.Body;
- if (m_isphysical)
- m_collisionCategories |= CollisionCategories.Body;
+ m_collisionFlags = m_default_collisionFlags;
- m_collisionFlags = m_default_collisionFlags;
-
- if (m_collidesLand)
- m_collisionFlags |= CollisionCategories.Land;
- if (m_collidesWater)
- m_collisionFlags |= CollisionCategories.Water;
+ if (m_collidesLand)
+ m_collisionFlags |= CollisionCategories.Land;
+ if (m_collidesWater)
+ m_collisionFlags |= CollisionCategories.Water;
if (prim_geom != IntPtr.Zero)
{
- d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ if (m_NoColide)
+ {
+ d.GeomSetCategoryBits(prim_geom, 0);
+ if (m_isphysical)
+ d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
+ else
+ {
+ d.GeomSetCollideBits(prim_geom, 0);
+ d.GeomDisable(prim_geom);
+ }
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
+ d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ }
}
if (Body != IntPtr.Zero)
{
@@ -2330,19 +1967,29 @@ namespace OpenSim.Region.Physics.OdePlugin
{
bool gottrimesh = false;
+ m_NoColide = false; // assume all will go well
+
if (_triMeshData != IntPtr.Zero)
{
d.GeomTriMeshDataDestroy(_triMeshData);
_triMeshData = IntPtr.Zero;
}
- if (_mesh != null) // Special - make mesh
+ if (_mesh != null)
{
gottrimesh = setMesh(_parent_scene, _mesh);
+ if (!gottrimesh)
+ {
+ // getting a mesh failed,
+ // lets go on having a basic box or sphere, with prim size but not coliding
+ // physical colides with land, non with nothing
+
+ m_NoColide = true;
+ }
}
- if (!gottrimesh) // not a mesh
- {
+ if (!gottrimesh)
+ { // we will have a basic box or sphere
IntPtr geo = IntPtr.Zero;
if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1
@@ -2376,14 +2023,17 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
- if (geo == IntPtr.Zero)
+ if (geo == IntPtr.Zero) // if this happens it must be fixed
{
+ // if it does lets stop what we can
+ // not sure this will not flame...
+
m_taintremove = true;
_parent_scene.AddPhysicsActorTaint(this);
return;
}
- SetGeom(geo);
+ SetGeom(geo); // this processes the m_NoColide
}
}
@@ -2415,7 +2065,6 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
-
lock (_parent_scene.OdeLock)
{
CreateGeom(m_targetSpace, _mesh);
@@ -2518,8 +2167,6 @@ namespace OpenSim.Region.Physics.OdePlugin
m_taintposition = _position;
}
-
-
public void rotate(float timestep)
{
d.Quaternion myrot = new d.Quaternion();
diff --git a/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs
index 7a1e671e99..5f5d5470c8 100644
--- a/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs
@@ -1735,7 +1735,7 @@ namespace OpenSim.Region.Physics.OdePlugin
return newPrim;
}
-
+/*
private PhysicsActor AddPrim(String name, Vector3 position, PhysicsActor parent,
PrimitiveBaseShape pbs, uint localid, byte[] sdata)
{
@@ -1751,7 +1751,7 @@ namespace OpenSim.Region.Physics.OdePlugin
return newPrim;
}
-
+*/
public void addActivePrim(OdePrim activatePrim)
{
@@ -1778,7 +1778,7 @@ namespace OpenSim.Region.Physics.OdePlugin
return result;
}
-
+/*
public override PhysicsActor AddPrimShape(string primName, PhysicsActor parent, PrimitiveBaseShape pbs, Vector3 position,
uint localid, byte[] sdata)
{
@@ -1789,7 +1789,7 @@ namespace OpenSim.Region.Physics.OdePlugin
return result;
}
-
+*/
public override float TimeDilation
{
get { return m_timeDilation; }
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
index f525e9e51e..1a0c2a76c1 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
@@ -72,11 +72,13 @@ namespace OpenSim.Region.Physics.Manager
{
public float mu;
public float bounce;
+ public bool softcolide;
- public ContactData(float _mu, float _bounce)
+ public ContactData(float _mu, float _bounce, bool _softcolide)
{
mu = _mu;
bounce = _bounce;
+ softcolide = _softcolide;
}
}
///
@@ -158,9 +160,10 @@ namespace OpenSim.Region.Physics.Manager
public virtual bool Building { get; set; }
- public virtual ContactData ContactData
+ public virtual void getContactData(ref ContactData cdata)
{
- get { return new ContactData(0, 0); }
+ cdata.mu = 0;
+ cdata.bounce = 0;
}
public abstract bool Stopped { get; }
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
index 793e281894..9a22331820 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs
@@ -136,7 +136,8 @@ namespace OpenSim.Region.Physics.OdePlugin
public UUID m_uuid;
public bool bad = false;
- public ContactData AvatarContactData = new ContactData(10f, 0.3f);
+ float mu;
+ float bounce;
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)
{
@@ -168,8 +169,8 @@ namespace OpenSim.Region.Physics.OdePlugin
m_density = density;
m_mass = 80f; // sure we have a default
- AvatarContactData.mu = parent_scene.AvatarFriction;
- AvatarContactData.bounce = parent_scene.AvatarBounce;
+ mu = parent_scene.AvatarFriction;
+ bounce = parent_scene.AvatarBounce;
walkDivisor = walk_divisor;
runDivisor = rundivisor;
@@ -190,9 +191,11 @@ namespace OpenSim.Region.Physics.OdePlugin
set { return; }
}
- public override ContactData ContactData
+ public override void getContactData(ref ContactData cdata)
{
- get { return AvatarContactData; }
+ cdata.mu = mu;
+ cdata.bounce = bounce;
+ cdata.softcolide = false;
}
public override bool Building { get; set; }
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs
index c9d0909a60..d0b45467a1 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs
@@ -38,7 +38,7 @@
* settings use.
*/
-// Ubit 2012
+// Extensive change Ubit 2012
using System;
using System.Collections.Generic;
@@ -119,7 +119,15 @@ namespace OpenSim.Region.Physics.OdePlugin
// auxiliar
private float m_lmEfect = 0; // current linear motor eficiency
private float m_amEfect = 0; // current angular motor eficiency
+ private float m_ffactor = 1.0f;
+ public float FrictionFactor
+ {
+ get
+ {
+ return m_ffactor;
+ }
+ }
public ODEDynamics(OdePrim rootp)
{
@@ -127,7 +135,6 @@ namespace OpenSim.Region.Physics.OdePlugin
_pParentScene = rootPrim._parent_scene;
}
-
public void DoSetVehicle(VehicleData vd)
{
@@ -152,6 +159,7 @@ namespace OpenSim.Region.Physics.OdePlugin
m_linearMotorTimescale = vd.m_linearMotorTimescale;
if (m_linearMotorTimescale < timestep) m_linearMotorTimescale = timestep;
+
m_linearMotorOffset = vd.m_linearMotorOffset;
//Angular properties
@@ -201,6 +209,7 @@ namespace OpenSim.Region.Physics.OdePlugin
m_lmEfect = 0;
m_amEfect = 0;
+ m_ffactor = 1.0f;
}
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
@@ -318,6 +327,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (len > 30.0f)
m_linearMotorDirection *= (30.0f / len);
m_lmEfect = 1.0f; // turn it on
+ m_ffactor = 0.01f;
if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
&& !rootPrim.m_isSelected && !rootPrim.m_disabled)
d.BodyEnable(rootPrim.Body);
@@ -368,6 +378,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (len > 30.0f)
m_linearMotorDirection *= (30.0f / len);
m_lmEfect = 1.0f; // turn it on
+ m_ffactor = 0.01f;
if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
&& !rootPrim.m_isSelected && !rootPrim.m_disabled)
d.BodyEnable(rootPrim.Body);
@@ -414,6 +425,7 @@ namespace OpenSim.Region.Physics.OdePlugin
float invtimestep = _pParentScene.ODE_STEPSIZE;
m_lmEfect = 0;
m_amEfect = 0;
+ m_ffactor = 1f;
m_linearMotorDirection = Vector3.Zero;
m_angularMotorDirection = Vector3.Zero;
@@ -591,6 +603,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{
m_lmEfect = 0;
m_amEfect = 0;
+ m_ffactor = 1f;
}
public static Vector3 Xrot(Quaternion rot)
@@ -614,6 +627,7 @@ namespace OpenSim.Region.Physics.OdePlugin
return vec;
}
+ private const float pi = (float)Math.PI;
private const float halfpi = 0.5f * (float)Math.PI;
public static Vector3 ubitRot2Euler(Quaternion rot)
@@ -740,9 +754,14 @@ namespace OpenSim.Region.Physics.OdePlugin
force.Z += tmpV.Z;
}
m_lmEfect *= (1.0f - 1.0f / m_linearMotorDecayTimescale);
+
+ m_ffactor = 0.01f + 1e-4f * curVel.LengthSquared();
}
else
+ {
m_lmEfect = 0;
+ m_ffactor = 1f;
+ }
// friction
if (curLocalVel.X != 0 || curLocalVel.Y != 0 || curLocalVel.Z != 0)
@@ -884,35 +903,64 @@ namespace OpenSim.Region.Physics.OdePlugin
float ftmp = 1.0f / m_verticalAttractionTimescale / m_verticalAttractionTimescale / _pParentScene.ODE_STEPSIZE;
float ftmp2 = m_verticalAttractionEfficiency / _pParentScene.ODE_STEPSIZE;
- if (Math.Abs(roll) > 0.01) // roll
+ if (roll > halfpi)
+ roll = pi - roll;
+ else if (roll < -halfpi)
+ roll = -pi - roll;
+
+ float effroll = pitch / halfpi;
+ effroll *= effroll;
+ effroll = 1 - effroll;
+ effroll *= roll;
+
+ if (Math.Abs(effroll) > 0.01) // roll
{
- torque.X -= -roll * ftmp + curLocalAngVel.X * ftmp2;
+ torque.X -= -effroll * ftmp + curLocalAngVel.X * ftmp2;
}
- if (Math.Abs(pitch) > 0.01 && ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) == 0)) // pitch
+ if ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) == 0)
{
- torque.Y -= -pitch * ftmp + curLocalAngVel.Y * ftmp2;
+ float effpitch = roll / halfpi;
+ effpitch *= effpitch;
+ effpitch = 1 - effpitch;
+ effpitch *= pitch;
+
+ if (Math.Abs(effpitch) > 0.01) // pitch
+ {
+ torque.Y -= -effpitch * ftmp + curLocalAngVel.Y * ftmp2;
+ }
}
- if (m_bankingEfficiency != 0 && Math.Abs(roll) > 0.01)
+ if (m_bankingEfficiency != 0 && Math.Abs(effroll) > 0.01)
{
- float broll = roll * m_bankingEfficiency; ;
+
+ float broll = effroll;
+/*
+ if (broll > halfpi)
+ broll = pi - broll;
+ else if (broll < -halfpi)
+ broll = -pi - broll;
+*/
+ broll *= m_bankingEfficiency;
if (m_bankingMix != 0)
{
float vfact = Math.Abs(curLocalVel.X) / 10.0f;
if (vfact > 1.0f) vfact = 1.0f;
- if (curLocalVel.X >= 0)
- broll *= ((1 - m_bankingMix) + vfact);
- else
- broll *= -((1 - m_bankingMix) + vfact);
- }
- broll = (broll - curLocalAngVel.Z) / m_bankingTimescale;
- // torque.Z += broll;
+ if (curLocalVel.X >= 0)
+ broll *= (1 + (vfact - 1) * m_bankingMix);
+ else
+ broll *= -(1 + (vfact - 1) * m_bankingMix);
+ }
// make z rot be in world Z not local as seems to be in sl
- tmpV.X = 0;
- tmpV.Y = 0;
- tmpV.Z = broll;
+
+ broll = broll / m_bankingTimescale;
+
+ ftmp = -Math.Abs(m_bankingEfficiency) / m_bankingTimescale;
+
+ tmpV.X = ftmp * curAngVel.X;
+ tmpV.Y = ftmp * curAngVel.Y;
+ tmpV.Z = broll + ftmp * curAngVel.Z;
tmpV *= irotq;
torque.X += tmpV.X;
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index 0ccdbc0d3a..b105f77da7 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
@@ -114,6 +114,9 @@ namespace OpenSim.Region.Physics.OdePlugin
// private bool m_collidesLand = true;
private bool m_collidesWater;
public bool m_returnCollisions;
+ private bool m_softcolide;
+
+ private bool m_NoColide; // for now only for internal use for bad meshs
// Default we're a Geometry
private CollisionCategories m_collisionCategories = (CollisionCategories.Geom);
@@ -155,6 +158,8 @@ namespace OpenSim.Region.Physics.OdePlugin
public float m_collisionscore;
int m_colliderfilter = 0;
+ public IntPtr collide_geom; // for objects: geom if single prim space it linkset
+
private float m_density = 10.000006836f; // Aluminum g/cm3;
public bool _zeroFlag;
@@ -185,7 +190,8 @@ namespace OpenSim.Region.Physics.OdePlugin
public ODEDynamics m_vehicle;
internal int m_material = (int)Material.Wood;
- protected ContactData primContactData = new ContactData { mu = 0f, bounce = 0.1f };
+ private float mu;
+ private float bounce;
///
/// 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
}
}
- public override ContactData ContactData
+ public override void getContactData(ref ContactData cdata)
{
- get
+ cdata.mu = mu;
+ cdata.bounce = bounce;
+
+ // cdata.softcolide = m_softcolide;
+ cdata.softcolide = false;
+
+ if (m_isphysical)
{
- return primContactData;
+ ODEDynamics veh;
+ if (_parent != null)
+ veh = ((OdePrim)_parent).m_vehicle;
+ else
+ veh = m_vehicle;
+
+ if (veh != null && veh.Type != Vehicle.TYPE_NONE)
+ cdata.mu *= veh.FrictionFactor;
}
- }
+ }
public override int PhysicsActorType
{
@@ -290,7 +309,10 @@ namespace OpenSim.Region.Physics.OdePlugin
}
if (m_colliderfilter == 0)
+ {
+ m_softcolide = false;
m_iscolliding = false;
+ }
else
m_iscolliding = true;
}
@@ -453,8 +475,6 @@ namespace OpenSim.Region.Physics.OdePlugin
{
get
{
- // Averate previous velocity with the new one so
- // client object interpolation works a 'little' better
if (_zeroFlag)
return Vector3.Zero;
return _velocity;
@@ -733,8 +753,8 @@ namespace OpenSim.Region.Physics.OdePlugin
public override void SetMaterial(int pMaterial)
{
m_material = pMaterial;
- primContactData.mu = _parent_scene.m_materialContactsData[pMaterial].mu;
- primContactData.bounce = _parent_scene.m_materialContactsData[pMaterial].bounce;
+ mu = _parent_scene.m_materialContactsData[pMaterial].mu;
+ bounce = _parent_scene.m_materialContactsData[pMaterial].bounce;
}
public void setPrimForRemoval()
@@ -833,6 +853,7 @@ namespace OpenSim.Region.Physics.OdePlugin
body_autodisable_frames = parent_scene.bodyFramesAutoDisable;
prim_geom = IntPtr.Zero;
+ collide_geom = IntPtr.Zero;
Body = IntPtr.Zero;
if (!size.IsFinite())
@@ -847,7 +868,6 @@ namespace OpenSim.Region.Physics.OdePlugin
_size = size;
-
if (!QuaternionIsFinite(rotation))
{
rotation = Quaternion.Identity;
@@ -878,6 +898,8 @@ namespace OpenSim.Region.Physics.OdePlugin
m_iscolliding = false;
m_colliderfilter = 0;
+ m_softcolide = true;
+ m_NoColide = false;
hasOOBoffsetFromMesh = false;
_triMeshData = IntPtr.Zero;
@@ -886,8 +908,8 @@ namespace OpenSim.Region.Physics.OdePlugin
m_isSelected = false;
m_delaySelect = false;
- primContactData.mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu;
- primContactData.bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce;
+ mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu;
+ bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce;
CalcPrimBodyData();
@@ -1025,34 +1047,42 @@ namespace OpenSim.Region.Physics.OdePlugin
if (vertexCount == 0 || indexCount == 0)
{
- 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);
- _size.X = 0.01f;
- _size.Y = 0.01f;
- _size.Z = 0.01f;
+ 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());
+ mesh.releaseSourceMeshData();
return false;
}
primOOBoffset = mesh.GetCentroid();
hasOOBoffsetFromMesh = true;
- _triMeshData = d.GeomTriMeshDataCreate();
-
- d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
- d.GeomTriMeshDataPreprocess(_triMeshData);
-
mesh.releaseSourceMeshData();
- _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ IntPtr geo = IntPtr.Zero;
+
try
{
- SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null));
+ _triMeshData = d.GeomTriMeshDataCreate();
+
+ d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
+ d.GeomTriMeshDataPreprocess(_triMeshData);
+
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ geo = d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null);
}
catch (Exception e)
{
m_log.ErrorFormat("[PHYSICS]: SetGeom Mesh failed for {0} exception: {1}", Name, e);
+ if (_triMeshData != IntPtr.Zero)
+ {
+ d.GeomTriMeshDataDestroy(_triMeshData);
+ _triMeshData = IntPtr.Zero;
+ }
return false;
}
+
+ SetGeom(geo);
return true;
}
@@ -1062,25 +1092,30 @@ namespace OpenSim.Region.Physics.OdePlugin
//Console.WriteLine("SetGeom to " + prim_geom + " for " + Name);
if (prim_geom != IntPtr.Zero)
{
- d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ if (m_NoColide)
+ {
+ d.GeomSetCategoryBits(prim_geom, 0);
+ if (m_isphysical)
+ {
+ d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
+ }
+ else
+ {
+ d.GeomSetCollideBits(prim_geom, 0);
+ d.GeomDisable(prim_geom);
+ }
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
+ d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ }
CalcPrimBodyData();
_parent_scene.geom_name_map[prim_geom] = Name;
_parent_scene.actor_name_map[prim_geom] = this;
- /*
- if (childPrim)
- {
- if (_parent != null && _parent is OdePrim)
- {
- OdePrim parent = (OdePrim)_parent;
- //Console.WriteLine("SetGeom calls ChildSetGeom");
- parent.ChildSetGeom(this);
- }
- }
- */
}
else
m_log.Warn("Setting bad Geom");
@@ -1102,10 +1137,13 @@ namespace OpenSim.Region.Physics.OdePlugin
bool haveMesh = false;
hasOOBoffsetFromMesh = false;
+ m_NoColide = false;
if (_parent_scene.needsMeshing(_pbs))
{
haveMesh = setMesh(_parent_scene); // this will give a mesh to non trivial known prims
+ if (!haveMesh)
+ m_NoColide = true;
}
if (!haveMesh)
@@ -1197,12 +1235,46 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (!childPrim && !m_isSelected)
{
- if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero)
+ if (m_isphysical && Body != IntPtr.Zero)
{
- d.GeomEnable(prim_geom);
- foreach (OdePrim prm in childrenPrim)
- d.GeomEnable(prm.prim_geom);
+ m_collisionCategories |= CollisionCategories.Body;
+ m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
+ foreach (OdePrim prm in childrenPrim)
+ {
+ prm.m_collisionCategories = m_collisionCategories;
+ prm.m_collisionFlags = m_collisionFlags;
+
+ if (prm.prim_geom != IntPtr.Zero)
+ {
+ if (prm.m_NoColide)
+ {
+ d.GeomSetCategoryBits(prm.prim_geom, 0);
+ d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
+ d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
+ }
+ d.GeomEnable(prm.prim_geom);
+ }
+ }
+
+ if (prim_geom != IntPtr.Zero)
+ {
+ if (m_NoColide)
+ {
+ d.GeomSetCategoryBits(prim_geom, 0);
+ d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
+ d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ }
+ d.GeomEnable(prim_geom);
+ }
d.BodyEnable(Body);
}
}
@@ -1215,11 +1287,47 @@ namespace OpenSim.Region.Physics.OdePlugin
m_disabled = true;
if (!childPrim)
{
- if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero)
+ if (m_isphysical && Body != IntPtr.Zero)
{
- d.GeomDisable(prim_geom);
+ m_collisionCategories &= ~CollisionCategories.Body;
+ m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
+
foreach (OdePrim prm in childrenPrim)
- d.GeomDisable(prm.prim_geom);
+ {
+ prm.m_collisionCategories = m_collisionCategories;
+ prm.m_collisionFlags = m_collisionFlags;
+
+ if (prm.prim_geom != IntPtr.Zero)
+ {
+ if (prm.m_NoColide)
+ {
+ d.GeomSetCategoryBits(prm.prim_geom, 0);
+ d.GeomSetCollideBits(prm.prim_geom, 0);
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
+ d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
+ }
+ d.GeomDisable(prm.prim_geom);
+ }
+ }
+
+ if (prim_geom != IntPtr.Zero)
+ {
+ if (m_NoColide)
+ {
+ d.GeomSetCategoryBits(prim_geom, 0);
+ d.GeomSetCollideBits(prim_geom, 0);
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
+ d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ }
+ d.GeomDisable(prim_geom);
+ }
+
d.BodyDisable(Body);
}
}
@@ -1298,8 +1406,6 @@ namespace OpenSim.Region.Physics.OdePlugin
continue;
}
-
-
DMassCopy(ref prm.primdMass, ref tmpdmass);
// apply prim current rotation to inertia
@@ -1361,14 +1467,7 @@ namespace OpenSim.Region.Physics.OdePlugin
// d.BodySetAngularDampingThreshold(Body, 0.001f);
d.BodySetDamping(Body, .002f, .002f);
- m_collisionCategories |= CollisionCategories.Body;
- m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
- d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
- m_collisionscore = 0;
- if (m_targetSpace != _parent_scene.ActiveSpace)
- {
if (m_targetSpace != IntPtr.Zero)
{
_parent_scene.waitForSpaceUnlock(m_targetSpace);
@@ -1376,9 +1475,22 @@ namespace OpenSim.Region.Physics.OdePlugin
d.SpaceRemove(m_targetSpace, prim_geom);
}
+
+ if (childrenPrim.Count == 0)
+ {
+ collide_geom = prim_geom;
m_targetSpace = _parent_scene.ActiveSpace;
d.SpaceAdd(m_targetSpace, prim_geom);
}
+ else
+ {
+ m_targetSpace = d.HashSpaceCreate(_parent_scene.ActiveSpace);
+ d.HashSpaceSetLevels(m_targetSpace, -2, 8);
+ d.SpaceSetSublevel(m_targetSpace, 3);
+ d.SpaceSetCleanup(m_targetSpace, false);
+ d.SpaceAdd(m_targetSpace, prim_geom);
+ collide_geom = m_targetSpace;
+ }
lock (childrenPrim)
{
@@ -1390,28 +1502,45 @@ namespace OpenSim.Region.Physics.OdePlugin
Vector3 ppos = prm._position;
d.GeomSetOffsetWorldPosition(prm.prim_geom, ppos.X, ppos.Y, ppos.Z); // set relative position
- prm.m_collisionCategories |= CollisionCategories.Body;
- prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
- d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories);
- d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags);
- prm.m_collisionscore = 0;
-
- if (prm.m_targetSpace != _parent_scene.ActiveSpace)
+ if (prm.m_targetSpace != m_targetSpace)
{
if (prm.m_targetSpace != IntPtr.Zero)
{
- _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ _parent_scene.waitForSpaceUnlock(prm.m_targetSpace);
if (d.SpaceQuery(prm.m_targetSpace, prm.prim_geom))
d.SpaceRemove(prm.m_targetSpace, prm.prim_geom);
}
- prm.m_targetSpace = _parent_scene.ActiveSpace;
+ prm.m_targetSpace = m_targetSpace;
d.SpaceAdd(m_targetSpace, prm.prim_geom);
}
if (m_isSelected || m_disabled)
+ {
+ prm.m_collisionCategories &= ~CollisionCategories.Body;
+ prm.m_collisionFlags &= ~(CollisionCategories.Land | CollisionCategories.Wind);
d.GeomDisable(prm.prim_geom);
+ }
+ else
+ {
+ prm.m_collisionCategories |= CollisionCategories.Body;
+ prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
+ }
+
+ if (prm.m_NoColide)
+ {
+ d.GeomSetCategoryBits(prm.prim_geom, 0);
+ d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
+ d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
+ }
+ prm.m_collisionscore = 0;
+
+ if(!m_disabled)
+ prm.m_disabled = false;
- prm.m_disabled = false;
_parent_scene.addActivePrim(prm);
}
}
@@ -1424,11 +1553,37 @@ namespace OpenSim.Region.Physics.OdePlugin
if (m_isSelected || m_disabled)
{
+ m_collisionCategories &= ~CollisionCategories.Body;
+ m_collisionFlags &= ~(CollisionCategories.Land | CollisionCategories.Wind);
+
d.GeomDisable(prim_geom);
d.BodyDisable(Body);
}
+ else
+ {
+ m_collisionCategories |= CollisionCategories.Body;
+ m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
+ d.BodySetAngularVel(Body, m_rotationalVelocity.X, m_rotationalVelocity.Y, m_rotationalVelocity.Z);
+ d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z);
+ }
+
+ if (m_NoColide)
+ {
+ d.GeomSetCategoryBits(prim_geom, 0);
+ d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
+ d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ }
+
+ m_collisionscore = 0;
+
+ m_softcolide = true;
_parent_scene.addActivePrim(this);
+ _parent_scene.addActiveGroups(this);
}
private void DestroyBody()
@@ -1440,8 +1595,16 @@ namespace OpenSim.Region.Physics.OdePlugin
m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
if (prim_geom != IntPtr.Zero)
{
- d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ if (m_NoColide)
+ {
+ d.GeomSetCategoryBits(prim_geom, 0);
+ d.GeomSetCollideBits(prim_geom, 0);
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
+ d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ }
UpdateDataFromGeom();
d.GeomSetBody(prim_geom, IntPtr.Zero);
SetInStaticSpace(this);
@@ -1454,12 +1617,20 @@ namespace OpenSim.Region.Physics.OdePlugin
foreach (OdePrim prm in childrenPrim)
{
_parent_scene.remActivePrim(prm);
- prm.m_collisionCategories &= ~CollisionCategories.Body;
- prm.m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
+ prm.m_collisionCategories = m_collisionCategories;
+ prm.m_collisionFlags = m_collisionFlags;
if (prm.prim_geom != IntPtr.Zero)
{
- d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
- d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
+ if (prm.m_NoColide)
+ {
+ d.GeomSetCategoryBits(prm.prim_geom, 0);
+ d.GeomSetCollideBits(prm.prim_geom, 0);
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
+ d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
+ }
prm.UpdateDataFromGeom();
SetInStaticSpace(prm);
}
@@ -1473,6 +1644,7 @@ namespace OpenSim.Region.Physics.OdePlugin
d.JointDestroy(Amotor);
Amotor = IntPtr.Zero;
}
+ _parent_scene.remActiveGroup(this);
d.BodyDestroy(Body);
}
Body = IntPtr.Zero;
@@ -2008,23 +2180,14 @@ namespace OpenSim.Region.Physics.OdePlugin
myrot.Z = _orientation.Z;
myrot.W = _orientation.W;
d.GeomSetQuaternion(prim_geom, ref myrot);
- // _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this;
+
if (!m_isphysical)
SetInStaticSpace(this);
}
if (m_isphysical && Body == IntPtr.Zero)
{
- /*
- if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
- {
- changeShape(_pbs);
- }
- else
- {
- */
MakeBody();
- // }
}
}
@@ -2133,17 +2296,52 @@ namespace OpenSim.Region.Physics.OdePlugin
if (!childPrim && Body != IntPtr.Zero)
d.BodyDisable(Body);
- if (m_delaySelect)
+ if (m_delaySelect || m_isphysical)
{
+ m_collisionCategories = CollisionCategories.Selected;
+ m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space);
+
if (!childPrim)
{
foreach (OdePrim prm in childrenPrim)
{
- d.GeomDisable(prm.prim_geom);
+ prm.m_collisionCategories = m_collisionCategories;
+ prm.m_collisionFlags = m_collisionFlags;
+
+ if (prm.prim_geom != null)
+ {
+
+ if (prm.m_NoColide)
+ {
+ d.GeomSetCategoryBits(prm.prim_geom, 0);
+ d.GeomSetCollideBits(prm.prim_geom, 0);
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
+ d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
+ }
+ d.GeomDisable(prm.prim_geom);
+ }
prm.m_delaySelect = false;
}
}
- d.GeomDisable(prim_geom);
+
+ if (prim_geom != null)
+ {
+ if (m_NoColide)
+ {
+ d.GeomSetCategoryBits(prim_geom, 0);
+ d.GeomSetCollideBits(prim_geom, 0);
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
+ d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ }
+ d.GeomDisable(prim_geom);
+ }
+
m_delaySelect = false;
}
else
@@ -2156,19 +2354,64 @@ namespace OpenSim.Region.Physics.OdePlugin
if (!childPrim && Body != IntPtr.Zero && !m_disabled)
d.BodyEnable(Body);
+ m_collisionCategories = CollisionCategories.Geom;
+ if (m_isphysical)
+ m_collisionCategories |= CollisionCategories.Body;
+
+ m_collisionFlags = m_default_collisionFlags | CollisionCategories.Land;
+
+ if (m_collidesWater)
+ m_collisionFlags |= CollisionCategories.Water;
+
if (!childPrim)
{
foreach (OdePrim prm in childrenPrim)
{
- if(!prm.m_disabled)
+ prm.m_collisionCategories = m_collisionCategories;
+ prm.m_collisionFlags = m_collisionFlags;
+
+ if (!prm.m_disabled && prm.prim_geom != IntPtr.Zero)
+ {
+ if (prm.m_NoColide)
+ {
+ d.GeomSetCategoryBits(prm.prim_geom, 0);
+ if (m_isphysical)
+ d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land);
+ else
+ d.GeomSetCollideBits(prm.prim_geom, 0);
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories);
+ d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags);
+ }
d.GeomEnable(prm.prim_geom);
+ }
prm.m_delaySelect = false;
+ prm.m_softcolide = true;
}
}
- if(!m_disabled)
+
+ if (!m_disabled && prim_geom != IntPtr.Zero)
+ {
+ if (m_NoColide)
+ {
+ d.GeomSetCategoryBits(prim_geom, 0);
+ if (m_isphysical)
+ d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land);
+ else
+ d.GeomSetCollideBits(prim_geom, 0);
+ }
+ else
+ {
+ d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
+ d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
+ }
d.GeomEnable(prim_geom);
+ }
m_delaySelect = false;
+ m_softcolide = true;
}
resetCollisionAccounting();
@@ -2214,6 +2457,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (givefakepos < 0)
givefakepos = 0;
// changeSelectedStatus();
+ m_softcolide = true;
resetCollisionAccounting();
}
@@ -2266,6 +2510,7 @@ namespace OpenSim.Region.Physics.OdePlugin
givefakeori--;
if (givefakeori < 0)
givefakeori = 0;
+ m_softcolide = true;
resetCollisionAccounting();
}
@@ -2336,6 +2581,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (givefakeori < 0)
givefakeori = 0;
+ m_softcolide = true;
resetCollisionAccounting();
}
@@ -2390,8 +2636,8 @@ namespace OpenSim.Region.Physics.OdePlugin
else
*/
DestroyBody();
- Stop();
}
+ Stop();
}
}
@@ -2452,6 +2698,7 @@ namespace OpenSim.Region.Physics.OdePlugin
else
MakeBody();
+ m_softcolide = true;
resetCollisionAccounting();
}
@@ -2576,7 +2823,8 @@ namespace OpenSim.Region.Physics.OdePlugin
if ((bool)newbuilding)
{
m_building = true;
- DestroyBody();
+ if (!childPrim)
+ DestroyBody();
}
else
{
@@ -2648,12 +2896,95 @@ namespace OpenSim.Region.Physics.OdePlugin
public void Move()
{
if (!childPrim && m_isphysical && Body != IntPtr.Zero &&
- !m_disabled && !m_isSelected && d.BodyIsEnabled(Body) && !m_building) // KF: Only move root prims.
+ !m_disabled && !m_isSelected && d.BodyIsEnabled(Body) && !m_building && !m_outbounds)
+ // !m_disabled && !m_isSelected && !m_building && !m_outbounds)
{
- // if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); // KF add 161009
+// if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); // KF add 161009
float timestep = _parent_scene.ODE_STEPSIZE;
+ // check outside region
+ d.Vector3 lpos;
+ d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator
+
+ if (lpos.Z < -100 || lpos.Z > 100000f)
+ {
+ m_outbounds = true;
+
+ lpos.Z = Util.Clip(lpos.Z, -100f, 100000f);
+ _acceleration.X = 0;
+ _acceleration.Y = 0;
+ _acceleration.Z = 0;
+
+ _velocity.X = 0;
+ _velocity.Y = 0;
+ _velocity.Z = 0;
+ m_rotationalVelocity.X = 0;
+ m_rotationalVelocity.Y = 0;
+ m_rotationalVelocity.Z = 0;
+
+ d.BodySetLinearVel(Body, 0, 0, 0); // stop it
+ d.BodySetAngularVel(Body, 0, 0, 0); // stop it
+ d.BodySetPosition(Body, lpos.X, lpos.Y, lpos.Z); // put it somewhere
+ m_lastposition = _position;
+ m_lastorientation = _orientation;
+
+ base.RequestPhysicsterseUpdate();
+
+ m_throttleUpdates = false;
+ throttleCounter = 0;
+ _zeroFlag = true;
+
+ disableBodySoft(); // disable it and colisions
+ base.RaiseOutOfBounds(_position);
+ return;
+ }
+
+ if (lpos.X < 0f)
+ {
+ _position.X = Util.Clip(lpos.X, -2f, -0.1f);
+ m_outbounds = true;
+ }
+ else if(lpos.X > _parent_scene.WorldExtents.X)
+ {
+ _position.X = Util.Clip(lpos.X, _parent_scene.WorldExtents.X + 0.1f, _parent_scene.WorldExtents.X + 2f);
+ m_outbounds = true;
+ }
+ if (lpos.Y < 0f)
+ {
+ _position.Y = Util.Clip(lpos.Y, -2f, -0.1f);
+ m_outbounds = true;
+ }
+ else if(lpos.Y > _parent_scene.WorldExtents.Y)
+ {
+ _position.Y = Util.Clip(lpos.Y, _parent_scene.WorldExtents.Y + 0.1f, _parent_scene.WorldExtents.Y + 2f);
+ m_outbounds = true;
+ }
+
+ if(m_outbounds)
+ {
+ m_lastposition = _position;
+ m_lastorientation = _orientation;
+
+ d.Vector3 dtmp = d.BodyGetAngularVel(Body);
+ m_rotationalVelocity.X = dtmp.X;
+ m_rotationalVelocity.Y = dtmp.Y;
+ m_rotationalVelocity.Z = dtmp.Z;
+
+ dtmp = d.BodyGetLinearVel(Body);
+ _velocity.X = dtmp.X;
+ _velocity.Y = dtmp.Y;
+ _velocity.Z = dtmp.Z;
+
+ d.BodySetLinearVel(Body, 0, 0, 0); // stop it
+ d.BodySetAngularVel(Body, 0, 0, 0);
+ d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
+ disableBodySoft(); // stop collisions
+ base.RequestPhysicsterseUpdate();
+ return;
+ }
+
+
float fx = 0;
float fy = 0;
float fz = 0;
@@ -2862,7 +3193,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public void UpdatePositionAndVelocity(float simulatedtime)
{
// no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
- if (_parent == null && !m_disabled && !m_building)
+ if (_parent == null && !m_disabled && !m_building && !m_outbounds)
{
if (Body != IntPtr.Zero)
{
@@ -2872,64 +3203,6 @@ namespace OpenSim.Region.Physics.OdePlugin
d.Vector3 lpos;
d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator
- // we need to use root position since that's all the rest of scene uses
- if (lpos.X < 0f || lpos.X > _parent_scene.WorldExtents.X
- || lpos.Y < 0f || lpos.Y > _parent_scene.WorldExtents.Y
- )
- {
- // we are outside current region
- // we can't let it keeping moving and having colisions
- // since it can be stucked between something like terrain and edge
- // so lets stop and disable it until something else kicks it
-
- _position.X = Util.Clip(lpos.X, -0.2f, _parent_scene.WorldExtents.X + 0.2f);
- _position.Y = Util.Clip(lpos.Y, -0.2f, _parent_scene.WorldExtents.Y + 0.2f);
- _position.Z = Util.Clip(lpos.Z, -100f, 50000f);
-
- m_lastposition = _position;
-// m_lastorientation = _orientation;
-
- d.BodySetLinearVel(Body, 0, 0, 0); // stop it
-// d.BodySetAngularVel(Body, 0, 0, 0);
- d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
- disableBodySoft(); // stop collisions
- m_outbounds = true;
- base.RequestPhysicsterseUpdate();
- return;
- }
-
- if (lpos.Z < -100 || lpos.Z > 100000f)
- {
- lpos.Z = Util.Clip(lpos.Z, -100f, 50000f);
-
- _acceleration.X = 0;
- _acceleration.Y = 0;
- _acceleration.Z = 0;
-
- _velocity.X = 0;
- _velocity.Y = 0;
- _velocity.Z = 0;
- m_rotationalVelocity.X = 0;
- m_rotationalVelocity.Y = 0;
- m_rotationalVelocity.Z = 0;
-
- d.BodySetLinearVel(Body, 0, 0, 0); // stop it
- d.BodySetAngularVel(Body, 0, 0, 0); // stop it
- d.BodySetPosition(Body, lpos.X, lpos.Y, lpos.Z); // put it somewhere
- m_lastposition = _position;
- m_lastorientation = _orientation;
-
- base.RequestPhysicsterseUpdate();
-
- m_throttleUpdates = false;
- throttleCounter = 0;
- _zeroFlag = true;
-
- disableBodySoft(); // disable it and colisions
- base.RaiseOutOfBounds(_position);
-
- return;
- }
d.Quaternion ori;
d.GeomCopyQuaternion(prim_geom, out ori);
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index 6e4c373a56..14516f98ed 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -155,7 +155,7 @@ namespace OpenSim.Region.Physics.OdePlugin
private readonly ILog m_log;
// private Dictionary m_storedCollisions = new Dictionary();
- private int threadid = 0;
+// private int threadid = 0;
private Random fluidRandomizer = new Random(Environment.TickCount);
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
const float comumSoftContactERP = 0.1f;
const float comumContactCFM = 0.0001f;
- float frictionScale = 1.0f;
-
float frictionMovementMult = 0.3f;
float TerrainBounce = 0.1f;
- float TerrainFriction = 0.1f;
+ float TerrainFriction = 0.3f;
public float AvatarBounce = 0.3f;
public float AvatarFriction = 0;// 0.9f * 0.5f;
@@ -189,8 +187,8 @@ namespace OpenSim.Region.Physics.OdePlugin
internal IntPtr WaterGeom;
- public float avPIDD = 3200f; // make it visible
- public float avPIDP = 1400f; // make it visible
+ public float avPIDD = 2200f; // make it visible
+ public float avPIDP = 900f; // make it visible
private float avCapRadius = 0.37f;
private float avDensity = 3f;
private float avMovementDivisorWalk = 1.3f;
@@ -202,7 +200,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public bool forceSimplePrimMeshing = false;
public float meshSculptLOD = 32;
- public float MeshSculptphysicalLOD = 16;
+ public float MeshSculptphysicalLOD = 32;
public float geomDefaultDensity = 10.000006836f;
@@ -212,18 +210,18 @@ namespace OpenSim.Region.Physics.OdePlugin
public float bodyPIDD = 35f;
public float bodyPIDG = 25;
- public int geomCrossingFailuresBeforeOutofbounds = 6;
+// public int geomCrossingFailuresBeforeOutofbounds = 6;
public int bodyFramesAutoDisable = 20;
private float[] _watermap;
- private bool m_filterCollisions = true;
private d.NearCallback nearCallback;
private readonly HashSet _characters = new HashSet();
private readonly HashSet _prims = new HashSet();
private readonly HashSet _activeprims = new HashSet();
+ private readonly HashSet _activegroups = new HashSet();
public OpenSim.Framework.LocklessQueue ChangesQueue = new OpenSim.Framework.LocklessQueue();
@@ -387,9 +385,6 @@ namespace OpenSim.Region.Physics.OdePlugin
// Defaults
- avPIDD = 2200.0f;
- avPIDP = 900.0f;
-
int contactsPerCollision = 80;
if (m_config != null)
@@ -397,90 +392,86 @@ namespace OpenSim.Region.Physics.OdePlugin
IConfig physicsconfig = m_config.Configs["ODEPhysicsSettings"];
if (physicsconfig != null)
{
- gravityx = physicsconfig.GetFloat("world_gravityx", 0f);
- gravityy = physicsconfig.GetFloat("world_gravityy", 0f);
- gravityz = physicsconfig.GetFloat("world_gravityz", -9.8f);
+ gravityx = physicsconfig.GetFloat("world_gravityx", gravityx);
+ gravityy = physicsconfig.GetFloat("world_gravityy", gravityy);
+ gravityz = physicsconfig.GetFloat("world_gravityz", gravityz);
- metersInSpace = physicsconfig.GetFloat("meters_in_small_space", 29.9f);
+ metersInSpace = physicsconfig.GetFloat("meters_in_small_space", metersInSpace);
contactsurfacelayer = physicsconfig.GetFloat("world_contact_surface_layer", contactsurfacelayer);
- ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", 0.020f);
- m_physicsiterations = physicsconfig.GetInt("world_internal_steps_without_collisions", 10);
+ ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", ODE_STEPSIZE);
+ m_physicsiterations = physicsconfig.GetInt("world_internal_steps_without_collisions", m_physicsiterations);
avDensity = physicsconfig.GetFloat("av_density", avDensity);
- avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", 1.3f);
- avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", 0.8f);
- avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f);
+ avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", avMovementDivisorWalk);
+ avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", avMovementDivisorRun);
+ avCapRadius = physicsconfig.GetFloat("av_capsule_radius", avCapRadius);
- contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80);
+ contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", contactsPerCollision);
geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 3);
geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15);
- geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5);
+// geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5);
- geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", 10.000006836f);
- bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", 20);
+ geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity);
+ bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable);
- bodyPIDD = physicsconfig.GetFloat("body_pid_derivative", 35f);
- bodyPIDG = physicsconfig.GetFloat("body_pid_gain", 25f);
+ bodyPIDD = physicsconfig.GetFloat("body_pid_derivative", bodyPIDD);
+ bodyPIDG = physicsconfig.GetFloat("body_pid_gain", bodyPIDG);
forceSimplePrimMeshing = physicsconfig.GetBoolean("force_simple_prim_meshing", forceSimplePrimMeshing);
- meshSculptedPrim = physicsconfig.GetBoolean("mesh_sculpted_prim", true);
- meshSculptLOD = physicsconfig.GetFloat("mesh_lod", 32f);
- MeshSculptphysicalLOD = physicsconfig.GetFloat("mesh_physical_lod", 16f);
- m_filterCollisions = physicsconfig.GetBoolean("filter_collisions", false);
+ meshSculptedPrim = physicsconfig.GetBoolean("mesh_sculpted_prim", meshSculptedPrim);
+ meshSculptLOD = physicsconfig.GetFloat("mesh_lod", meshSculptLOD);
+ MeshSculptphysicalLOD = physicsconfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD);
if (Environment.OSVersion.Platform == PlatformID.Unix)
{
- avPIDD = physicsconfig.GetFloat("av_pid_derivative_linux", 2200.0f);
- avPIDP = physicsconfig.GetFloat("av_pid_proportional_linux", 900.0f);
+ avPIDD = physicsconfig.GetFloat("av_pid_derivative_linux", avPIDD);
+ avPIDP = physicsconfig.GetFloat("av_pid_proportional_linux", avPIDP);
}
else
{
- avPIDD = physicsconfig.GetFloat("av_pid_derivative_win", 2200.0f);
- avPIDP = physicsconfig.GetFloat("av_pid_proportional_win", 900.0f);
+ avPIDD = physicsconfig.GetFloat("av_pid_derivative_win", avPIDD);
+ avPIDP = physicsconfig.GetFloat("av_pid_proportional_win", avPIDP);
}
physics_logging = physicsconfig.GetBoolean("physics_logging", false);
physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0);
physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false);
- minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", 3f);
- maximumMassObject = physicsconfig.GetFloat("maximum_mass_object", 10000.01f);
+ minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", minimumGroundFlightOffset);
+ maximumMassObject = physicsconfig.GetFloat("maximum_mass_object", maximumMassObject);
}
}
ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf);
GlobalContactsArray = GlobalContactsArray = Marshal.AllocHGlobal(maxContactsbeforedeath * d.Contact.unmanagedSizeOf);
- m_materialContactsData[(int)Material.Stone].mu = frictionScale * 0.8f;
+ m_materialContactsData[(int)Material.Stone].mu = 0.8f;
m_materialContactsData[(int)Material.Stone].bounce = 0.4f;
- m_materialContactsData[(int)Material.Metal].mu = frictionScale * 0.3f;
+ m_materialContactsData[(int)Material.Metal].mu = 0.3f;
m_materialContactsData[(int)Material.Metal].bounce = 0.4f;
- m_materialContactsData[(int)Material.Glass].mu = frictionScale * 0.2f;
+ m_materialContactsData[(int)Material.Glass].mu = 0.2f;
m_materialContactsData[(int)Material.Glass].bounce = 0.7f;
- m_materialContactsData[(int)Material.Wood].mu = frictionScale * 0.6f;
+ m_materialContactsData[(int)Material.Wood].mu = 0.6f;
m_materialContactsData[(int)Material.Wood].bounce = 0.5f;
- m_materialContactsData[(int)Material.Flesh].mu = frictionScale * 0.9f;
+ m_materialContactsData[(int)Material.Flesh].mu = 0.9f;
m_materialContactsData[(int)Material.Flesh].bounce = 0.3f;
- m_materialContactsData[(int)Material.Plastic].mu = frictionScale * 0.4f;
+ m_materialContactsData[(int)Material.Plastic].mu = 0.4f;
m_materialContactsData[(int)Material.Plastic].bounce = 0.7f;
- m_materialContactsData[(int)Material.Rubber].mu = frictionScale * 0.9f;
+ m_materialContactsData[(int)Material.Rubber].mu = 0.9f;
m_materialContactsData[(int)Material.Rubber].bounce = 0.95f;
m_materialContactsData[(int)Material.light].mu = 0.0f;
m_materialContactsData[(int)Material.light].bounce = 0.0f;
- TerrainFriction *= frictionScale;
-// AvatarFriction *= frictionScale;
-
// Set the gravity,, don't disable things automatically (we set it explicitly on some things)
d.WorldSetGravity(world, gravityx, gravityy, gravityz);
@@ -566,13 +557,6 @@ namespace OpenSim.Region.Physics.OdePlugin
}
- ///
- /// This is our near callback. A geometry is near a body
- ///
- /// The space that contains the geoms. Remember, spaces are also geoms
- /// a geometry or space
- /// another geometry or space
- ///
private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom)
{
@@ -584,7 +568,13 @@ namespace OpenSim.Region.Physics.OdePlugin
return true;
}
-
+ ///
+ /// This is our near callback. A geometry is near a body
+ ///
+ /// The space that contains the geoms. Remember, spaces are also geoms
+ /// a geometry or space
+ /// another geometry or space
+ ///
private void near(IntPtr space, IntPtr g1, IntPtr g2)
{
@@ -703,8 +693,8 @@ namespace OpenSim.Region.Physics.OdePlugin
// big messy collision analises
float mu = 0;
float bounce = 0;
- ContactData contactdata1;
- ContactData contactdata2;
+ ContactData contactdata1 = new ContactData(0, 0, false);
+ ContactData contactdata2 = new ContactData(0, 0, false);
bool erpSoft = false;
String name = null;
@@ -718,8 +708,9 @@ namespace OpenSim.Region.Physics.OdePlugin
switch (p2.PhysicsActorType)
{
case (int)ActorTypes.Agent:
- contactdata1 = p1.ContactData;
- contactdata2 = p2.ContactData;
+ p1.getContactData(ref contactdata1);
+ p2.getContactData(ref contactdata2);
+
bounce = contactdata1.bounce * contactdata2.bounce;
mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu);
@@ -727,12 +718,13 @@ namespace OpenSim.Region.Physics.OdePlugin
if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f))
mu *= frictionMovementMult;
+ erpSoft = contactdata1.softcolide | contactdata2.softcolide;
p1.CollidingObj = true;
p2.CollidingObj = true;
break;
case (int)ActorTypes.Prim:
- contactdata1 = p1.ContactData;
- contactdata2 = p2.ContactData;
+ p1.getContactData(ref contactdata1);
+ p2.getContactData(ref contactdata2);
bounce = contactdata1.bounce * contactdata2.bounce;
mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu);
@@ -741,6 +733,9 @@ namespace OpenSim.Region.Physics.OdePlugin
mu *= frictionMovementMult;
if (p2.Velocity.LengthSquared() > 0.0f)
p2.CollidingObj = true;
+
+ erpSoft = contactdata1.softcolide | contactdata2.softcolide;
+
dop1foot = true;
break;
default:
@@ -753,8 +748,8 @@ namespace OpenSim.Region.Physics.OdePlugin
switch (p2.PhysicsActorType)
{
case (int)ActorTypes.Agent:
- contactdata1 = p1.ContactData;
- contactdata2 = p2.ContactData;
+ p1.getContactData(ref contactdata1);
+ p2.getContactData(ref contactdata2);
bounce = contactdata1.bounce * contactdata2.bounce;
mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu);
@@ -762,6 +757,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f))
mu *= frictionMovementMult;
+ erpSoft = contactdata1.softcolide | contactdata2.softcolide;
dop2foot = true;
if (p1.Velocity.LengthSquared() > 0.0f)
p1.CollidingObj = true;
@@ -772,10 +768,10 @@ namespace OpenSim.Region.Physics.OdePlugin
p1.CollidingObj = true;
p2.CollidingObj = true;
}
- contactdata1 = p1.ContactData;
- contactdata2 = p2.ContactData;
+ p1.getContactData(ref contactdata1);
+ p2.getContactData(ref contactdata2);
bounce = contactdata1.bounce * contactdata2.bounce;
- erpSoft = true;
+ erpSoft = contactdata1.softcolide | contactdata2.softcolide;
mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu);
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
{
if (name == "Terrain")
{
- erpSoft = true;
- contactdata1 = p1.ContactData;
+ p1.getContactData(ref contactdata1);
bounce = contactdata1.bounce * TerrainBounce;
mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction);
if (Math.Abs(p1.Velocity.X) > 0.1f || Math.Abs(p1.Velocity.Y) > 0.1f)
mu *= frictionMovementMult;
+ erpSoft = contactdata1.softcolide;
p1.CollidingGround = true;
}
else if (name == "Water")
@@ -813,11 +809,11 @@ namespace OpenSim.Region.Physics.OdePlugin
{
if (p2.PhysicsActorType == (int)ActorTypes.Prim)
{
- erpSoft = true;
p2.CollidingGround = true;
- contactdata2 = p2.ContactData;
+ p2.getContactData(ref contactdata2);
bounce = contactdata2.bounce * TerrainBounce;
mu = (float)Math.Sqrt(contactdata2.mu * TerrainFriction);
+ erpSoft = contactdata2.softcolide;
if (Math.Abs(p2.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y) > 0.1f)
mu *= frictionMovementMult;
@@ -1013,15 +1009,24 @@ namespace OpenSim.Region.Physics.OdePlugin
}
- // collide active prims with static enviroment
lock (_activeprims)
+ {
+ foreach (OdePrim aprim in _activeprims)
+ {
+ aprim.CollisionScore = 0;
+ aprim.IsColliding = false;
+ }
+ }
+
+ // collide active prims with static enviroment
+ lock (_activegroups)
{
try
{
- foreach (OdePrim prm in _activeprims)
+ foreach (OdePrim prm in _activegroups)
{
- if (d.BodyIsEnabled(prm.Body))
- d.SpaceCollide2(StaticSpace, prm.prim_geom, IntPtr.Zero, nearCallback);
+ if (d.BodyIsEnabled(prm.Body) && !prm.m_outbounds)
+ d.SpaceCollide2(StaticSpace, prm.collide_geom, IntPtr.Zero, nearCallback);
}
}
catch (AccessViolationException)
@@ -1029,7 +1034,6 @@ namespace OpenSim.Region.Physics.OdePlugin
m_log.Warn("[PHYSICS]: Unable to collide Active prim to static space");
}
}
-
// finally colide active things amoung them
try
{
@@ -1039,7 +1043,6 @@ namespace OpenSim.Region.Physics.OdePlugin
{
m_log.Warn("[PHYSICS]: Unable to collide in Active space");
}
-
// _perloopContact.Clear();
}
@@ -1148,13 +1151,20 @@ namespace OpenSim.Region.Physics.OdePlugin
public void addActivePrim(OdePrim activatePrim)
{
- // adds active prim.. (ones that should be iterated over in collisions_optimized
+ // adds active prim..
lock (_activeprims)
{
if (!_activeprims.Contains(activatePrim))
_activeprims.Add(activatePrim);
- //else
- // m_log.Warn("[PHYSICS]: Double Entry in _activeprims detected, potential crash immenent");
+ }
+ }
+
+ public void addActiveGroups(OdePrim activatePrim)
+ {
+ lock (_activegroups)
+ {
+ if (!_activegroups.Contains(activatePrim))
+ _activegroups.Add(activatePrim);
}
}
@@ -1186,6 +1196,13 @@ namespace OpenSim.Region.Physics.OdePlugin
_activeprims.Remove(deactivatePrim);
}
}
+ public void remActiveGroup(OdePrim deactivatePrim)
+ {
+ lock (_activegroups)
+ {
+ _activegroups.Remove(deactivatePrim);
+ }
+ }
public override void RemovePrim(PhysicsActor prim)
{
@@ -1258,6 +1275,11 @@ namespace OpenSim.Region.Physics.OdePlugin
{
waitForSpaceUnlock(currentspace);
d.SpaceRemove(currentspace, geom);
+
+ if (d.SpaceGetSublevel(currentspace) > 2 && d.SpaceGetNumGeoms(currentspace) == 0)
+ {
+ d.SpaceDestroy(currentspace);
+ }
}
else
{
@@ -1274,6 +1296,12 @@ namespace OpenSim.Region.Physics.OdePlugin
{
waitForSpaceUnlock(currentspace);
d.SpaceRemove(currentspace, geom);
+
+ if (d.SpaceGetSublevel(currentspace) > 2 && d.SpaceGetNumGeoms(currentspace) == 0)
+ {
+ d.SpaceDestroy(currentspace);
+ }
+
}
}
}
@@ -1577,42 +1605,14 @@ namespace OpenSim.Region.Physics.OdePlugin
statchanges += Util.EnvironmentTickCountSubtract(statstart);
- // Move characters
- lock (_characters)
- {
- List defects = new List();
- foreach (OdeCharacter actor in _characters)
- {
- if (actor != null)
- actor.Move(ODE_STEPSIZE, defects);
- }
- if (defects.Count != 0)
- {
- foreach (OdeCharacter defect in defects)
- {
- RemoveCharacter(defect);
- }
- }
- }
- statchmove += Util.EnvironmentTickCountSubtract(statstart);
-
- // Move other active objects
- lock (_activeprims)
- {
- foreach (OdePrim aprim in _activeprims)
- {
- aprim.CollisionScore = 0;
- aprim.IsColliding = false;
- aprim.Move();
- }
- }
-
statactmove += Util.EnvironmentTickCountSubtract(statstart);
//if ((framecount % m_randomizeWater) == 0)
// randomizeWater(waterlevel);
m_rayCastManager.ProcessQueuedRequests();
+
+
statray += Util.EnvironmentTickCountSubtract(statstart);
collision_optimized();
statcol += Util.EnvironmentTickCountSubtract(statstart);
@@ -1642,8 +1642,35 @@ namespace OpenSim.Region.Physics.OdePlugin
d.WorldQuickStep(world, ODE_STEPSIZE);
statstep += Util.EnvironmentTickCountSubtract(statstart);
- d.JointGroupEmpty(contactgroup);
- totjcontact += m_global_contactcount;
+
+ // Move characters
+ lock (_characters)
+ {
+ List defects = new List();
+ foreach (OdeCharacter actor in _characters)
+ {
+ if (actor != null)
+ actor.Move(ODE_STEPSIZE, defects);
+ }
+ if (defects.Count != 0)
+ {
+ foreach (OdeCharacter defect in defects)
+ {
+ RemoveCharacter(defect);
+ }
+ }
+ }
+ statchmove += Util.EnvironmentTickCountSubtract(statstart);
+
+ // Move other active objects
+ lock (_activegroups)
+ {
+ foreach (OdePrim aprim in _activegroups)
+ {
+ aprim.Move();
+ }
+ }
+
//ode.dunlock(world);
}
catch (Exception e)
@@ -1652,6 +1679,9 @@ namespace OpenSim.Region.Physics.OdePlugin
// ode.dunlock(world);
}
+ d.JointGroupEmpty(contactgroup);
+ totjcontact += m_global_contactcount;
+
step_time -= ODE_STEPSIZE;
nodeframes++;
}
@@ -1686,10 +1716,10 @@ namespace OpenSim.Region.Physics.OdePlugin
}
statmovchar = Util.EnvironmentTickCountSubtract(statstart);
- lock (_activeprims)
+ lock (_activegroups)
{
{
- foreach (OdePrim actor in _activeprims)
+ foreach (OdePrim actor in _activegroups)
{
if (actor.IsPhysical)
{
@@ -1906,13 +1936,14 @@ namespace OpenSim.Region.Physics.OdePlugin
yy += regionsize;
val = heightMap[yy + xx];
+ if (val < 0.0f)
+ val = 0.0f; // no neg terrain as in chode
_heightmap[xt + y] = val;
if (hfmin > val)
hfmin = val;
if (hfmax < val)
hfmax = val;
-
}
xt += heightmapHeightSamples;
}
@@ -1966,7 +1997,7 @@ namespace OpenSim.Region.Physics.OdePlugin
d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
d.GeomSetRotation(GroundGeom, ref R);
- d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f - 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f - 0.5f, 0);
+ d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f, 0);
RegionTerrain.Add(pOffset, GroundGeom, GroundGeom);
// TerrainHeightFieldHeights.Add(GroundGeom, ODElandMap);
TerrainHeightFieldHeights.Add(GroundGeom, _heightmap);