From 8dd5f08b6e7d68663307b4346d19ceef711c8425 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 11 May 2012 15:53:31 +0100 Subject: [PATCH 1/7] revert terminal vel reduction. It helped but not efective --- OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index 43b45819d5..b0711d786d 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs @@ -1006,9 +1006,9 @@ namespace OpenSim.Region.Physics.OdePlugin } } - if (velLengthSquared > 625.0f) // 25m/s apply breaks + if (velLengthSquared > 2500.0f) // 50m/s apply breaks { - breakfactor = 0.31f * m_mass; + breakfactor = 0.16f * m_mass; vec.X -= breakfactor * vel.X; vec.Y -= breakfactor * vel.Y; vec.Z -= breakfactor * vel.Z; From 46095c963c633ef7e690fc033d5e7213fa4ed46e Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 12 May 2012 12:17:28 +0100 Subject: [PATCH 2/7] ubitODE: trial workaround for avatar colisions --- .../Region/Physics/UbitOdePlugin/OdeScene.cs | 55 +++++++++++++++++-- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs index e0de6cca11..63462b16a0 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -537,7 +537,7 @@ namespace OpenSim.Region.Physics.OdePlugin // Essentially Steps * m_physicsiterations d.WorldSetQuickStepNumIterations(world, m_physicsiterations); - d.WorldSetContactMaxCorrectingVel(world, 50.0f); + d.WorldSetContactMaxCorrectingVel(world, 100.0f); spacesPerMeter = 1 / metersInSpace; spaceGridMaxX = (int)(WorldExtents.X * spacesPerMeter); @@ -754,14 +754,15 @@ namespace OpenSim.Region.Physics.OdePlugin } // big messy collision analises + + Vector3 normoverride = Vector3.Zero; //damm c# + float mu = 0; float bounce = 0; float cfm = 0.0001f; - float erp = 0.1f; float erpscale = 1.0f; float dscale = 1.0f; bool IgnoreNegSides = false; - ContactData contactdata1 = new ContactData(0, 0, false); ContactData contactdata2 = new ContactData(0, 0, false); @@ -770,14 +771,30 @@ namespace OpenSim.Region.Physics.OdePlugin bool dop1foot = false; bool dop2foot = false; bool ignore = false; + bool AvanormOverride = false; switch (p1.PhysicsActorType) { case (int)ActorTypes.Agent: { - bounce = 0; - mu = 0; - cfm = 0.0001f; + AvanormOverride = true; + Vector3 tmp = p2.Position - p1.Position; + normoverride = p2.Velocity - p1.Velocity; + mu = normoverride.LengthSquared(); + + if (mu > 1e-6) + { + mu = 1.0f / (float)Math.Sqrt(mu); + normoverride *= mu; + mu = Vector3.Dot(tmp, normoverride); + if (mu > 0) + normoverride *= -1; + } + else + { + tmp.Normalize(); + normoverride = -tmp; + } switch (p2.PhysicsActorType) { @@ -824,6 +841,25 @@ namespace OpenSim.Region.Physics.OdePlugin // p1.getContactData(ref contactdata1); // p2.getContactData(ref contactdata2); + AvanormOverride = true; + + Vector3 tmp = p2.Position - p1.Position; + normoverride = p2.Velocity - p1.Velocity; + mu = normoverride.LengthSquared(); + if (mu > 1e-6) + { + mu = 1.0f / (float)Math.Sqrt(mu); + normoverride *= mu; + mu = Vector3.Dot(tmp, normoverride); + if (mu > 0) + normoverride *= -1; + } + else + { + tmp.Normalize(); + normoverride = -tmp; + } + bounce = 0; mu = 0; cfm = 0.0001f; @@ -974,6 +1010,13 @@ namespace OpenSim.Region.Physics.OdePlugin if (dop2foot && (p2.Position.Z - curContact.pos.Z) > (p2.Size.Z - avCapRadius) * 0.5f) p2.IsColliding = true; + if (AvanormOverride && curContact.depth > 0.3f) + { + curContact.normal.X = normoverride.X; + curContact.normal.Y = normoverride.Y; + curContact.normal.Z = normoverride.Z; + } + Joint = CreateContacJoint(ref curContact, mu, bounce, cfm, erpscale, dscale); d.JointAttach(Joint, b1, b2); From 792e8db45695a6151c4e7d039b792bdfeb5c0f87 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 12 May 2012 13:44:47 +0100 Subject: [PATCH 3/7] ubitODE reduced again a bit the max allowed correction velocity on colisions, to reduce a bit bouncing inerent to colisions. --- 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 63462b16a0..7367719679 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs @@ -537,7 +537,7 @@ namespace OpenSim.Region.Physics.OdePlugin // Essentially Steps * m_physicsiterations d.WorldSetQuickStepNumIterations(world, m_physicsiterations); - d.WorldSetContactMaxCorrectingVel(world, 100.0f); + d.WorldSetContactMaxCorrectingVel(world, 60.0f); spacesPerMeter = 1 / metersInSpace; spaceGridMaxX = (int)(WorldExtents.X * spacesPerMeter); From 4d98a291a2d1440afd8f7375d14842fd91d8083f Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 12 May 2012 14:00:08 +0100 Subject: [PATCH 4/7] ubitODE let vehicles responde faster to changes of some parameters like motors decay times --- .../Physics/UbitOdePlugin/ODEDynamics.cs | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs index e88e559ba4..56d0f1ab95 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs @@ -63,6 +63,9 @@ namespace OpenSim.Region.Physics.OdePlugin private OdeScene _pParentScene; // Vehicle properties + // WARNING this are working copies for internel use + // their values may not be the corresponding parameter + private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier private Quaternion m_RollreferenceFrame = Quaternion.Identity; // what hell is this ? @@ -244,6 +247,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (pValue < m_timestep) pValue = m_timestep; else if (pValue > 120) pValue = 120; m_angularMotorDecayTimescale = pValue * m_invtimestep; + m_amDecay = 1.0f - 1.0f / m_angularMotorDecayTimescale; break; case Vehicle.ANGULAR_MOTOR_TIMESCALE: if (pValue < m_timestep) pValue = m_timestep; @@ -293,6 +297,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (pValue < m_timestep) pValue = m_timestep; else if (pValue > 120) pValue = 120; m_linearMotorDecayTimescale = (0.2f +pValue) * m_invtimestep; + m_lmDecay = (1.0f - 1.0f / m_linearMotorDecayTimescale); break; case Vehicle.LINEAR_MOTOR_TIMESCALE: if (pValue < m_timestep) pValue = m_timestep; @@ -320,7 +325,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (len > 12.566f) m_angularMotorDirection *= (12.566f / len); - m_amEfect = 1.0f / m_angularMotorTimescale; // turn it on + m_amEfect = 1.0f ; // turn it on m_amDecay = 1.0f - 1.0f / m_angularMotorDecayTimescale; if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) @@ -338,7 +343,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_linearMotorDirection *= (100.0f / len); m_lmDecay = 1.0f - 1.0f / m_linearMotorDecayTimescale; - m_lmEfect = 1.0f / m_linearMotorTimescale; // turn it on + m_lmEfect = 1.0f; // turn it on m_ffactor = 0.01f; if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) @@ -374,7 +379,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (len > 12.566f) m_angularMotorDirection *= (12.566f / len); - m_amEfect = 1.0f / m_angularMotorTimescale; // turn it on + m_amEfect = 1.0f; // turn it on m_amDecay = 1.0f - 1.0f / m_angularMotorDecayTimescale; if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) @@ -393,11 +398,9 @@ namespace OpenSim.Region.Physics.OdePlugin if (len > 100.0f) m_linearMotorDirection *= (100.0f / len); - m_lmEfect = 1.0f / m_linearMotorTimescale; // turn it on + m_lmEfect = 1.0f; // turn it on m_lmDecay = 1.0f - 1.0f / m_linearMotorDecayTimescale; - - m_ffactor = 0.01f; if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) && !rootPrim.m_isSelected && !rootPrim.m_disabled) @@ -776,10 +779,10 @@ namespace OpenSim.Region.Physics.OdePlugin float ldampZ = 0; // linear motor - if (m_lmEfect > 0.001 && m_linearMotorTimescale < 1000) + if (m_lmEfect > 0.01 && m_linearMotorTimescale < 1000) { tmpV = m_linearMotorDirection - curLocalVel; // velocity error - tmpV *= m_lmEfect; // error to correct in this timestep + tmpV *= m_lmEfect / m_linearMotorTimescale; // error to correct in this timestep tmpV *= rotq; // to world if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0) @@ -799,9 +802,7 @@ namespace OpenSim.Region.Physics.OdePlugin } m_lmEfect *= m_lmDecay; - - // m_ffactor = 0.01f + 1e-4f * curVel.LengthSquared(); - m_ffactor = 0; + m_ffactor = 0.01f + 1e-4f * curVel.LengthSquared(); } else { @@ -1007,7 +1008,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (m_amEfect > 0.01 && m_angularMotorTimescale < 1000) { tmpV = m_angularMotorDirection - curLocalAngVel; // velocity error - tmpV *= m_amEfect; // error to correct in this timestep + tmpV *= m_amEfect / m_angularMotorTimescale; // error to correct in this timestep torque.X += tmpV.X * m_ampwr; torque.Y += tmpV.Y * m_ampwr; torque.Z += tmpV.Z; From 7461fe4554f8104212071e3e01b07786f8eb546f Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 12 May 2012 15:27:37 +0100 Subject: [PATCH 5/7] =?UTF-8?q?=AATEST=20MESS*=20=20reduce=20animation=20p?= =?UTF-8?q?ackets=20send.=20Added=20onchangeanim=20event=20with=20paramete?= =?UTF-8?q?rs=20to=20define=20if=20to=20add=20or=20remove,=20and=20if=20to?= =?UTF-8?q?=20send=20anims=20pack=20on=20that=20evocation,=20etc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenSim/Framework/IClientAPI.cs | 3 +++ .../ClientStack/Linden/UDP/LLClientView.cs | 22 ++++++++++++++++++- .../Scenes/Animation/ScenePresenceAnimator.cs | 20 +++++++++++++++-- .../Region/Framework/Scenes/ScenePresence.cs | 8 +++++++ .../Server/IRCClientView.cs | 1 + .../OptionalModules/World/NPC/NPCAvatar.cs | 1 + OpenSim/Tests/Common/Mock/TestClient.cs | 1 + 7 files changed, 53 insertions(+), 3 deletions(-) diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 2be78dacf1..c1bd07886d 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -70,6 +70,8 @@ namespace OpenSim.Framework public delegate void StopAnim(IClientAPI remoteClient, UUID animID); + public delegate void ChangeAnim(UUID animID, bool addOrRemove, bool sendPack); + public delegate void LinkObjects(IClientAPI remoteClient, uint parent, List children); public delegate void DelinkObjects(List primIds, IClientAPI client); @@ -791,6 +793,7 @@ namespace OpenSim.Framework event ObjectDrop OnObjectDrop; event StartAnim OnStartAnim; event StopAnim OnStopAnim; + event ChangeAnim OnChangeAnim; event LinkObjects OnLinkObjects; event DelinkObjects OnDelinkObjects; event RequestMapBlocks OnRequestMapBlocks; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index bb7671797b..7db601490e 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -98,6 +98,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event AvatarPickerRequest OnAvatarPickerRequest; public event StartAnim OnStartAnim; public event StopAnim OnStopAnim; + public event ChangeAnim OnChangeAnim; public event Action OnRequestAvatarsData; public event LinkObjects OnLinkObjects; public event DelinkObjects OnDelinkObjects; @@ -6386,7 +6387,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP return true; } #endregion - +/* StartAnim handlerStartAnim = null; StopAnim handlerStopAnim = null; @@ -6409,6 +6410,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } } + return true; +*/ + ChangeAnim handlerChangeAnim = null; + + for (int i = 0; i < AgentAni.AnimationList.Length; i++) + { + handlerChangeAnim = OnChangeAnim; + if (handlerChangeAnim != null) + { + handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false); + } + } + + handlerChangeAnim = OnChangeAnim; + if (handlerChangeAnim != null) + { + handlerChangeAnim(UUID.Zero, false, true); + } + return true; } diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index f5623bdf69..e577958839 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -79,13 +79,13 @@ namespace OpenSim.Region.Framework.Scenes.Animation m_scenePresence = sp; CurrentMovementAnimation = "CROUCH"; } - + public void AddAnimation(UUID animID, UUID objectID) { if (m_scenePresence.IsChildAgent) return; -// m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} for {1}", animID, m_scenePresence.Name); + // m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Adding animation {0} for {1}", animID, m_scenePresence.Name); if (m_animations.Add(animID, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, objectID)) SendAnimPack(); @@ -117,6 +117,22 @@ namespace OpenSim.Region.Framework.Scenes.Animation SendAnimPack(); } + public void avnChangeAnim(UUID animID, bool addRemove, bool sendPack) + { + if (m_scenePresence.IsChildAgent) + return; + + if (animID != UUID.Zero) + { + if (addRemove) + m_animations.Add(animID, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, UUID.Zero); + else + m_animations.Remove(animID); + } + if(sendPack) + SendAnimPack(); + } + // Called from scripts public void RemoveAnimation(string name) { diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 212720e62b..ba0ed95b00 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -781,6 +781,7 @@ namespace OpenSim.Region.Framework.Scenes ControllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; ControllingClient.OnStartAnim += HandleStartAnim; ControllingClient.OnStopAnim += HandleStopAnim; + ControllingClient.OnChangeAnim += avnHandleChangeAnim; ControllingClient.OnForceReleaseControls += HandleForceReleaseControls; ControllingClient.OnAutoPilotGo += MoveToTarget; @@ -2432,6 +2433,13 @@ namespace OpenSim.Region.Framework.Scenes Animator.RemoveAnimation(animID); } + public void avnHandleChangeAnim(UUID animID, bool addRemove,bool sendPack) + { + Animator.avnChangeAnim(animID, addRemove, sendPack); + } + + + /// /// Rotate the avatar to the given rotation and apply a movement in the given relative vector /// diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index a37e99714d..eac8e8460e 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -669,6 +669,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server public event ObjectDrop OnObjectDrop; public event StartAnim OnStartAnim; public event StopAnim OnStopAnim; + public event ChangeAnim OnChangeAnim; public event LinkObjects OnLinkObjects; public event DelinkObjects OnDelinkObjects; public event RequestMapBlocks OnRequestMapBlocks; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index c3335f099e..89968654cf 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -189,6 +189,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC public event ObjectDrop OnObjectDrop; public event StartAnim OnStartAnim; public event StopAnim OnStopAnim; + public event ChangeAnim OnChangeAnim; public event LinkObjects OnLinkObjects; public event DelinkObjects OnDelinkObjects; public event RequestMapBlocks OnRequestMapBlocks; diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 6a7cb0aa83..b2c824c81e 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -88,6 +88,7 @@ namespace OpenSim.Tests.Common.Mock public event ObjectDrop OnObjectDrop; public event StartAnim OnStartAnim; public event StopAnim OnStopAnim; + public event ChangeAnim OnChangeAnim; public event LinkObjects OnLinkObjects; public event DelinkObjects OnDelinkObjects; public event RequestMapBlocks OnRequestMapBlocks; From 9b7023a159c69d599248783d88ba96a328a584f2 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 12 May 2012 17:58:36 +0100 Subject: [PATCH 6/7] display a sleep time of zero if forced spare time to zero, when sim fps is lower than desired, for better display coerence. --- OpenSim/Region/Framework/Scenes/SimStatsReporter.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs index 94f1b151b7..a4afd4705f 100644 --- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs +++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs @@ -264,8 +264,12 @@ namespace OpenSim.Region.Framework.Scenes float targetframetime = 1100.0f / (float)m_nominalReportedFps; float sparetime; - if (TotalFrameTime > targetframetime ) + float sleeptime; + if (TotalFrameTime > targetframetime) + { sparetime = 0; + sleeptime = 0; + } else { sparetime = m_frameMS - m_physicsMS - m_agentMS; @@ -274,6 +278,7 @@ namespace OpenSim.Region.Framework.Scenes sparetime = 0; else if (sparetime > TotalFrameTime) sparetime = TotalFrameTime; + sleeptime = m_sleeptimeMS * perframe; } // other MS is actually simulation time @@ -363,7 +368,7 @@ namespace OpenSim.Region.Framework.Scenes sb[21].StatValue = sparetime; sb[22].StatID = (uint)Stats.SimSleepTime; - sb[22].StatValue = m_sleeptimeMS * perframe; + sb[22].StatValue = sleeptime; for (int i = 0; i < 23; i++) { From 9870d7e4e787ca64011ef817ea2ab40310f4cf26 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 13 May 2012 01:28:20 +0100 Subject: [PATCH 7/7] ubitODE fix force in case of mlinear motor offset present --- OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs index 56d0f1ab95..e27be1eab7 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEDynamics.cs @@ -750,6 +750,9 @@ namespace OpenSim.Region.Physics.OdePlugin { IntPtr Body = rootPrim.Body; + d.Mass dmass; + d.BodyGetMass(Body, out dmass); + d.Quaternion rot = d.BodyGetQuaternion(Body); Quaternion objrotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object Quaternion rotq = objrotq; // rotq = rotation of object @@ -791,7 +794,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (m_linearMotorOffset.X != 0 || m_linearMotorOffset.Y != 0 || m_linearMotorOffset.Z != 0) { // have offset, do it now - tmpV *= rootPrim.Mass; + tmpV *= dmass.mass; d.BodyAddForceAtRelPos(Body, tmpV.X, tmpV.Y, tmpV.Z, m_linearMotorOffset.X, m_linearMotorOffset.Y, m_linearMotorOffset.Z); } else @@ -1058,13 +1061,11 @@ namespace OpenSim.Region.Physics.OdePlugin } - d.Mass dmass; - d.BodyGetMass(Body,out dmass); if (force.X != 0 || force.Y != 0 || force.Z != 0) { force *= dmass.mass; - d.BodySetForce(Body, force.X, force.Y, force.Z); + d.BodyAddForce(Body, force.X, force.Y, force.Z); } if (torque.X != 0 || torque.Y != 0 || torque.Z != 0)