From 9e0db36c82da303a0d9c709b84b1c35879a39e86 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 27 Nov 2012 05:23:50 -0800 Subject: [PATCH 1/8] BulletSim: add 'infinite' timescale that does not reduce motor target or friction. --- .../Region/Physics/BulletSPlugin/BSMotors.cs | 37 ++++++++++++++----- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs index 480da2c9ee..e91bfa8496 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSMotors.cs @@ -7,6 +7,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin { public abstract class BSMotor { + // Timescales and other things can be turned off by setting them to 'infinite'. + public const float Infinite = 10000f; + public readonly static Vector3 InfiniteVector = new Vector3(BSMotor.Infinite, BSMotor.Infinite, BSMotor.Infinite); + public BSMotor(string useName) { UseName = useName; @@ -46,8 +50,9 @@ public class BSVMotor : BSMotor public BSVMotor(string useName) : base(useName) { - TimeScale = TargetValueDecayTimeScale = Efficiency = 1f; - FrictionTimescale = Vector3.Zero; + TimeScale = TargetValueDecayTimeScale = BSMotor.Infinite; + Efficiency = 1f; + FrictionTimescale = BSMotor.InfiniteVector; CurrentValue = TargetValue = Vector3.Zero; } public BSVMotor(string useName, float timeScale, float decayTimeScale, Vector3 frictionTimeScale, float efficiency) @@ -78,23 +83,35 @@ public class BSVMotor : BSMotor // Addition = (desiredVector - currentAppliedVector) / secondsItShouldTakeToComplete Vector3 addAmount = (TargetValue - CurrentValue)/TimeScale * timeStep; CurrentValue += addAmount; + returnCurrent = CurrentValue; - // The desired value reduces to zero when also reduces the difference with current. - float decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep; - TargetValue *= (1f - decayFactor); + // The desired value reduces to zero which also reduces the difference with current. + // If the decay time is infinite, don't decay at all. + float decayFactor = 0f; + if (TargetValueDecayTimeScale != BSMotor.Infinite) + { + decayFactor = (1.0f / TargetValueDecayTimeScale) * timeStep; + TargetValue *= (1f - decayFactor); + } Vector3 frictionFactor = Vector3.Zero; - frictionFactor = (Vector3.One / FrictionTimescale) * timeStep; - CurrentValue *= (Vector3.One - frictionFactor); + if (FrictionTimescale != BSMotor.InfiniteVector) + { + // frictionFactor = (Vector3.One / FrictionTimescale) * timeStep; + frictionFactor.X = FrictionTimescale.X == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.X) * timeStep; + frictionFactor.Y = FrictionTimescale.Y == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.Y) * timeStep; + frictionFactor.Z = FrictionTimescale.Z == BSMotor.Infinite ? 0f : (1f / FrictionTimescale.Z) * timeStep; + CurrentValue *= (Vector3.One - frictionFactor); + } - MDetailLog("{0},BSVMotor.Step,nonZero,{1},origTarget={2},origCurr={3},timeStep={4},timeScale={5},addAmnt={6},targetDecay={7},decayFact={8},fricTS={9},frictFact={10}", - BSScene.DetailLogZero, UseName, origTarget, origCurrVal, + MDetailLog("{0},BSVMotor.Step,nonZero,{1},origCurr={2},origTarget={3},timeStep={4},timeScale={5},addAmnt={6},targetDecay={7},decayFact={8},fricTS={9},frictFact={10}", + BSScene.DetailLogZero, UseName, origCurrVal, origTarget, timeStep, TimeScale, addAmount, TargetValueDecayTimeScale, decayFactor, FrictionTimescale, frictionFactor); MDetailLog("{0},BSVMotor.Step,nonZero,{1},curr={2},target={3},add={4},decay={5},frict={6},ret={7}", - BSScene.DetailLogZero, UseName, TargetValue, CurrentValue, + BSScene.DetailLogZero, UseName, CurrentValue, TargetValue, addAmount, decayFactor, frictionFactor, returnCurrent); } else From 59554758b155c7965dc414a16e8b35c115ad3f64 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 27 Nov 2012 05:24:29 -0800 Subject: [PATCH 2/8] BulletSim: implementation of vertical attraction motor. --- .../Physics/BulletSPlugin/BSDynamics.cs | 99 +++++++++++-------- 1 file changed, 60 insertions(+), 39 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index 6ff8a48a27..d94abf44ea 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -125,6 +125,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. //Attractor properties + private BSVMotor m_verticalAttractionMotor = new BSVMotor("VerticalAttraction"); private float m_verticalAttractionEfficiency = 1.0f; // damped private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. @@ -197,9 +198,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin break; case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: m_verticalAttractionEfficiency = Math.Max(0.1f, Math.Min(pValue, 1f)); + m_verticalAttractionMotor.Efficiency = m_verticalAttractionEfficiency; break; case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: m_verticalAttractionTimescale = Math.Max(pValue, 0.01f); + m_verticalAttractionMotor.TimeScale = m_verticalAttractionTimescale; break; // These are vector properties but the engine lets you use a single float value to @@ -530,12 +533,22 @@ namespace OpenSim.Region.Physics.BulletSPlugin Refresh(); m_linearMotor = new BSVMotor("LinearMotor", m_linearMotorTimescale, - m_linearMotorDecayTimescale, m_linearFrictionTimescale, 1f); + m_linearMotorDecayTimescale, m_linearFrictionTimescale, + 1f); m_linearMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) + m_angularMotor = new BSVMotor("AngularMotor", m_angularMotorTimescale, - m_angularMotorDecayTimescale, m_angularFrictionTimescale, 1f); + m_angularMotorDecayTimescale, m_angularFrictionTimescale, + 1f); m_angularMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) + m_verticalAttractionMotor = new BSVMotor("VerticalAttraction", m_verticalAttractionTimescale, + BSMotor.Infinite, BSMotor.InfiniteVector, + m_verticalAttractionEfficiency); + // Z goes away and we keep X and Y + m_verticalAttractionMotor.FrictionTimescale = new Vector3(BSMotor.Infinite, BSMotor.Infinite, 0.1f); + m_verticalAttractionMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG DEBUG (enables detail logging) + // m_bankingMotor = new BSVMotor("BankingMotor", ...); } @@ -828,47 +841,64 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep); + // ================================================================== + // NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement + if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) + { + angularMotorContribution.X = 0f; + angularMotorContribution.Y = 0f; + VDetailLog("{0},MoveAngular,noDeflectionUp,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); + } + // ================================================================== Vector3 verticalAttractionContribution = Vector3.Zero; // If vertical attaction timescale is reasonable and we applied an angular force last time... - if (m_verticalAttractionTimescale < 300 && m_lastAngularVelocity != Vector3.Zero) + if (m_verticalAttractionTimescale < 500) { - float VAservo = pTimestep * 0.2f / m_verticalAttractionTimescale; - if (Prim.IsColliding) - VAservo = pTimestep * 0.05f / m_verticalAttractionTimescale; - - VAservo *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); - - // Create a vector of the vehicle "up" in world coordinates Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; - // verticalError.X and .Y are the World error amounts. They are 0 when there is no - // error (Vehicle Body is 'vertical'), and .Z will be 1. As the body leans to its - // side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall - // and .Z will go negative. Similar for tilt and |.Y|. .X and .Y must be - // modulated to prevent a stable inverted body. + verticalError.Normalize(); + m_verticalAttractionMotor.SetCurrent(verticalError); + m_verticalAttractionMotor.SetTarget(Vector3.UnitZ); + verticalAttractionContribution = m_verticalAttractionMotor.Step(pTimestep); + /* + // Take a vector pointing up and convert it from world to vehicle relative coords. + Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; + verticalError.Normalize(); - // Error is 0 (no error) to +/- 2 (max error) - verticalError.X = Math.Max(-2f, Math.Min(verticalError.X, 2f)); - verticalError.Y = Math.Max(-2f, Math.Min(verticalError.Y, 2f)); + // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) + // is now leaning to one side (rotated around the X axis) and the Y value will + // go from zero (nearly straight up) to one (completely to the side) or leaning + // front-to-back (rotated around the Y axis) and the value of X will be between + // zero and one. + // The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees. - // scale it by VAservo (timestep and timescale) - verticalError = verticalError * VAservo; + // If verticalError.Z is negative, the vehicle is upside down. Add additional push. + if (verticalError.Z < 0f) + { + verticalError.X = 2f - verticalError.X; + verticalError.Y = 2f - verticalError.Y; + } - // As the body rotates around the X axis, then verticalError.Y increases; Rotated around Y - // then .X increases, so change Body angular velocity X based on Y, and Y based on X. - // Z is not changed. + // Y error means needed rotation around X axis and visa versa. verticalAttractionContribution.X = verticalError.Y; verticalAttractionContribution.Y = - verticalError.X; verticalAttractionContribution.Z = 0f; - // scaling appears better usingsquare-law - Vector3 angularVelocity = Prim.ForceRotationalVelocity; - float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); - verticalAttractionContribution.X += bounce * angularVelocity.X; - verticalAttractionContribution.Y += bounce * angularVelocity.Y; + // scale by the time scale and timestep + Vector3 unscaledContrib = verticalAttractionContribution; + verticalAttractionContribution /= m_verticalAttractionTimescale; + verticalAttractionContribution *= pTimestep; - VDetailLog("{0},MoveAngular,verticalAttraction,VAservo={1},effic={2},verticalError={3},bounce={4},vertattr={5}", - Prim.LocalID, VAservo, m_verticalAttractionEfficiency, verticalError, bounce, verticalAttractionContribution); + // apply efficiency + Vector3 preEfficiencyContrib = verticalAttractionContribution; + float efficencySquared = m_verticalAttractionEfficiency * m_verticalAttractionEfficiency; + verticalAttractionContribution *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); + + VDetailLog("{0},MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},preEff={3},eff={4},effSq={5},vertAttr={6}", + Prim.LocalID, verticalError, unscaledContrib, preEfficiencyContrib, + m_verticalAttractionEfficiency, efficencySquared, + verticalAttractionContribution); + */ } @@ -988,15 +1018,6 @@ namespace OpenSim.Region.Physics.BulletSPlugin VDetailLog("{0},BSDynamic.MoveAngular,motorOffset,applyTorqueImpulse={1}", Prim.LocalID, torqueFromOffset); } - // ================================================================== - // NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement - if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0) - { - m_lastAngularVelocity.X = 0; - m_lastAngularVelocity.Y = 0; - VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity); - } - // ================================================================== if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) { From 68fe7dff20fb38480a1c760f1347dafac43899c5 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 27 Nov 2012 05:37:06 -0800 Subject: [PATCH 3/8] BulletSim: reorganize angular movement routine into separate subroutines enabling external calibration routines and unit testing. --- .../Physics/BulletSPlugin/BSDynamics.cs | 289 ++++++++++-------- 1 file changed, 154 insertions(+), 135 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index d94abf44ea..eb4d06a95e 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -317,7 +317,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_VhoverEfficiency = 0; m_VhoverTimescale = 0; m_VehicleBuoyancy = 0; - + m_linearDeflectionEfficiency = 1; m_linearDeflectionTimescale = 1; @@ -366,8 +366,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin m_bankingMix = 1; m_referenceFrame = Quaternion.Identity; - m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY - | VehicleFlag.HOVER_TERRAIN_ONLY + m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY + | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); m_flags |= (VehicleFlag.NO_DEFLECTION_UP @@ -575,7 +575,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin Vector3 localInertia = new Vector3(m_vehicleMass, m_vehicleMass, m_vehicleMass); BulletSimAPI.SetMassProps2(Prim.PhysBody.ptr, m_vehicleMass, localInertia); - VDetailLog("{0},BSDynamics.Refresh,frict={1},inert={2},aDamp={3}", + VDetailLog("{0},BSDynamics.Refresh,frict={1},inert={2},aDamp={3}", Prim.LocalID, friction, localInertia, angularDamping); } } @@ -759,13 +759,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce // has a decay factor. This says this force should // be computed with a motor. - VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}", + VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}", Prim.LocalID, distanceAboveGround, limitMotorUpContribution); } // ================================================================== - Vector3 newVelocity = linearMotorContribution - + terrainHeightContribution + Vector3 newVelocity = linearMotorContribution + + terrainHeightContribution + hoverContribution + limitMotorUpContribution; @@ -801,7 +801,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin } VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},primVel={4},totalDown={5}", - Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, + Prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, newVelocity, Prim.Velocity, totalDownForce); } // end MoveLinear() @@ -850,139 +850,17 @@ namespace OpenSim.Region.Physics.BulletSPlugin VDetailLog("{0},MoveAngular,noDeflectionUp,angularMotorContrib={1}", Prim.LocalID, angularMotorContribution); } - // ================================================================== - Vector3 verticalAttractionContribution = Vector3.Zero; - // If vertical attaction timescale is reasonable and we applied an angular force last time... - if (m_verticalAttractionTimescale < 500) - { - Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; - verticalError.Normalize(); - m_verticalAttractionMotor.SetCurrent(verticalError); - m_verticalAttractionMotor.SetTarget(Vector3.UnitZ); - verticalAttractionContribution = m_verticalAttractionMotor.Step(pTimestep); - /* - // Take a vector pointing up and convert it from world to vehicle relative coords. - Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; - verticalError.Normalize(); + Vector3 verticalAttractionContribution = ComputeAngularVerticalAttraction(pTimestep); - // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) - // is now leaning to one side (rotated around the X axis) and the Y value will - // go from zero (nearly straight up) to one (completely to the side) or leaning - // front-to-back (rotated around the Y axis) and the value of X will be between - // zero and one. - // The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees. + Vector3 deflectionContribution = ComputeAngularDeflection(pTimestep); - // If verticalError.Z is negative, the vehicle is upside down. Add additional push. - if (verticalError.Z < 0f) - { - verticalError.X = 2f - verticalError.X; - verticalError.Y = 2f - verticalError.Y; - } - - // Y error means needed rotation around X axis and visa versa. - verticalAttractionContribution.X = verticalError.Y; - verticalAttractionContribution.Y = - verticalError.X; - verticalAttractionContribution.Z = 0f; - - // scale by the time scale and timestep - Vector3 unscaledContrib = verticalAttractionContribution; - verticalAttractionContribution /= m_verticalAttractionTimescale; - verticalAttractionContribution *= pTimestep; - - // apply efficiency - Vector3 preEfficiencyContrib = verticalAttractionContribution; - float efficencySquared = m_verticalAttractionEfficiency * m_verticalAttractionEfficiency; - verticalAttractionContribution *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); - - VDetailLog("{0},MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},preEff={3},eff={4},effSq={5},vertAttr={6}", - Prim.LocalID, verticalError, unscaledContrib, preEfficiencyContrib, - m_verticalAttractionEfficiency, efficencySquared, - verticalAttractionContribution); - */ - - } - - // ================================================================== - Vector3 deflectionContribution = Vector3.Zero; - if (m_angularDeflectionEfficiency != 0) - { - // Compute a scaled vector that points in the preferred axis (X direction) - Vector3 scaledDefaultDirection = - new Vector3((pTimestep * 10 * (m_angularDeflectionEfficiency / m_angularDeflectionTimescale)), 0, 0); - // Adding the current vehicle orientation and reference frame displaces the orientation to the frame. - // Rotate the scaled default axix relative to the actual vehicle direction giving where it should point. - Vector3 preferredAxisOfMotion = scaledDefaultDirection * Quaternion.Add(Prim.ForceOrientation, m_referenceFrame); - - // Scale by efficiency and timescale - deflectionContribution = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep; - - VDetailLog("{0},MoveAngular,Deflection,perfAxis={1},deflection={2}", - Prim.LocalID, preferredAxisOfMotion, deflectionContribution); - // This deflection computation is not correct. - deflectionContribution = Vector3.Zero; - } - - // ================================================================== - Vector3 bankingContribution = Vector3.Zero; - if (m_bankingEfficiency != 0) - { - Vector3 dir = Vector3.One * Prim.ForceOrientation; - float mult = (m_bankingMix*m_bankingMix)*-1*(m_bankingMix < 0 ? -1 : 1); - //Changes which way it banks in and out of turns - - //Use the square of the efficiency, as it looks much more how SL banking works - float effSquared = (m_bankingEfficiency*m_bankingEfficiency); - if (m_bankingEfficiency < 0) - effSquared *= -1; //Keep the negative! - - float mix = Math.Abs(m_bankingMix); - if (m_angularMotorVelocity.X == 0) - { - // The vehicle is stopped - /*if (!parent.Orientation.ApproxEquals(this.m_referenceFrame, 0.25f)) - { - Vector3 axisAngle; - float angle; - parent.Orientation.GetAxisAngle(out axisAngle, out angle); - Vector3 rotatedVel = parent.Velocity * parent.Orientation; - if ((rotatedVel.X < 0 && axisAngle.Y > 0) || (rotatedVel.X > 0 && axisAngle.Y < 0)) - m_angularMotorVelocity.X += (effSquared * (mult * mix)) * (1f) * 10; - else - m_angularMotorVelocity.X += (effSquared * (mult * mix)) * (-1f) * 10; - }*/ - } - else - { - bankingContribution.Z += (effSquared * (mult * mix)) * (m_angularMotorVelocity.X) * 4; - } - - //If they are colliding, we probably shouldn't shove the prim around... probably - if (!Prim.IsColliding && Math.Abs(m_angularMotorVelocity.X) > mix) - { - float angVelZ = m_angularMotorVelocity.X*-1; - /*if(angVelZ > mix) - angVelZ = mix; - else if(angVelZ < -mix) - angVelZ = -mix;*/ - //This controls how fast and how far the banking occurs - Vector3 bankingRot = new Vector3(angVelZ*(effSquared*mult), 0, 0); - if (bankingRot.X > 3) - bankingRot.X = 3; - else if (bankingRot.X < -3) - bankingRot.X = -3; - bankingRot *= Prim.ForceOrientation; - bankingContribution += bankingRot; - } - m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency; - VDetailLog("{0},MoveAngular,Banking,bEff={1},angMotVel={2},effSq={3},mult={4},mix={5},banking={6}", - Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, effSquared, mult, mix, bankingContribution); - } + Vector3 bankingContribution = ComputeAngularBanking(pTimestep); // ================================================================== m_lastVertAttractor = verticalAttractionContribution; // Sum velocities - m_lastAngularVelocity = angularMotorContribution + m_lastAngularVelocity = angularMotorContribution + verticalAttractionContribution + bankingContribution + deflectionContribution; @@ -1032,7 +910,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin // Since we are stuffing the angular velocity directly into the object, the computed // velocity needs to be scaled by the timestep. // Also remove any motion that is on the object so added motion is only from vehicle. - Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) + Vector3 applyAngularForce = ((m_lastAngularVelocity * pTimestep) - Prim.ForceRotationalVelocity); // Unscale the force by the angular factor so it overwhelmes the Bullet additions. Prim.ForceRotationalVelocity = applyAngularForce; @@ -1046,6 +924,147 @@ namespace OpenSim.Region.Physics.BulletSPlugin } } + public Vector3 ComputeAngularVerticalAttraction(float pTimestep) + { + Vector3 ret = Vector3.Zero; + + // If vertical attaction timescale is reasonable and we applied an angular force last time... + if (m_verticalAttractionTimescale < 500) + { + Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; + verticalError.Normalize(); + m_verticalAttractionMotor.SetCurrent(verticalError); + m_verticalAttractionMotor.SetTarget(Vector3.UnitZ); + ret = m_verticalAttractionMotor.Step(pTimestep); + /* + // Take a vector pointing up and convert it from world to vehicle relative coords. + Vector3 verticalError = Vector3.UnitZ * Prim.ForceOrientation; + verticalError.Normalize(); + + // If vertical attraction correction is needed, the vector that was pointing up (UnitZ) + // is now leaning to one side (rotated around the X axis) and the Y value will + // go from zero (nearly straight up) to one (completely to the side) or leaning + // front-to-back (rotated around the Y axis) and the value of X will be between + // zero and one. + // The value of Z is how far the rotation is off with 1 meaning none and 0 being 90 degrees. + + // If verticalError.Z is negative, the vehicle is upside down. Add additional push. + if (verticalError.Z < 0f) + { + verticalError.X = 2f - verticalError.X; + verticalError.Y = 2f - verticalError.Y; + } + + // Y error means needed rotation around X axis and visa versa. + verticalAttractionContribution.X = verticalError.Y; + verticalAttractionContribution.Y = - verticalError.X; + verticalAttractionContribution.Z = 0f; + + // scale by the time scale and timestep + Vector3 unscaledContrib = verticalAttractionContribution; + verticalAttractionContribution /= m_verticalAttractionTimescale; + verticalAttractionContribution *= pTimestep; + + // apply efficiency + Vector3 preEfficiencyContrib = verticalAttractionContribution; + float efficencySquared = m_verticalAttractionEfficiency * m_verticalAttractionEfficiency; + verticalAttractionContribution *= (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); + + VDetailLog("{0},MoveAngular,verticalAttraction,,verticalError={1},unscaled={2},preEff={3},eff={4},effSq={5},vertAttr={6}", + Prim.LocalID, verticalError, unscaledContrib, preEfficiencyContrib, + m_verticalAttractionEfficiency, efficencySquared, + verticalAttractionContribution); + */ + + } + return ret; + } + + public Vector3 ComputeAngularDeflection(float pTimestep) + { + Vector3 ret = Vector3.Zero; + + if (m_angularDeflectionEfficiency != 0) + { + // Compute a scaled vector that points in the preferred axis (X direction) + Vector3 scaledDefaultDirection = + new Vector3((pTimestep * 10 * (m_angularDeflectionEfficiency / m_angularDeflectionTimescale)), 0, 0); + // Adding the current vehicle orientation and reference frame displaces the orientation to the frame. + // Rotate the scaled default axix relative to the actual vehicle direction giving where it should point. + Vector3 preferredAxisOfMotion = scaledDefaultDirection * Quaternion.Add(Prim.ForceOrientation, m_referenceFrame); + + // Scale by efficiency and timescale + ret = (preferredAxisOfMotion * (m_angularDeflectionEfficiency) / m_angularDeflectionTimescale) * pTimestep; + + VDetailLog("{0},MoveAngular,Deflection,perfAxis={1},deflection={2}", Prim.LocalID, preferredAxisOfMotion, ret); + + // This deflection computation is not correct. + ret = Vector3.Zero; + } + return ret; + } + + public Vector3 ComputeAngularBanking(float pTimestep) + { + Vector3 ret = Vector3.Zero; + + if (m_bankingEfficiency != 0) + { + Vector3 dir = Vector3.One * Prim.ForceOrientation; + float mult = (m_bankingMix * m_bankingMix) * -1 * (m_bankingMix < 0 ? -1 : 1); + //Changes which way it banks in and out of turns + + //Use the square of the efficiency, as it looks much more how SL banking works + float effSquared = (m_bankingEfficiency * m_bankingEfficiency); + if (m_bankingEfficiency < 0) + effSquared *= -1; //Keep the negative! + + float mix = Math.Abs(m_bankingMix); + if (m_angularMotorVelocity.X == 0) + { + // The vehicle is stopped + /*if (!parent.Orientation.ApproxEquals(this.m_referenceFrame, 0.25f)) + { + Vector3 axisAngle; + float angle; + parent.Orientation.GetAxisAngle(out axisAngle, out angle); + Vector3 rotatedVel = parent.Velocity * parent.Orientation; + if ((rotatedVel.X < 0 && axisAngle.Y > 0) || (rotatedVel.X > 0 && axisAngle.Y < 0)) + m_angularMotorVelocity.X += (effSquared * (mult * mix)) * (1f) * 10; + else + m_angularMotorVelocity.X += (effSquared * (mult * mix)) * (-1f) * 10; + }*/ + } + else + { + ret.Z += (effSquared * (mult * mix)) * (m_angularMotorVelocity.X) * 4; + } + + //If they are colliding, we probably shouldn't shove the prim around... probably + if (!Prim.IsColliding && Math.Abs(m_angularMotorVelocity.X) > mix) + { + float angVelZ = m_angularMotorVelocity.X * -1; + /*if(angVelZ > mix) + angVelZ = mix; + else if(angVelZ < -mix) + angVelZ = -mix;*/ + //This controls how fast and how far the banking occurs + Vector3 bankingRot = new Vector3(angVelZ * (effSquared * mult), 0, 0); + if (bankingRot.X > 3) + bankingRot.X = 3; + else if (bankingRot.X < -3) + bankingRot.X = -3; + bankingRot *= Prim.ForceOrientation; + ret += bankingRot; + } + m_angularMotorVelocity.X *= m_bankingEfficiency == 1 ? 0.0f : 1 - m_bankingEfficiency; + VDetailLog("{0},MoveAngular,Banking,bEff={1},angMotVel={2},effSq={3},mult={4},mix={5},banking={6}", + Prim.LocalID, m_bankingEfficiency, m_angularMotorVelocity, effSquared, mult, mix, ret); + } + return ret; + } + + // This is from previous instantiations of XXXDynamics.cs. // Applies roll reference frame. // TODO: is this the right way to separate the code to do this operation? From a5100cafee7e1e79f911c1e33fb1742075ca7283 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 27 Nov 2012 10:01:25 -0800 Subject: [PATCH 4/8] BulletSim: fix terrain mesh generation for problem with regions that have unequal edge heights. Thanks UBit. --- .../Physics/BulletSPlugin/BSTerrainMesh.cs | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs index d7afdeb038..5f6675d526 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainMesh.cs @@ -88,9 +88,11 @@ public sealed class BSTerrainMesh : BSTerrainPhys // Something is very messed up and a crash is in our future. return; } + PhysicsScene.DetailLog("{0},BSTerrainMesh.create,meshed,indices={1},indSz={2},vertices={3},vertSz={4}", + ID, indicesCount, indices.Length, verticesCount, vertices.Length); m_terrainShape = new BulletShape(BulletSimAPI.CreateMeshShape2(PhysicsScene.World.ptr, - indicesCount, indices, verticesCount, vertices), + indicesCount, indices, verticesCount, vertices), BSPhysicsShapeType.SHAPE_MESH); if (m_terrainShape.ptr == IntPtr.Zero) { @@ -122,10 +124,10 @@ public sealed class BSTerrainMesh : BSTerrainPhys // Static objects are not very massive. BulletSimAPI.SetMassProps2(m_terrainBody.ptr, 0f, Vector3.Zero); - // Return the new terrain to the world of physical objects + // Put the new terrain to the world of physical objects BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_terrainBody.ptr); - // redo its bounding box now that it is in the world + // Redo its bounding box now that it is in the world BulletSimAPI.UpdateSingleAabb2(PhysicsScene.World.ptr, m_terrainBody.ptr); BulletSimAPI.SetCollisionFilterMask2(m_terrainBody.ptr, @@ -188,6 +190,11 @@ public sealed class BSTerrainMesh : BSTerrainPhys // Simple mesh creation which assumes magnification == 1. // TODO: do a more general solution that scales, adds new vertices and smoothes the result. + // Create an array of vertices that is sizeX+1 by sizeY+1 (note the loop + // from zero to <= sizeX). The triangle indices are then generated as two triangles + // per heightmap point. There are sizeX by sizeY of these squares. The extra row and + // column of vertices are used to complete the triangles of the last row and column + // of the heightmap. try { // One vertice per heightmap value plus the vertices off the top and bottom edge. @@ -200,16 +207,18 @@ public sealed class BSTerrainMesh : BSTerrainPhys float magY = (float)sizeY / extentY; physicsScene.DetailLog("{0},BSTerrainMesh.ConvertHeightMapToMesh,totVert={1},totInd={2},extentBase={3},magX={4},magY={5}", BSScene.DetailLogZero, totalVertices, totalIndices, extentBase, magX, magY); + float minHeight = float.MaxValue; // Note that sizeX+1 vertices are created since there is land between this and the next region. for (int yy = 0; yy <= sizeY; yy++) { - for (int xx = 0; xx <= sizeX; xx++) // Hint: the "<=" means we got through sizeX + 1 times + for (int xx = 0; xx <= sizeX; xx++) // Hint: the "<=" means we go around sizeX + 1 times { int offset = yy * sizeX + xx; - // Extend the height from the height from the last row or column + // Extend the height with the height from the last row or column if (yy == sizeY) offset -= sizeX; if (xx == sizeX) offset -= 1; float height = heightMap[offset]; + minHeight = Math.Min(minHeight, height); vertices[verticesCount + 0] = (float)xx * magX + extentBase.X; vertices[verticesCount + 1] = (float)yy * magY + extentBase.Y; vertices[verticesCount + 2] = height + extentBase.Z; @@ -222,7 +231,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys { for (int xx = 0; xx < sizeX; xx++) { - int offset = yy * sizeX + xx; + int offset = yy * (sizeX + 1) + xx; // Each vertices is presumed to be the upper left corner of a box of two triangles indices[indicesCount + 0] = offset; indices[indicesCount + 1] = offset + 1; @@ -233,6 +242,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys indicesCount += 6; } } + ret = true; } catch (Exception e) From 8e459a03467ffa45145f90ea764854deaf2615ed Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Tue, 27 Nov 2012 10:02:29 -0800 Subject: [PATCH 5/8] BulletSim: reorganize linear movement routine into separate subroutines enabling external calibration routines and unit tests. --- .../Physics/BulletSPlugin/BSDynamics.cs | 273 ++++++++++-------- 1 file changed, 147 insertions(+), 126 deletions(-) diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index eb4d06a95e..74eb9ab408 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs @@ -630,138 +630,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; Vector3 grav = Prim.PhysicsScene.DefaultGravity * (1f - m_VehicleBuoyancy); - // Current vehicle position Vector3 pos = Prim.ForcePosition; - - // ================================================================== - Vector3 terrainHeightContribution = Vector3.Zero; - // If below the terrain, move us above the ground a little. float terrainHeight = Prim.PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(pos); - // Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset. - // TODO: Add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass. - // Vector3 rotatedSize = m_prim.Size * m_prim.ForceOrientation; - // if (rotatedSize.Z < terrainHeight) - if (pos.Z < terrainHeight) - { - // TODO: correct position by applying force rather than forcing position. - pos.Z = terrainHeight + 2; - Prim.ForcePosition = pos; - VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, terrainHeight, pos); - } - // ================================================================== - Vector3 hoverContribution = Vector3.Zero; - // Check if hovering - // m_VhoverEfficiency: 0=bouncy, 1=totally damped - // m_VhoverTimescale: time to achieve height - if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) - { - // We should hover, get the target height - if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0) - { - m_VhoverTargetHeight = Prim.PhysicsScene.GetWaterLevelAtXYZ(pos) + m_VhoverHeight; - } - if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) - { - m_VhoverTargetHeight = terrainHeight + m_VhoverHeight; - } - if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) - { - m_VhoverTargetHeight = m_VhoverHeight; - } + Vector3 terrainHeightContribution = ComputeLinearTerrainHeightCorrection(pTimestep, ref pos, terrainHeight); - if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0) - { - // If body is already heigher, use its height as target height - if (pos.Z > m_VhoverTargetHeight) - m_VhoverTargetHeight = pos.Z; - } - if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) - { - if (Math.Abs(pos.Z - m_VhoverTargetHeight) > 0.2f) - { - pos.Z = m_VhoverTargetHeight; - Prim.ForcePosition = pos; - } - } - else - { - float verticalError = pos.Z - m_VhoverTargetHeight; - // RA: where does the 50 come from? - float verticalCorrectionVelocity = pTimestep * ((verticalError * 50.0f) / m_VhoverTimescale); - // Replace Vertical speed with correction figure if significant - if (verticalError > 0.01f) - { - hoverContribution = new Vector3(0f, 0f, verticalCorrectionVelocity); - //KF: m_VhoverEfficiency is not yet implemented - } - else if (verticalError < -0.01) - { - hoverContribution = new Vector3(0f, 0f, -verticalCorrectionVelocity); - } - } + Vector3 hoverContribution = ComputeLinearHover(pTimestep, ref pos, terrainHeight); - VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", - Prim.LocalID, pos, hoverContribution, m_VhoverHeight, m_VhoverTargetHeight); - } + ComputeLinearBlockingEndPoint(pTimestep, ref pos); - // ================================================================== - Vector3 posChange = pos - m_lastPositionVector; - if (m_BlockingEndPoint != Vector3.Zero) - { - bool changed = false; - if (pos.X >= (m_BlockingEndPoint.X - (float)1)) - { - pos.X -= posChange.X + 1; - changed = true; - } - if (pos.Y >= (m_BlockingEndPoint.Y - (float)1)) - { - pos.Y -= posChange.Y + 1; - changed = true; - } - if (pos.Z >= (m_BlockingEndPoint.Z - (float)1)) - { - pos.Z -= posChange.Z + 1; - changed = true; - } - if (pos.X <= 0) - { - pos.X += posChange.X + 1; - changed = true; - } - if (pos.Y <= 0) - { - pos.Y += posChange.Y + 1; - changed = true; - } - if (changed) - { - Prim.ForcePosition = pos; - VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", - Prim.LocalID, m_BlockingEndPoint, posChange, pos); - } - } - - // ================================================================== - Vector3 limitMotorUpContribution = Vector3.Zero; - if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) - { - // If the vehicle is motoring into the sky, get it going back down. - float distanceAboveGround = pos.Z - terrainHeight; - if (distanceAboveGround > 1f) - { - // downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep); - // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); - limitMotorUpContribution = new Vector3(0, 0, -distanceAboveGround); - } - // TODO: this calculation is all wrong. From the description at - // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce - // has a decay factor. This says this force should - // be computed with a motor. - VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}", - Prim.LocalID, distanceAboveGround, limitMotorUpContribution); - } + Vector3 limitMotorUpContribution = ComputeLinearMotorUp(pTimestep, pos, terrainHeight); // ================================================================== Vector3 newVelocity = linearMotorContribution @@ -806,6 +684,149 @@ namespace OpenSim.Region.Physics.BulletSPlugin } // end MoveLinear() + public Vector3 ComputeLinearTerrainHeightCorrection(float pTimestep, ref Vector3 pos, float terrainHeight) + { + Vector3 ret = Vector3.Zero; + // If below the terrain, move us above the ground a little. + // Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset. + // TODO: Add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass. + // Vector3 rotatedSize = m_prim.Size * m_prim.ForceOrientation; + // if (rotatedSize.Z < terrainHeight) + if (pos.Z < terrainHeight) + { + // TODO: correct position by applying force rather than forcing position. + pos.Z = terrainHeight + 2; + Prim.ForcePosition = pos; + VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", Prim.LocalID, terrainHeight, pos); + } + return ret; + } + + public Vector3 ComputeLinearHover(float pTimestep, ref Vector3 pos, float terrainHeight) + { + Vector3 ret = Vector3.Zero; + + // m_VhoverEfficiency: 0=bouncy, 1=totally damped + // m_VhoverTimescale: time to achieve height + if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) + { + // We should hover, get the target height + if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0) + { + m_VhoverTargetHeight = Prim.PhysicsScene.GetWaterLevelAtXYZ(pos) + m_VhoverHeight; + } + if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) + { + m_VhoverTargetHeight = terrainHeight + m_VhoverHeight; + } + if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) + { + m_VhoverTargetHeight = m_VhoverHeight; + } + + if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0) + { + // If body is already heigher, use its height as target height + if (pos.Z > m_VhoverTargetHeight) + m_VhoverTargetHeight = pos.Z; + } + if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) + { + if (Math.Abs(pos.Z - m_VhoverTargetHeight) > 0.2f) + { + pos.Z = m_VhoverTargetHeight; + Prim.ForcePosition = pos; + } + } + else + { + float verticalError = pos.Z - m_VhoverTargetHeight; + // RA: where does the 50 come from? + float verticalCorrectionVelocity = pTimestep * ((verticalError * 50.0f) / m_VhoverTimescale); + // Replace Vertical speed with correction figure if significant + if (verticalError > 0.01f) + { + ret = new Vector3(0f, 0f, verticalCorrectionVelocity); + //KF: m_VhoverEfficiency is not yet implemented + } + else if (verticalError < -0.01) + { + ret = new Vector3(0f, 0f, -verticalCorrectionVelocity); + } + } + + VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", + Prim.LocalID, pos, ret, m_VhoverHeight, m_VhoverTargetHeight); + } + + return ret; + } + + public bool ComputeLinearBlockingEndPoint(float pTimestep, ref Vector3 pos) + { + bool changed = false; + + Vector3 posChange = pos - m_lastPositionVector; + if (m_BlockingEndPoint != Vector3.Zero) + { + if (pos.X >= (m_BlockingEndPoint.X - (float)1)) + { + pos.X -= posChange.X + 1; + changed = true; + } + if (pos.Y >= (m_BlockingEndPoint.Y - (float)1)) + { + pos.Y -= posChange.Y + 1; + changed = true; + } + if (pos.Z >= (m_BlockingEndPoint.Z - (float)1)) + { + pos.Z -= posChange.Z + 1; + changed = true; + } + if (pos.X <= 0) + { + pos.X += posChange.X + 1; + changed = true; + } + if (pos.Y <= 0) + { + pos.Y += posChange.Y + 1; + changed = true; + } + if (changed) + { + Prim.ForcePosition = pos; + VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}", + Prim.LocalID, m_BlockingEndPoint, posChange, pos); + } + } + return changed; + } + + public Vector3 ComputeLinearMotorUp(float pTimestep, Vector3 pos, float terrainHeight) + { + Vector3 ret = Vector3.Zero; + if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) + { + // If the vehicle is motoring into the sky, get it going back down. + float distanceAboveGround = pos.Z - terrainHeight; + if (distanceAboveGround > 1f) + { + // downForce = new Vector3(0, 0, (-distanceAboveGround / m_bankingTimescale) * pTimestep); + // downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale); + ret = new Vector3(0, 0, -distanceAboveGround); + } + // TODO: this calculation is all wrong. From the description at + // (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce + // has a decay factor. This says this force should + // be computed with a motor. + VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}", + Prim.LocalID, distanceAboveGround, ret); + } + return ret; + } + // ======================================================================= // ======================================================================= // Apply the effect of the angular motor. From 2cd88787af52213e1f0b2d863b75e35ca83e8032 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Tue, 27 Nov 2012 14:42:28 -0800 Subject: [PATCH 6/8] Prevent the core Groups module from being enabled when its name doesn't match the "default" ini choice --- OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs b/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs index af54c1a1de..b735c611bb 100644 --- a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs @@ -81,7 +81,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups } if (groupsConfig.GetString("Module", "Default") != "Default") + { + m_Enabled = false; return; + } } } From c17ea2049b3027abb5bc5446a8c5b0d4985953b9 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 28 Nov 2012 01:42:58 +0000 Subject: [PATCH 7/8] Show many more primitive properties on console command "show part name/id/pos" --- .../Objects/Commands/ObjectCommandsModule.cs | 60 ++++++++++++++++++- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index ab8f14344b..7b235aef74 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs @@ -365,7 +365,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands if (mainParams.Count < 4) { - m_console.OutputFormat("Usage: show part id [--full] "); + //m_console.OutputFormat("Usage: show part id [--full] "); + m_console.OutputFormat("Usage: show part id "); return; } @@ -405,6 +406,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands if (mainParams.Count < 5) { + //m_console.OutputFormat("Usage: show part pos to "); m_console.OutputFormat("Usage: show part pos [--full] to "); return; } @@ -445,7 +447,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands if (mainParams.Count < 4) { - m_console.OutputFormat("Usage: show part name [--full] [--regex] "); + m_console.OutputFormat("Usage: show part name [--regex] "); + //m_console.OutputFormat("Usage: show part name [--full] [--regex] "); return; } @@ -577,6 +580,58 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands cdl.AddRow("Link number", sop.LinkNum); cdl.AddRow("Flags", sop.Flags); + if (showFull) + { + PrimitiveBaseShape s = sop.Shape; + cdl.AddRow("FlexiDrag", s.FlexiDrag); + cdl.AddRow("FlexiEntry", s.FlexiEntry); + cdl.AddRow("FlexiForce", string.Format("<{0},{1},{2}>", s.FlexiForceX, s.FlexiForceY, s.FlexiForceZ)); + cdl.AddRow("FlexiGravity", s.FlexiGravity); + cdl.AddRow("FlexiSoftness", s.FlexiSoftness); + cdl.AddRow("HollowShape", s.HollowShape); + cdl.AddRow( + "LightColor", + string.Format("<{0},{1},{2},{3}>", s.LightColorR, s.LightColorB, s.LightColorG, s.LightColorA)); + cdl.AddRow("FlexiDrag", s.LightCutoff); + cdl.AddRow("FlexiDrag", s.LightEntry); + cdl.AddRow("FlexiDrag", s.LightFalloff); + cdl.AddRow("FlexiDrag", s.LightIntensity); + cdl.AddRow("FlexiDrag", s.LightRadius); + cdl.AddRow("Media", string.Format("{0} entries", s.Media != null ? s.Media.Count.ToString() : "n/a")); + cdl.AddRow("PathBegin", s.PathBegin); + cdl.AddRow("PathEnd", s.PathEnd); + cdl.AddRow("PathCurve", s.PathCurve); + cdl.AddRow("PathRadiusOffset", s.PathRadiusOffset); + cdl.AddRow("PathRevolutions", s.PathRevolutions); + cdl.AddRow("PathScale", string.Format("<{0},{1}>", s.PathScaleX, s.PathScaleY)); + cdl.AddRow("PathSkew", string.Format("<{0},{1}>", s.PathShearX, s.PathShearY)); + cdl.AddRow("FlexiDrag", s.PathSkew); + cdl.AddRow("PathTaper", string.Format("<{0},{1}>", s.PathTaperX, s.PathTaperY)); + cdl.AddRow("PathTwist", s.PathTwist); + cdl.AddRow("PathTwistBegin", s.PathTwistBegin); + cdl.AddRow("PCode", s.PCode); + cdl.AddRow("ProfileBegin", s.ProfileBegin); + cdl.AddRow("ProfileEnd", s.ProfileEnd); + cdl.AddRow("ProfileHollow", s.ProfileHollow); + cdl.AddRow("ProfileShape", s.ProfileShape); + cdl.AddRow("ProjectionAmbiance", s.ProjectionAmbiance); + cdl.AddRow("ProjectionEntry", s.ProjectionEntry); + cdl.AddRow("ProjectionFocus", s.ProjectionFocus); + cdl.AddRow("ProjectionFOV", s.ProjectionFOV); + cdl.AddRow("ProjectionTextureUUID", s.ProjectionTextureUUID); + cdl.AddRow("Scale", s.Scale); + cdl.AddRow( + "SculptData", + string.Format("{0} bytes", s.SculptData != null ? s.SculptData.Length.ToString() : "n/a")); + cdl.AddRow("SculptEntry", s.SculptEntry); + cdl.AddRow("SculptTexture", s.SculptTexture); + cdl.AddRow("SculptType", s.SculptType); + cdl.AddRow("State", s.State); + + // TODO, unpack and display texture entries + //cdl.AddRow("Textures", string.Format("{0} entries", s.Textures. + } + object itemsOutput; if (showFull) { @@ -588,7 +643,6 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands itemsOutput = sop.Inventory.Count; } - cdl.AddRow("Items", itemsOutput); return sb.Append(cdl.ToString()); From aae76f7be4f62db230bf4750496b913b6d013eb8 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 28 Nov 2012 02:01:04 +0000 Subject: [PATCH 8/8] Stop logging spurious asset data for {0} is zero length error for sculpts/mesh ODEPrim, for instance, always hits this code path twice at the moment Firstly before any sculpt data has been loaded (hence the spurious message) Secondly when any sculpt data has been loaded or failed to load (when the message would be valid). Hence comment this out and rely on the message in ODEPrim.MeshAssetReceived() instead (though this is not ideal since it requires all physics plugins to copy/paste similar code). --- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 5 ++++- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 3bd15ce5af..6fa91ab89b 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -321,7 +321,10 @@ namespace OpenSim.Region.Physics.Meshing if (primShape.SculptData.Length <= 0) { - m_log.ErrorFormat("[MESH]: asset data for {0} is zero length", primName); + // XXX: At the moment we can not log here since ODEPrim, for instance, ends up triggering this + // method twice - once before it has loaded sculpt data from the asset service and once afterwards. + // The first time will always call with unloaded SculptData if this needs to be uploaded. +// m_log.ErrorFormat("[MESH]: asset data for {0} is zero length", primName); return false; } diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 5a0b8d1fe1..0d66496338 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -3361,6 +3361,11 @@ Console.WriteLine(" JointCreateFixed"); _pbs.SculptData = new byte[asset.Data.Length]; asset.Data.CopyTo(_pbs.SculptData, 0); // m_assetFailed = false; + +// m_log.DebugFormat( +// "[ODE PRIM]: Received mesh/sculpt data asset {0} with {1} bytes for {2} at {3} in {4}", +// _pbs.SculptTexture, _pbs.SculptData.Length, Name, _position, _parent_scene.Name); + m_taintshape = true; _parent_scene.AddPhysicsActorTaint(this); }