Merge branch 'master' of ssh://melanie@3dhosting.de/var/git/careminster into careminster

avinationmerge
Melanie 2012-03-07 00:51:24 +00:00
commit f3e04beb2e
10 changed files with 877 additions and 809 deletions

View File

@ -957,12 +957,12 @@ namespace OpenSim.Region.Framework.Scenes
/// <returns></returns> /// <returns></returns>
public void GetAxisAlignedBoundingBoxRaw(out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ) public void GetAxisAlignedBoundingBoxRaw(out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ)
{ {
maxX = -256f; maxX = float.MinValue;
maxY = -256f; maxY = float.MinValue;
maxZ = -256f; maxZ = float.MinValue;
minX = 256f; minX = float.MaxValue;
minY = 256f; minY = float.MaxValue;
minZ = 8192f; minZ = float.MaxValue;
SceneObjectPart[] parts = m_parts.GetArray(); SceneObjectPart[] parts = m_parts.GetArray();
foreach (SceneObjectPart part in parts) foreach (SceneObjectPart part in parts)
@ -1988,7 +1988,12 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="cGroupID"></param> /// <param name="cGroupID"></param>
public void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) 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) if (userExposed)
RootPart.Velocity = Vector3.Zero; // In case source is moving RootPart.Velocity = Vector3.Zero; // In case source is moving
} }
@ -2191,7 +2196,10 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="cGroupID"></param> /// <param name="cGroupID"></param>
public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) 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); newPart.SetParent(this);
AddPart(newPart); AddPart(newPart);
@ -2485,6 +2493,11 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectPart linkPart = objectGroup.m_rootPart; 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; Vector3 oldGroupPosition = linkPart.GroupPosition;
Quaternion oldRootRotation = linkPart.RotationOffset; Quaternion oldRootRotation = linkPart.RotationOffset;
@ -2528,6 +2541,13 @@ namespace OpenSim.Region.Framework.Scenes
linkPart.SetParent(this); linkPart.SetParent(this);
linkPart.CreateSelected = true; 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++; linkPart.LinkNum = linkNum++;
SceneObjectPart[] ogParts = objectGroup.Parts; SceneObjectPart[] ogParts = objectGroup.Parts;
@ -2540,7 +2560,15 @@ namespace OpenSim.Region.Framework.Scenes
{ {
SceneObjectPart part = ogParts[i]; SceneObjectPart part = ogParts[i];
if (part.UUID != objectGroup.m_rootPart.UUID) if (part.UUID != objectGroup.m_rootPart.UUID)
{
LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); 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(); part.ClearUndoState();
} }
} }
@ -2560,6 +2588,9 @@ namespace OpenSim.Region.Framework.Scenes
// unmoved prims! // unmoved prims!
ResetChildPrimPhysicsPositions(); ResetChildPrimPhysicsPositions();
if (m_rootPart.PhysActor != null)
m_rootPart.PhysActor.Building = false;
//HasGroupChanged = true; //HasGroupChanged = true;
//ScheduleGroupForFullUpdate(); //ScheduleGroupForFullUpdate();
} }
@ -2613,6 +2644,9 @@ namespace OpenSim.Region.Framework.Scenes
// "[SCENE OBJECT GROUP]: Delinking part {0}, {1} from group with root part {2}, {3}", // "[SCENE OBJECT GROUP]: Delinking part {0}, {1} from group with root part {2}, {3}",
// linkPart.Name, linkPart.UUID, RootPart.Name, RootPart.UUID); // linkPart.Name, linkPart.UUID, RootPart.Name, RootPart.UUID);
if (m_rootPart.PhysActor != null)
m_rootPart.PhysActor.Building = true;
linkPart.ClearUndoState(); linkPart.ClearUndoState();
Quaternion worldRot = linkPart.GetWorldRotation(); 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 // 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) // (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; objectGroup.HasGroupChangedDueToDelink = true;
return objectGroup; return objectGroup;
@ -3284,6 +3322,10 @@ namespace OpenSim.Region.Framework.Scenes
part.StoreUndoState(false); part.StoreUndoState(false);
part.IgnoreUndoUpdate = true; part.IgnoreUndoUpdate = true;
// unlock parts position change
if (m_rootPart.PhysActor != null)
m_rootPart.PhysActor.Building = true;
if (part.UUID == m_rootPart.UUID) if (part.UUID == m_rootPart.UUID)
{ {
UpdateRootPosition(pos); UpdateRootPosition(pos);
@ -3293,6 +3335,9 @@ namespace OpenSim.Region.Framework.Scenes
part.UpdateOffSet(pos); part.UpdateOffSet(pos);
} }
if (m_rootPart.PhysActor != null)
m_rootPart.PhysActor.Building = false;
HasGroupChanged = true; HasGroupChanged = true;
part.IgnoreUndoUpdate = false; part.IgnoreUndoUpdate = false;
} }
@ -3434,6 +3479,9 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.DebugFormat( // m_log.DebugFormat(
// "[SCENE OBJECT GROUP]: Updating single rotation of {0} {1} to {2}", part.Name, part.LocalId, rot); // "[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) if (part.UUID == m_rootPart.UUID)
{ {
UpdateRootRotation(rot); UpdateRootRotation(rot);
@ -3442,6 +3490,9 @@ namespace OpenSim.Region.Framework.Scenes
{ {
part.UpdateRotation(rot); 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.StoreUndoState();
part.IgnoreUndoUpdate = true; part.IgnoreUndoUpdate = true;
if (m_rootPart.PhysActor != null)
m_rootPart.PhysActor.Building = true;
if (part.UUID == m_rootPart.UUID) if (part.UUID == m_rootPart.UUID)
{ {
UpdateRootRotation(rot); UpdateRootRotation(rot);
@ -3482,6 +3536,9 @@ namespace OpenSim.Region.Framework.Scenes
part.OffsetPosition = pos; part.OffsetPosition = pos;
} }
if (m_rootPart.PhysActor != null)
m_rootPart.PhysActor.Building = false;
part.IgnoreUndoUpdate = false; part.IgnoreUndoUpdate = false;
} }
} }

View File

@ -1691,10 +1691,9 @@ namespace OpenSim.Region.Framework.Scenes
if (userExposed) if (userExposed)
dupe.UUID = UUID.Random(); dupe.UUID = UUID.Random();
//memberwiseclone means it also clones the physics actor reference // The PhysActor cannot be valid on a copy because the copy is not in the scene yet.
// This will make physical prim 'bounce' if not set to null. // Null it, the caller has to create a new one once the object is added to a scene
if (!userExposed) dupe.PhysActor = null;
dupe.PhysActor = null;
dupe.OwnerID = AgentID; dupe.OwnerID = AgentID;
dupe.GroupID = GroupID; dupe.GroupID = GroupID;
@ -1727,8 +1726,6 @@ namespace OpenSim.Region.Framework.Scenes
// Move afterwards ResetIDs as it clears the localID // Move afterwards ResetIDs as it clears the localID
dupe.LocalId = 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. // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
dupe.LastOwnerID = OwnerID; dupe.LastOwnerID = OwnerID;
@ -1749,6 +1746,9 @@ namespace OpenSim.Region.Framework.Scenes
dupe.DoPhysicsPropertyUpdate(UsePhysics, true); dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
} }
if (dupe.PhysActor != null)
dupe.PhysActor.LocalID = localID;
ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed);
// m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); // m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID);

View File

@ -121,12 +121,18 @@ namespace OpenSim.Region.OptionalModules
private bool CanObjectEnter(UUID objectID, bool enteringRegion, Vector3 newPoint, Scene scene) 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); SceneObjectPart obj = scene.GetSceneObjectPart(objectID);
Vector3 oldPoint = obj.GroupPosition; Vector3 oldPoint = obj.GroupPosition;
int objectCount = obj.ParentGroup.PrimCount; int objectCount = obj.ParentGroup.PrimCount;
ILandObject oldParcel = scene.LandChannel.GetLandObject(oldPoint.X, oldPoint.Y); ILandObject oldParcel = scene.LandChannel.GetLandObject(oldPoint.X, oldPoint.Y);
ILandObject newParcel = scene.LandChannel.GetLandObject(newPoint.X, newPoint.Y); ILandObject newParcel = scene.LandChannel.GetLandObject(newPoint.X, newPoint.Y);
if (newParcel == null)
return true;
int usedPrims = newParcel.PrimCounts.Total; int usedPrims = newParcel.PrimCounts.Total;
int simulatorCapacity = newParcel.GetSimulatorMaxPrimCount(); int simulatorCapacity = newParcel.GetSimulatorMaxPrimCount();

View File

@ -163,6 +163,8 @@ namespace OpenSim.Region.Physics.OdePlugin
private bool m_isphysical; private bool m_isphysical;
private bool m_isSelected; 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 internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively
private bool m_throttleUpdates; private bool m_throttleUpdates;
@ -253,7 +255,7 @@ namespace OpenSim.Region.Physics.OdePlugin
private float m_verticalAttractionEfficiency = 1.0f; // damped private float m_verticalAttractionEfficiency = 1.0f; // damped
private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor.
SerialControl m_taintserial = null; // SerialControl m_taintserial = null;
object m_taintvehicledata = null; object m_taintvehicledata = null;
public void DoSetVehicle() public void DoSetVehicle()
@ -309,410 +311,6 @@ namespace OpenSim.Region.Physics.OdePlugin
m_taintvehicledata = vdata; m_taintvehicledata = vdata;
_parent_scene.AddPhysicsActorTaint(this); _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, public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size,
Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode, uint localid) Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode, uint localid)
{ {
@ -776,8 +374,9 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
_triMeshData = IntPtr.Zero; _triMeshData = IntPtr.Zero;
m_NoColide = false;
m_taintserial = null; // m_taintserial = null;
m_primName = primName; m_primName = primName;
m_taintadd = true; m_taintadd = true;
_parent_scene.AddPhysicsActorTaint(this); _parent_scene.AddPhysicsActorTaint(this);
@ -814,7 +413,6 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
set set
{ {
//Console.WriteLine("Sel {0} {1} {2}", m_primName, value, m_isphysical); //Console.WriteLine("Sel {0} {1} {2}", m_primName, value, m_isphysical);
// This only makes the object not collidable if the object // This only makes the object not collidable if the object
// is physical or the object is modified somehow *IN THE FUTURE* // is physical or the object is modified somehow *IN THE FUTURE*
@ -1077,7 +675,6 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
} }
public override bool FloatOnWater public override bool FloatOnWater
{ {
set set
@ -1270,7 +867,6 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
} }
public void SetGeom(IntPtr geom) public void SetGeom(IntPtr geom)
{ {
if (prim_geom != IntPtr.Zero) 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.geom_name_map[prim_geom] = this.m_primName;
_parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this; _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); //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) if (childPrim)
@ -1351,11 +963,20 @@ namespace OpenSim.Region.Physics.OdePlugin
myrot.W = _orientation.W; myrot.W = _orientation.W;
d.BodySetQuaternion(Body, ref myrot); d.BodySetQuaternion(Body, ref myrot);
d.GeomSetBody(prim_geom, Body); d.GeomSetBody(prim_geom, Body);
m_collisionCategories |= CollisionCategories.Body; m_collisionCategories |= CollisionCategories.Body;
m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); if (m_NoColide)
d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); {
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.BodySetAutoDisableFlag(Body, true);
d.BodySetAutoDisableSteps(Body, body_autodisable_frames); d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
@ -1723,11 +1344,19 @@ namespace OpenSim.Region.Physics.OdePlugin
if (prim_geom != IntPtr.Zero) if (prim_geom != IntPtr.Zero)
{ {
d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); if (m_NoColide)
d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); {
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); d.BodyDestroy(Body);
lock (childrenPrim) lock (childrenPrim)
{ {
@ -1735,6 +1364,13 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
foreach (OdePrim prm in childrenPrim) 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); _parent_scene.remActivePrim(prm);
prm.Body = IntPtr.Zero; prm.Body = IntPtr.Zero;
} }
@ -1752,8 +1388,18 @@ namespace OpenSim.Region.Physics.OdePlugin
if (prim_geom != IntPtr.Zero) if (prim_geom != IntPtr.Zero)
{ {
d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); if (m_NoColide)
d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); {
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) 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 //Kill Body so that mesh can re-make the geom
if (IsPhysical && Body != IntPtr.Zero) 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; IntPtr vertices, indices;
int vertexCount, indexCount; int vertexCount, indexCount;
int vertexStride, triStride; int vertexStride, triStride;
@ -1809,38 +1442,20 @@ namespace OpenSim.Region.Physics.OdePlugin
if (vertexCount == 0 || indexCount == 0) 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); 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());
_size.X = 0.05f;
_size.Y = 0.05f;
_size.Z = 0.05f;
return false; return false;
} }
/* IntPtr geo = IntPtr.Zero;
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);
try try
{ {
// if (prim_geom == IntPtr.Zero) // setGeom takes care of phys engine recreate and prim_geom pointer _triMeshData = d.GeomTriMeshDataCreate();
// { d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
// SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null)); d.GeomTriMeshDataPreprocess(_triMeshData);
SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null));
// } _parent_scene.waitForSpaceUnlock(m_targetSpace);
geo = d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null);
} }
catch (Exception e) catch (Exception e)
{ {
@ -1851,21 +1466,11 @@ namespace OpenSim.Region.Physics.OdePlugin
d.GeomTriMeshDataDestroy(_triMeshData); d.GeomTriMeshDataDestroy(_triMeshData);
_triMeshData = IntPtr.Zero; _triMeshData = IntPtr.Zero;
} }
_size.X = 0.05f;
_size.Y = 0.05f;
_size.Z = 0.05f;
return false; return false;
} }
SetGeom(geo);
// if (IsPhysical && Body == (IntPtr) 0)
// {
// Recreate the body
// m_interpenetrationcount = 0;
// m_collisionscore = 0;
// enableBody();
// }
return true; return true;
} }
@ -1943,18 +1548,21 @@ namespace OpenSim.Region.Physics.OdePlugin
if (m_taintvehicledata != null) if (m_taintvehicledata != null)
DoSetVehicle(); DoSetVehicle();
if (m_taintserial != null)
DoSerialize(m_taintserial);
/* obsolete /* obsolete
if (!m_angularLock.ApproxEquals(m_taintAngularLock,0f)) if (!m_angularLock.ApproxEquals(m_taintAngularLock,0f))
changeAngularLock(timestep); changeAngularLock(timestep);
*/ */
} }
else 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 /* obsolete
@ -2058,7 +1666,6 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
foreach (OdePrim prm in childrenPrim) foreach (OdePrim prm in childrenPrim)
{ {
prm.m_collisionCategories |= CollisionCategories.Body; prm.m_collisionCategories |= CollisionCategories.Body;
prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); 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"); m_log.Warn("[PHYSICS]: Unable to link one of the linkset elements. No geom yet");
continue; 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(); d.Quaternion quat = new d.Quaternion();
quat.W = prm._orientation.W; 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"); m_log.Debug("[PHYSICS]:I ain't got no boooooooooddy, no body");
} }
prm.m_interpenetrationcount = 0; prm.m_interpenetrationcount = 0;
prm.m_collisionscore = 0; prm.m_collisionscore = 0;
prm.m_disabled = false; prm.m_disabled = false;
prm.Body = Body; prm.Body = Body;
_parent_scene.addActivePrim(prm);
_parent_scene.addActivePrim(prm);
} }
m_collisionCategories |= CollisionCategories.Body; m_collisionCategories |= CollisionCategories.Body;
m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); if (m_NoColide)
d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); {
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(); d.Quaternion quat2 = new d.Quaternion();
quat2.W = _orientation.W; quat2.W = _orientation.W;
@ -2134,19 +1757,18 @@ namespace OpenSim.Region.Physics.OdePlugin
d.BodySetAutoDisableFlag(Body, true); d.BodySetAutoDisableFlag(Body, true);
d.BodySetAutoDisableSteps(Body, body_autodisable_frames); d.BodySetAutoDisableSteps(Body, body_autodisable_frames);
m_interpenetrationcount = 0; m_interpenetrationcount = 0;
m_collisionscore = 0; m_collisionscore = 0;
m_disabled = false; m_disabled = false;
d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); d.BodySetPosition(Body, Position.X, Position.Y, Position.Z);
if (m_type != Vehicle.TYPE_NONE) Enable(Body, _parent_scene); if (m_type != Vehicle.TYPE_NONE) Enable(Body, _parent_scene);
_parent_scene.addActivePrim(this); _parent_scene.addActivePrim(this);
} }
} }
} }
} }
} }
private void ChildSetGeom(OdePrim odePrim) private void ChildSetGeom(OdePrim odePrim)
@ -2258,6 +1880,8 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories);
d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags);
if (m_NoColide)
d.GeomDisable(prim_geom);
} }
if (m_isphysical) if (m_isphysical)
@ -2275,22 +1899,35 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
else else
{ {
m_collisionCategories = CollisionCategories.Geom; m_collisionCategories = CollisionCategories.Geom;
if (m_isphysical)
m_collisionCategories |= CollisionCategories.Body;
if (m_isphysical) m_collisionFlags = m_default_collisionFlags;
m_collisionCategories |= CollisionCategories.Body;
m_collisionFlags = m_default_collisionFlags; if (m_collidesLand)
m_collisionFlags |= CollisionCategories.Land;
if (m_collidesLand) if (m_collidesWater)
m_collisionFlags |= CollisionCategories.Land; m_collisionFlags |= CollisionCategories.Water;
if (m_collidesWater)
m_collisionFlags |= CollisionCategories.Water;
if (prim_geom != IntPtr.Zero) if (prim_geom != IntPtr.Zero)
{ {
d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); if (m_NoColide)
d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); {
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) if (Body != IntPtr.Zero)
{ {
@ -2330,19 +1967,29 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
bool gottrimesh = false; bool gottrimesh = false;
m_NoColide = false; // assume all will go well
if (_triMeshData != IntPtr.Zero) if (_triMeshData != IntPtr.Zero)
{ {
d.GeomTriMeshDataDestroy(_triMeshData); d.GeomTriMeshDataDestroy(_triMeshData);
_triMeshData = IntPtr.Zero; _triMeshData = IntPtr.Zero;
} }
if (_mesh != null) // Special - make mesh if (_mesh != null)
{ {
gottrimesh = setMesh(_parent_scene, _mesh); 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; IntPtr geo = IntPtr.Zero;
if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1 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; m_taintremove = true;
_parent_scene.AddPhysicsActorTaint(this); _parent_scene.AddPhysicsActorTaint(this);
return; return;
} }
SetGeom(geo); SetGeom(geo); // this processes the m_NoColide
} }
} }
@ -2415,7 +2065,6 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
} }
lock (_parent_scene.OdeLock) lock (_parent_scene.OdeLock)
{ {
CreateGeom(m_targetSpace, _mesh); CreateGeom(m_targetSpace, _mesh);
@ -2518,8 +2167,6 @@ namespace OpenSim.Region.Physics.OdePlugin
m_taintposition = _position; m_taintposition = _position;
} }
public void rotate(float timestep) public void rotate(float timestep)
{ {
d.Quaternion myrot = new d.Quaternion(); d.Quaternion myrot = new d.Quaternion();

View File

@ -1735,7 +1735,7 @@ namespace OpenSim.Region.Physics.OdePlugin
return newPrim; return newPrim;
} }
/*
private PhysicsActor AddPrim(String name, Vector3 position, PhysicsActor parent, private PhysicsActor AddPrim(String name, Vector3 position, PhysicsActor parent,
PrimitiveBaseShape pbs, uint localid, byte[] sdata) PrimitiveBaseShape pbs, uint localid, byte[] sdata)
{ {
@ -1751,7 +1751,7 @@ namespace OpenSim.Region.Physics.OdePlugin
return newPrim; return newPrim;
} }
*/
public void addActivePrim(OdePrim activatePrim) public void addActivePrim(OdePrim activatePrim)
{ {
@ -1778,7 +1778,7 @@ namespace OpenSim.Region.Physics.OdePlugin
return result; return result;
} }
/*
public override PhysicsActor AddPrimShape(string primName, PhysicsActor parent, PrimitiveBaseShape pbs, Vector3 position, public override PhysicsActor AddPrimShape(string primName, PhysicsActor parent, PrimitiveBaseShape pbs, Vector3 position,
uint localid, byte[] sdata) uint localid, byte[] sdata)
{ {
@ -1789,7 +1789,7 @@ namespace OpenSim.Region.Physics.OdePlugin
return result; return result;
} }
*/
public override float TimeDilation public override float TimeDilation
{ {
get { return m_timeDilation; } get { return m_timeDilation; }

View File

@ -72,11 +72,13 @@ namespace OpenSim.Region.Physics.Manager
{ {
public float mu; public float mu;
public float bounce; public float bounce;
public bool softcolide;
public ContactData(float _mu, float _bounce) public ContactData(float _mu, float _bounce, bool _softcolide)
{ {
mu = _mu; mu = _mu;
bounce = _bounce; bounce = _bounce;
softcolide = _softcolide;
} }
} }
/// <summary> /// <summary>
@ -158,9 +160,10 @@ namespace OpenSim.Region.Physics.Manager
public virtual bool Building { get; set; } 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; } public abstract bool Stopped { get; }

View File

@ -136,7 +136,8 @@ namespace OpenSim.Region.Physics.OdePlugin
public UUID m_uuid; public UUID m_uuid;
public bool bad = false; 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) 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_density = density;
m_mass = 80f; // sure we have a default m_mass = 80f; // sure we have a default
AvatarContactData.mu = parent_scene.AvatarFriction; mu = parent_scene.AvatarFriction;
AvatarContactData.bounce = parent_scene.AvatarBounce; bounce = parent_scene.AvatarBounce;
walkDivisor = walk_divisor; walkDivisor = walk_divisor;
runDivisor = rundivisor; runDivisor = rundivisor;
@ -190,9 +191,11 @@ namespace OpenSim.Region.Physics.OdePlugin
set { return; } 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; } public override bool Building { get; set; }

View File

@ -38,7 +38,7 @@
* settings use. * settings use.
*/ */
// Ubit 2012 // Extensive change Ubit 2012
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -119,7 +119,15 @@ namespace OpenSim.Region.Physics.OdePlugin
// auxiliar // auxiliar
private float m_lmEfect = 0; // current linear motor eficiency private float m_lmEfect = 0; // current linear motor eficiency
private float m_amEfect = 0; // current angular 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) public ODEDynamics(OdePrim rootp)
{ {
@ -127,7 +135,6 @@ namespace OpenSim.Region.Physics.OdePlugin
_pParentScene = rootPrim._parent_scene; _pParentScene = rootPrim._parent_scene;
} }
public void DoSetVehicle(VehicleData vd) public void DoSetVehicle(VehicleData vd)
{ {
@ -152,6 +159,7 @@ namespace OpenSim.Region.Physics.OdePlugin
m_linearMotorTimescale = vd.m_linearMotorTimescale; m_linearMotorTimescale = vd.m_linearMotorTimescale;
if (m_linearMotorTimescale < timestep) m_linearMotorTimescale = timestep; if (m_linearMotorTimescale < timestep) m_linearMotorTimescale = timestep;
m_linearMotorOffset = vd.m_linearMotorOffset; m_linearMotorOffset = vd.m_linearMotorOffset;
//Angular properties //Angular properties
@ -201,6 +209,7 @@ namespace OpenSim.Region.Physics.OdePlugin
m_lmEfect = 0; m_lmEfect = 0;
m_amEfect = 0; m_amEfect = 0;
m_ffactor = 1.0f;
} }
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
@ -318,6 +327,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (len > 30.0f) if (len > 30.0f)
m_linearMotorDirection *= (30.0f / len); m_linearMotorDirection *= (30.0f / len);
m_lmEfect = 1.0f; // turn it on m_lmEfect = 1.0f; // turn it on
m_ffactor = 0.01f;
if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
&& !rootPrim.m_isSelected && !rootPrim.m_disabled) && !rootPrim.m_isSelected && !rootPrim.m_disabled)
d.BodyEnable(rootPrim.Body); d.BodyEnable(rootPrim.Body);
@ -368,6 +378,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (len > 30.0f) if (len > 30.0f)
m_linearMotorDirection *= (30.0f / len); m_linearMotorDirection *= (30.0f / len);
m_lmEfect = 1.0f; // turn it on m_lmEfect = 1.0f; // turn it on
m_ffactor = 0.01f;
if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body)
&& !rootPrim.m_isSelected && !rootPrim.m_disabled) && !rootPrim.m_isSelected && !rootPrim.m_disabled)
d.BodyEnable(rootPrim.Body); d.BodyEnable(rootPrim.Body);
@ -414,6 +425,7 @@ namespace OpenSim.Region.Physics.OdePlugin
float invtimestep = _pParentScene.ODE_STEPSIZE; float invtimestep = _pParentScene.ODE_STEPSIZE;
m_lmEfect = 0; m_lmEfect = 0;
m_amEfect = 0; m_amEfect = 0;
m_ffactor = 1f;
m_linearMotorDirection = Vector3.Zero; m_linearMotorDirection = Vector3.Zero;
m_angularMotorDirection = Vector3.Zero; m_angularMotorDirection = Vector3.Zero;
@ -591,6 +603,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
m_lmEfect = 0; m_lmEfect = 0;
m_amEfect = 0; m_amEfect = 0;
m_ffactor = 1f;
} }
public static Vector3 Xrot(Quaternion rot) public static Vector3 Xrot(Quaternion rot)
@ -614,6 +627,7 @@ namespace OpenSim.Region.Physics.OdePlugin
return vec; return vec;
} }
private const float pi = (float)Math.PI;
private const float halfpi = 0.5f * (float)Math.PI; private const float halfpi = 0.5f * (float)Math.PI;
public static Vector3 ubitRot2Euler(Quaternion rot) public static Vector3 ubitRot2Euler(Quaternion rot)
@ -740,9 +754,14 @@ namespace OpenSim.Region.Physics.OdePlugin
force.Z += tmpV.Z; force.Z += tmpV.Z;
} }
m_lmEfect *= (1.0f - 1.0f / m_linearMotorDecayTimescale); m_lmEfect *= (1.0f - 1.0f / m_linearMotorDecayTimescale);
m_ffactor = 0.01f + 1e-4f * curVel.LengthSquared();
} }
else else
{
m_lmEfect = 0; m_lmEfect = 0;
m_ffactor = 1f;
}
// friction // friction
if (curLocalVel.X != 0 || curLocalVel.Y != 0 || curLocalVel.Z != 0) 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 ftmp = 1.0f / m_verticalAttractionTimescale / m_verticalAttractionTimescale / _pParentScene.ODE_STEPSIZE;
float ftmp2 = m_verticalAttractionEfficiency / _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) if (m_bankingMix != 0)
{ {
float vfact = Math.Abs(curLocalVel.X) / 10.0f; float vfact = Math.Abs(curLocalVel.X) / 10.0f;
if (vfact > 1.0f) vfact = 1.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 // make z rot be in world Z not local as seems to be in sl
tmpV.X = 0;
tmpV.Y = 0; broll = broll / m_bankingTimescale;
tmpV.Z = broll;
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; tmpV *= irotq;
torque.X += tmpV.X; torque.X += tmpV.X;

View File

@ -114,6 +114,9 @@ namespace OpenSim.Region.Physics.OdePlugin
// private bool m_collidesLand = true; // private bool m_collidesLand = true;
private bool m_collidesWater; private bool m_collidesWater;
public bool m_returnCollisions; 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 // Default we're a Geometry
private CollisionCategories m_collisionCategories = (CollisionCategories.Geom); private CollisionCategories m_collisionCategories = (CollisionCategories.Geom);
@ -155,6 +158,8 @@ namespace OpenSim.Region.Physics.OdePlugin
public float m_collisionscore; public float m_collisionscore;
int m_colliderfilter = 0; 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; private float m_density = 10.000006836f; // Aluminum g/cm3;
public bool _zeroFlag; public bool _zeroFlag;
@ -185,7 +190,8 @@ namespace OpenSim.Region.Physics.OdePlugin
public ODEDynamics m_vehicle; public ODEDynamics m_vehicle;
internal int m_material = (int)Material.Wood; internal int m_material = (int)Material.Wood;
protected ContactData primContactData = new ContactData { mu = 0f, bounce = 0.1f }; private float mu;
private float bounce;
/// <summary> /// <summary>
/// Is this prim subject to physics? Even if not, it's still solid for collision purposes. /// Is this prim subject to physics? Even if not, it's still solid for collision purposes.
@ -216,11 +222,24 @@ 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;
} }
} }
@ -290,7 +309,10 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
if (m_colliderfilter == 0) if (m_colliderfilter == 0)
{
m_softcolide = false;
m_iscolliding = false; m_iscolliding = false;
}
else else
m_iscolliding = true; m_iscolliding = true;
} }
@ -453,8 +475,6 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
get get
{ {
// Averate previous velocity with the new one so
// client object interpolation works a 'little' better
if (_zeroFlag) if (_zeroFlag)
return Vector3.Zero; return Vector3.Zero;
return _velocity; return _velocity;
@ -733,8 +753,8 @@ namespace OpenSim.Region.Physics.OdePlugin
public override void SetMaterial(int pMaterial) public override void SetMaterial(int pMaterial)
{ {
m_material = pMaterial; m_material = pMaterial;
primContactData.mu = _parent_scene.m_materialContactsData[pMaterial].mu; mu = _parent_scene.m_materialContactsData[pMaterial].mu;
primContactData.bounce = _parent_scene.m_materialContactsData[pMaterial].bounce; bounce = _parent_scene.m_materialContactsData[pMaterial].bounce;
} }
public void setPrimForRemoval() public void setPrimForRemoval()
@ -833,6 +853,7 @@ namespace OpenSim.Region.Physics.OdePlugin
body_autodisable_frames = parent_scene.bodyFramesAutoDisable; body_autodisable_frames = parent_scene.bodyFramesAutoDisable;
prim_geom = IntPtr.Zero; prim_geom = IntPtr.Zero;
collide_geom = IntPtr.Zero;
Body = IntPtr.Zero; Body = IntPtr.Zero;
if (!size.IsFinite()) if (!size.IsFinite())
@ -847,7 +868,6 @@ namespace OpenSim.Region.Physics.OdePlugin
_size = size; _size = size;
if (!QuaternionIsFinite(rotation)) if (!QuaternionIsFinite(rotation))
{ {
rotation = Quaternion.Identity; rotation = Quaternion.Identity;
@ -878,6 +898,8 @@ namespace OpenSim.Region.Physics.OdePlugin
m_iscolliding = false; m_iscolliding = false;
m_colliderfilter = 0; m_colliderfilter = 0;
m_softcolide = true;
m_NoColide = false;
hasOOBoffsetFromMesh = false; hasOOBoffsetFromMesh = false;
_triMeshData = IntPtr.Zero; _triMeshData = IntPtr.Zero;
@ -886,8 +908,8 @@ namespace OpenSim.Region.Physics.OdePlugin
m_isSelected = false; m_isSelected = false;
m_delaySelect = false; m_delaySelect = false;
primContactData.mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu; mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu;
primContactData.bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce; bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce;
CalcPrimBodyData(); CalcPrimBodyData();
@ -1025,34 +1047,42 @@ namespace OpenSim.Region.Physics.OdePlugin
if (vertexCount == 0 || indexCount == 0) 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); m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. mesh UUID {4}",
_size.X = 0.01f; Name, _position.X, _position.Y, _position.Z, _pbs.SculptTexture.ToString());
_size.Y = 0.01f; mesh.releaseSourceMeshData();
_size.Z = 0.01f;
return false; return false;
} }
primOOBoffset = mesh.GetCentroid(); primOOBoffset = mesh.GetCentroid();
hasOOBoffsetFromMesh = true; hasOOBoffsetFromMesh = true;
_triMeshData = d.GeomTriMeshDataCreate();
d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
d.GeomTriMeshDataPreprocess(_triMeshData);
mesh.releaseSourceMeshData(); mesh.releaseSourceMeshData();
_parent_scene.waitForSpaceUnlock(m_targetSpace); IntPtr geo = IntPtr.Zero;
try 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) catch (Exception e)
{ {
m_log.ErrorFormat("[PHYSICS]: SetGeom Mesh failed for {0} exception: {1}", Name, 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; return false;
} }
SetGeom(geo);
return true; return true;
} }
@ -1062,25 +1092,30 @@ namespace OpenSim.Region.Physics.OdePlugin
//Console.WriteLine("SetGeom to " + prim_geom + " for " + Name); //Console.WriteLine("SetGeom to " + prim_geom + " for " + Name);
if (prim_geom != IntPtr.Zero) if (prim_geom != IntPtr.Zero)
{ {
d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); if (m_NoColide)
d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); {
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(); CalcPrimBodyData();
_parent_scene.geom_name_map[prim_geom] = Name; _parent_scene.geom_name_map[prim_geom] = Name;
_parent_scene.actor_name_map[prim_geom] = this; _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 else
m_log.Warn("Setting bad Geom"); m_log.Warn("Setting bad Geom");
@ -1102,10 +1137,13 @@ namespace OpenSim.Region.Physics.OdePlugin
bool haveMesh = false; bool haveMesh = false;
hasOOBoffsetFromMesh = false; hasOOBoffsetFromMesh = false;
m_NoColide = false;
if (_parent_scene.needsMeshing(_pbs)) if (_parent_scene.needsMeshing(_pbs))
{ {
haveMesh = setMesh(_parent_scene); // this will give a mesh to non trivial known prims haveMesh = setMesh(_parent_scene); // this will give a mesh to non trivial known prims
if (!haveMesh)
m_NoColide = true;
} }
if (!haveMesh) if (!haveMesh)
@ -1197,12 +1235,46 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
if (!childPrim && !m_isSelected) if (!childPrim && !m_isSelected)
{ {
if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero) if (m_isphysical && Body != IntPtr.Zero)
{ {
d.GeomEnable(prim_geom); m_collisionCategories |= CollisionCategories.Body;
foreach (OdePrim prm in childrenPrim) m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind);
d.GeomEnable(prm.prim_geom);
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); d.BodyEnable(Body);
} }
} }
@ -1215,11 +1287,47 @@ namespace OpenSim.Region.Physics.OdePlugin
m_disabled = true; m_disabled = true;
if (!childPrim) 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) 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); d.BodyDisable(Body);
} }
} }
@ -1298,8 +1406,6 @@ namespace OpenSim.Region.Physics.OdePlugin
continue; continue;
} }
DMassCopy(ref prm.primdMass, ref tmpdmass); DMassCopy(ref prm.primdMass, ref tmpdmass);
// apply prim current rotation to inertia // apply prim current rotation to inertia
@ -1361,14 +1467,7 @@ namespace OpenSim.Region.Physics.OdePlugin
// d.BodySetAngularDampingThreshold(Body, 0.001f); // d.BodySetAngularDampingThreshold(Body, 0.001f);
d.BodySetDamping(Body, .002f, .002f); 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) if (m_targetSpace != IntPtr.Zero)
{ {
_parent_scene.waitForSpaceUnlock(m_targetSpace); _parent_scene.waitForSpaceUnlock(m_targetSpace);
@ -1376,9 +1475,22 @@ namespace OpenSim.Region.Physics.OdePlugin
d.SpaceRemove(m_targetSpace, prim_geom); d.SpaceRemove(m_targetSpace, prim_geom);
} }
if (childrenPrim.Count == 0)
{
collide_geom = prim_geom;
m_targetSpace = _parent_scene.ActiveSpace; m_targetSpace = _parent_scene.ActiveSpace;
d.SpaceAdd(m_targetSpace, prim_geom); 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) lock (childrenPrim)
{ {
@ -1390,28 +1502,45 @@ namespace OpenSim.Region.Physics.OdePlugin
Vector3 ppos = prm._position; Vector3 ppos = prm._position;
d.GeomSetOffsetWorldPosition(prm.prim_geom, ppos.X, ppos.Y, ppos.Z); // set relative position d.GeomSetOffsetWorldPosition(prm.prim_geom, ppos.X, ppos.Y, ppos.Z); // set relative position
prm.m_collisionCategories |= CollisionCategories.Body; if (prm.m_targetSpace != m_targetSpace)
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 != IntPtr.Zero) 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)) if (d.SpaceQuery(prm.m_targetSpace, prm.prim_geom))
d.SpaceRemove(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); d.SpaceAdd(m_targetSpace, prm.prim_geom);
} }
if (m_isSelected || m_disabled) if (m_isSelected || m_disabled)
{
prm.m_collisionCategories &= ~CollisionCategories.Body;
prm.m_collisionFlags &= ~(CollisionCategories.Land | CollisionCategories.Wind);
d.GeomDisable(prm.prim_geom); 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); _parent_scene.addActivePrim(prm);
} }
} }
@ -1424,11 +1553,37 @@ namespace OpenSim.Region.Physics.OdePlugin
if (m_isSelected || m_disabled) if (m_isSelected || m_disabled)
{ {
m_collisionCategories &= ~CollisionCategories.Body;
m_collisionFlags &= ~(CollisionCategories.Land | CollisionCategories.Wind);
d.GeomDisable(prim_geom); d.GeomDisable(prim_geom);
d.BodyDisable(Body); 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.addActivePrim(this);
_parent_scene.addActiveGroups(this);
} }
private void DestroyBody() private void DestroyBody()
@ -1440,8 +1595,16 @@ namespace OpenSim.Region.Physics.OdePlugin
m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land);
if (prim_geom != IntPtr.Zero) if (prim_geom != IntPtr.Zero)
{ {
d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); if (m_NoColide)
d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); {
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(); UpdateDataFromGeom();
d.GeomSetBody(prim_geom, IntPtr.Zero); d.GeomSetBody(prim_geom, IntPtr.Zero);
SetInStaticSpace(this); SetInStaticSpace(this);
@ -1454,12 +1617,20 @@ namespace OpenSim.Region.Physics.OdePlugin
foreach (OdePrim prm in childrenPrim) foreach (OdePrim prm in childrenPrim)
{ {
_parent_scene.remActivePrim(prm); _parent_scene.remActivePrim(prm);
prm.m_collisionCategories &= ~CollisionCategories.Body; prm.m_collisionCategories = m_collisionCategories;
prm.m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); prm.m_collisionFlags = m_collisionFlags;
if (prm.prim_geom != IntPtr.Zero) if (prm.prim_geom != IntPtr.Zero)
{ {
d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); if (prm.m_NoColide)
d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); {
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(); prm.UpdateDataFromGeom();
SetInStaticSpace(prm); SetInStaticSpace(prm);
} }
@ -1473,6 +1644,7 @@ namespace OpenSim.Region.Physics.OdePlugin
d.JointDestroy(Amotor); d.JointDestroy(Amotor);
Amotor = IntPtr.Zero; Amotor = IntPtr.Zero;
} }
_parent_scene.remActiveGroup(this);
d.BodyDestroy(Body); d.BodyDestroy(Body);
} }
Body = IntPtr.Zero; Body = IntPtr.Zero;
@ -2008,23 +2180,14 @@ namespace OpenSim.Region.Physics.OdePlugin
myrot.Z = _orientation.Z; myrot.Z = _orientation.Z;
myrot.W = _orientation.W; myrot.W = _orientation.W;
d.GeomSetQuaternion(prim_geom, ref myrot); d.GeomSetQuaternion(prim_geom, ref myrot);
// _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this;
if (!m_isphysical) if (!m_isphysical)
SetInStaticSpace(this); SetInStaticSpace(this);
} }
if (m_isphysical && Body == IntPtr.Zero) if (m_isphysical && Body == IntPtr.Zero)
{ {
/*
if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim)
{
changeShape(_pbs);
}
else
{
*/
MakeBody(); MakeBody();
// }
} }
} }
@ -2133,17 +2296,52 @@ namespace OpenSim.Region.Physics.OdePlugin
if (!childPrim && Body != IntPtr.Zero) if (!childPrim && Body != IntPtr.Zero)
d.BodyDisable(Body); d.BodyDisable(Body);
if (m_delaySelect) if (m_delaySelect || m_isphysical)
{ {
m_collisionCategories = CollisionCategories.Selected;
m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space);
if (!childPrim) if (!childPrim)
{ {
foreach (OdePrim prm in childrenPrim) 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; 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; m_delaySelect = false;
} }
else else
@ -2156,19 +2354,64 @@ namespace OpenSim.Region.Physics.OdePlugin
if (!childPrim && Body != IntPtr.Zero && !m_disabled) if (!childPrim && Body != IntPtr.Zero && !m_disabled)
d.BodyEnable(Body); 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) if (!childPrim)
{ {
foreach (OdePrim prm in childrenPrim) 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); d.GeomEnable(prm.prim_geom);
}
prm.m_delaySelect = false; 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); d.GeomEnable(prim_geom);
}
m_delaySelect = false; m_delaySelect = false;
m_softcolide = true;
} }
resetCollisionAccounting(); resetCollisionAccounting();
@ -2214,6 +2457,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (givefakepos < 0) if (givefakepos < 0)
givefakepos = 0; givefakepos = 0;
// changeSelectedStatus(); // changeSelectedStatus();
m_softcolide = true;
resetCollisionAccounting(); resetCollisionAccounting();
} }
@ -2266,6 +2510,7 @@ namespace OpenSim.Region.Physics.OdePlugin
givefakeori--; givefakeori--;
if (givefakeori < 0) if (givefakeori < 0)
givefakeori = 0; givefakeori = 0;
m_softcolide = true;
resetCollisionAccounting(); resetCollisionAccounting();
} }
@ -2336,6 +2581,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (givefakeori < 0) if (givefakeori < 0)
givefakeori = 0; givefakeori = 0;
m_softcolide = true;
resetCollisionAccounting(); resetCollisionAccounting();
} }
@ -2390,8 +2636,8 @@ namespace OpenSim.Region.Physics.OdePlugin
else else
*/ */
DestroyBody(); DestroyBody();
Stop();
} }
Stop();
} }
} }
@ -2452,6 +2698,7 @@ namespace OpenSim.Region.Physics.OdePlugin
else else
MakeBody(); MakeBody();
m_softcolide = true;
resetCollisionAccounting(); resetCollisionAccounting();
} }
@ -2576,7 +2823,8 @@ namespace OpenSim.Region.Physics.OdePlugin
if ((bool)newbuilding) if ((bool)newbuilding)
{ {
m_building = true; m_building = true;
DestroyBody(); if (!childPrim)
DestroyBody();
} }
else else
{ {
@ -2648,12 +2896,95 @@ namespace OpenSim.Region.Physics.OdePlugin
public void Move() public void Move()
{ {
if (!childPrim && m_isphysical && Body != IntPtr.Zero && 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; 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 fx = 0;
float fy = 0; float fy = 0;
float fz = 0; float fz = 0;
@ -2862,7 +3193,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public void UpdatePositionAndVelocity(float simulatedtime) public void UpdatePositionAndVelocity(float simulatedtime)
{ {
// no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! // 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) if (Body != IntPtr.Zero)
{ {
@ -2872,64 +3203,6 @@ namespace OpenSim.Region.Physics.OdePlugin
d.Vector3 lpos; d.Vector3 lpos;
d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator 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.Quaternion ori;
d.GeomCopyQuaternion(prim_geom, out ori); d.GeomCopyQuaternion(prim_geom, out ori);

View File

@ -155,7 +155,7 @@ namespace OpenSim.Region.Physics.OdePlugin
private readonly ILog m_log; private readonly ILog m_log;
// private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>(); // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>();
private int threadid = 0; // private int threadid = 0;
private Random fluidRandomizer = new Random(Environment.TickCount); private Random fluidRandomizer = new Random(Environment.TickCount);
const d.ContactFlags comumContactFlags = d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM |d.ContactFlags.Approx1 | d.ContactFlags.Bounce; 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 comumSoftContactERP = 0.1f;
const float comumContactCFM = 0.0001f; const float comumContactCFM = 0.0001f;
float frictionScale = 1.0f;
float frictionMovementMult = 0.3f; float frictionMovementMult = 0.3f;
float TerrainBounce = 0.1f; float TerrainBounce = 0.1f;
float TerrainFriction = 0.1f; float TerrainFriction = 0.3f;
public float AvatarBounce = 0.3f; public float AvatarBounce = 0.3f;
public float AvatarFriction = 0;// 0.9f * 0.5f; public float AvatarFriction = 0;// 0.9f * 0.5f;
@ -189,8 +187,8 @@ namespace OpenSim.Region.Physics.OdePlugin
internal IntPtr WaterGeom; internal IntPtr WaterGeom;
public float avPIDD = 3200f; // make it visible public float avPIDD = 2200f; // make it visible
public float avPIDP = 1400f; // make it visible public float avPIDP = 900f; // make it visible
private float avCapRadius = 0.37f; private float avCapRadius = 0.37f;
private float avDensity = 3f; private float avDensity = 3f;
private float avMovementDivisorWalk = 1.3f; private float avMovementDivisorWalk = 1.3f;
@ -202,7 +200,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public bool forceSimplePrimMeshing = false; public bool forceSimplePrimMeshing = false;
public float meshSculptLOD = 32; public float meshSculptLOD = 32;
public float MeshSculptphysicalLOD = 16; public float MeshSculptphysicalLOD = 32;
public float geomDefaultDensity = 10.000006836f; public float geomDefaultDensity = 10.000006836f;
@ -212,18 +210,18 @@ namespace OpenSim.Region.Physics.OdePlugin
public float bodyPIDD = 35f; public float bodyPIDD = 35f;
public float bodyPIDG = 25; public float bodyPIDG = 25;
public int geomCrossingFailuresBeforeOutofbounds = 6; // public int geomCrossingFailuresBeforeOutofbounds = 6;
public int bodyFramesAutoDisable = 20; public int bodyFramesAutoDisable = 20;
private float[] _watermap; private float[] _watermap;
private bool m_filterCollisions = true;
private d.NearCallback nearCallback; private d.NearCallback nearCallback;
private readonly HashSet<OdeCharacter> _characters = new HashSet<OdeCharacter>(); private readonly HashSet<OdeCharacter> _characters = new HashSet<OdeCharacter>();
private readonly HashSet<OdePrim> _prims = new HashSet<OdePrim>(); private readonly HashSet<OdePrim> _prims = new HashSet<OdePrim>();
private readonly HashSet<OdePrim> _activeprims = new HashSet<OdePrim>(); private readonly HashSet<OdePrim> _activeprims = new HashSet<OdePrim>();
private readonly HashSet<OdePrim> _activegroups = new HashSet<OdePrim>();
public OpenSim.Framework.LocklessQueue<ODEchangeitem> ChangesQueue = new OpenSim.Framework.LocklessQueue<ODEchangeitem>(); public OpenSim.Framework.LocklessQueue<ODEchangeitem> ChangesQueue = new OpenSim.Framework.LocklessQueue<ODEchangeitem>();
@ -387,9 +385,6 @@ namespace OpenSim.Region.Physics.OdePlugin
// Defaults // Defaults
avPIDD = 2200.0f;
avPIDP = 900.0f;
int contactsPerCollision = 80; int contactsPerCollision = 80;
if (m_config != null) if (m_config != null)
@ -397,90 +392,86 @@ namespace OpenSim.Region.Physics.OdePlugin
IConfig physicsconfig = m_config.Configs["ODEPhysicsSettings"]; IConfig physicsconfig = m_config.Configs["ODEPhysicsSettings"];
if (physicsconfig != null) if (physicsconfig != null)
{ {
gravityx = physicsconfig.GetFloat("world_gravityx", 0f); gravityx = physicsconfig.GetFloat("world_gravityx", gravityx);
gravityy = physicsconfig.GetFloat("world_gravityy", 0f); gravityy = physicsconfig.GetFloat("world_gravityy", gravityy);
gravityz = physicsconfig.GetFloat("world_gravityz", -9.8f); 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); contactsurfacelayer = physicsconfig.GetFloat("world_contact_surface_layer", contactsurfacelayer);
ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", 0.020f); ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", ODE_STEPSIZE);
m_physicsiterations = physicsconfig.GetInt("world_internal_steps_without_collisions", 10); m_physicsiterations = physicsconfig.GetInt("world_internal_steps_without_collisions", m_physicsiterations);
avDensity = physicsconfig.GetFloat("av_density", avDensity); avDensity = physicsconfig.GetFloat("av_density", avDensity);
avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", 1.3f); avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", avMovementDivisorWalk);
avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", 0.8f); avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", avMovementDivisorRun);
avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f); 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); geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 3);
geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15); 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); geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity);
bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", 20); bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable);
bodyPIDD = physicsconfig.GetFloat("body_pid_derivative", 35f); bodyPIDD = physicsconfig.GetFloat("body_pid_derivative", bodyPIDD);
bodyPIDG = physicsconfig.GetFloat("body_pid_gain", 25f); bodyPIDG = physicsconfig.GetFloat("body_pid_gain", bodyPIDG);
forceSimplePrimMeshing = physicsconfig.GetBoolean("force_simple_prim_meshing", forceSimplePrimMeshing); forceSimplePrimMeshing = physicsconfig.GetBoolean("force_simple_prim_meshing", forceSimplePrimMeshing);
meshSculptedPrim = physicsconfig.GetBoolean("mesh_sculpted_prim", true); meshSculptedPrim = physicsconfig.GetBoolean("mesh_sculpted_prim", meshSculptedPrim);
meshSculptLOD = physicsconfig.GetFloat("mesh_lod", 32f); meshSculptLOD = physicsconfig.GetFloat("mesh_lod", meshSculptLOD);
MeshSculptphysicalLOD = physicsconfig.GetFloat("mesh_physical_lod", 16f); MeshSculptphysicalLOD = physicsconfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD);
m_filterCollisions = physicsconfig.GetBoolean("filter_collisions", false);
if (Environment.OSVersion.Platform == PlatformID.Unix) if (Environment.OSVersion.Platform == PlatformID.Unix)
{ {
avPIDD = physicsconfig.GetFloat("av_pid_derivative_linux", 2200.0f); avPIDD = physicsconfig.GetFloat("av_pid_derivative_linux", avPIDD);
avPIDP = physicsconfig.GetFloat("av_pid_proportional_linux", 900.0f); avPIDP = physicsconfig.GetFloat("av_pid_proportional_linux", avPIDP);
} }
else else
{ {
avPIDD = physicsconfig.GetFloat("av_pid_derivative_win", 2200.0f); avPIDD = physicsconfig.GetFloat("av_pid_derivative_win", avPIDD);
avPIDP = physicsconfig.GetFloat("av_pid_proportional_win", 900.0f); avPIDP = physicsconfig.GetFloat("av_pid_proportional_win", avPIDP);
} }
physics_logging = physicsconfig.GetBoolean("physics_logging", false); physics_logging = physicsconfig.GetBoolean("physics_logging", false);
physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0); physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0);
physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false); physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false);
minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", 3f); minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", minimumGroundFlightOffset);
maximumMassObject = physicsconfig.GetFloat("maximum_mass_object", 10000.01f); maximumMassObject = physicsconfig.GetFloat("maximum_mass_object", maximumMassObject);
} }
} }
ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf); ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf);
GlobalContactsArray = GlobalContactsArray = Marshal.AllocHGlobal(maxContactsbeforedeath * d.Contact.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.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.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.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.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.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.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.Rubber].bounce = 0.95f;
m_materialContactsData[(int)Material.light].mu = 0.0f; m_materialContactsData[(int)Material.light].mu = 0.0f;
m_materialContactsData[(int)Material.light].bounce = 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) // Set the gravity,, don't disable things automatically (we set it explicitly on some things)
d.WorldSetGravity(world, gravityx, gravityy, gravityz); d.WorldSetGravity(world, gravityx, gravityy, gravityz);
@ -566,13 +557,6 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
/// <summary>
/// This is our near callback. A geometry is near a body
/// </summary>
/// <param name="space">The space that contains the geoms. Remember, spaces are also geoms</param>
/// <param name="g1">a geometry or space</param>
/// <param name="g2">another geometry or space</param>
///
private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom) private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom)
{ {
@ -584,7 +568,13 @@ namespace OpenSim.Region.Physics.OdePlugin
return true; return true;
} }
/// <summary>
/// This is our near callback. A geometry is near a body
/// </summary>
/// <param name="space">The space that contains the geoms. Remember, spaces are also geoms</param>
/// <param name="g1">a geometry or space</param>
/// <param name="g2">another geometry or space</param>
///
private void near(IntPtr space, IntPtr g1, IntPtr g2) private void near(IntPtr space, IntPtr g1, IntPtr g2)
{ {
@ -703,8 +693,8 @@ namespace OpenSim.Region.Physics.OdePlugin
// big messy collision analises // big messy collision analises
float mu = 0; float mu = 0;
float bounce = 0; float bounce = 0;
ContactData contactdata1; ContactData contactdata1 = new ContactData(0, 0, false);
ContactData contactdata2; ContactData contactdata2 = new ContactData(0, 0, false);
bool erpSoft = false; bool erpSoft = false;
String name = null; String name = null;
@ -718,8 +708,9 @@ namespace OpenSim.Region.Physics.OdePlugin
switch (p2.PhysicsActorType) switch (p2.PhysicsActorType)
{ {
case (int)ActorTypes.Agent: case (int)ActorTypes.Agent:
contactdata1 = p1.ContactData; p1.getContactData(ref contactdata1);
contactdata2 = p2.ContactData; p2.getContactData(ref contactdata2);
bounce = contactdata1.bounce * contactdata2.bounce; bounce = contactdata1.bounce * contactdata2.bounce;
mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); 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)) if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f))
mu *= frictionMovementMult; mu *= frictionMovementMult;
erpSoft = contactdata1.softcolide | contactdata2.softcolide;
p1.CollidingObj = true; p1.CollidingObj = true;
p2.CollidingObj = true; p2.CollidingObj = true;
break; break;
case (int)ActorTypes.Prim: case (int)ActorTypes.Prim:
contactdata1 = p1.ContactData; p1.getContactData(ref contactdata1);
contactdata2 = p2.ContactData; p2.getContactData(ref contactdata2);
bounce = contactdata1.bounce * contactdata2.bounce; bounce = contactdata1.bounce * contactdata2.bounce;
mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu);
@ -741,6 +733,9 @@ namespace OpenSim.Region.Physics.OdePlugin
mu *= frictionMovementMult; mu *= frictionMovementMult;
if (p2.Velocity.LengthSquared() > 0.0f) if (p2.Velocity.LengthSquared() > 0.0f)
p2.CollidingObj = true; p2.CollidingObj = true;
erpSoft = contactdata1.softcolide | contactdata2.softcolide;
dop1foot = true; dop1foot = true;
break; break;
default: default:
@ -753,8 +748,8 @@ namespace OpenSim.Region.Physics.OdePlugin
switch (p2.PhysicsActorType) switch (p2.PhysicsActorType)
{ {
case (int)ActorTypes.Agent: case (int)ActorTypes.Agent:
contactdata1 = p1.ContactData; p1.getContactData(ref contactdata1);
contactdata2 = p2.ContactData; p2.getContactData(ref contactdata2);
bounce = contactdata1.bounce * contactdata2.bounce; bounce = contactdata1.bounce * contactdata2.bounce;
mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); 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)) if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f))
mu *= frictionMovementMult; mu *= frictionMovementMult;
erpSoft = contactdata1.softcolide | contactdata2.softcolide;
dop2foot = true; dop2foot = true;
if (p1.Velocity.LengthSquared() > 0.0f) if (p1.Velocity.LengthSquared() > 0.0f)
p1.CollidingObj = true; p1.CollidingObj = true;
@ -772,10 +768,10 @@ namespace OpenSim.Region.Physics.OdePlugin
p1.CollidingObj = true; p1.CollidingObj = true;
p2.CollidingObj = true; p2.CollidingObj = true;
} }
contactdata1 = p1.ContactData; p1.getContactData(ref contactdata1);
contactdata2 = p2.ContactData; p2.getContactData(ref contactdata2);
bounce = contactdata1.bounce * contactdata2.bounce; bounce = contactdata1.bounce * contactdata2.bounce;
erpSoft = true; erpSoft = contactdata1.softcolide | contactdata2.softcolide;
mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); 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)) 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") if (name == "Terrain")
{ {
erpSoft = true; p1.getContactData(ref contactdata1);
contactdata1 = p1.ContactData;
bounce = contactdata1.bounce * TerrainBounce; bounce = contactdata1.bounce * TerrainBounce;
mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction); mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction);
if (Math.Abs(p1.Velocity.X) > 0.1f || Math.Abs(p1.Velocity.Y) > 0.1f) if (Math.Abs(p1.Velocity.X) > 0.1f || Math.Abs(p1.Velocity.Y) > 0.1f)
mu *= frictionMovementMult; mu *= frictionMovementMult;
erpSoft = contactdata1.softcolide;
p1.CollidingGround = true; p1.CollidingGround = true;
} }
else if (name == "Water") else if (name == "Water")
@ -813,11 +809,11 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
if (p2.PhysicsActorType == (int)ActorTypes.Prim) if (p2.PhysicsActorType == (int)ActorTypes.Prim)
{ {
erpSoft = true;
p2.CollidingGround = true; p2.CollidingGround = true;
contactdata2 = p2.ContactData; p2.getContactData(ref contactdata2);
bounce = contactdata2.bounce * TerrainBounce; bounce = contactdata2.bounce * TerrainBounce;
mu = (float)Math.Sqrt(contactdata2.mu * TerrainFriction); 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) if (Math.Abs(p2.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y) > 0.1f)
mu *= frictionMovementMult; mu *= frictionMovementMult;
@ -1013,15 +1009,24 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
// collide active prims with static enviroment
lock (_activeprims) lock (_activeprims)
{
foreach (OdePrim aprim in _activeprims)
{
aprim.CollisionScore = 0;
aprim.IsColliding = false;
}
}
// collide active prims with static enviroment
lock (_activegroups)
{ {
try try
{ {
foreach (OdePrim prm in _activeprims) foreach (OdePrim prm in _activegroups)
{ {
if (d.BodyIsEnabled(prm.Body)) if (d.BodyIsEnabled(prm.Body) && !prm.m_outbounds)
d.SpaceCollide2(StaticSpace, prm.prim_geom, IntPtr.Zero, nearCallback); d.SpaceCollide2(StaticSpace, prm.collide_geom, IntPtr.Zero, nearCallback);
} }
} }
catch (AccessViolationException) catch (AccessViolationException)
@ -1029,7 +1034,6 @@ namespace OpenSim.Region.Physics.OdePlugin
m_log.Warn("[PHYSICS]: Unable to collide Active prim to static space"); m_log.Warn("[PHYSICS]: Unable to collide Active prim to static space");
} }
} }
// finally colide active things amoung them // finally colide active things amoung them
try try
{ {
@ -1039,7 +1043,6 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
m_log.Warn("[PHYSICS]: Unable to collide in Active space"); m_log.Warn("[PHYSICS]: Unable to collide in Active space");
} }
// _perloopContact.Clear(); // _perloopContact.Clear();
} }
@ -1148,13 +1151,20 @@ namespace OpenSim.Region.Physics.OdePlugin
public void addActivePrim(OdePrim activatePrim) public void addActivePrim(OdePrim activatePrim)
{ {
// adds active prim.. (ones that should be iterated over in collisions_optimized // adds active prim..
lock (_activeprims) lock (_activeprims)
{ {
if (!_activeprims.Contains(activatePrim)) if (!_activeprims.Contains(activatePrim))
_activeprims.Add(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); _activeprims.Remove(deactivatePrim);
} }
} }
public void remActiveGroup(OdePrim deactivatePrim)
{
lock (_activegroups)
{
_activegroups.Remove(deactivatePrim);
}
}
public override void RemovePrim(PhysicsActor prim) public override void RemovePrim(PhysicsActor prim)
{ {
@ -1258,6 +1275,11 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
waitForSpaceUnlock(currentspace); waitForSpaceUnlock(currentspace);
d.SpaceRemove(currentspace, geom); d.SpaceRemove(currentspace, geom);
if (d.SpaceGetSublevel(currentspace) > 2 && d.SpaceGetNumGeoms(currentspace) == 0)
{
d.SpaceDestroy(currentspace);
}
} }
else else
{ {
@ -1274,6 +1296,12 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
waitForSpaceUnlock(currentspace); waitForSpaceUnlock(currentspace);
d.SpaceRemove(currentspace, geom); 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); statchanges += Util.EnvironmentTickCountSubtract(statstart);
// Move characters
lock (_characters)
{
List<OdeCharacter> defects = new List<OdeCharacter>();
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); statactmove += Util.EnvironmentTickCountSubtract(statstart);
//if ((framecount % m_randomizeWater) == 0) //if ((framecount % m_randomizeWater) == 0)
// randomizeWater(waterlevel); // randomizeWater(waterlevel);
m_rayCastManager.ProcessQueuedRequests(); m_rayCastManager.ProcessQueuedRequests();
statray += Util.EnvironmentTickCountSubtract(statstart); statray += Util.EnvironmentTickCountSubtract(statstart);
collision_optimized(); collision_optimized();
statcol += Util.EnvironmentTickCountSubtract(statstart); statcol += Util.EnvironmentTickCountSubtract(statstart);
@ -1642,8 +1642,35 @@ namespace OpenSim.Region.Physics.OdePlugin
d.WorldQuickStep(world, ODE_STEPSIZE); d.WorldQuickStep(world, ODE_STEPSIZE);
statstep += Util.EnvironmentTickCountSubtract(statstart); statstep += Util.EnvironmentTickCountSubtract(statstart);
d.JointGroupEmpty(contactgroup);
totjcontact += m_global_contactcount; // Move characters
lock (_characters)
{
List<OdeCharacter> defects = new List<OdeCharacter>();
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); //ode.dunlock(world);
} }
catch (Exception e) catch (Exception e)
@ -1652,6 +1679,9 @@ namespace OpenSim.Region.Physics.OdePlugin
// ode.dunlock(world); // ode.dunlock(world);
} }
d.JointGroupEmpty(contactgroup);
totjcontact += m_global_contactcount;
step_time -= ODE_STEPSIZE; step_time -= ODE_STEPSIZE;
nodeframes++; nodeframes++;
} }
@ -1686,10 +1716,10 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
statmovchar = Util.EnvironmentTickCountSubtract(statstart); statmovchar = Util.EnvironmentTickCountSubtract(statstart);
lock (_activeprims) lock (_activegroups)
{ {
{ {
foreach (OdePrim actor in _activeprims) foreach (OdePrim actor in _activegroups)
{ {
if (actor.IsPhysical) if (actor.IsPhysical)
{ {
@ -1906,13 +1936,14 @@ namespace OpenSim.Region.Physics.OdePlugin
yy += regionsize; yy += regionsize;
val = heightMap[yy + xx]; val = heightMap[yy + xx];
if (val < 0.0f)
val = 0.0f; // no neg terrain as in chode
_heightmap[xt + y] = val; _heightmap[xt + y] = val;
if (hfmin > val) if (hfmin > val)
hfmin = val; hfmin = val;
if (hfmax < val) if (hfmax < val)
hfmax = val; hfmax = val;
} }
xt += heightmapHeightSamples; xt += heightmapHeightSamples;
} }
@ -1966,7 +1997,7 @@ namespace OpenSim.Region.Physics.OdePlugin
d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
d.GeomSetRotation(GroundGeom, ref R); 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); RegionTerrain.Add(pOffset, GroundGeom, GroundGeom);
// TerrainHeightFieldHeights.Add(GroundGeom, ODElandMap); // TerrainHeightFieldHeights.Add(GroundGeom, ODElandMap);
TerrainHeightFieldHeights.Add(GroundGeom, _heightmap); TerrainHeightFieldHeights.Add(GroundGeom, _heightmap);