From 84b5b3e89b4814c29b7782578dfcd6fa2f0c77f9 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 29 Apr 2012 06:39:09 +0100 Subject: [PATCH 1/3] llGetGeometricCenter... --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 16 ++++++++++++++-- .../Shared/Api/Implementation/LSL_Api.cs | 3 ++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index bc2ca4c46d..f81cfe2f7b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -4024,13 +4024,25 @@ namespace OpenSim.Region.Framework.Scenes if (nparts <= 1) return gc; + Quaternion parentRot = RootPart.RotationOffset; + Vector3 pPos; + // average all parts positions for (int i = 0; i < nparts; i++) - gc += parts[i].GetWorldPosition(); + { + // do it directly + // gc += parts[i].GetWorldPosition(); + if (parts[i] != RootPart) + { + pPos = parts[i].OffsetPosition; + gc += pPos; + } + + } gc /= nparts; // relative to root: - gc -= AbsolutePosition; +// gc -= AbsolutePosition; return gc; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 6ee1a5dbbf..0c28bf54dc 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -8527,7 +8527,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llGetGeometricCenter() { - return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); + Vector3 tmp = m_host.GetGeometricCenter(); + return new LSL_Vector(tmp.X, tmp.Y, tmp.Z); } public LSL_List llGetPrimitiveParams(LSL_List rules) From be176b1e4948059e041d06be2caea1eb10b5ee68 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 29 Apr 2012 08:24:41 +0100 Subject: [PATCH 2/3] ubitode fix inertia for same cases. Added a nasty lock on llGetCenterOfMass and simulate --- .../Region/Physics/UbitOdePlugin/ODEPrim.cs | 176 +++++++++--------- .../Region/Physics/UbitOdePlugin/OdeScene.cs | 10 +- 2 files changed, 90 insertions(+), 96 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index c9a453dd22..2bcce3168f 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs @@ -449,54 +449,57 @@ namespace OpenSim.Region.Physics.OdePlugin { get { - d.Vector3 dtmp; - if (!childPrim && Body != IntPtr.Zero) + lock (_parent_scene.OdeLock) { - dtmp = d.BodyGetPosition(Body); - return new Vector3(dtmp.X, dtmp.Y, dtmp.Z); - } - else if (prim_geom != IntPtr.Zero) - { - d.Quaternion dq; - d.GeomCopyQuaternion(prim_geom, out dq); - Quaternion q; - q.X = dq.X; - q.Y = dq.Y; - q.Z = dq.Z; - q.W = dq.W; - - Vector3 Ptot = primOOBoffset * q; - dtmp = d.GeomGetPosition(prim_geom); - Ptot.X += dtmp.X; - Ptot.Y += dtmp.Y; - Ptot.Z += dtmp.Z; - -// if(childPrim) we only know about physical linksets - return Ptot; -/* - float tmass = _mass; - Ptot *= tmass; - - float m; - - foreach (OdePrim prm in childrenPrim) + d.Vector3 dtmp; + if (!childPrim && Body != IntPtr.Zero) { - m = prm._mass; - Ptot += prm.CenterOfMass * m; - tmass += m; + dtmp = d.BodyGetPosition(Body); + return new Vector3(dtmp.X, dtmp.Y, dtmp.Z); } + else if (prim_geom != IntPtr.Zero) + { + d.Quaternion dq; + d.GeomCopyQuaternion(prim_geom, out dq); + Quaternion q; + q.X = dq.X; + q.Y = dq.Y; + q.Z = dq.Z; + q.W = dq.W; - if (tmass == 0) - tmass = 0; + Vector3 Ptot = primOOBoffset * q; + dtmp = d.GeomGetPosition(prim_geom); + Ptot.X += dtmp.X; + Ptot.Y += dtmp.Y; + Ptot.Z += dtmp.Z; + + // if(childPrim) we only know about physical linksets + return Ptot; + /* + float tmass = _mass; + Ptot *= tmass; + + float m; + + foreach (OdePrim prm in childrenPrim) + { + m = prm._mass; + Ptot += prm.CenterOfMass * m; + tmass += m; + } + + if (tmass == 0) + tmass = 0; + else + tmass = 1.0f / tmass; + + Ptot *= tmass; + return Ptot; + */ + } else - tmass = 1.0f / tmass; - - Ptot *= tmass; - return Ptot; - */ + return _position; } - else - return _position; } } /* @@ -1511,7 +1514,6 @@ namespace OpenSim.Region.Physics.OdePlugin } Body = IntPtr.Zero; hasOOBoffsetFromMesh = false; - CalcPrimBodyData(); } /* private void ChildSetGeom(OdePrim odePrim) @@ -1601,7 +1603,7 @@ namespace OpenSim.Region.Physics.OdePlugin Body = d.BodyCreate(_parent_scene.world); - DMassDup(ref primdMass, out objdmass); + objdmass = primdMass; // rotate inertia myrot.X = _orientation.X; @@ -1623,9 +1625,9 @@ namespace OpenSim.Region.Physics.OdePlugin d.Mass tmpdmass = new d.Mass { }; Vector3 rcm; - rcm.X = _position.X + objdmass.c.X; - rcm.Y = _position.Y + objdmass.c.Y; - rcm.Z = _position.Z + objdmass.c.Z; + rcm.X = _position.X; + rcm.Y = _position.Y; + rcm.Z = _position.Z; lock (childrenPrim) { @@ -1637,7 +1639,7 @@ namespace OpenSim.Region.Physics.OdePlugin continue; } - DMassCopy(ref prm.primdMass, ref tmpdmass); + tmpdmass = prm.primdMass; // apply prim current rotation to inertia quat.X = prm._orientation.X; @@ -1648,10 +1650,9 @@ namespace OpenSim.Region.Physics.OdePlugin d.MassRotate(ref tmpdmass, ref mat); Vector3 ppos = prm._position; - ppos.X += tmpdmass.c.X - rcm.X; - ppos.Y += tmpdmass.c.Y - rcm.Y; - ppos.Z += tmpdmass.c.Z - rcm.Z; - + ppos.X -= rcm.X; + ppos.Y -= rcm.Y; + ppos.Z -= rcm.Z; // refer inertia to root prim center of mass position d.MassTranslate(ref tmpdmass, ppos.X, @@ -1683,9 +1684,13 @@ namespace OpenSim.Region.Physics.OdePlugin d.GeomSetOffsetWorldPosition(prim_geom, _position.X, _position.Y, _position.Z); d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body - myrot.W = -myrot.W; + myrot.X = -myrot.X; + myrot.Y = -myrot.Y; + myrot.Z = -myrot.Z; + d.RfromQ(out mymat, ref myrot); d.MassRotate(ref objdmass, ref mymat); + d.BodySetMass(Body, ref objdmass); _mass = objdmass.mass; @@ -2237,7 +2242,33 @@ namespace OpenSim.Region.Physics.OdePlugin case ProfileShape.HalfCircle: if (_pbs.PathCurve == (byte)Extrusion.Curve1) { - volume *= 0.52359877559829887307710723054658f; + volume *= 0.5236f; + + if (hollowAmount > 0.0) + { + hollowVolume *= hollowAmount; + + switch (_pbs.HollowShape) + { + case HollowShape.Circle: + case HollowShape.Triangle: // diference in sl is minor and odd + case HollowShape.Same: + break; + + case HollowShape.Square: + hollowVolume *= 0.909f; + break; + + // case HollowShape.Triangle: + // hollowVolume *= .827f; + // break; + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } + } break; @@ -3704,24 +3735,6 @@ namespace OpenSim.Region.Physics.OdePlugin return true; } - internal static void DMassCopy(ref d.Mass src, ref d.Mass dst) - { - dst.c.W = src.c.W; - dst.c.X = src.c.X; - dst.c.Y = src.c.Y; - dst.c.Z = src.c.Z; - dst.mass = src.mass; - dst.I.M00 = src.I.M00; - dst.I.M01 = src.I.M01; - dst.I.M02 = src.I.M02; - dst.I.M10 = src.I.M10; - dst.I.M11 = src.I.M11; - dst.I.M12 = src.I.M12; - dst.I.M20 = src.I.M20; - dst.I.M21 = src.I.M21; - dst.I.M22 = src.I.M22; - } - internal static void DMassSubPartFromObj(ref d.Mass part, ref d.Mass theobj) { // assumes object center of mass is zero @@ -3745,25 +3758,6 @@ namespace OpenSim.Region.Physics.OdePlugin theobj.I.M22 -= part.I.M22; } - private static void DMassDup(ref d.Mass src, out d.Mass dst) - { - dst = new d.Mass { }; - - dst.c.W = src.c.W; - dst.c.X = src.c.X; - dst.c.Y = src.c.Y; - dst.c.Z = src.c.Z; - dst.mass = src.mass; - dst.I.M00 = src.I.M00; - dst.I.M01 = src.I.M01; - dst.I.M02 = src.I.M02; - dst.I.M10 = src.I.M10; - dst.I.M11 = src.I.M11; - dst.I.M12 = src.I.M12; - dst.I.M20 = src.I.M20; - dst.I.M21 = src.I.M21; - dst.I.M22 = src.I.M22; - } private void donullchange() { } diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index fa3d33e728..84195d34e6 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -301,7 +301,7 @@ namespace OpenSim.Region.Physics.OdePlugin // split static geometry collision into a grid as before private IntPtr[,] staticPrimspace; - private Object OdeLock; + public Object OdeLock; private static Object SimulationLock; public IMesher mesher; @@ -746,8 +746,7 @@ namespace OpenSim.Region.Physics.OdePlugin ); // do volume detection case if ( - (p1 is OdePrim) && (((OdePrim)p1).m_isVolumeDetect) || - (p2 is OdePrim) && (((OdePrim)p2).m_isVolumeDetect)) + (p1.IsVolumeDtc || p2.IsVolumeDtc)) { collision_accounting_events(p1, p2, maxDepthContact); return; @@ -1024,9 +1023,9 @@ namespace OpenSim.Region.Physics.OdePlugin bool p1events = p1.SubscribedEvents(); bool p2events = p2.SubscribedEvents(); - if (p1 is OdePrim && p1.IsVolumeDtc) + if (p1.IsVolumeDtc) p2events = false; - if (p2 is OdePrim && p2.IsVolumeDtc) + if (p2.IsVolumeDtc) p1events = false; if (!(p2events || p1events)) @@ -1725,6 +1724,7 @@ namespace OpenSim.Region.Physics.OdePlugin // checkThread(); lock (SimulationLock) + lock(OdeLock) { // adjust number of iterations per step try From 303739622cc9b0f173d9ff88211f28c7295e8c65 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 29 Apr 2012 11:46:16 +0100 Subject: [PATCH 3/3] ubitODE fix applyROtationImpulse, let vehicle hover be relative to root prim and not center of mass ( as SL docs said) updated some flags to current ones --- .../Physics/UbitOdePlugin/ODEDynamics.cs | 43 +++++++++++++------ .../Region/Physics/UbitOdePlugin/ODEPrim.cs | 4 +- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs index d1066772c8..7b232c185b 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs @@ -470,15 +470,20 @@ namespace OpenSim.Region.Physics.OdePlugin m_linearDeflectionEfficiency = 1; m_linearDeflectionTimescale = 1; m_angularDeflectionEfficiency = 0; - m_angularDeflectionTimescale = 1000; + m_angularDeflectionTimescale = 10; + m_verticalAttractionEfficiency = 1; + m_verticalAttractionTimescale = 1000; m_bankingEfficiency = 0; m_bankingMix = 1; m_bankingTimescale = 10; m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); - m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP); + m_flags |= (VehicleFlag.NO_DEFLECTION_UP | + VehicleFlag.LIMIT_ROLL_ONLY | + VehicleFlag.LIMIT_MOTOR_UP); break; + case Vehicle.TYPE_CAR: m_linearFrictionTimescale = new Vector3(100, 2, 1000); m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); @@ -499,9 +504,13 @@ namespace OpenSim.Region.Physics.OdePlugin m_bankingEfficiency = -0.2f; m_bankingMix = 1; m_bankingTimescale = 1; - m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); - m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | - VehicleFlag.LIMIT_MOTOR_UP | VehicleFlag.HOVER_UP_ONLY); + m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | + VehicleFlag.HOVER_TERRAIN_ONLY | + VehicleFlag.HOVER_GLOBAL_HEIGHT); + m_flags |= (VehicleFlag.NO_DEFLECTION_UP | + VehicleFlag.LIMIT_ROLL_ONLY | + VehicleFlag.LIMIT_MOTOR_UP | + VehicleFlag.HOVER_UP_ONLY); break; case Vehicle.TYPE_BOAT: m_linearFrictionTimescale = new Vector3(10, 3, 2); @@ -525,12 +534,14 @@ namespace OpenSim.Region.Physics.OdePlugin m_bankingTimescale = 1; m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT | - VehicleFlag.HOVER_UP_ONLY | - VehicleFlag.LIMIT_ROLL_ONLY); + VehicleFlag.HOVER_UP_ONLY); // | +// VehicleFlag.LIMIT_ROLL_ONLY); m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP | + VehicleFlag.HOVER_UP_ONLY | // new sl VehicleFlag.HOVER_WATER_ONLY); break; + case Vehicle.TYPE_AIRPLANE: m_linearFrictionTimescale = new Vector3(200, 10, 5); m_angularFrictionTimescale = new Vector3(20, 20, 20); @@ -559,6 +570,7 @@ namespace OpenSim.Region.Physics.OdePlugin VehicleFlag.LIMIT_MOTOR_UP); m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); break; + case Vehicle.TYPE_BALLOON: m_linearFrictionTimescale = new Vector3(5, 5, 5); m_angularFrictionTimescale = new Vector3(10, 10, 10); @@ -574,7 +586,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_linearDeflectionTimescale = 5 * m_invtimestep; m_angularDeflectionEfficiency = 0; m_angularDeflectionTimescale = 5; - m_verticalAttractionEfficiency = 0f; + m_verticalAttractionEfficiency = 1f; m_verticalAttractionTimescale = 1000f; m_bankingEfficiency = 0; m_bankingMix = 0.7f; @@ -583,9 +595,12 @@ namespace OpenSim.Region.Physics.OdePlugin VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_UP_ONLY | VehicleFlag.NO_DEFLECTION_UP | - VehicleFlag.LIMIT_MOTOR_UP); - m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY | - VehicleFlag.HOVER_GLOBAL_HEIGHT); + VehicleFlag.LIMIT_MOTOR_UP | //); + VehicleFlag.LIMIT_ROLL_ONLY | // new sl + VehicleFlag.HOVER_GLOBAL_HEIGHT); // new sl + +// m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY | +// VehicleFlag.HOVER_GLOBAL_HEIGHT); break; } @@ -768,9 +783,11 @@ namespace OpenSim.Region.Physics.OdePlugin } // hover - if (m_VhoverTimescale < 300) + if (m_VhoverTimescale < 300 && rootPrim.prim_geom != IntPtr.Zero) { - d.Vector3 pos = d.BodyGetPosition(Body); + // d.Vector3 pos = d.BodyGetPosition(Body); + d.Vector3 pos = d.GeomGetPosition(rootPrim.prim_geom); + pos.Z -= 0.21f; // minor offset that seems to be always there in sl float t = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y); float perr; diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs index 2bcce3168f..e4f2e6bfb3 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs @@ -843,7 +843,7 @@ namespace OpenSim.Region.Physics.OdePlugin { if (force.IsFinite()) { - AddChange(changes.AddAngForce, force * m_invTimeStep); + AddChange(changes.AddAngForce, force); } else { @@ -3217,7 +3217,7 @@ namespace OpenSim.Region.Physics.OdePlugin private void changeAddImpulse(Vector3 impulse) { - m_forceacc += impulse * m_invTimeStep; + m_forceacc += impulse *m_invTimeStep; if (!m_isSelected) { lock (this)