From 5534cf8b57466396634f60695a3d8cfcce6009e2 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 29 Feb 2012 05:03:26 +0000 Subject: [PATCH 01/12] chODE: bad meshs get a a basic box or sphere geom with setted prim size. They will not colide if non-physical and Will collide with land if physical. assume UNTESTED --- OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 649 ++++-------------- .../Region/Physics/ChOdePlugin/OdePlugin.cs | 8 +- 2 files changed, 151 insertions(+), 506 deletions(-) diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index 0a4ebe4db5..514074c2cf 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -163,6 +163,8 @@ namespace OpenSim.Region.Physics.OdePlugin private bool m_isphysical; private bool m_isSelected; + private bool m_NoColide; // for now only for internal use for bad meshs + internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively private bool m_throttleUpdates; @@ -253,7 +255,7 @@ namespace OpenSim.Region.Physics.OdePlugin private float m_verticalAttractionEfficiency = 1.0f; // damped private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. - SerialControl m_taintserial = null; +// SerialControl m_taintserial = null; object m_taintvehicledata = null; public void DoSetVehicle() @@ -309,410 +311,6 @@ namespace OpenSim.Region.Physics.OdePlugin m_taintvehicledata = vdata; _parent_scene.AddPhysicsActorTaint(this); } - - public override byte[] Serialize(bool PhysIsRunning) - { - SerialControl sc = new SerialControl(); - - lock (sc.alock) - { - if (PhysIsRunning) - { - m_taintserial = sc; - - if (!Monitor.Wait(sc.alock, 1000)) - { - m_log.Error("[chOde] prim data serialization timed out"); - m_taintserial = null; - return new byte[0]; - } - } - else - DoSerialize(sc); - } - - return sc.data; - } - - public void DoSerialize(SerialControl sc) - { - wstreamer st = new wstreamer(); - Vector3 vtmp; - - ushort version = 2; - if (!BitConverter.IsLittleEndian) - version |= 1; - st.Wushort(version); //version lower bit codes endian type for future use - - // compact booleans in a ushort - ushort flags = 0; - - if (m_isphysical) // this should be true for now - flags |= 1; - if (m_isSelected) - flags |= 2; - if (m_isVolumeDetect) - flags |= 4; - if (m_disabled) - flags |= 8; - if (m_collidesWater) - flags |= 16; - if (m_collidesLand) - flags |= 32; - if (m_usePID) - flags |= 64; - if (m_useAPID) - flags |= 128; - if (m_useHoverPID) - flags |= 256; - if (m_throttleUpdates) - flags |= 512; - - st.Wushort(flags); - - st.Wvector3(_size); - st.Wint(m_material); - st.Wfloat(m_density); - st.Wfloat(0); // future gravity mod V3 - st.Wfloat(0); // future friction V3 - st.Wfloat(0); // future bounce V3 - -// st.Wuint((uint)m_collisionCategories); -// st.Wuint((uint)m_collisionFlags); - - if (_parent == null) - { - st.Wvector3(_position); // ?? - st.Wquat(_orientation); - } - else // for childs save offsets - { - Quaternion to; - Quaternion ipo = Quaternion.Inverse(_parent.Orientation); - - if (m_isphysical && prim_geom != IntPtr.Zero) - { - d.Vector3 dvt; - d.GeomCopyPosition(prim_geom, out dvt); - - vtmp.X = dvt.X; - vtmp.Y = dvt.Y; - vtmp.Z = dvt.Z; - - d.Quaternion dqt; - d.GeomCopyQuaternion(prim_geom, out dqt); - - to.X = dqt.X; - to.Y = dqt.Y; - to.Z = dqt.Z; - to.W = dqt.W; // rotation in world - } - else - { - vtmp = _position; - to = _orientation; - } - - vtmp -= _parent.Position; // offset in world - vtmp *= ipo; // offset in local - st.Wvector3(vtmp); - - ipo *= to; // own rotation - st.Wquat(ipo); - } - - st.Wvector3(_velocity); - st.Wvector3(m_rotationalVelocity); - st.Wvector3(_acceleration); - st.Wvector3(m_rotateEnable); - - vtmp = Vector3.Zero; - for (int i = 0; i < m_forcelist.Count; i++) - { - - vtmp += (m_forcelist[i] * 100); - } - - st.Wvector3(vtmp); // force acc - - vtmp = Vector3.Zero; - for (int i = 0; i < m_angularforcelist.Count; i++) - { - vtmp += (m_angularforcelist[i] * 100); - } - - st.Wvector3(vtmp); // angular force acc - - st.Wvector3(m_PIDTarget); - st.Wfloat(m_PIDTau); - st.Wfloat(PID_D); - st.Wfloat(PID_G); - st.Wquat(m_APIDTarget); - st.Wfloat(m_APIDStrength); - st.Wfloat(m_APIDDamping); - st.Wfloat(m_APIDdamper); - - st.Wint((int)m_PIDHoverType); - st.Wfloat(m_PIDHoverHeight); - st.Wfloat(m_PIDHoverTau); - st.Wfloat(m_targetHoverHeight); - - st.Wfloat(m_groundHeight); - st.Wfloat(m_waterHeight); - - st.Wfloat(m_buoyancy); - - // this must be last since type none ends stream - if (m_type == Vehicle.TYPE_NONE) - st.Wint((int)Vehicle.TYPE_NONE); - else - { - st.Wint((int)m_type); - - st.Wquat(Quaternion.Identity); //m_referenceFrame - - st.Wint((int)m_flags); - - st.Wvector3(m_linearMotorDirection); - st.Wfloat( - (float)Math.Sqrt(m_lLinMotorDVel.LengthSquared() / m_linearMotorDirection.LengthSquared())); - - st.Wvector3(m_linearFrictionTimescale); - st.Wfloat(m_linearMotorDecayTimescale); - st.Wfloat(m_linearMotorTimescale); - st.Wvector3(new Vector3(0, 0, 0)); //m_linearMotorOffset); - - st.Wvector3(m_angularMotorDirection); - st.Wfloat((float)Math.Sqrt(m_angularMotorDVel.LengthSquared() / m_angularMotorDirection.LengthSquared())); - - st.Wvector3(m_angularFrictionTimescale); - st.Wfloat(m_angularMotorDecayTimescale); - st.Wfloat(m_angularMotorTimescale); - - st.Wfloat(0); //m_linearDeflectionEfficiency); - st.Wfloat(1000); //m_linearDeflectionTimescale); - - st.Wfloat(0); //m_angularDeflectionEfficiency); - st.Wfloat(120); //m_angularDeflectionTimescale); - - st.Wfloat(0); // m_bankingEfficiency); - st.Wfloat(0); //m_bankingMix); - st.Wfloat(1000); //m_bankingTimescale); - - st.Wfloat(m_VhoverHeight); - st.Wfloat(0.5f); //m_VhoverEfficiency); - st.Wfloat(m_VhoverTimescale); - - st.Wfloat(m_VehicleBuoyancy); - - st.Wfloat(m_verticalAttractionEfficiency); - st.Wfloat(m_verticalAttractionTimescale); - } - sc.data = st.close(); - m_taintserial = null; - Monitor.PulseAll(sc.alock); - } - - public bool DeSerialize(byte[] data) - { - rstreamer st = new rstreamer(data); - - int version =st.Rushort(); //version - - // merge booleans in a ushort - ushort flags = st.Rushort(); - if ((flags & 1) != 0) - m_isphysical = true; - if ((flags & 2) != 0) - m_taintselected = true; - if ((flags & 4) != 0) - m_isVolumeDetect = true; - if ((flags & 8) != 0) - m_taintdisable = true; - if ((flags & 16) != 0) - m_taintCollidesWater = true; - if ((flags & 32) != 0) - m_collidesLand = true; - if ((flags & 64) != 0) - m_usePID = true; - if ((flags & 128) != 0) - m_useAPID = true; - if ((flags & 256) != 0) - m_useHoverPID = true; - if ((flags & 512) != 0) - m_throttleUpdates = true; - - _size = st.Rvector3(); - m_taintsize = _size; - - m_material= st.Rint(); - m_density = st.Rfloat(); - st.Rfloat(); // future gravity mod V3 - st.Rfloat(); // future friction V3 - st.Rfloat(); // future bounce V3 - -// m_collisionCategories = (CollisionCategories)st.Ruint(); -// m_collisionFlags = (CollisionCategories) st.Ruint(); - - if (m_taintparent == null) - { - st.Rvector3(); // ignore old position sop/sog as to tell the new one - m_taintrot = st.Rquat(); // - _orientation = m_taintrot; - } - else - { - m_taintrot = _parent.Orientation; - m_taintposition = st.Rvector3(); // ?? - _position = m_taintposition; - - m_taintposition *= m_taintrot; - m_taintposition += _parent.Position; - - m_taintrot *= st.Rquat(); // - _orientation = m_taintrot; - } - - m_taintVelocity = st.Rvector3(); - m_rotationalVelocity = st.Rvector3(); - - _acceleration = st.Rvector3(); - m_rotateEnableRequest = st.Rvector3(); - m_rotateEnableUpdate = true; - - Vector3 vtmp; - - vtmp = st.Rvector3(); // forces acc - m_forcelist.Add(vtmp); - m_taintforce = true; - - vtmp = st.Rvector3(); // angular forces acc - m_angularforcelist.Add(vtmp); - m_taintaddangularforce = true; - - m_PIDTarget = st.Rvector3(); - m_PIDTau = st.Rfloat(); - PID_D = st.Rfloat(); - PID_G = st.Rfloat(); - - m_APIDTarget = st.Rquat(); - m_APIDStrength = st.Rfloat(); - m_APIDDamping = st.Rfloat(); - m_APIDdamper = st.Rfloat(); - - m_PIDHoverType = (PIDHoverType) st.Rint(); - m_PIDHoverHeight = st.Rfloat(); - m_PIDHoverTau = st.Rfloat(); - m_targetHoverHeight = st.Rfloat(); - - m_groundHeight = st.Rfloat(); - m_waterHeight = st.Rfloat(); - - m_buoyancy = st.Rfloat(); - - - // this must be last since type none ends stream - - m_type = (Vehicle) st.Rint(); - - if (m_type != Vehicle.TYPE_NONE) - { - float ftmp; - - st.Rquat(); //m_referenceFrame - - m_flags = (VehicleFlag) st.Rint(); - - m_linearMotorDirection = st.Rvector3(); - - ftmp = st.Rfloat(); - m_lLinMotorDVel = m_linearMotorDirection * ftmp; - - m_linearFrictionTimescale = st.Rvector3(); - m_linearMotorDecayTimescale = st.Rfloat(); - m_linearMotorTimescale = st.Rfloat(); - st.Rvector3(); //m_linearMotorOffset); - - m_angularMotorDirection = st.Rvector3(); - ftmp = st.Rfloat(); - m_angularMotorDVel = m_angularMotorDirection * ftmp; - - m_angularFrictionTimescale = st.Rvector3(); - m_angularMotorDecayTimescale = st.Rfloat(); - m_angularMotorTimescale = st.Rfloat(); - - st.Rfloat(); //m_linearDeflectionEfficiency); - st.Rfloat(); //m_linearDeflectionTimescale); - - st.Rfloat(); //m_angularDeflectionEfficiency); - st.Rfloat(); //m_angularDeflectionTimescale); - - st.Rfloat(); // m_bankingEfficiency); - st.Rfloat(); //m_bankingMix); - st.Rfloat(); //m_bankingTimescale); - - m_VhoverHeight = st.Rfloat(); - st.Rfloat(); //m_VhoverEfficiency); - m_VhoverTimescale = st.Rfloat(); - - m_VehicleBuoyancy = st.Rfloat(); - - m_verticalAttractionEfficiency = st.Rfloat(); - m_verticalAttractionTimescale = st.Rfloat(); - } - st.close(); - return true; - } - - public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, PhysicsActor parent, - PrimitiveBaseShape pbs, CollisionLocker dode, uint localid, byte[] sdata) - { - m_localID = localid; - ode = dode; - - if (parent == null) - { - m_taintparent = null; - - if (!pos.IsFinite()) - { - pos = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), - parent_scene.GetTerrainHeightAtXY(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f)) + 0.5f); - m_log.Warn("[PHYSICS]: Got nonFinite Object create Position"); - } - - _position = pos; - m_taintposition = pos; - } - else - m_taintparent = parent; - - body_autodisable_frames = parent_scene.bodyFramesAutoDisable; - - prim_geom = IntPtr.Zero; - - _mesh = null; - m_meshfailed = false; - _pbs = pbs; - - _parent_scene = parent_scene; - m_targetSpace = (IntPtr)0; - - if(sdata != null && sdata.Length > 1) - DeSerialize(sdata); - - if (m_isphysical) - m_targetSpace = _parent_scene.space; - - _triMeshData = IntPtr.Zero; - - m_primName = primName; - m_taintserial = null; - m_taintadd = true; - _parent_scene.AddPhysicsActorTaint(this); - // don't do .add() here; old geoms get recycled with the same hash - } - public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size, Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode, uint localid) { @@ -776,8 +374,9 @@ namespace OpenSim.Region.Physics.OdePlugin } _triMeshData = IntPtr.Zero; + m_NoColide = false; - m_taintserial = null; +// m_taintserial = null; m_primName = primName; m_taintadd = true; _parent_scene.AddPhysicsActorTaint(this); @@ -814,7 +413,6 @@ namespace OpenSim.Region.Physics.OdePlugin { set { - //Console.WriteLine("Sel {0} {1} {2}", m_primName, value, m_isphysical); // This only makes the object not collidable if the object // is physical or the object is modified somehow *IN THE FUTURE* @@ -1077,7 +675,6 @@ namespace OpenSim.Region.Physics.OdePlugin } } - public override bool FloatOnWater { set @@ -1270,7 +867,6 @@ namespace OpenSim.Region.Physics.OdePlugin } } - public void SetGeom(IntPtr geom) { if (prim_geom != IntPtr.Zero) @@ -1290,9 +886,23 @@ namespace OpenSim.Region.Physics.OdePlugin { _parent_scene.geom_name_map[prim_geom] = this.m_primName; _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this; - d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); //Console.WriteLine("**** Create {2} Dicts: actor={0} name={1}", _parent_scene.actor_name_map.Count, _parent_scene.geom_name_map.Count, this.m_primName); + if (m_NoColide) + { + d.GeomSetCategoryBits(prim_geom, 0); + if (m_isphysical) + { + d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); + d.GeomDisable(prim_geom); + } + else + d.GeomSetCollideBits(prim_geom, 0); + } + else + { + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + } } if (childPrim) @@ -1351,11 +961,20 @@ namespace OpenSim.Region.Physics.OdePlugin myrot.W = _orientation.W; d.BodySetQuaternion(Body, ref myrot); d.GeomSetBody(prim_geom, Body); + m_collisionCategories |= CollisionCategories.Body; m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); - d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + if (m_NoColide) + { + d.GeomSetCategoryBits(prim_geom, 0); + d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); + } + else + { + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + } d.BodySetAutoDisableFlag(Body, true); d.BodySetAutoDisableSteps(Body, body_autodisable_frames); @@ -1723,11 +1342,19 @@ namespace OpenSim.Region.Physics.OdePlugin if (prim_geom != IntPtr.Zero) { - d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + if (m_NoColide) + { + d.GeomSetCategoryBits(prim_geom, 0); + d.GeomSetCollideBits(prim_geom, 0); + d.GeomDisable(prim_geom); + } + else + { + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + } } - d.BodyDestroy(Body); lock (childrenPrim) { @@ -1735,6 +1362,13 @@ namespace OpenSim.Region.Physics.OdePlugin { foreach (OdePrim prm in childrenPrim) { + if (prm.m_NoColide && prm.prim_geom != IntPtr.Zero) + { + d.GeomSetCategoryBits(prm.prim_geom, 0); + d.GeomSetCollideBits(prm.prim_geom, 0); + d.GeomDisable(prm.prim_geom); + } + _parent_scene.remActivePrim(prm); prm.Body = IntPtr.Zero; } @@ -1752,8 +1386,18 @@ namespace OpenSim.Region.Physics.OdePlugin if (prim_geom != IntPtr.Zero) { - d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + if (m_NoColide) + { + d.GeomSetCategoryBits(prim_geom, 0); + d.GeomSetCollideBits(prim_geom, 0); + d.GeomDisable(prim_geom); + } + else + { + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + } + } @@ -1768,11 +1412,6 @@ namespace OpenSim.Region.Physics.OdePlugin public bool setMesh(OdeScene parent_scene, IMesh mesh) { - // This sleeper is there to moderate how long it takes between - // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object - - //Thread.Sleep(10); - //Kill Body so that mesh can re-make the geom if (IsPhysical && Body != IntPtr.Zero) { @@ -1790,14 +1429,6 @@ namespace OpenSim.Region.Physics.OdePlugin } } -// do it on caller instead -/* - if (_triMeshData != IntPtr.Zero) - { - d.GeomTriMeshDataDestroy(_triMeshData); - _triMeshData = IntPtr.Zero; - } -*/ IntPtr vertices, indices; int vertexCount, indexCount; int vertexStride, triStride; @@ -1809,38 +1440,20 @@ namespace OpenSim.Region.Physics.OdePlugin if (vertexCount == 0 || indexCount == 0) { - m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. It can be a sculp with alpha channel in map. Replacing it by a small box.", Name, _position.X, _position.Y, _position.Z); - _size.X = 0.05f; - _size.Y = 0.05f; - _size.Z = 0.05f; + m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. mesh UUID {4}", Name, _position.X, _position.Y, _position.Z, _pbs.SculptTexture.ToString()); return false; } -/* - if (m_MeshToTriMeshMap.ContainsKey(mesh)) - { - _triMeshData = m_MeshToTriMeshMap[mesh]; - } - else -*/ - - - { - _triMeshData = d.GeomTriMeshDataCreate(); - - d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); - d.GeomTriMeshDataPreprocess(_triMeshData); -// m_MeshToTriMeshMap[mesh] = _triMeshData; - } - - _parent_scene.waitForSpaceUnlock(m_targetSpace); + IntPtr geo = IntPtr.Zero; try { - // if (prim_geom == IntPtr.Zero) // setGeom takes care of phys engine recreate and prim_geom pointer - // { - // SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null)); - SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null)); - // } + _triMeshData = d.GeomTriMeshDataCreate(); + d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); + d.GeomTriMeshDataPreprocess(_triMeshData); + + _parent_scene.waitForSpaceUnlock(m_targetSpace); + + geo = d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null); } catch (Exception e) { @@ -1851,21 +1464,11 @@ namespace OpenSim.Region.Physics.OdePlugin d.GeomTriMeshDataDestroy(_triMeshData); _triMeshData = IntPtr.Zero; } - _size.X = 0.05f; - _size.Y = 0.05f; - _size.Z = 0.05f; return false; } + SetGeom(geo); - // if (IsPhysical && Body == (IntPtr) 0) - // { - // Recreate the body - // m_interpenetrationcount = 0; - // m_collisionscore = 0; - - // enableBody(); - // } return true; } @@ -1943,18 +1546,21 @@ namespace OpenSim.Region.Physics.OdePlugin if (m_taintvehicledata != null) DoSetVehicle(); - if (m_taintserial != null) - DoSerialize(m_taintserial); - /* obsolete if (!m_angularLock.ApproxEquals(m_taintAngularLock,0f)) changeAngularLock(timestep); */ } + else { - m_log.Error("[PHYSICS]: The scene reused a disposed PhysActor! *waves finger*, Don't be evil. A couple of things can cause this. An improper prim breakdown(be sure to set prim_geom to zero after d.GeomDestroy! An improper buildup (creating the geom failed). Or, the Scene Reused a physics actor after disposing it.)"); + m_log.Error("[PHYSICS]: prim {0} at <{1},{2},{3}> as invalid geom"); + + // not sure this will not flame... + m_taintremove = true; + _parent_scene.AddPhysicsActorTaint(this); } + } /* obsolete @@ -2058,7 +1664,6 @@ namespace OpenSim.Region.Physics.OdePlugin } foreach (OdePrim prm in childrenPrim) { - prm.m_collisionCategories |= CollisionCategories.Body; prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); @@ -2067,9 +1672,17 @@ namespace OpenSim.Region.Physics.OdePlugin m_log.Warn("[PHYSICS]: Unable to link one of the linkset elements. No geom yet"); continue; } - d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); - d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); + if (prm.m_NoColide) + { + d.GeomSetCategoryBits(prm.prim_geom, 0); + d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land); + } + else + { + d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); + d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); + } d.Quaternion quat = new d.Quaternion(); quat.W = prm._orientation.W; @@ -2098,20 +1711,28 @@ namespace OpenSim.Region.Physics.OdePlugin m_log.Debug("[PHYSICS]:I ain't got no boooooooooddy, no body"); } - prm.m_interpenetrationcount = 0; prm.m_collisionscore = 0; prm.m_disabled = false; prm.Body = Body; - _parent_scene.addActivePrim(prm); + + _parent_scene.addActivePrim(prm); } + m_collisionCategories |= CollisionCategories.Body; m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); - d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); - + if (m_NoColide) + { + d.GeomSetCategoryBits(prim_geom, 0); + d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); + } + else + { + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + } d.Quaternion quat2 = new d.Quaternion(); quat2.W = _orientation.W; @@ -2134,19 +1755,18 @@ namespace OpenSim.Region.Physics.OdePlugin d.BodySetAutoDisableFlag(Body, true); d.BodySetAutoDisableSteps(Body, body_autodisable_frames); - m_interpenetrationcount = 0; m_collisionscore = 0; m_disabled = false; d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); if (m_type != Vehicle.TYPE_NONE) Enable(Body, _parent_scene); + _parent_scene.addActivePrim(this); } } } } - } private void ChildSetGeom(OdePrim odePrim) @@ -2258,6 +1878,8 @@ namespace OpenSim.Region.Physics.OdePlugin { d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + if (m_NoColide) + d.GeomDisable(prim_geom); } if (m_isphysical) @@ -2275,22 +1897,35 @@ namespace OpenSim.Region.Physics.OdePlugin } else { - m_collisionCategories = CollisionCategories.Geom; + m_collisionCategories = CollisionCategories.Geom; + if (m_isphysical) + m_collisionCategories |= CollisionCategories.Body; - if (m_isphysical) - m_collisionCategories |= CollisionCategories.Body; + m_collisionFlags = m_default_collisionFlags; - m_collisionFlags = m_default_collisionFlags; - - if (m_collidesLand) - m_collisionFlags |= CollisionCategories.Land; - if (m_collidesWater) - m_collisionFlags |= CollisionCategories.Water; + if (m_collidesLand) + m_collisionFlags |= CollisionCategories.Land; + if (m_collidesWater) + m_collisionFlags |= CollisionCategories.Water; if (prim_geom != IntPtr.Zero) { - d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + if (m_NoColide) + { + d.GeomSetCategoryBits(prim_geom, 0); + if (m_isphysical) + d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); + else + { + d.GeomSetCollideBits(prim_geom, 0); + d.GeomDisable(prim_geom); + } + } + else + { + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + } } if (Body != IntPtr.Zero) { @@ -2330,19 +1965,29 @@ namespace OpenSim.Region.Physics.OdePlugin { bool gottrimesh = false; + m_NoColide = false; // assume all will go well + if (_triMeshData != IntPtr.Zero) { d.GeomTriMeshDataDestroy(_triMeshData); _triMeshData = IntPtr.Zero; } - if (_mesh != null) // Special - make mesh + if (_mesh != null) { gottrimesh = setMesh(_parent_scene, _mesh); + if (!gottrimesh) + { + // getting a mesh failed, + // lets go on having a basic box or sphere, with prim size but not coliding + // physical colides with land, non with nothing + + m_NoColide = true; + } } - if (!gottrimesh) // not a mesh - { + if (!gottrimesh) + { // we will have a basic box or sphere IntPtr geo = IntPtr.Zero; if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1 @@ -2376,14 +2021,17 @@ namespace OpenSim.Region.Physics.OdePlugin } } - if (geo == IntPtr.Zero) + if (geo == IntPtr.Zero) // if this happens it must be fixed { + // if it does lets stop what we can + // not sure this will not flame... + m_taintremove = true; _parent_scene.AddPhysicsActorTaint(this); return; } - SetGeom(geo); + SetGeom(geo); // this processes the m_NoColide } } @@ -2415,7 +2063,6 @@ namespace OpenSim.Region.Physics.OdePlugin } } - lock (_parent_scene.OdeLock) { CreateGeom(m_targetSpace, _mesh); @@ -2518,8 +2165,6 @@ namespace OpenSim.Region.Physics.OdePlugin m_taintposition = _position; } - - public void rotate(float timestep) { d.Quaternion myrot = new d.Quaternion(); diff --git a/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs index a57ebe9af9..0266ef0ef5 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs @@ -1735,7 +1735,7 @@ namespace OpenSim.Region.Physics.OdePlugin return newPrim; } - +/* private PhysicsActor AddPrim(String name, Vector3 position, PhysicsActor parent, PrimitiveBaseShape pbs, uint localid, byte[] sdata) { @@ -1751,7 +1751,7 @@ namespace OpenSim.Region.Physics.OdePlugin return newPrim; } - +*/ public void addActivePrim(OdePrim activatePrim) { @@ -1778,7 +1778,7 @@ namespace OpenSim.Region.Physics.OdePlugin return result; } - +/* public override PhysicsActor AddPrimShape(string primName, PhysicsActor parent, PrimitiveBaseShape pbs, Vector3 position, uint localid, byte[] sdata) { @@ -1789,7 +1789,7 @@ namespace OpenSim.Region.Physics.OdePlugin return result; } - +*/ public override float TimeDilation { get { return m_timeDilation; } From a0d75be56be66e7e7dd04c8ae7760596d135af99 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 29 Feb 2012 05:14:29 +0000 Subject: [PATCH 02/12] fix --- OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index 514074c2cf..3ed3b5a3c8 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -893,10 +893,12 @@ namespace OpenSim.Region.Physics.OdePlugin if (m_isphysical) { d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); - d.GeomDisable(prim_geom); } else + { d.GeomSetCollideBits(prim_geom, 0); + d.GeomDisable(prim_geom); + } } else { From a8f1cd7e8643fc6f4f4f12b1af3e52b9830f5a5a Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 29 Feb 2012 19:32:23 +0000 Subject: [PATCH 03/12] update ubitODE to current working state --- .../Region/Physics/UbitOdePlugin/ODEPrim.cs | 189 +++++++++++------- .../Region/Physics/UbitOdePlugin/OdeScene.cs | 123 ++++++++---- 2 files changed, 199 insertions(+), 113 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index 0ccdbc0d3a..17f38e881b 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs @@ -155,6 +155,8 @@ namespace OpenSim.Region.Physics.OdePlugin public float m_collisionscore; int m_colliderfilter = 0; + public IntPtr collide_geom; // for objects: geom if single prim space it linkset + private float m_density = 10.000006836f; // Aluminum g/cm3; public bool _zeroFlag; @@ -453,8 +455,6 @@ namespace OpenSim.Region.Physics.OdePlugin { get { - // Averate previous velocity with the new one so - // client object interpolation works a 'little' better if (_zeroFlag) return Vector3.Zero; return _velocity; @@ -833,6 +833,7 @@ namespace OpenSim.Region.Physics.OdePlugin body_autodisable_frames = parent_scene.bodyFramesAutoDisable; prim_geom = IntPtr.Zero; + collide_geom = IntPtr.Zero; Body = IntPtr.Zero; if (!size.IsFinite()) @@ -1367,7 +1368,7 @@ namespace OpenSim.Region.Physics.OdePlugin d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); m_collisionscore = 0; - if (m_targetSpace != _parent_scene.ActiveSpace) +// if (m_targetSpace != _parent_scene.ActiveSpace) { if (m_targetSpace != IntPtr.Zero) { @@ -1376,9 +1377,26 @@ namespace OpenSim.Region.Physics.OdePlugin d.SpaceRemove(m_targetSpace, prim_geom); } +// m_targetSpace = _parent_scene.ActiveSpace; +// d.SpaceAdd(m_targetSpace, prim_geom); + } + + + if (childrenPrim.Count == 0) + { + collide_geom = prim_geom; m_targetSpace = _parent_scene.ActiveSpace; d.SpaceAdd(m_targetSpace, prim_geom); } + else + { + m_targetSpace = d.HashSpaceCreate(_parent_scene.ActiveSpace); + d.HashSpaceSetLevels(m_targetSpace, -2, 8); + d.SpaceSetSublevel(m_targetSpace, 3); + d.SpaceSetCleanup(m_targetSpace, false); + d.SpaceAdd(m_targetSpace, prim_geom); + collide_geom = m_targetSpace; + } lock (childrenPrim) { @@ -1396,15 +1414,15 @@ namespace OpenSim.Region.Physics.OdePlugin d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); prm.m_collisionscore = 0; - if (prm.m_targetSpace != _parent_scene.ActiveSpace) + if (prm.m_targetSpace != m_targetSpace) { if (prm.m_targetSpace != IntPtr.Zero) { - _parent_scene.waitForSpaceUnlock(m_targetSpace); + _parent_scene.waitForSpaceUnlock(prm.m_targetSpace); if (d.SpaceQuery(prm.m_targetSpace, prm.prim_geom)) d.SpaceRemove(prm.m_targetSpace, prm.prim_geom); } - prm.m_targetSpace = _parent_scene.ActiveSpace; + prm.m_targetSpace = m_targetSpace; d.SpaceAdd(m_targetSpace, prm.prim_geom); } @@ -1427,8 +1445,14 @@ namespace OpenSim.Region.Physics.OdePlugin d.GeomDisable(prim_geom); d.BodyDisable(Body); } + else + { + d.BodySetAngularVel(Body, m_rotationalVelocity.X, m_rotationalVelocity.Y, m_rotationalVelocity.Z); + d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z); + } _parent_scene.addActivePrim(this); + _parent_scene.addActiveGroups(this); } private void DestroyBody() @@ -1473,6 +1497,7 @@ namespace OpenSim.Region.Physics.OdePlugin d.JointDestroy(Amotor); Amotor = IntPtr.Zero; } + _parent_scene.remActiveGroup(this); d.BodyDestroy(Body); } Body = IntPtr.Zero; @@ -2390,8 +2415,8 @@ namespace OpenSim.Region.Physics.OdePlugin else */ DestroyBody(); - Stop(); } + Stop(); } } @@ -2576,7 +2601,8 @@ namespace OpenSim.Region.Physics.OdePlugin if ((bool)newbuilding) { m_building = true; - DestroyBody(); + if (!childPrim) + DestroyBody(); } else { @@ -2648,12 +2674,95 @@ namespace OpenSim.Region.Physics.OdePlugin public void Move() { if (!childPrim && m_isphysical && Body != IntPtr.Zero && - !m_disabled && !m_isSelected && d.BodyIsEnabled(Body) && !m_building) // KF: Only move root prims. + !m_disabled && !m_isSelected && d.BodyIsEnabled(Body) && !m_building && !m_outbounds) + // !m_disabled && !m_isSelected && !m_building && !m_outbounds) { - // if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); // KF add 161009 +// if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); // KF add 161009 float timestep = _parent_scene.ODE_STEPSIZE; + // check outside region + d.Vector3 lpos; + d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator + + if (lpos.Z < -100 || lpos.Z > 100000f) + { + m_outbounds = true; + + lpos.Z = Util.Clip(lpos.Z, -100f, 100000f); + _acceleration.X = 0; + _acceleration.Y = 0; + _acceleration.Z = 0; + + _velocity.X = 0; + _velocity.Y = 0; + _velocity.Z = 0; + m_rotationalVelocity.X = 0; + m_rotationalVelocity.Y = 0; + m_rotationalVelocity.Z = 0; + + d.BodySetLinearVel(Body, 0, 0, 0); // stop it + d.BodySetAngularVel(Body, 0, 0, 0); // stop it + d.BodySetPosition(Body, lpos.X, lpos.Y, lpos.Z); // put it somewhere + m_lastposition = _position; + m_lastorientation = _orientation; + + base.RequestPhysicsterseUpdate(); + + m_throttleUpdates = false; + throttleCounter = 0; + _zeroFlag = true; + + disableBodySoft(); // disable it and colisions + base.RaiseOutOfBounds(_position); + return; + } + + if (lpos.X < 0f) + { + _position.X = Util.Clip(lpos.X, -2f, -0.1f); + m_outbounds = true; + } + else if(lpos.X > _parent_scene.WorldExtents.X) + { + _position.X = Util.Clip(lpos.X, _parent_scene.WorldExtents.X + 0.1f, _parent_scene.WorldExtents.X + 2f); + m_outbounds = true; + } + if (lpos.Y < 0f) + { + _position.Y = Util.Clip(lpos.Y, -2f, -0.1f); + m_outbounds = true; + } + else if(lpos.Y > _parent_scene.WorldExtents.Y) + { + _position.Y = Util.Clip(lpos.Y, _parent_scene.WorldExtents.Y + 0.1f, _parent_scene.WorldExtents.Y + 2f); + m_outbounds = true; + } + + if(m_outbounds) + { + m_lastposition = _position; + m_lastorientation = _orientation; + + d.Vector3 dtmp = d.BodyGetAngularVel(Body); + m_rotationalVelocity.X = dtmp.X; + m_rotationalVelocity.Y = dtmp.Y; + m_rotationalVelocity.Z = dtmp.Z; + + dtmp = d.BodyGetLinearVel(Body); + _velocity.X = dtmp.X; + _velocity.Y = dtmp.Y; + _velocity.Z = dtmp.Z; + + d.BodySetLinearVel(Body, 0, 0, 0); // stop it + d.BodySetAngularVel(Body, 0, 0, 0); + d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + disableBodySoft(); // stop collisions + base.RequestPhysicsterseUpdate(); + return; + } + + float fx = 0; float fy = 0; float fz = 0; @@ -2862,7 +2971,7 @@ namespace OpenSim.Region.Physics.OdePlugin public void UpdatePositionAndVelocity(float simulatedtime) { // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! - if (_parent == null && !m_disabled && !m_building) + if (_parent == null && !m_disabled && !m_building && !m_outbounds) { if (Body != IntPtr.Zero) { @@ -2872,64 +2981,6 @@ namespace OpenSim.Region.Physics.OdePlugin d.Vector3 lpos; d.GeomCopyPosition(prim_geom, out lpos); // root position that is seem by rest of simulator - // we need to use root position since that's all the rest of scene uses - if (lpos.X < 0f || lpos.X > _parent_scene.WorldExtents.X - || lpos.Y < 0f || lpos.Y > _parent_scene.WorldExtents.Y - ) - { - // we are outside current region - // we can't let it keeping moving and having colisions - // since it can be stucked between something like terrain and edge - // so lets stop and disable it until something else kicks it - - _position.X = Util.Clip(lpos.X, -0.2f, _parent_scene.WorldExtents.X + 0.2f); - _position.Y = Util.Clip(lpos.Y, -0.2f, _parent_scene.WorldExtents.Y + 0.2f); - _position.Z = Util.Clip(lpos.Z, -100f, 50000f); - - m_lastposition = _position; -// m_lastorientation = _orientation; - - d.BodySetLinearVel(Body, 0, 0, 0); // stop it -// d.BodySetAngularVel(Body, 0, 0, 0); - d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); - disableBodySoft(); // stop collisions - m_outbounds = true; - base.RequestPhysicsterseUpdate(); - return; - } - - if (lpos.Z < -100 || lpos.Z > 100000f) - { - lpos.Z = Util.Clip(lpos.Z, -100f, 50000f); - - _acceleration.X = 0; - _acceleration.Y = 0; - _acceleration.Z = 0; - - _velocity.X = 0; - _velocity.Y = 0; - _velocity.Z = 0; - m_rotationalVelocity.X = 0; - m_rotationalVelocity.Y = 0; - m_rotationalVelocity.Z = 0; - - d.BodySetLinearVel(Body, 0, 0, 0); // stop it - d.BodySetAngularVel(Body, 0, 0, 0); // stop it - d.BodySetPosition(Body, lpos.X, lpos.Y, lpos.Z); // put it somewhere - m_lastposition = _position; - m_lastorientation = _orientation; - - base.RequestPhysicsterseUpdate(); - - m_throttleUpdates = false; - throttleCounter = 0; - _zeroFlag = true; - - disableBodySoft(); // disable it and colisions - base.RaiseOutOfBounds(_position); - - return; - } d.Quaternion ori; d.GeomCopyQuaternion(prim_geom, out ori); diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 6e4c373a56..ccb4c23a9d 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -224,6 +224,7 @@ namespace OpenSim.Region.Physics.OdePlugin private readonly HashSet _characters = new HashSet(); private readonly HashSet _prims = new HashSet(); private readonly HashSet _activeprims = new HashSet(); + private readonly HashSet _activegroups = new HashSet(); public OpenSim.Framework.LocklessQueue ChangesQueue = new OpenSim.Framework.LocklessQueue(); @@ -1013,15 +1014,24 @@ namespace OpenSim.Region.Physics.OdePlugin } - // collide active prims with static enviroment lock (_activeprims) + { + foreach (OdePrim aprim in _activeprims) + { + aprim.CollisionScore = 0; + aprim.IsColliding = false; + } + } + + // collide active prims with static enviroment + lock (_activegroups) { try { - foreach (OdePrim prm in _activeprims) + foreach (OdePrim prm in _activegroups) { - if (d.BodyIsEnabled(prm.Body)) - d.SpaceCollide2(StaticSpace, prm.prim_geom, IntPtr.Zero, nearCallback); + if (d.BodyIsEnabled(prm.Body) && !prm.m_outbounds) + d.SpaceCollide2(StaticSpace, prm.collide_geom, IntPtr.Zero, nearCallback); } } catch (AccessViolationException) @@ -1029,7 +1039,6 @@ namespace OpenSim.Region.Physics.OdePlugin m_log.Warn("[PHYSICS]: Unable to collide Active prim to static space"); } } - // finally colide active things amoung them try { @@ -1039,7 +1048,6 @@ namespace OpenSim.Region.Physics.OdePlugin { m_log.Warn("[PHYSICS]: Unable to collide in Active space"); } - // _perloopContact.Clear(); } @@ -1148,13 +1156,20 @@ namespace OpenSim.Region.Physics.OdePlugin public void addActivePrim(OdePrim activatePrim) { - // adds active prim.. (ones that should be iterated over in collisions_optimized + // adds active prim.. lock (_activeprims) { if (!_activeprims.Contains(activatePrim)) _activeprims.Add(activatePrim); - //else - // m_log.Warn("[PHYSICS]: Double Entry in _activeprims detected, potential crash immenent"); + } + } + + public void addActiveGroups(OdePrim activatePrim) + { + lock (_activegroups) + { + if (!_activegroups.Contains(activatePrim)) + _activegroups.Add(activatePrim); } } @@ -1186,6 +1201,13 @@ namespace OpenSim.Region.Physics.OdePlugin _activeprims.Remove(deactivatePrim); } } + public void remActiveGroup(OdePrim deactivatePrim) + { + lock (_activegroups) + { + _activegroups.Remove(deactivatePrim); + } + } public override void RemovePrim(PhysicsActor prim) { @@ -1258,6 +1280,11 @@ namespace OpenSim.Region.Physics.OdePlugin { waitForSpaceUnlock(currentspace); d.SpaceRemove(currentspace, geom); + + if (d.SpaceGetSublevel(currentspace) > 2 && d.SpaceGetNumGeoms(currentspace) == 0) + { + d.SpaceDestroy(currentspace); + } } else { @@ -1274,6 +1301,12 @@ namespace OpenSim.Region.Physics.OdePlugin { waitForSpaceUnlock(currentspace); d.SpaceRemove(currentspace, geom); + + if (d.SpaceGetSublevel(currentspace) > 1 && d.SpaceGetNumGeoms(currentspace) == 0) + { + d.SpaceDestroy(currentspace); + } + } } } @@ -1577,42 +1610,14 @@ namespace OpenSim.Region.Physics.OdePlugin statchanges += Util.EnvironmentTickCountSubtract(statstart); - // Move characters - lock (_characters) - { - List defects = new List(); - foreach (OdeCharacter actor in _characters) - { - if (actor != null) - actor.Move(ODE_STEPSIZE, defects); - } - if (defects.Count != 0) - { - foreach (OdeCharacter defect in defects) - { - RemoveCharacter(defect); - } - } - } - statchmove += Util.EnvironmentTickCountSubtract(statstart); - - // Move other active objects - lock (_activeprims) - { - foreach (OdePrim aprim in _activeprims) - { - aprim.CollisionScore = 0; - aprim.IsColliding = false; - aprim.Move(); - } - } - statactmove += Util.EnvironmentTickCountSubtract(statstart); //if ((framecount % m_randomizeWater) == 0) // randomizeWater(waterlevel); m_rayCastManager.ProcessQueuedRequests(); + + statray += Util.EnvironmentTickCountSubtract(statstart); collision_optimized(); statcol += Util.EnvironmentTickCountSubtract(statstart); @@ -1642,8 +1647,35 @@ namespace OpenSim.Region.Physics.OdePlugin d.WorldQuickStep(world, ODE_STEPSIZE); statstep += Util.EnvironmentTickCountSubtract(statstart); - d.JointGroupEmpty(contactgroup); - totjcontact += m_global_contactcount; + + // Move characters + lock (_characters) + { + List defects = new List(); + foreach (OdeCharacter actor in _characters) + { + if (actor != null) + actor.Move(ODE_STEPSIZE, defects); + } + if (defects.Count != 0) + { + foreach (OdeCharacter defect in defects) + { + RemoveCharacter(defect); + } + } + } + statchmove += Util.EnvironmentTickCountSubtract(statstart); + + // Move other active objects + lock (_activegroups) + { + foreach (OdePrim aprim in _activegroups) + { + aprim.Move(); + } + } + //ode.dunlock(world); } catch (Exception e) @@ -1652,6 +1684,9 @@ namespace OpenSim.Region.Physics.OdePlugin // ode.dunlock(world); } + d.JointGroupEmpty(contactgroup); + totjcontact += m_global_contactcount; + step_time -= ODE_STEPSIZE; nodeframes++; } @@ -1686,10 +1721,10 @@ namespace OpenSim.Region.Physics.OdePlugin } statmovchar = Util.EnvironmentTickCountSubtract(statstart); - lock (_activeprims) + lock (_activegroups) { { - foreach (OdePrim actor in _activeprims) + foreach (OdePrim actor in _activegroups) { if (actor.IsPhysical) { @@ -1966,7 +2001,7 @@ namespace OpenSim.Region.Physics.OdePlugin d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); d.GeomSetRotation(GroundGeom, ref R); - d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f - 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f - 0.5f, 0); + d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f, 0); RegionTerrain.Add(pOffset, GroundGeom, GroundGeom); // TerrainHeightFieldHeights.Add(GroundGeom, ODElandMap); TerrainHeightFieldHeights.Add(GroundGeom, _heightmap); From ee4d3bfad2c9660637c24195a68d3f4484fed0b7 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 29 Feb 2012 19:36:16 +0000 Subject: [PATCH 04/12] ubitODE bug fix --- OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index ccb4c23a9d..eb5c687add 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -1302,7 +1302,7 @@ namespace OpenSim.Region.Physics.OdePlugin waitForSpaceUnlock(currentspace); d.SpaceRemove(currentspace, geom); - if (d.SpaceGetSublevel(currentspace) > 1 && d.SpaceGetNumGeoms(currentspace) == 0) + if (d.SpaceGetSublevel(currentspace) > 2 && d.SpaceGetNumGeoms(currentspace) == 0) { d.SpaceDestroy(currentspace); } From f42fd7fb773cc317f36e747579e9f8e28cfe2049 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 2 Mar 2012 15:05:30 +0000 Subject: [PATCH 05/12] update ubitODE --- .../Physics/UbitOdePlugin/ODEDynamics.cs | 64 ++++++++++++++----- 1 file changed, 47 insertions(+), 17 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs index c9d0909a60..4f82c243a3 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs @@ -38,7 +38,7 @@ * settings use. */ -// Ubit 2012 +// Extensive change Ubit 2012 using System; using System.Collections.Generic; @@ -614,6 +614,7 @@ namespace OpenSim.Region.Physics.OdePlugin return vec; } + private const float pi = (float)Math.PI; private const float halfpi = 0.5f * (float)Math.PI; public static Vector3 ubitRot2Euler(Quaternion rot) @@ -884,35 +885,64 @@ namespace OpenSim.Region.Physics.OdePlugin float ftmp = 1.0f / m_verticalAttractionTimescale / m_verticalAttractionTimescale / _pParentScene.ODE_STEPSIZE; float ftmp2 = m_verticalAttractionEfficiency / _pParentScene.ODE_STEPSIZE; - if (Math.Abs(roll) > 0.01) // roll + if (roll > halfpi) + roll = pi - roll; + else if (roll < -halfpi) + roll = -pi - roll; + + float effroll = pitch / halfpi; + effroll *= effroll; + effroll = 1 - effroll; + effroll *= roll; + + if (Math.Abs(effroll) > 0.01) // roll { - torque.X -= -roll * ftmp + curLocalAngVel.X * ftmp2; + torque.X -= -effroll * ftmp + curLocalAngVel.X * ftmp2; } - if (Math.Abs(pitch) > 0.01 && ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) == 0)) // pitch + if ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) == 0) { - torque.Y -= -pitch * ftmp + curLocalAngVel.Y * ftmp2; + float effpitch = roll / halfpi; + effpitch *= effpitch; + effpitch = 1 - effpitch; + effpitch *= pitch; + + if (Math.Abs(effpitch) > 0.01) // pitch + { + torque.Y -= -effpitch * ftmp + curLocalAngVel.Y * ftmp2; + } } - if (m_bankingEfficiency != 0 && Math.Abs(roll) > 0.01) + if (m_bankingEfficiency != 0 && Math.Abs(effroll) > 0.01) { - float broll = roll * m_bankingEfficiency; ; + + float broll = effroll; +/* + if (broll > halfpi) + broll = pi - broll; + else if (broll < -halfpi) + broll = -pi - broll; +*/ + broll *= m_bankingEfficiency; if (m_bankingMix != 0) { float vfact = Math.Abs(curLocalVel.X) / 10.0f; if (vfact > 1.0f) vfact = 1.0f; - if (curLocalVel.X >= 0) - broll *= ((1 - m_bankingMix) + vfact); - else - broll *= -((1 - m_bankingMix) + vfact); - } - broll = (broll - curLocalAngVel.Z) / m_bankingTimescale; - // torque.Z += broll; + if (curLocalVel.X >= 0) + broll *= (1 + (vfact - 1) * m_bankingMix); + else + broll *= -(1 + (vfact - 1) * m_bankingMix); + } // make z rot be in world Z not local as seems to be in sl - tmpV.X = 0; - tmpV.Y = 0; - tmpV.Z = broll; + + broll = broll / m_bankingTimescale; + + ftmp = -Math.Abs(m_bankingEfficiency) / m_bankingTimescale; + + tmpV.X = ftmp * curAngVel.X; + tmpV.Y = ftmp * curAngVel.Y; + tmpV.Z = broll + ftmp * curAngVel.Z; tmpV *= irotq; torque.X += tmpV.X; From 7c931037bd9d43b7de52534870ad15a645fe67d6 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 4 Mar 2012 01:40:12 +0000 Subject: [PATCH 06/12] update UbitODE --- .../Physics/UbitOdePlugin/ODEDynamics.cs | 11 +++ .../Region/Physics/UbitOdePlugin/ODEPrim.cs | 12 ++++ .../Region/Physics/UbitOdePlugin/OdeScene.cs | 68 +++++++++---------- 3 files changed, 55 insertions(+), 36 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs index 4f82c243a3..0fabb5670c 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs @@ -120,6 +120,16 @@ namespace OpenSim.Region.Physics.OdePlugin private float m_lmEfect = 0; // current linear motor eficiency private float m_amEfect = 0; // current angular motor eficiency + public bool EngineActive + { + get + { + if (m_lmEfect > 0.01) + return true; + return false; + } + } + public ODEDynamics(OdePrim rootp) { @@ -152,6 +162,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_linearMotorTimescale = vd.m_linearMotorTimescale; if (m_linearMotorTimescale < timestep) m_linearMotorTimescale = timestep; + m_linearMotorOffset = vd.m_linearMotorOffset; //Angular properties diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index 17f38e881b..e5fa1d773f 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs @@ -222,6 +222,18 @@ namespace OpenSim.Region.Physics.OdePlugin { get { + if (m_isphysical) + { + ODEDynamics veh; + if (_parent != null) + veh = ((OdePrim)_parent).m_vehicle; + else + veh = m_vehicle; + + if (veh != null) + if (veh.Type != Vehicle.TYPE_NONE && veh.EngineActive) + return new ContactData(0, 0); + } return primContactData; } } diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index eb5c687add..129db5d367 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -155,7 +155,7 @@ namespace OpenSim.Region.Physics.OdePlugin private readonly ILog m_log; // private Dictionary m_storedCollisions = new Dictionary(); - private int threadid = 0; +// private int threadid = 0; private Random fluidRandomizer = new Random(Environment.TickCount); const d.ContactFlags comumContactFlags = d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM |d.ContactFlags.Approx1 | d.ContactFlags.Bounce; @@ -168,7 +168,7 @@ namespace OpenSim.Region.Physics.OdePlugin float frictionMovementMult = 0.3f; float TerrainBounce = 0.1f; - float TerrainFriction = 0.1f; + float TerrainFriction = 0.3f; public float AvatarBounce = 0.3f; public float AvatarFriction = 0;// 0.9f * 0.5f; @@ -189,8 +189,8 @@ namespace OpenSim.Region.Physics.OdePlugin internal IntPtr WaterGeom; - public float avPIDD = 3200f; // make it visible - public float avPIDP = 1400f; // make it visible + public float avPIDD = 2200f; // make it visible + public float avPIDP = 900f; // make it visible private float avCapRadius = 0.37f; private float avDensity = 3f; private float avMovementDivisorWalk = 1.3f; @@ -202,7 +202,7 @@ namespace OpenSim.Region.Physics.OdePlugin public bool forceSimplePrimMeshing = false; public float meshSculptLOD = 32; - public float MeshSculptphysicalLOD = 16; + public float MeshSculptphysicalLOD = 32; public float geomDefaultDensity = 10.000006836f; @@ -212,12 +212,11 @@ namespace OpenSim.Region.Physics.OdePlugin public float bodyPIDD = 35f; public float bodyPIDG = 25; - public int geomCrossingFailuresBeforeOutofbounds = 6; +// public int geomCrossingFailuresBeforeOutofbounds = 6; public int bodyFramesAutoDisable = 20; private float[] _watermap; - private bool m_filterCollisions = true; private d.NearCallback nearCallback; @@ -388,9 +387,6 @@ namespace OpenSim.Region.Physics.OdePlugin // Defaults - avPIDD = 2200.0f; - avPIDP = 900.0f; - int contactsPerCollision = 80; if (m_config != null) @@ -398,57 +394,56 @@ namespace OpenSim.Region.Physics.OdePlugin IConfig physicsconfig = m_config.Configs["ODEPhysicsSettings"]; if (physicsconfig != null) { - gravityx = physicsconfig.GetFloat("world_gravityx", 0f); - gravityy = physicsconfig.GetFloat("world_gravityy", 0f); - gravityz = physicsconfig.GetFloat("world_gravityz", -9.8f); + gravityx = physicsconfig.GetFloat("world_gravityx", gravityx); + gravityy = physicsconfig.GetFloat("world_gravityy", gravityy); + gravityz = physicsconfig.GetFloat("world_gravityz", gravityz); - metersInSpace = physicsconfig.GetFloat("meters_in_small_space", 29.9f); + metersInSpace = physicsconfig.GetFloat("meters_in_small_space", metersInSpace); contactsurfacelayer = physicsconfig.GetFloat("world_contact_surface_layer", contactsurfacelayer); - ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", 0.020f); - m_physicsiterations = physicsconfig.GetInt("world_internal_steps_without_collisions", 10); + ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", ODE_STEPSIZE); + m_physicsiterations = physicsconfig.GetInt("world_internal_steps_without_collisions", m_physicsiterations); avDensity = physicsconfig.GetFloat("av_density", avDensity); - avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", 1.3f); - avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", 0.8f); - avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f); + avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", avMovementDivisorWalk); + avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", avMovementDivisorRun); + avCapRadius = physicsconfig.GetFloat("av_capsule_radius", avCapRadius); - contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80); + contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", contactsPerCollision); geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 3); geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15); - geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5); +// geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5); - geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", 10.000006836f); - bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", 20); + geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity); + bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable); - bodyPIDD = physicsconfig.GetFloat("body_pid_derivative", 35f); - bodyPIDG = physicsconfig.GetFloat("body_pid_gain", 25f); + bodyPIDD = physicsconfig.GetFloat("body_pid_derivative", bodyPIDD); + bodyPIDG = physicsconfig.GetFloat("body_pid_gain", bodyPIDG); forceSimplePrimMeshing = physicsconfig.GetBoolean("force_simple_prim_meshing", forceSimplePrimMeshing); - meshSculptedPrim = physicsconfig.GetBoolean("mesh_sculpted_prim", true); - meshSculptLOD = physicsconfig.GetFloat("mesh_lod", 32f); - MeshSculptphysicalLOD = physicsconfig.GetFloat("mesh_physical_lod", 16f); - m_filterCollisions = physicsconfig.GetBoolean("filter_collisions", false); + meshSculptedPrim = physicsconfig.GetBoolean("mesh_sculpted_prim", meshSculptedPrim); + meshSculptLOD = physicsconfig.GetFloat("mesh_lod", meshSculptLOD); + MeshSculptphysicalLOD = physicsconfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD); if (Environment.OSVersion.Platform == PlatformID.Unix) { - avPIDD = physicsconfig.GetFloat("av_pid_derivative_linux", 2200.0f); - avPIDP = physicsconfig.GetFloat("av_pid_proportional_linux", 900.0f); + avPIDD = physicsconfig.GetFloat("av_pid_derivative_linux", avPIDD); + avPIDP = physicsconfig.GetFloat("av_pid_proportional_linux", avPIDP); } else { - avPIDD = physicsconfig.GetFloat("av_pid_derivative_win", 2200.0f); - avPIDP = physicsconfig.GetFloat("av_pid_proportional_win", 900.0f); + avPIDD = physicsconfig.GetFloat("av_pid_derivative_win", avPIDD); + avPIDP = physicsconfig.GetFloat("av_pid_proportional_win", avPIDP); } physics_logging = physicsconfig.GetBoolean("physics_logging", false); physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0); physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false); - minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", 3f); - maximumMassObject = physicsconfig.GetFloat("maximum_mass_object", 10000.01f); + minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", minimumGroundFlightOffset); + maximumMassObject = physicsconfig.GetFloat("maximum_mass_object", maximumMassObject); } } @@ -1941,13 +1936,14 @@ namespace OpenSim.Region.Physics.OdePlugin yy += regionsize; val = heightMap[yy + xx]; + if (val < 0.0f) + val = 0.0f; // no neg terrain as in chode _heightmap[xt + y] = val; if (hfmin > val) hfmin = val; if (hfmax < val) hfmax = val; - } xt += heightmapHeightSamples; } From 01fcd400d7651be5f4aae3547a0489a7ccc5d7f7 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 4 Mar 2012 04:26:05 +0000 Subject: [PATCH 07/12] update UbitOde --- .../Region/Physics/Manager/PhysicsActor.cs | 5 +- .../Physics/UbitOdePlugin/ODECharacter.cs | 12 ++-- .../Physics/UbitOdePlugin/ODEDynamics.cs | 19 ++++-- .../Region/Physics/UbitOdePlugin/ODEPrim.cs | 41 +++++++------ .../Region/Physics/UbitOdePlugin/OdeScene.cs | 59 +++++++++---------- 5 files changed, 70 insertions(+), 66 deletions(-) diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index f525e9e51e..25aa4dc2ce 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -158,9 +158,10 @@ namespace OpenSim.Region.Physics.Manager public virtual bool Building { get; set; } - public virtual ContactData ContactData + public virtual void getContactData(ref ContactData cdata) { - get { return new ContactData(0, 0); } + cdata.mu = 0; + cdata.bounce = 0; } public abstract bool Stopped { get; } diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index 793e281894..94cadb2a0f 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs @@ -136,7 +136,8 @@ namespace OpenSim.Region.Physics.OdePlugin public UUID m_uuid; public bool bad = false; - public ContactData AvatarContactData = new ContactData(10f, 0.3f); + float mu; + float bounce; public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, Vector3 size, float pid_d, float pid_p, float capsule_radius, float density, float walk_divisor, float rundivisor) { @@ -168,8 +169,8 @@ namespace OpenSim.Region.Physics.OdePlugin m_density = density; m_mass = 80f; // sure we have a default - AvatarContactData.mu = parent_scene.AvatarFriction; - AvatarContactData.bounce = parent_scene.AvatarBounce; + mu = parent_scene.AvatarFriction; + bounce = parent_scene.AvatarBounce; walkDivisor = walk_divisor; runDivisor = rundivisor; @@ -190,9 +191,10 @@ namespace OpenSim.Region.Physics.OdePlugin set { return; } } - public override ContactData ContactData + public override void getContactData(ref ContactData cdata) { - get { return AvatarContactData; } + cdata.mu = mu; + cdata.bounce = bounce; } public override bool Building { get; set; } diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs index 0fabb5670c..d0b45467a1 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs @@ -119,25 +119,22 @@ namespace OpenSim.Region.Physics.OdePlugin // auxiliar private float m_lmEfect = 0; // current linear motor eficiency private float m_amEfect = 0; // current angular motor eficiency + private float m_ffactor = 1.0f; - public bool EngineActive + public float FrictionFactor { get { - if (m_lmEfect > 0.01) - return true; - return false; + return m_ffactor; } } - public ODEDynamics(OdePrim rootp) { rootPrim = rootp; _pParentScene = rootPrim._parent_scene; } - public void DoSetVehicle(VehicleData vd) { @@ -212,6 +209,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_lmEfect = 0; m_amEfect = 0; + m_ffactor = 1.0f; } internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) @@ -329,6 +327,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (len > 30.0f) m_linearMotorDirection *= (30.0f / len); m_lmEfect = 1.0f; // turn it on + m_ffactor = 0.01f; if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) && !rootPrim.m_isSelected && !rootPrim.m_disabled) d.BodyEnable(rootPrim.Body); @@ -379,6 +378,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (len > 30.0f) m_linearMotorDirection *= (30.0f / len); m_lmEfect = 1.0f; // turn it on + m_ffactor = 0.01f; if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) && !rootPrim.m_isSelected && !rootPrim.m_disabled) d.BodyEnable(rootPrim.Body); @@ -425,6 +425,7 @@ namespace OpenSim.Region.Physics.OdePlugin float invtimestep = _pParentScene.ODE_STEPSIZE; m_lmEfect = 0; m_amEfect = 0; + m_ffactor = 1f; m_linearMotorDirection = Vector3.Zero; m_angularMotorDirection = Vector3.Zero; @@ -602,6 +603,7 @@ namespace OpenSim.Region.Physics.OdePlugin { m_lmEfect = 0; m_amEfect = 0; + m_ffactor = 1f; } public static Vector3 Xrot(Quaternion rot) @@ -752,9 +754,14 @@ namespace OpenSim.Region.Physics.OdePlugin force.Z += tmpV.Z; } m_lmEfect *= (1.0f - 1.0f / m_linearMotorDecayTimescale); + + m_ffactor = 0.01f + 1e-4f * curVel.LengthSquared(); } else + { m_lmEfect = 0; + m_ffactor = 1f; + } // friction if (curLocalVel.X != 0 || curLocalVel.Y != 0 || curLocalVel.Z != 0) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index e5fa1d773f..db07565a96 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs @@ -187,7 +187,8 @@ namespace OpenSim.Region.Physics.OdePlugin public ODEDynamics m_vehicle; internal int m_material = (int)Material.Wood; - protected ContactData primContactData = new ContactData { mu = 0f, bounce = 0.1f }; + private float mu; + private float bounce; /// /// Is this prim subject to physics? Even if not, it's still solid for collision purposes. @@ -218,25 +219,23 @@ namespace OpenSim.Region.Physics.OdePlugin } } - public override ContactData ContactData + public override void getContactData(ref ContactData cdata) { - get - { - if (m_isphysical) - { - ODEDynamics veh; - if (_parent != null) - veh = ((OdePrim)_parent).m_vehicle; - else - veh = m_vehicle; + cdata.mu = mu; + cdata.bounce = bounce; - if (veh != null) - if (veh.Type != Vehicle.TYPE_NONE && veh.EngineActive) - return new ContactData(0, 0); - } - return primContactData; + if (m_isphysical) + { + ODEDynamics veh; + if (_parent != null) + veh = ((OdePrim)_parent).m_vehicle; + else + veh = m_vehicle; + + if (veh != null && veh.Type != Vehicle.TYPE_NONE) + cdata.mu *= veh.FrictionFactor; } - } + } public override int PhysicsActorType { @@ -745,8 +744,8 @@ namespace OpenSim.Region.Physics.OdePlugin public override void SetMaterial(int pMaterial) { m_material = pMaterial; - primContactData.mu = _parent_scene.m_materialContactsData[pMaterial].mu; - primContactData.bounce = _parent_scene.m_materialContactsData[pMaterial].bounce; + mu = _parent_scene.m_materialContactsData[pMaterial].mu; + bounce = _parent_scene.m_materialContactsData[pMaterial].bounce; } public void setPrimForRemoval() @@ -899,8 +898,8 @@ namespace OpenSim.Region.Physics.OdePlugin m_isSelected = false; m_delaySelect = false; - primContactData.mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu; - primContactData.bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce; + mu = parent_scene.m_materialContactsData[(int)Material.Wood].mu; + bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce; CalcPrimBodyData(); diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 129db5d367..884a5a7946 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -163,8 +163,6 @@ namespace OpenSim.Region.Physics.OdePlugin const float comumSoftContactERP = 0.1f; const float comumContactCFM = 0.0001f; - float frictionScale = 1.0f; - float frictionMovementMult = 0.3f; float TerrainBounce = 0.1f; @@ -450,33 +448,30 @@ namespace OpenSim.Region.Physics.OdePlugin ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf); GlobalContactsArray = GlobalContactsArray = Marshal.AllocHGlobal(maxContactsbeforedeath * d.Contact.unmanagedSizeOf); - m_materialContactsData[(int)Material.Stone].mu = frictionScale * 0.8f; + m_materialContactsData[(int)Material.Stone].mu = 0.8f; m_materialContactsData[(int)Material.Stone].bounce = 0.4f; - m_materialContactsData[(int)Material.Metal].mu = frictionScale * 0.3f; + m_materialContactsData[(int)Material.Metal].mu = 0.3f; m_materialContactsData[(int)Material.Metal].bounce = 0.4f; - m_materialContactsData[(int)Material.Glass].mu = frictionScale * 0.2f; + m_materialContactsData[(int)Material.Glass].mu = 0.2f; m_materialContactsData[(int)Material.Glass].bounce = 0.7f; - m_materialContactsData[(int)Material.Wood].mu = frictionScale * 0.6f; + m_materialContactsData[(int)Material.Wood].mu = 0.6f; m_materialContactsData[(int)Material.Wood].bounce = 0.5f; - m_materialContactsData[(int)Material.Flesh].mu = frictionScale * 0.9f; + m_materialContactsData[(int)Material.Flesh].mu = 0.9f; m_materialContactsData[(int)Material.Flesh].bounce = 0.3f; - m_materialContactsData[(int)Material.Plastic].mu = frictionScale * 0.4f; + m_materialContactsData[(int)Material.Plastic].mu = 0.4f; m_materialContactsData[(int)Material.Plastic].bounce = 0.7f; - m_materialContactsData[(int)Material.Rubber].mu = frictionScale * 0.9f; + m_materialContactsData[(int)Material.Rubber].mu = 0.9f; m_materialContactsData[(int)Material.Rubber].bounce = 0.95f; m_materialContactsData[(int)Material.light].mu = 0.0f; m_materialContactsData[(int)Material.light].bounce = 0.0f; - TerrainFriction *= frictionScale; -// AvatarFriction *= frictionScale; - // Set the gravity,, don't disable things automatically (we set it explicitly on some things) d.WorldSetGravity(world, gravityx, gravityy, gravityz); @@ -562,13 +557,6 @@ namespace OpenSim.Region.Physics.OdePlugin } - /// - /// This is our near callback. A geometry is near a body - /// - /// The space that contains the geoms. Remember, spaces are also geoms - /// a geometry or space - /// another geometry or space - /// private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom) { @@ -580,7 +568,13 @@ namespace OpenSim.Region.Physics.OdePlugin return true; } - + /// + /// This is our near callback. A geometry is near a body + /// + /// The space that contains the geoms. Remember, spaces are also geoms + /// a geometry or space + /// another geometry or space + /// private void near(IntPtr space, IntPtr g1, IntPtr g2) { @@ -699,8 +693,8 @@ namespace OpenSim.Region.Physics.OdePlugin // big messy collision analises float mu = 0; float bounce = 0; - ContactData contactdata1; - ContactData contactdata2; + ContactData contactdata1 = new ContactData(0, 0); + ContactData contactdata2 = new ContactData(0, 0); bool erpSoft = false; String name = null; @@ -714,8 +708,9 @@ namespace OpenSim.Region.Physics.OdePlugin switch (p2.PhysicsActorType) { case (int)ActorTypes.Agent: - contactdata1 = p1.ContactData; - contactdata2 = p2.ContactData; + p1.getContactData(ref contactdata1); + p2.getContactData(ref contactdata2); + bounce = contactdata1.bounce * contactdata2.bounce; mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); @@ -727,8 +722,8 @@ namespace OpenSim.Region.Physics.OdePlugin p2.CollidingObj = true; break; case (int)ActorTypes.Prim: - contactdata1 = p1.ContactData; - contactdata2 = p2.ContactData; + p1.getContactData(ref contactdata1); + p2.getContactData(ref contactdata2); bounce = contactdata1.bounce * contactdata2.bounce; mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); @@ -749,8 +744,8 @@ namespace OpenSim.Region.Physics.OdePlugin switch (p2.PhysicsActorType) { case (int)ActorTypes.Agent: - contactdata1 = p1.ContactData; - contactdata2 = p2.ContactData; + p1.getContactData(ref contactdata1); + p2.getContactData(ref contactdata2); bounce = contactdata1.bounce * contactdata2.bounce; mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); @@ -768,8 +763,8 @@ namespace OpenSim.Region.Physics.OdePlugin p1.CollidingObj = true; p2.CollidingObj = true; } - contactdata1 = p1.ContactData; - contactdata2 = p2.ContactData; + p1.getContactData(ref contactdata1); + p2.getContactData(ref contactdata2); bounce = contactdata1.bounce * contactdata2.bounce; erpSoft = true; mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); @@ -784,7 +779,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (name == "Terrain") { erpSoft = true; - contactdata1 = p1.ContactData; + p1.getContactData(ref contactdata1); bounce = contactdata1.bounce * TerrainBounce; mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction); if (Math.Abs(p1.Velocity.X) > 0.1f || Math.Abs(p1.Velocity.Y) > 0.1f) @@ -811,7 +806,7 @@ namespace OpenSim.Region.Physics.OdePlugin { erpSoft = true; p2.CollidingGround = true; - contactdata2 = p2.ContactData; + p2.getContactData(ref contactdata2); bounce = contactdata2.bounce * TerrainBounce; mu = (float)Math.Sqrt(contactdata2.mu * TerrainFriction); From 7377e633c73f7ee34240cb70f0f75fcd9b705168 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 5 Mar 2012 12:37:21 +0000 Subject: [PATCH 08/12] update ubitOde --- .../Region/Physics/Manager/PhysicsActor.cs | 4 +- .../Physics/UbitOdePlugin/ODECharacter.cs | 1 + .../Region/Physics/UbitOdePlugin/ODEPrim.cs | 357 ++++++++++++++---- .../Region/Physics/UbitOdePlugin/OdeScene.cs | 15 +- 4 files changed, 298 insertions(+), 79 deletions(-) diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index 25aa4dc2ce..1a0c2a76c1 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -72,11 +72,13 @@ namespace OpenSim.Region.Physics.Manager { public float mu; public float bounce; + public bool softcolide; - public ContactData(float _mu, float _bounce) + public ContactData(float _mu, float _bounce, bool _softcolide) { mu = _mu; bounce = _bounce; + softcolide = _softcolide; } } /// diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index 94cadb2a0f..9a22331820 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs @@ -195,6 +195,7 @@ namespace OpenSim.Region.Physics.OdePlugin { cdata.mu = mu; cdata.bounce = bounce; + cdata.softcolide = false; } public override bool Building { get; set; } diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index db07565a96..b105f77da7 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs @@ -114,6 +114,9 @@ namespace OpenSim.Region.Physics.OdePlugin // private bool m_collidesLand = true; private bool m_collidesWater; public bool m_returnCollisions; + private bool m_softcolide; + + private bool m_NoColide; // for now only for internal use for bad meshs // Default we're a Geometry private CollisionCategories m_collisionCategories = (CollisionCategories.Geom); @@ -224,6 +227,9 @@ namespace OpenSim.Region.Physics.OdePlugin cdata.mu = mu; cdata.bounce = bounce; + // cdata.softcolide = m_softcolide; + cdata.softcolide = false; + if (m_isphysical) { ODEDynamics veh; @@ -303,7 +309,10 @@ namespace OpenSim.Region.Physics.OdePlugin } if (m_colliderfilter == 0) + { + m_softcolide = false; m_iscolliding = false; + } else m_iscolliding = true; } @@ -859,7 +868,6 @@ namespace OpenSim.Region.Physics.OdePlugin _size = size; - if (!QuaternionIsFinite(rotation)) { rotation = Quaternion.Identity; @@ -890,6 +898,8 @@ namespace OpenSim.Region.Physics.OdePlugin m_iscolliding = false; m_colliderfilter = 0; + m_softcolide = true; + m_NoColide = false; hasOOBoffsetFromMesh = false; _triMeshData = IntPtr.Zero; @@ -1037,34 +1047,42 @@ namespace OpenSim.Region.Physics.OdePlugin if (vertexCount == 0 || indexCount == 0) { - m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. It can be a sculp with alpha channel in map. Replacing it by a small box.", Name, _position.X, _position.Y, _position.Z); - _size.X = 0.01f; - _size.Y = 0.01f; - _size.Z = 0.01f; + m_log.WarnFormat("[PHYSICS]: Got invalid mesh on prim {0} at <{1},{2},{3}>. mesh UUID {4}", + Name, _position.X, _position.Y, _position.Z, _pbs.SculptTexture.ToString()); + mesh.releaseSourceMeshData(); return false; } primOOBoffset = mesh.GetCentroid(); hasOOBoffsetFromMesh = true; - _triMeshData = d.GeomTriMeshDataCreate(); - - d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); - d.GeomTriMeshDataPreprocess(_triMeshData); - mesh.releaseSourceMeshData(); - _parent_scene.waitForSpaceUnlock(m_targetSpace); + IntPtr geo = IntPtr.Zero; + try { - SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null)); + _triMeshData = d.GeomTriMeshDataCreate(); + + d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); + d.GeomTriMeshDataPreprocess(_triMeshData); + + _parent_scene.waitForSpaceUnlock(m_targetSpace); + geo = d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null); } catch (Exception e) { m_log.ErrorFormat("[PHYSICS]: SetGeom Mesh failed for {0} exception: {1}", Name, e); + if (_triMeshData != IntPtr.Zero) + { + d.GeomTriMeshDataDestroy(_triMeshData); + _triMeshData = IntPtr.Zero; + } return false; } + + SetGeom(geo); return true; } @@ -1074,25 +1092,30 @@ namespace OpenSim.Region.Physics.OdePlugin //Console.WriteLine("SetGeom to " + prim_geom + " for " + Name); if (prim_geom != IntPtr.Zero) { - d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + if (m_NoColide) + { + d.GeomSetCategoryBits(prim_geom, 0); + if (m_isphysical) + { + d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); + } + else + { + d.GeomSetCollideBits(prim_geom, 0); + d.GeomDisable(prim_geom); + } + } + else + { + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + } CalcPrimBodyData(); _parent_scene.geom_name_map[prim_geom] = Name; _parent_scene.actor_name_map[prim_geom] = this; - /* - if (childPrim) - { - if (_parent != null && _parent is OdePrim) - { - OdePrim parent = (OdePrim)_parent; - //Console.WriteLine("SetGeom calls ChildSetGeom"); - parent.ChildSetGeom(this); - } - } - */ } else m_log.Warn("Setting bad Geom"); @@ -1114,10 +1137,13 @@ namespace OpenSim.Region.Physics.OdePlugin bool haveMesh = false; hasOOBoffsetFromMesh = false; + m_NoColide = false; if (_parent_scene.needsMeshing(_pbs)) { haveMesh = setMesh(_parent_scene); // this will give a mesh to non trivial known prims + if (!haveMesh) + m_NoColide = true; } if (!haveMesh) @@ -1209,12 +1235,46 @@ namespace OpenSim.Region.Physics.OdePlugin { if (!childPrim && !m_isSelected) { - if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero) + if (m_isphysical && Body != IntPtr.Zero) { - d.GeomEnable(prim_geom); - foreach (OdePrim prm in childrenPrim) - d.GeomEnable(prm.prim_geom); + m_collisionCategories |= CollisionCategories.Body; + m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); + foreach (OdePrim prm in childrenPrim) + { + prm.m_collisionCategories = m_collisionCategories; + prm.m_collisionFlags = m_collisionFlags; + + if (prm.prim_geom != IntPtr.Zero) + { + if (prm.m_NoColide) + { + d.GeomSetCategoryBits(prm.prim_geom, 0); + d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land); + } + else + { + d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); + } + d.GeomEnable(prm.prim_geom); + } + } + + if (prim_geom != IntPtr.Zero) + { + if (m_NoColide) + { + d.GeomSetCategoryBits(prim_geom, 0); + d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); + } + else + { + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + } + d.GeomEnable(prim_geom); + } d.BodyEnable(Body); } } @@ -1227,11 +1287,47 @@ namespace OpenSim.Region.Physics.OdePlugin m_disabled = true; if (!childPrim) { - if (m_isphysical && Body != IntPtr.Zero && prim_geom != IntPtr.Zero) + if (m_isphysical && Body != IntPtr.Zero) { - d.GeomDisable(prim_geom); + m_collisionCategories &= ~CollisionCategories.Body; + m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); + foreach (OdePrim prm in childrenPrim) - d.GeomDisable(prm.prim_geom); + { + prm.m_collisionCategories = m_collisionCategories; + prm.m_collisionFlags = m_collisionFlags; + + if (prm.prim_geom != IntPtr.Zero) + { + if (prm.m_NoColide) + { + d.GeomSetCategoryBits(prm.prim_geom, 0); + d.GeomSetCollideBits(prm.prim_geom, 0); + } + else + { + d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); + } + d.GeomDisable(prm.prim_geom); + } + } + + if (prim_geom != IntPtr.Zero) + { + if (m_NoColide) + { + d.GeomSetCategoryBits(prim_geom, 0); + d.GeomSetCollideBits(prim_geom, 0); + } + else + { + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + } + d.GeomDisable(prim_geom); + } + d.BodyDisable(Body); } } @@ -1310,8 +1406,6 @@ namespace OpenSim.Region.Physics.OdePlugin continue; } - - DMassCopy(ref prm.primdMass, ref tmpdmass); // apply prim current rotation to inertia @@ -1373,14 +1467,7 @@ namespace OpenSim.Region.Physics.OdePlugin // d.BodySetAngularDampingThreshold(Body, 0.001f); d.BodySetDamping(Body, .002f, .002f); - m_collisionCategories |= CollisionCategories.Body; - m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); - d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); - m_collisionscore = 0; -// if (m_targetSpace != _parent_scene.ActiveSpace) - { if (m_targetSpace != IntPtr.Zero) { _parent_scene.waitForSpaceUnlock(m_targetSpace); @@ -1388,10 +1475,6 @@ namespace OpenSim.Region.Physics.OdePlugin d.SpaceRemove(m_targetSpace, prim_geom); } -// m_targetSpace = _parent_scene.ActiveSpace; -// d.SpaceAdd(m_targetSpace, prim_geom); - } - if (childrenPrim.Count == 0) { @@ -1419,12 +1502,6 @@ namespace OpenSim.Region.Physics.OdePlugin Vector3 ppos = prm._position; d.GeomSetOffsetWorldPosition(prm.prim_geom, ppos.X, ppos.Y, ppos.Z); // set relative position - prm.m_collisionCategories |= CollisionCategories.Body; - prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); - d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); - d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); - prm.m_collisionscore = 0; - if (prm.m_targetSpace != m_targetSpace) { if (prm.m_targetSpace != IntPtr.Zero) @@ -1438,9 +1515,32 @@ namespace OpenSim.Region.Physics.OdePlugin } if (m_isSelected || m_disabled) + { + prm.m_collisionCategories &= ~CollisionCategories.Body; + prm.m_collisionFlags &= ~(CollisionCategories.Land | CollisionCategories.Wind); d.GeomDisable(prm.prim_geom); + } + else + { + prm.m_collisionCategories |= CollisionCategories.Body; + prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); + } + + if (prm.m_NoColide) + { + d.GeomSetCategoryBits(prm.prim_geom, 0); + d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land); + } + else + { + d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); + } + prm.m_collisionscore = 0; + + if(!m_disabled) + prm.m_disabled = false; - prm.m_disabled = false; _parent_scene.addActivePrim(prm); } } @@ -1453,15 +1553,35 @@ namespace OpenSim.Region.Physics.OdePlugin if (m_isSelected || m_disabled) { + m_collisionCategories &= ~CollisionCategories.Body; + m_collisionFlags &= ~(CollisionCategories.Land | CollisionCategories.Wind); + d.GeomDisable(prim_geom); d.BodyDisable(Body); } else { + m_collisionCategories |= CollisionCategories.Body; + m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); + d.BodySetAngularVel(Body, m_rotationalVelocity.X, m_rotationalVelocity.Y, m_rotationalVelocity.Z); d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z); } + if (m_NoColide) + { + d.GeomSetCategoryBits(prim_geom, 0); + d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); + } + else + { + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + } + + m_collisionscore = 0; + + m_softcolide = true; _parent_scene.addActivePrim(this); _parent_scene.addActiveGroups(this); } @@ -1475,8 +1595,16 @@ namespace OpenSim.Region.Physics.OdePlugin m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); if (prim_geom != IntPtr.Zero) { - d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + if (m_NoColide) + { + d.GeomSetCategoryBits(prim_geom, 0); + d.GeomSetCollideBits(prim_geom, 0); + } + else + { + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + } UpdateDataFromGeom(); d.GeomSetBody(prim_geom, IntPtr.Zero); SetInStaticSpace(this); @@ -1489,12 +1617,20 @@ namespace OpenSim.Region.Physics.OdePlugin foreach (OdePrim prm in childrenPrim) { _parent_scene.remActivePrim(prm); - prm.m_collisionCategories &= ~CollisionCategories.Body; - prm.m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); + prm.m_collisionCategories = m_collisionCategories; + prm.m_collisionFlags = m_collisionFlags; if (prm.prim_geom != IntPtr.Zero) { - d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); - d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); + if (prm.m_NoColide) + { + d.GeomSetCategoryBits(prm.prim_geom, 0); + d.GeomSetCollideBits(prm.prim_geom, 0); + } + else + { + d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); + } prm.UpdateDataFromGeom(); SetInStaticSpace(prm); } @@ -2044,23 +2180,14 @@ namespace OpenSim.Region.Physics.OdePlugin myrot.Z = _orientation.Z; myrot.W = _orientation.W; d.GeomSetQuaternion(prim_geom, ref myrot); - // _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this; + if (!m_isphysical) SetInStaticSpace(this); } if (m_isphysical && Body == IntPtr.Zero) { - /* - if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim) - { - changeShape(_pbs); - } - else - { - */ MakeBody(); - // } } } @@ -2169,17 +2296,52 @@ namespace OpenSim.Region.Physics.OdePlugin if (!childPrim && Body != IntPtr.Zero) d.BodyDisable(Body); - if (m_delaySelect) + if (m_delaySelect || m_isphysical) { + m_collisionCategories = CollisionCategories.Selected; + m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space); + if (!childPrim) { foreach (OdePrim prm in childrenPrim) { - d.GeomDisable(prm.prim_geom); + prm.m_collisionCategories = m_collisionCategories; + prm.m_collisionFlags = m_collisionFlags; + + if (prm.prim_geom != null) + { + + if (prm.m_NoColide) + { + d.GeomSetCategoryBits(prm.prim_geom, 0); + d.GeomSetCollideBits(prm.prim_geom, 0); + } + else + { + d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); + } + d.GeomDisable(prm.prim_geom); + } prm.m_delaySelect = false; } } - d.GeomDisable(prim_geom); + + if (prim_geom != null) + { + if (m_NoColide) + { + d.GeomSetCategoryBits(prim_geom, 0); + d.GeomSetCollideBits(prim_geom, 0); + } + else + { + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + } + d.GeomDisable(prim_geom); + } + m_delaySelect = false; } else @@ -2192,19 +2354,64 @@ namespace OpenSim.Region.Physics.OdePlugin if (!childPrim && Body != IntPtr.Zero && !m_disabled) d.BodyEnable(Body); + m_collisionCategories = CollisionCategories.Geom; + if (m_isphysical) + m_collisionCategories |= CollisionCategories.Body; + + m_collisionFlags = m_default_collisionFlags | CollisionCategories.Land; + + if (m_collidesWater) + m_collisionFlags |= CollisionCategories.Water; + if (!childPrim) { foreach (OdePrim prm in childrenPrim) { - if(!prm.m_disabled) + prm.m_collisionCategories = m_collisionCategories; + prm.m_collisionFlags = m_collisionFlags; + + if (!prm.m_disabled && prm.prim_geom != IntPtr.Zero) + { + if (prm.m_NoColide) + { + d.GeomSetCategoryBits(prm.prim_geom, 0); + if (m_isphysical) + d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land); + else + d.GeomSetCollideBits(prm.prim_geom, 0); + } + else + { + d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); + } d.GeomEnable(prm.prim_geom); + } prm.m_delaySelect = false; + prm.m_softcolide = true; } } - if(!m_disabled) + + if (!m_disabled && prim_geom != IntPtr.Zero) + { + if (m_NoColide) + { + d.GeomSetCategoryBits(prim_geom, 0); + if (m_isphysical) + d.GeomSetCollideBits(prim_geom, (int)CollisionCategories.Land); + else + d.GeomSetCollideBits(prim_geom, 0); + } + else + { + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + } d.GeomEnable(prim_geom); + } m_delaySelect = false; + m_softcolide = true; } resetCollisionAccounting(); @@ -2250,6 +2457,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (givefakepos < 0) givefakepos = 0; // changeSelectedStatus(); + m_softcolide = true; resetCollisionAccounting(); } @@ -2302,6 +2510,7 @@ namespace OpenSim.Region.Physics.OdePlugin givefakeori--; if (givefakeori < 0) givefakeori = 0; + m_softcolide = true; resetCollisionAccounting(); } @@ -2372,6 +2581,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (givefakeori < 0) givefakeori = 0; + m_softcolide = true; resetCollisionAccounting(); } @@ -2488,6 +2698,7 @@ namespace OpenSim.Region.Physics.OdePlugin else MakeBody(); + m_softcolide = true; resetCollisionAccounting(); } diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index 884a5a7946..14516f98ed 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -693,8 +693,8 @@ namespace OpenSim.Region.Physics.OdePlugin // big messy collision analises float mu = 0; float bounce = 0; - ContactData contactdata1 = new ContactData(0, 0); - ContactData contactdata2 = new ContactData(0, 0); + ContactData contactdata1 = new ContactData(0, 0, false); + ContactData contactdata2 = new ContactData(0, 0, false); bool erpSoft = false; String name = null; @@ -718,6 +718,7 @@ namespace OpenSim.Region.Physics.OdePlugin if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f)) mu *= frictionMovementMult; + erpSoft = contactdata1.softcolide | contactdata2.softcolide; p1.CollidingObj = true; p2.CollidingObj = true; break; @@ -732,6 +733,9 @@ namespace OpenSim.Region.Physics.OdePlugin mu *= frictionMovementMult; if (p2.Velocity.LengthSquared() > 0.0f) p2.CollidingObj = true; + + erpSoft = contactdata1.softcolide | contactdata2.softcolide; + dop1foot = true; break; default: @@ -753,6 +757,7 @@ namespace OpenSim.Region.Physics.OdePlugin if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f)) mu *= frictionMovementMult; + erpSoft = contactdata1.softcolide | contactdata2.softcolide; dop2foot = true; if (p1.Velocity.LengthSquared() > 0.0f) p1.CollidingObj = true; @@ -766,7 +771,7 @@ namespace OpenSim.Region.Physics.OdePlugin p1.getContactData(ref contactdata1); p2.getContactData(ref contactdata2); bounce = contactdata1.bounce * contactdata2.bounce; - erpSoft = true; + erpSoft = contactdata1.softcolide | contactdata2.softcolide; mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f)) @@ -778,12 +783,12 @@ namespace OpenSim.Region.Physics.OdePlugin { if (name == "Terrain") { - erpSoft = true; p1.getContactData(ref contactdata1); bounce = contactdata1.bounce * TerrainBounce; mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction); if (Math.Abs(p1.Velocity.X) > 0.1f || Math.Abs(p1.Velocity.Y) > 0.1f) mu *= frictionMovementMult; + erpSoft = contactdata1.softcolide; p1.CollidingGround = true; } else if (name == "Water") @@ -804,11 +809,11 @@ namespace OpenSim.Region.Physics.OdePlugin { if (p2.PhysicsActorType == (int)ActorTypes.Prim) { - erpSoft = true; p2.CollidingGround = true; p2.getContactData(ref contactdata2); bounce = contactdata2.bounce * TerrainBounce; mu = (float)Math.Sqrt(contactdata2.mu * TerrainFriction); + erpSoft = contactdata2.softcolide; if (Math.Abs(p2.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y) > 0.1f) mu *= frictionMovementMult; From cca94aaefc36fad366e789d6d2e902dda078e3f7 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 6 Mar 2012 05:13:39 +0000 Subject: [PATCH 09/12] make copied parts have diferent LocalIds than original. More building control for ubitODE. for all let physics know about linking of physical parts. Assume UNTESTED --- .../Framework/Scenes/SceneObjectGroup.cs | 74 ++++++++++++++++++- .../Framework/Scenes/SceneObjectPart.cs | 5 +- 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index c9ea8e49c5..b99f80db22 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -957,12 +957,21 @@ namespace OpenSim.Region.Framework.Scenes /// public void GetAxisAlignedBoundingBoxRaw(out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ) { + /* ???? maxX = -256f; maxY = -256f; maxZ = -256f; minX = 256f; minY = 256f; minZ = 8192f; + */ + + maxX = float.MinValue; + maxY = float.MinValue; + maxZ = float.MinValue; + minX = float.MaxValue; + minY = float.MaxValue; + minZ = float.MaxValue; SceneObjectPart[] parts = m_parts.GetArray(); foreach (SceneObjectPart part in parts) @@ -1918,6 +1927,8 @@ namespace OpenSim.Region.Framework.Scenes dupe.IsAttachment = previousAttachmentStatus; } + + dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); dupe.m_rootPart.LinkNum = m_rootPart.LinkNum; @@ -1988,7 +1999,12 @@ namespace OpenSim.Region.Framework.Scenes /// public void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) { - SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed)); + // SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed)); + // give newpart a new local ID lettng old part keep same + SceneObjectPart newpart = part.Copy(part.LocalId, OwnerID, GroupID, 0, userExposed); + newpart.LocalId = m_scene.AllocateLocalId(); + + SetRootPart(newpart); if (userExposed) RootPart.Velocity = Vector3.Zero; // In case source is moving } @@ -2191,7 +2207,10 @@ namespace OpenSim.Region.Framework.Scenes /// public SceneObjectPart CopyPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) { - SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); + // give new ID to the new part, letting old keep original + // SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); + SceneObjectPart newPart = part.Copy(part.LocalId, OwnerID, GroupID, m_parts.Count, userExposed); + newPart.LocalId = m_scene.AllocateLocalId(); newPart.SetParent(this); AddPart(newPart); @@ -2485,6 +2504,11 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart linkPart = objectGroup.m_rootPart; + if (m_rootPart.PhysActor != null) + m_rootPart.PhysActor.Building = true; + if (linkPart.PhysActor != null) + linkPart.PhysActor.Building = true; + Vector3 oldGroupPosition = linkPart.GroupPosition; Quaternion oldRootRotation = linkPart.RotationOffset; @@ -2528,6 +2552,13 @@ namespace OpenSim.Region.Framework.Scenes linkPart.SetParent(this); linkPart.CreateSelected = true; + // let physics know + if (linkPart.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical) + { + linkPart.PhysActor.link(m_rootPart.PhysActor); + this.Scene.PhysicsScene.AddPhysicsActorTaint(linkPart.PhysActor); + } + linkPart.LinkNum = linkNum++; SceneObjectPart[] ogParts = objectGroup.Parts; @@ -2540,7 +2571,15 @@ namespace OpenSim.Region.Framework.Scenes { SceneObjectPart part = ogParts[i]; if (part.UUID != objectGroup.m_rootPart.UUID) + { LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); + // let physics know + if (part.PhysActor != null && m_rootPart.PhysActor != null && m_rootPart.PhysActor.IsPhysical) + { + part.PhysActor.link(m_rootPart.PhysActor); + this.Scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); + } + } part.ClearUndoState(); } } @@ -2560,6 +2599,9 @@ namespace OpenSim.Region.Framework.Scenes // unmoved prims! ResetChildPrimPhysicsPositions(); + if (m_rootPart.PhysActor != null) + m_rootPart.PhysActor.Building = false; + //HasGroupChanged = true; //ScheduleGroupForFullUpdate(); } @@ -2612,7 +2654,10 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat( // "[SCENE OBJECT GROUP]: Delinking part {0}, {1} from group with root part {2}, {3}", // linkPart.Name, linkPart.UUID, RootPart.Name, RootPart.UUID); - + + if (m_rootPart.PhysActor != null) + m_rootPart.PhysActor.Building = true; + linkPart.ClearUndoState(); Quaternion worldRot = linkPart.GetWorldRotation(); @@ -2672,6 +2717,10 @@ namespace OpenSim.Region.Framework.Scenes // When we delete a group, we currently have to force persist to the database if the object id has changed // (since delete works by deleting all rows which have a given object id) + + if (m_rootPart.PhysActor != null) + m_rootPart.PhysActor.Building = false; + objectGroup.HasGroupChangedDueToDelink = true; return objectGroup; @@ -3284,6 +3333,10 @@ namespace OpenSim.Region.Framework.Scenes part.StoreUndoState(false); part.IgnoreUndoUpdate = true; +// unlock parts position change + if (m_rootPart.PhysActor != null) + m_rootPart.PhysActor.Building = true; + if (part.UUID == m_rootPart.UUID) { UpdateRootPosition(pos); @@ -3293,6 +3346,9 @@ namespace OpenSim.Region.Framework.Scenes part.UpdateOffSet(pos); } + if (m_rootPart.PhysActor != null) + m_rootPart.PhysActor.Building = false; + HasGroupChanged = true; part.IgnoreUndoUpdate = false; } @@ -3434,6 +3490,9 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat( // "[SCENE OBJECT GROUP]: Updating single rotation of {0} {1} to {2}", part.Name, part.LocalId, rot); + if (m_rootPart.PhysActor != null) + m_rootPart.PhysActor.Building = true; + if (part.UUID == m_rootPart.UUID) { UpdateRootRotation(rot); @@ -3442,6 +3501,9 @@ namespace OpenSim.Region.Framework.Scenes { part.UpdateRotation(rot); } + + if (m_rootPart.PhysActor != null) + m_rootPart.PhysActor.Building = false; } } @@ -3462,6 +3524,9 @@ namespace OpenSim.Region.Framework.Scenes part.StoreUndoState(); part.IgnoreUndoUpdate = true; + if (m_rootPart.PhysActor != null) + m_rootPart.PhysActor.Building = true; + if (part.UUID == m_rootPart.UUID) { UpdateRootRotation(rot); @@ -3482,6 +3547,9 @@ namespace OpenSim.Region.Framework.Scenes part.OffsetPosition = pos; } + if (m_rootPart.PhysActor != null) + m_rootPart.PhysActor.Building = false; + part.IgnoreUndoUpdate = false; } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 1c72b10646..b132a192d9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1727,8 +1727,6 @@ namespace OpenSim.Region.Framework.Scenes // Move afterwards ResetIDs as it clears the localID dupe.LocalId = localID; - if(dupe.PhysActor != null) - dupe.PhysActor.LocalID = localID; // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. dupe.LastOwnerID = OwnerID; @@ -1749,6 +1747,9 @@ namespace OpenSim.Region.Framework.Scenes dupe.DoPhysicsPropertyUpdate(UsePhysics, true); } + if (dupe.PhysActor != null) + dupe.PhysActor.LocalID = localID; + ParentGroup.Scene.EventManager.TriggerOnSceneObjectPartCopy(dupe, this, userExposed); // m_log.DebugFormat("[SCENE OBJECT PART]: Clone of {0} {1} finished", Name, UUID); From de03d1ece0f4b4b9337ded53a71fcc68676c77d9 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 6 Mar 2012 09:56:19 +0100 Subject: [PATCH 10/12] Removed some whitespace errors - don't be naughty, don't use hard tabs! Also removed commented code block. --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index b99f80db22..8809cd04a0 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -957,15 +957,6 @@ namespace OpenSim.Region.Framework.Scenes /// public void GetAxisAlignedBoundingBoxRaw(out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ) { - /* ???? - maxX = -256f; - maxY = -256f; - maxZ = -256f; - minX = 256f; - minY = 256f; - minZ = 8192f; - */ - maxX = float.MinValue; maxY = float.MinValue; maxZ = float.MinValue; @@ -1927,8 +1918,6 @@ namespace OpenSim.Region.Framework.Scenes dupe.IsAttachment = previousAttachmentStatus; } - - dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); dupe.m_rootPart.LinkNum = m_rootPart.LinkNum; From 17b1454d6f3b45618b1007c85fe97242284aff3c Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 6 Mar 2012 20:20:12 +0100 Subject: [PATCH 11/12] Null PhysActor on SOP.Copy() to prevent clobbering the original one --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index b132a192d9..9c06786b8b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1691,10 +1691,9 @@ namespace OpenSim.Region.Framework.Scenes if (userExposed) dupe.UUID = UUID.Random(); - //memberwiseclone means it also clones the physics actor reference - // This will make physical prim 'bounce' if not set to null. - if (!userExposed) - dupe.PhysActor = null; + // The PhysActor cannot be valid on a copy because the copy is not in the scene yet. + // Null it, the caller has to create a new one once the object is added to a scene + dupe.PhysActor = null; dupe.OwnerID = AgentID; dupe.GroupID = GroupID; From 0be4ed3df42d4cd566110b30d84780e85f848c92 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 6 Mar 2012 22:27:01 +0100 Subject: [PATCH 12/12] Prevent scripted region crossings from crashing with prim limits enabled --- .../OptionalModules/PrimLimitsModule/PrimLimitsModule.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs index c1957e2cb8..59ff9b8a19 100644 --- a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs +++ b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs @@ -121,12 +121,18 @@ namespace OpenSim.Region.OptionalModules private bool CanObjectEnter(UUID objectID, bool enteringRegion, Vector3 newPoint, Scene scene) { + if ((newPoint.X > 257f || newPoint.X < -1f || newPoint.Y > 257f || newPoint.Y < -1f)) + return true; + SceneObjectPart obj = scene.GetSceneObjectPart(objectID); Vector3 oldPoint = obj.GroupPosition; int objectCount = obj.ParentGroup.PrimCount; ILandObject oldParcel = scene.LandChannel.GetLandObject(oldPoint.X, oldPoint.Y); ILandObject newParcel = scene.LandChannel.GetLandObject(newPoint.X, newPoint.Y); + if (newParcel == null) + return true; + int usedPrims = newParcel.PrimCounts.Total; int simulatorCapacity = newParcel.GetSimulatorMaxPrimCount(); @@ -171,4 +177,4 @@ namespace OpenSim.Region.OptionalModules return true; } } -} \ No newline at end of file +}