From 0a29842caf5dbe711490b9b323ae922c418c6c30 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Tue, 22 Dec 2009 00:20:04 -0500 Subject: Include ChOdePlugin --- OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 1353 ++++++++++++++++++++ 1 file changed, 1353 insertions(+) create mode 100644 OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs (limited to 'OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs new file mode 100644 index 0000000..aa0acb7 --- /dev/null +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -0,0 +1,1353 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using OpenMetaverse; +using Ode.NET; +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; +using log4net; + +namespace OpenSim.Region.Physics.OdePlugin +{ + /// + /// Various properties that ODE uses for AMotors but isn't exposed in ODE.NET so we must define them ourselves. + /// + + public enum dParam : int + { + LowStop = 0, + HiStop = 1, + Vel = 2, + FMax = 3, + FudgeFactor = 4, + Bounce = 5, + CFM = 6, + StopERP = 7, + StopCFM = 8, + LoStop2 = 256, + HiStop2 = 257, + Vel2 = 258, + FMax2 = 259, + StopERP2 = 7 + 256, + StopCFM2 = 8 + 256, + LoStop3 = 512, + HiStop3 = 513, + Vel3 = 514, + FMax3 = 515, + StopERP3 = 7 + 512, + StopCFM3 = 8 + 512 + } + public class OdeCharacter : PhysicsActor + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Vector3 _position; + private d.Vector3 _zeroPosition; + // private d.Matrix3 m_StandUpRotation; + private bool _zeroFlag = false; + private bool m_lastUpdateSent = false; + private Vector3 _velocity; + private Vector3 _target_velocity; + private Vector3 _acceleration; + private Vector3 m_rotationalVelocity; + private float m_mass = 80f; + public float m_density = 60f; + private bool m_pidControllerActive = true; + public float PID_D = 800.0f; + public float PID_P = 900.0f; + //private static float POSTURE_SERVO = 10000.0f; + public float CAPSULE_RADIUS = 0.37f; + public float CAPSULE_LENGTH = 2.140599f; + public float m_tensor = 3800000f; + public float heightFudgeFactor = 0.52f; + public float walkDivisor = 1.3f; + public float runDivisor = 0.8f; + private bool flying = false; + private bool m_iscolliding = false; + private bool m_iscollidingGround = false; + private bool m_wascolliding = false; + private bool m_wascollidingGround = false; + private bool m_iscollidingObj = false; + private bool m_alwaysRun = false; + private bool m_hackSentFall = false; + private bool m_hackSentFly = false; + private int m_requestedUpdateFrequency = 0; + private Vector3 m_taintPosition = Vector3.Zero; + public uint m_localID = 0; + public bool m_returnCollisions = false; + // taints and their non-tainted counterparts + public bool m_isPhysical = false; // the current physical status + public bool m_tainted_isPhysical = false; // set when the physical status is tainted (false=not existing in physics engine, true=existing) + public float MinimumGroundFlightOffset = 3f; + + private float m_tainted_CAPSULE_LENGTH; // set when the capsule length changes. + private float m_tiltMagnitudeWhenProjectedOnXYPlane = 0.1131371f; // used to introduce a fixed tilt because a straight-up capsule falls through terrain, probably a bug in terrain collider + + + private float m_buoyancy = 0f; + + // private CollisionLocker ode; + + private string m_name = String.Empty; + + private bool[] m_colliderarr = new bool[11]; + private bool[] m_colliderGroundarr = new bool[11]; + + // Default we're a Character + private CollisionCategories m_collisionCategories = (CollisionCategories.Character); + + // Default, Collide with Other Geometries, spaces, bodies and characters. + private CollisionCategories m_collisionFlags = (CollisionCategories.Geom + | CollisionCategories.Space + | CollisionCategories.Body + | CollisionCategories.Character + | CollisionCategories.Land); + public IntPtr Body = IntPtr.Zero; + private OdeScene _parent_scene; + public IntPtr Shell = IntPtr.Zero; + public IntPtr Amotor = IntPtr.Zero; + public d.Mass ShellMass; + public bool collidelock = false; + + public int m_eventsubscription = 0; + private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate(); + + // unique UUID of this character object + public UUID m_uuid; + public bool bad = false; + + public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, CollisionLocker dode, Vector3 size, float pid_d, float pid_p, float capsule_radius, float tensor, float density, float height_fudge_factor, float walk_divisor, float rundivisor) + { + m_uuid = UUID.Random(); + + if (pos.IsFinite()) + { + if (pos.Z > 9999999f) + { + pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5; + } + if (pos.Z < -90000f) + { + pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5; + } + _position = pos; + m_taintPosition.X = pos.X; + m_taintPosition.Y = pos.Y; + m_taintPosition.Z = pos.Z; + } + else + { + _position = new Vector3(((float)_parent_scene.WorldExtents.X * 0.5f), ((float)_parent_scene.WorldExtents.Y * 0.5f), parent_scene.GetTerrainHeightAtXY(128f, 128f) + 10f); + m_taintPosition.X = _position.X; + m_taintPosition.Y = _position.Y; + m_taintPosition.Z = _position.Z; + m_log.Warn("[PHYSICS]: Got NaN Position on Character Create"); + } + + _parent_scene = parent_scene; + + PID_D = pid_d; + PID_P = pid_p; + CAPSULE_RADIUS = capsule_radius; + m_tensor = tensor; + m_density = density; + heightFudgeFactor = height_fudge_factor; + walkDivisor = walk_divisor; + runDivisor = rundivisor; + + // m_StandUpRotation = + // new d.Matrix3(0.5f, 0.7071068f, 0.5f, -0.7071068f, 0f, 0.7071068f, 0.5f, -0.7071068f, + // 0.5f); + + for (int i = 0; i < 11; i++) + { + m_colliderarr[i] = false; + } + CAPSULE_LENGTH = (size.Z * 1.15f) - CAPSULE_RADIUS * 2.0f; + //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); + m_tainted_CAPSULE_LENGTH = CAPSULE_LENGTH; + + m_isPhysical = false; // current status: no ODE information exists + m_tainted_isPhysical = true; // new tainted status: need to create ODE information + + _parent_scene.AddPhysicsActorTaint(this); + + m_name = avName; + } + + public override int PhysicsActorType + { + get { return (int) ActorTypes.Agent; } + set { return; } + } + + /// + /// If this is set, the avatar will move faster + /// + public override bool SetAlwaysRun + { + get { return m_alwaysRun; } + set { m_alwaysRun = value; } + } + + public override uint LocalID + { + set { m_localID = value; } + } + + public override bool Grabbed + { + set { return; } + } + + public override bool Selected + { + set { return; } + } + + public override float Buoyancy + { + get { return m_buoyancy; } + set { m_buoyancy = value; } + } + + public override bool FloatOnWater + { + set { return; } + } + + public override bool IsPhysical + { + get { return false; } + set { return; } + } + + public override bool ThrottleUpdates + { + get { return false; } + set { return; } + } + + public override bool Flying + { + get { return flying; } + set { flying = value; } + } + + /// + /// Returns if the avatar is colliding in general. + /// This includes the ground and objects and avatar. + /// + public override bool IsColliding + { + get { return m_iscolliding; } + set + { + int i; + int truecount = 0; + int falsecount = 0; + + if (m_colliderarr.Length >= 10) + { + for (i = 0; i < 10; i++) + { + m_colliderarr[i] = m_colliderarr[i + 1]; + } + } + m_colliderarr[10] = value; + + for (i = 0; i < 11; i++) + { + if (m_colliderarr[i]) + { + truecount++; + } + else + { + falsecount++; + } + } + + // Equal truecounts and false counts means we're colliding with something. + + if (falsecount > 1.2*truecount) + { + m_iscolliding = false; + } + else + { + m_iscolliding = true; + } + if (m_wascolliding != m_iscolliding) + { + //base.SendCollisionUpdate(new CollisionEventUpdate()); + } + m_wascolliding = m_iscolliding; + } + } + + /// + /// Returns if an avatar is colliding with the ground + /// + public override bool CollidingGround + { + get { return m_iscollidingGround; } + set + { + // Collisions against the ground are not really reliable + // So, to get a consistant value we have to average the current result over time + // Currently we use 1 second = 10 calls to this. + int i; + int truecount = 0; + int falsecount = 0; + + if (m_colliderGroundarr.Length >= 10) + { + for (i = 0; i < 10; i++) + { + m_colliderGroundarr[i] = m_colliderGroundarr[i + 1]; + } + } + m_colliderGroundarr[10] = value; + + for (i = 0; i < 11; i++) + { + if (m_colliderGroundarr[i]) + { + truecount++; + } + else + { + falsecount++; + } + } + + // Equal truecounts and false counts means we're colliding with something. + + if (falsecount > 1.2*truecount) + { + m_iscollidingGround = false; + } + else + { + m_iscollidingGround = true; + } + if (m_wascollidingGround != m_iscollidingGround) + { + //base.SendCollisionUpdate(new CollisionEventUpdate()); + } + m_wascollidingGround = m_iscollidingGround; + } + } + + /// + /// Returns if the avatar is colliding with an object + /// + public override bool CollidingObj + { + get { return m_iscollidingObj; } + set + { + m_iscollidingObj = value; + if (value) + m_pidControllerActive = false; + else + m_pidControllerActive = true; + } + } + + /// + /// turn the PID controller on or off. + /// The PID Controller will turn on all by itself in many situations + /// + /// + public void SetPidStatus(bool status) + { + m_pidControllerActive = status; + } + + public override bool Stopped + { + get { return _zeroFlag; } + } + + /// + /// This 'puts' an avatar somewhere in the physics space. + /// Not really a good choice unless you 'know' it's a good + /// spot otherwise you're likely to orbit the avatar. + /// + public override Vector3 Position + { + get { return _position; } + set + { + if (Body == IntPtr.Zero || Shell == IntPtr.Zero) + { + if (value.IsFinite()) + { + if (value.Z > 9999999f) + { + value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5; + } + if (value.Z < -90000f) + { + value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5; + } + + _position.X = value.X; + _position.Y = value.Y; + _position.Z = value.Z; + + m_taintPosition.X = value.X; + m_taintPosition.Y = value.Y; + m_taintPosition.Z = value.Z; + _parent_scene.AddPhysicsActorTaint(this); + } + else + { + m_log.Warn("[PHYSICS]: Got a NaN Position from Scene on a Character"); + } + } + } + } + + public override Vector3 RotationalVelocity + { + get { return m_rotationalVelocity; } + set { m_rotationalVelocity = value; } + } + + /// + /// This property sets the height of the avatar only. We use the height to make sure the avatar stands up straight + /// and use it to offset landings properly + /// + public override Vector3 Size + { + get { return new Vector3(CAPSULE_RADIUS * 2, CAPSULE_RADIUS * 2, CAPSULE_LENGTH); } + set + { + if (value.IsFinite()) + { + m_pidControllerActive = true; + + Vector3 SetSize = value; + m_tainted_CAPSULE_LENGTH = (SetSize.Z*1.15f) - CAPSULE_RADIUS*2.0f; + //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); + + Velocity = Vector3.Zero; + + _parent_scene.AddPhysicsActorTaint(this); + } + else + { + m_log.Warn("[PHYSICS]: Got a NaN Size from Scene on a Character"); + } + } + } + + private void AlignAvatarTiltWithCurrentDirectionOfMovement(Vector3 movementVector) + { + movementVector.Z = 0f; + float magnitude = (float)Math.Sqrt((double)(movementVector.X * movementVector.X + movementVector.Y * movementVector.Y)); + if (magnitude < 0.1f) return; + + // normalize the velocity vector + float invMagnitude = 1.0f / magnitude; + movementVector.X *= invMagnitude; + movementVector.Y *= invMagnitude; + + // if we change the capsule heading too often, the capsule can fall down + // therefore we snap movement vector to just 1 of 4 predefined directions (ne, nw, se, sw), + // meaning only 4 possible capsule tilt orientations + if (movementVector.X > 0) + { + // east + if (movementVector.Y > 0) + { + // northeast + movementVector.X = (float)Math.Sqrt(2.0); + movementVector.Y = (float)Math.Sqrt(2.0); + } + else + { + // southeast + movementVector.X = (float)Math.Sqrt(2.0); + movementVector.Y = -(float)Math.Sqrt(2.0); + } + } + else + { + // west + if (movementVector.Y > 0) + { + // northwest + movementVector.X = -(float)Math.Sqrt(2.0); + movementVector.Y = (float)Math.Sqrt(2.0); + } + else + { + // southwest + movementVector.X = -(float)Math.Sqrt(2.0); + movementVector.Y = -(float)Math.Sqrt(2.0); + } + } + + + // movementVector.Z is zero + + // calculate tilt components based on desired amount of tilt and current (snapped) heading. + // the "-" sign is to force the tilt to be OPPOSITE the direction of movement. + float xTiltComponent = -movementVector.X * m_tiltMagnitudeWhenProjectedOnXYPlane; + float yTiltComponent = -movementVector.Y * m_tiltMagnitudeWhenProjectedOnXYPlane; + + //m_log.Debug("[PHYSICS] changing avatar tilt"); + d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, xTiltComponent); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, xTiltComponent); // must be same as lowstop, else a different, spurious tilt is introduced + d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, yTiltComponent); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, yTiltComponent); // same as lowstop + d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, 0f); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop + } + + /// + /// This creates the Avatar's physical Surrogate at the position supplied + /// + /// + /// + /// + + // WARNING: This MUST NOT be called outside of ProcessTaints, else we can have unsynchronized access + // to ODE internals. ProcessTaints is called from within thread-locked Simulate(), so it is the only + // place that is safe to call this routine AvatarGeomAndBodyCreation. + private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ, float tensor) + { + //CAPSULE_LENGTH = -5; + //CAPSULE_RADIUS = -5; + int dAMotorEuler = 1; + _parent_scene.waitForSpaceUnlock(_parent_scene.space); + if (CAPSULE_LENGTH <= 0) + { + m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!"); + CAPSULE_LENGTH = 0.01f; + + } + + if (CAPSULE_RADIUS <= 0) + { + m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!"); + CAPSULE_RADIUS = 0.01f; + + } + Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH); + + d.GeomSetCategoryBits(Shell, (int)m_collisionCategories); + d.GeomSetCollideBits(Shell, (int)m_collisionFlags); + + d.MassSetCapsuleTotal(out ShellMass, m_mass, 2, CAPSULE_RADIUS, CAPSULE_LENGTH); + Body = d.BodyCreate(_parent_scene.world); + d.BodySetPosition(Body, npositionX, npositionY, npositionZ); + + _position.X = npositionX; + _position.Y = npositionY; + _position.Z = npositionZ; + + + m_taintPosition.X = npositionX; + m_taintPosition.Y = npositionY; + m_taintPosition.Z = npositionZ; + + d.BodySetMass(Body, ref ShellMass); + d.Matrix3 m_caprot; + // 90 Stand up on the cap of the capped cyllinder + if (_parent_scene.IsAvCapsuleTilted) + { + d.RFromAxisAndAngle(out m_caprot, 1, 0, 1, (float)(Math.PI / 2)); + } + else + { + d.RFromAxisAndAngle(out m_caprot, 0, 0, 1, (float)(Math.PI / 2)); + } + + + d.GeomSetRotation(Shell, ref m_caprot); + d.BodySetRotation(Body, ref m_caprot); + + d.GeomSetBody(Shell, Body); + + + // The purpose of the AMotor here is to keep the avatar's physical + // surrogate from rotating while moving + Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); + d.JointAttach(Amotor, Body, IntPtr.Zero); + d.JointSetAMotorMode(Amotor, dAMotorEuler); + d.JointSetAMotorNumAxes(Amotor, 3); + d.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0); + d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0); + d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1); + d.JointSetAMotorAngle(Amotor, 0, 0); + d.JointSetAMotorAngle(Amotor, 1, 0); + d.JointSetAMotorAngle(Amotor, 2, 0); + + // These lowstops and high stops are effectively (no wiggle room) + if (_parent_scene.IsAvCapsuleTilted) + { + d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -0.000000000001f); + d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0.000000000001f); + d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -0.000000000001f); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.000000000001f); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0.000000000001f); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.000000000001f); + } + else + { + #region Documentation of capsule motor LowStop and HighStop parameters + // Intentionally introduce some tilt into the capsule by setting + // the motor stops to small epsilon values. This small tilt prevents + // the capsule from falling into the terrain; a straight-up capsule + // (with -0..0 motor stops) falls into the terrain for reasons yet + // to be comprehended in their entirety. + #endregion + AlignAvatarTiltWithCurrentDirectionOfMovement(Vector3.Zero); + d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, 0.08f); + d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0f); + d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, 0.08f); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.08f); // must be same as lowstop, else a different, spurious tilt is introduced + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.08f); // same as lowstop + } + + // Fudge factor is 1f by default, we're setting it to 0. We don't want it to Fudge or the + // capped cyllinder will fall over + d.JointSetAMotorParam(Amotor, (int)dParam.FudgeFactor, 0f); + d.JointSetAMotorParam(Amotor, (int)dParam.FMax, tensor); + + //d.Matrix3 bodyrotation = d.BodyGetRotation(Body); + //d.QfromR( + //d.Matrix3 checkrotation = new d.Matrix3(0.7071068,0.5, -0.7071068, + // + //m_log.Info("[PHYSICSAV]: Rotation: " + bodyrotation.M00 + " : " + bodyrotation.M01 + " : " + bodyrotation.M02 + " : " + bodyrotation.M10 + " : " + bodyrotation.M11 + " : " + bodyrotation.M12 + " : " + bodyrotation.M20 + " : " + bodyrotation.M21 + " : " + bodyrotation.M22); + //standupStraight(); + } + + // + /// + /// Uses the capped cyllinder volume formula to calculate the avatar's mass. + /// This may be used in calculations in the scene/scenepresence + /// + public override float Mass + { + get + { + float AVvolume = (float) (Math.PI*Math.Pow(CAPSULE_RADIUS, 2)*CAPSULE_LENGTH); + return m_density*AVvolume; + } + } + public override void link(PhysicsActor obj) + { + + } + + public override void delink() + { + + } + + public override void LockAngularMotion(Vector3 axis) + { + + } + +// This code is very useful. Written by DanX0r. We're just not using it right now. +// Commented out to prevent a warning. +// +// private void standupStraight() +// { +// // The purpose of this routine here is to quickly stabilize the Body while it's popped up in the air. +// // The amotor needs a few seconds to stabilize so without it, the avatar shoots up sky high when you +// // change appearance and when you enter the simulator +// // After this routine is done, the amotor stabilizes much quicker +// d.Vector3 feet; +// d.Vector3 head; +// d.BodyGetRelPointPos(Body, 0.0f, 0.0f, -1.0f, out feet); +// d.BodyGetRelPointPos(Body, 0.0f, 0.0f, 1.0f, out head); +// float posture = head.Z - feet.Z; + +// // restoring force proportional to lack of posture: +// float servo = (2.5f - posture) * POSTURE_SERVO; +// d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, servo, 0.0f, 0.0f, 1.0f); +// d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, -servo, 0.0f, 0.0f, -1.0f); +// //d.Matrix3 bodyrotation = d.BodyGetRotation(Body); +// //m_log.Info("[PHYSICSAV]: Rotation: " + bodyrotation.M00 + " : " + bodyrotation.M01 + " : " + bodyrotation.M02 + " : " + bodyrotation.M10 + " : " + bodyrotation.M11 + " : " + bodyrotation.M12 + " : " + bodyrotation.M20 + " : " + bodyrotation.M21 + " : " + bodyrotation.M22); +// } + + public override Vector3 Force + { + get { return _target_velocity; } + set { return; } + } + + public override int VehicleType + { + get { return 0; } + set { return; } + } + + public override void VehicleFloatParam(int param, float value) + { + + } + + public override void VehicleVectorParam(int param, Vector3 value) + { + + } + + public override void VehicleRotationParam(int param, Quaternion rotation) + { + + } + + public override void SetVolumeDetect(int param) + { + + } + + public override Vector3 CenterOfMass + { + get { return Vector3.Zero; } + } + + public override Vector3 GeometricCenter + { + get { return Vector3.Zero; } + } + + public override PrimitiveBaseShape Shape + { + set { return; } + } + + public override Vector3 Velocity + { + get { + // There's a problem with Vector3.Zero! Don't Use it Here! + if (_zeroFlag) + return Vector3.Zero; + m_lastUpdateSent = false; + return _velocity; + } + set + { + if (value.IsFinite()) + { + m_pidControllerActive = true; + _target_velocity = value; + } + else + { + m_log.Warn("[PHYSICS]: Got a NaN velocity from Scene in a Character"); + } + } + } + + public override Vector3 Torque + { + get { return Vector3.Zero; } + set { return; } + } + + public override float CollisionScore + { + get { return 0f; } + set { } + } + + public override bool Kinematic + { + get { return false; } + set { } + } + + public override Quaternion Orientation + { + get { return Quaternion.Identity; } + set { + //Matrix3 or = Orientation.ToRotationMatrix(); + //d.Matrix3 ord = new d.Matrix3(or.m00, or.m10, or.m20, or.m01, or.m11, or.m21, or.m02, or.m12, or.m22); + //d.BodySetRotation(Body, ref ord); + } + } + + public override Vector3 Acceleration + { + get { return _acceleration; } + } + + public void SetAcceleration(Vector3 accel) + { + m_pidControllerActive = true; + _acceleration = accel; + } + + /// + /// Adds the force supplied to the Target Velocity + /// The PID controller takes this target velocity and tries to make it a reality + /// + /// + public override void AddForce(Vector3 force, bool pushforce) + { + if (force.IsFinite()) + { + if (pushforce) + { + m_pidControllerActive = false; + force *= 100f; + doForce(force); + // If uncommented, things get pushed off world + // + // m_log.Debug("Push!"); + // _target_velocity.X += force.X; + // _target_velocity.Y += force.Y; + // _target_velocity.Z += force.Z; + } + else + { + m_pidControllerActive = true; + _target_velocity.X += force.X; + _target_velocity.Y += force.Y; + _target_velocity.Z += force.Z; + } + } + else + { + m_log.Warn("[PHYSICS]: Got a NaN force applied to a Character"); + } + //m_lastUpdateSent = false; + } + + public override void AddAngularForce(Vector3 force, bool pushforce) + { + + } + + /// + /// After all of the forces add up with 'add force' we apply them with doForce + /// + /// + public void doForce(Vector3 force) + { + if (!collidelock) + { + d.BodyAddForce(Body, force.X, force.Y, force.Z); + //d.BodySetRotation(Body, ref m_StandUpRotation); + //standupStraight(); + + } + } + + public override void SetMomentum(Vector3 momentum) + { + } + + + /// + /// Called from Simulate + /// This is the avatar's movement control + PID Controller + /// + /// + public void Move(float timeStep, List defects) + { + // no lock; for now it's only called from within Simulate() + + // If the PID Controller isn't active then we set our force + // calculating base velocity to the current position + + if (Body == IntPtr.Zero) + return; + + if (m_pidControllerActive == false) + { + _zeroPosition = d.BodyGetPosition(Body); + } + //PidStatus = true; + + d.Vector3 localpos = d.BodyGetPosition(Body); + Vector3 localPos = new Vector3(localpos.X, localpos.Y, localpos.Z); + + if (!localPos.IsFinite()) + { + + m_log.Warn("[PHYSICS]: Avatar Position is non-finite!"); + defects.Add(this); + // _parent_scene.RemoveCharacter(this); + + // destroy avatar capsule and related ODE data + if (Amotor != IntPtr.Zero) + { + // Kill the Amotor + d.JointDestroy(Amotor); + Amotor = IntPtr.Zero; + } + + //kill the Geometry + _parent_scene.waitForSpaceUnlock(_parent_scene.space); + + if (Body != IntPtr.Zero) + { + //kill the body + d.BodyDestroy(Body); + + Body = IntPtr.Zero; + } + + if (Shell != IntPtr.Zero) + { + d.GeomDestroy(Shell); + _parent_scene.geom_name_map.Remove(Shell); + Shell = IntPtr.Zero; + } + + return; + } + + Vector3 vec = Vector3.Zero; + d.Vector3 vel = d.BodyGetLinearVel(Body); + + float movementdivisor = 1f; + + if (!m_alwaysRun) + { + movementdivisor = walkDivisor; + } + else + { + movementdivisor = runDivisor; + } + + // if velocity is zero, use position control; otherwise, velocity control + if (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f && m_iscolliding) + { + // keep track of where we stopped. No more slippin' & slidin' + if (!_zeroFlag) + { + _zeroFlag = true; + _zeroPosition = d.BodyGetPosition(Body); + } + if (m_pidControllerActive) + { + // We only want to deactivate the PID Controller if we think we want to have our surrogate + // react to the physics scene by moving it's position. + // Avatar to Avatar collisions + // Prim to avatar collisions + + d.Vector3 pos = d.BodyGetPosition(Body); + vec.X = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2); + vec.Y = (_target_velocity.Y - vel.Y)*(PID_D) + (_zeroPosition.Y - pos.Y)* (PID_P * 2); + if (flying) + { + vec.Z = (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P; + } + } + //PidStatus = true; + } + else + { + m_pidControllerActive = true; + _zeroFlag = false; + if (m_iscolliding && !flying) + { + // We're standing on something + vec.X = ((_target_velocity.X / movementdivisor) - vel.X) * (PID_D); + vec.Y = ((_target_velocity.Y / movementdivisor) - vel.Y) * (PID_D); + } + else if (m_iscolliding && flying) + { + // We're flying and colliding with something + vec.X = ((_target_velocity.X/movementdivisor) - vel.X)*(PID_D / 16); + vec.Y = ((_target_velocity.Y/movementdivisor) - vel.Y)*(PID_D / 16); + } + else if (!m_iscolliding && flying) + { + // we're in mid air suspended + vec.X = ((_target_velocity.X / movementdivisor) - vel.X) * (PID_D/6); + vec.Y = ((_target_velocity.Y / movementdivisor) - vel.Y) * (PID_D/6); + } + + if (m_iscolliding && !flying && _target_velocity.Z > 0.0f) + { + // We're colliding with something and we're not flying but we're moving + // This means we're walking or running. + d.Vector3 pos = d.BodyGetPosition(Body); + vec.Z = (_target_velocity.Z - vel.Z)*PID_D + (_zeroPosition.Z - pos.Z)*PID_P; + if (_target_velocity.X > 0) + { + vec.X = ((_target_velocity.X - vel.X)/1.2f)*PID_D; + } + if (_target_velocity.Y > 0) + { + vec.Y = ((_target_velocity.Y - vel.Y)/1.2f)*PID_D; + } + } + else if (!m_iscolliding && !flying) + { + // we're not colliding and we're not flying so that means we're falling! + // m_iscolliding includes collisions with the ground. + + // d.Vector3 pos = d.BodyGetPosition(Body); + if (_target_velocity.X > 0) + { + vec.X = ((_target_velocity.X - vel.X)/1.2f)*PID_D; + } + if (_target_velocity.Y > 0) + { + vec.Y = ((_target_velocity.Y - vel.Y)/1.2f)*PID_D; + } + } + + if (flying) + { + vec.Z = (_target_velocity.Z - vel.Z) * (PID_D); + } + } + if (flying) + { + vec.Z += ((-1 * _parent_scene.gravityz)*m_mass); + + //Added for auto fly height. Kitto Flora + //d.Vector3 pos = d.BodyGetPosition(Body); + float target_altitude = _parent_scene.GetTerrainHeightAtXY(_position.X, _position.Y) + MinimumGroundFlightOffset; + + if (_position.Z < target_altitude) + { + vec.Z += (target_altitude - _position.Z) * PID_P * 5.0f; + } + // end add Kitto Flora + } + if (vec.IsFinite()) + { + doForce(vec); + if (!_zeroFlag) + { + AlignAvatarTiltWithCurrentDirectionOfMovement(vec); + } + } + else + { + m_log.Warn("[PHYSICS]: Got a NaN force vector in Move()"); + m_log.Warn("[PHYSICS]: Avatar Position is non-finite!"); + defects.Add(this); + // _parent_scene.RemoveCharacter(this); + // destroy avatar capsule and related ODE data + if (Amotor != IntPtr.Zero) + { + // Kill the Amotor + d.JointDestroy(Amotor); + Amotor = IntPtr.Zero; + } + //kill the Geometry + _parent_scene.waitForSpaceUnlock(_parent_scene.space); + + if (Body != IntPtr.Zero) + { + //kill the body + d.BodyDestroy(Body); + + Body = IntPtr.Zero; + } + + if (Shell != IntPtr.Zero) + { + d.GeomDestroy(Shell); + _parent_scene.geom_name_map.Remove(Shell); + Shell = IntPtr.Zero; + } + } + } + + /// + /// Updates the reported position and velocity. This essentially sends the data up to ScenePresence. + /// + public void UpdatePositionAndVelocity() + { + // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! + d.Vector3 vec; + try + { + vec = d.BodyGetPosition(Body); + } + catch (NullReferenceException) + { + bad = true; + _parent_scene.BadCharacter(this); + vec = new d.Vector3(_position.X, _position.Y, _position.Z); + base.RaiseOutOfBounds(_position); // Tells ScenePresence that there's a problem! + m_log.WarnFormat("[ODEPLUGIN]: Avatar Null reference for Avatar {0}, physical actor {1}", m_name, m_uuid); + } + + + // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!) + if (vec.X < 0.0f) vec.X = 0.0f; + if (vec.Y < 0.0f) vec.Y = 0.0f; + if (vec.X > (int)_parent_scene.WorldExtents.X - 0.05f) vec.X = (int)_parent_scene.WorldExtents.X - 0.05f; + if (vec.Y > (int)_parent_scene.WorldExtents.Y - 0.05f) vec.Y = (int)_parent_scene.WorldExtents.Y - 0.05f; + + _position.X = vec.X; + _position.Y = vec.Y; + _position.Z = vec.Z; + + // Did we move last? = zeroflag + // This helps keep us from sliding all over + + if (_zeroFlag) + { + _velocity.X = 0.0f; + _velocity.Y = 0.0f; + _velocity.Z = 0.0f; + + // Did we send out the 'stopped' message? + if (!m_lastUpdateSent) + { + m_lastUpdateSent = true; + //base.RequestPhysicsterseUpdate(); + + } + } + else + { + m_lastUpdateSent = false; + try + { + vec = d.BodyGetLinearVel(Body); + } + catch (NullReferenceException) + { + vec.X = _velocity.X; + vec.Y = _velocity.Y; + vec.Z = _velocity.Z; + } + _velocity.X = (vec.X); + _velocity.Y = (vec.Y); + + _velocity.Z = (vec.Z); + + if (_velocity.Z < -6 && !m_hackSentFall) + { + m_hackSentFall = true; + m_pidControllerActive = false; + } + else if (flying && !m_hackSentFly) + { + //m_hackSentFly = true; + //base.SendCollisionUpdate(new CollisionEventUpdate()); + } + else + { + m_hackSentFly = false; + m_hackSentFall = false; + } + } + } + + /// + /// Cleanup the things we use in the scene. + /// + public void Destroy() + { + m_tainted_isPhysical = false; + _parent_scene.AddPhysicsActorTaint(this); + } + + public override void CrossingFailure() + { + } + + public override Vector3 PIDTarget { set { return; } } + public override bool PIDActive { set { return; } } + public override float PIDTau { set { return; } } + + public override float PIDHoverHeight { set { return; } } + public override bool PIDHoverActive { set { return; } } + public override PIDHoverType PIDHoverType { set { return; } } + public override float PIDHoverTau { set { return; } } + + public override Quaternion APIDTarget{ set { return; } } + + public override bool APIDActive{ set { return; } } + + public override float APIDStrength{ set { return; } } + + public override float APIDDamping{ set { return; } } + + + public override void SubscribeEvents(int ms) + { + m_requestedUpdateFrequency = ms; + m_eventsubscription = ms; + _parent_scene.addCollisionEventReporting(this); + } + public override void UnSubscribeEvents() + { + _parent_scene.remCollisionEventReporting(this); + m_requestedUpdateFrequency = 0; + m_eventsubscription = 0; + } + public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) + { + if (m_eventsubscription > 0) + { + CollisionEventsThisFrame.addCollider(CollidedWith, contact); + } + } + + public void SendCollisions() + { + if (m_eventsubscription > m_requestedUpdateFrequency) + { + if (CollisionEventsThisFrame != null) + { + base.SendCollisionUpdate(CollisionEventsThisFrame); + } + CollisionEventsThisFrame = new CollisionEventUpdate(); + m_eventsubscription = 0; + } + } + public override bool SubscribedEvents() + { + if (m_eventsubscription > 0) + return true; + return false; + } + + public void ProcessTaints(float timestep) + { + + if (m_tainted_isPhysical != m_isPhysical) + { + if (m_tainted_isPhysical) + { + // Create avatar capsule and related ODE data + if (!(Shell == IntPtr.Zero && Body == IntPtr.Zero && Amotor == IntPtr.Zero)) + { + m_log.Warn("[PHYSICS]: re-creating the following avatar ODE data, even though it already exists - " + + (Shell!=IntPtr.Zero ? "Shell ":"") + + (Body!=IntPtr.Zero ? "Body ":"") + + (Amotor!=IntPtr.Zero ? "Amotor ":"")); + } + AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z, m_tensor); + + _parent_scene.geom_name_map[Shell] = m_name; + _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; + _parent_scene.AddCharacter(this); + } + else + { + _parent_scene.RemoveCharacter(this); + // destroy avatar capsule and related ODE data + if (Amotor != IntPtr.Zero) + { + // Kill the Amotor + d.JointDestroy(Amotor); + Amotor = IntPtr.Zero; + } + //kill the Geometry + _parent_scene.waitForSpaceUnlock(_parent_scene.space); + + if (Body != IntPtr.Zero) + { + //kill the body + d.BodyDestroy(Body); + + Body = IntPtr.Zero; + } + + if (Shell != IntPtr.Zero) + { + d.GeomDestroy(Shell); + _parent_scene.geom_name_map.Remove(Shell); + Shell = IntPtr.Zero; + } + + } + + m_isPhysical = m_tainted_isPhysical; + } + + if (m_tainted_CAPSULE_LENGTH != CAPSULE_LENGTH) + { + if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero) + { + + m_pidControllerActive = true; + // no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate() + d.JointDestroy(Amotor); + float prevCapsule = CAPSULE_LENGTH; + CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH; + //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); + d.BodyDestroy(Body); + d.GeomDestroy(Shell); + AvatarGeomAndBodyCreation(_position.X, _position.Y, + _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor); + Velocity = Vector3.Zero; + + _parent_scene.geom_name_map[Shell] = m_name; + _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; + } + else + { + m_log.Warn("[PHYSICS]: trying to change capsule size, but the following ODE data is missing - " + + (Shell==IntPtr.Zero ? "Shell ":"") + + (Body==IntPtr.Zero ? "Body ":"") + + (Amotor==IntPtr.Zero ? "Amotor ":"")); + } + } + + if (!m_taintPosition.ApproxEquals(_position, 0.05f)) + { + if (Body != IntPtr.Zero) + { + d.BodySetPosition(Body, m_taintPosition.X, m_taintPosition.Y, m_taintPosition.Z); + + _position.X = m_taintPosition.X; + _position.Y = m_taintPosition.Y; + _position.Z = m_taintPosition.Z; + } + } + + } + + internal void AddCollisionFrameTime(int p) + { + // protect it from overflow crashing + if (m_eventsubscription + p >= int.MaxValue) + m_eventsubscription = 0; + m_eventsubscription += p; + } + } +} -- cgit v1.1 From 1abb70cc73c997c08a416fecf689b83453f853d0 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Thu, 21 Jan 2010 19:31:02 -0500 Subject: Add glue for llSetVehicleFlags(), llRemoveVehicleFlags(). ChODE: Add associated methods. --- OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs index aa0acb7..2eb519f 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -733,7 +733,17 @@ namespace OpenSim.Region.Physics.OdePlugin { } + + public override void VehicleFlagsSet(int flags) + { + } + + public override void VehicleFlagsRemove(int flags) + { + + } + public override void SetVolumeDetect(int param) { -- cgit v1.1 From f3c21524be94dac139e15b0cd80b1e79570f7916 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Thu, 29 Apr 2010 19:41:08 -0400 Subject: Fix Av jump motion S/W --- OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs index 8e87ad9..7a5093b 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -1025,11 +1025,11 @@ namespace OpenSim.Region.Physics.OdePlugin // m_iscolliding includes collisions with the ground. // d.Vector3 pos = d.BodyGetPosition(Body); - if (_target_velocity.X > 0) + if (Math.Abs(_target_velocity.X) > 0) { vec.X = ((_target_velocity.X - vel.X)/1.2f)*PID_D; } - if (_target_velocity.Y > 0) + if (Math.Abs(_target_velocity.Y) > 0) { vec.Y = ((_target_velocity.Y - vel.Y)/1.2f)*PID_D; } -- cgit v1.1 From add7abc1de2fce8db4c6d01cc4b5305bafa4bd87 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Fri, 7 May 2010 14:12:07 -0400 Subject: Fix Mouse+WASD makes Av rise; Fix PREJUMP. --- OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 30 +++++++++++++++------- 1 file changed, 21 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs index 7a5093b..38c38b6 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -142,7 +142,7 @@ namespace OpenSim.Region.Physics.OdePlugin // unique UUID of this character object public UUID m_uuid; public bool bad = false; - + public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, CollisionLocker dode, Vector3 size, float pid_d, float pid_p, float capsule_radius, float tensor, float density, float height_fudge_factor, float walk_divisor, float rundivisor) { m_uuid = UUID.Random(); @@ -892,7 +892,7 @@ namespace OpenSim.Region.Physics.OdePlugin // If the PID Controller isn't active then we set our force // calculating base velocity to the current position - + if (Body == IntPtr.Zero) return; @@ -972,8 +972,17 @@ namespace OpenSim.Region.Physics.OdePlugin // Prim to avatar collisions d.Vector3 pos = d.BodyGetPosition(Body); - vec.X = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2); - vec.Y = (_target_velocity.Y - vel.Y)*(PID_D) + (_zeroPosition.Y - pos.Y)* (PID_P * 2); + float errX = _zeroPosition.X - pos.X; + float errY = _zeroPosition.Y - pos.Y; + if( (Math.Abs(errX) > 0.1f) || (Math.Abs(errY) > 0.1f) ) + { + vec.X = (_target_velocity.X - vel.X) * (PID_D) + (errX) * (PID_P * 2); + vec.Y = (_target_velocity.Y - vel.Y) * (PID_D) + (errY) * (PID_P * 2); + } + else + { // close, jump to lateral destination + d.BodySetPosition(Body, _zeroPosition.X, _zeroPosition.Y, pos.Z); + } if (flying) { vec.Z = (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P; @@ -1056,11 +1065,14 @@ namespace OpenSim.Region.Physics.OdePlugin } if (vec.IsFinite()) { - doForce(vec); - if (!_zeroFlag) - { - AlignAvatarTiltWithCurrentDirectionOfMovement(vec); - } + if (!vec.ApproxEquals(Vector3.Zero, 0.01f)) + { + doForce(vec); + if (!_zeroFlag) + { + AlignAvatarTiltWithCurrentDirectionOfMovement(vec); + } + } } else { -- cgit v1.1 From 7ab103c96f3e82cac592f20d61358e1928da8e27 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Tue, 13 Jul 2010 20:37:13 +0000 Subject: Rewrite collision dictionary handling, cleans up deleted obects/avs. Fixes occasional collision event failure. ChOde only. --- OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 90 +++++++++++++++++----- 1 file changed, 71 insertions(+), 19 deletions(-) (limited to 'OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs index 38c38b6..61c16b8 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -565,7 +565,29 @@ namespace OpenSim.Region.Physics.OdePlugin CAPSULE_RADIUS = 0.01f; } + + if(Shell != IntPtr.Zero) + { + try + { + d.GeomDestroy(Shell); + } + catch (System.AccessViolationException) + { + m_log.Error("[PHYSICS]: PrimGeom dead"); + } + // Remove any old entries +//string tShell; +//_parent_scene.geom_name_map.TryGetValue(Shell, out tShell); +//Console.WriteLine("**** Remove {0}", tShell); + if(_parent_scene.geom_name_map.ContainsKey(Shell)) _parent_scene.geom_name_map.Remove(Shell); + if(_parent_scene.actor_name_map.ContainsKey(Shell)) _parent_scene.actor_name_map.Remove(Shell); + } + Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH); + _parent_scene.geom_name_map[Shell] = m_name; + _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; +//Console.WriteLine("**** Create {2} Dicts: actor={0} name={1}", _parent_scene.actor_name_map.Count, _parent_scene.geom_name_map.Count, m_name); d.GeomSetCategoryBits(Shell, (int)m_collisionCategories); d.GeomSetCollideBits(Shell, (int)m_collisionFlags); @@ -931,10 +953,23 @@ namespace OpenSim.Region.Physics.OdePlugin Body = IntPtr.Zero; } - if (Shell != IntPtr.Zero) + if(Shell != IntPtr.Zero) { - d.GeomDestroy(Shell); - _parent_scene.geom_name_map.Remove(Shell); + try + { + d.GeomDestroy(Shell); + } + catch (System.AccessViolationException) + { + m_log.Error("[PHYSICS]: PrimGeom dead"); + } + // Remove any old entries +//string tShell; +//_parent_scene.geom_name_map.TryGetValue(Shell, out tShell); +//Console.WriteLine("**** Remove {0}", tShell); + + if(_parent_scene.geom_name_map.ContainsKey(Shell)) _parent_scene.geom_name_map.Remove(Shell); + if(_parent_scene.actor_name_map.ContainsKey(Shell)) _parent_scene.actor_name_map.Remove(Shell); Shell = IntPtr.Zero; } @@ -1097,11 +1132,24 @@ namespace OpenSim.Region.Physics.OdePlugin Body = IntPtr.Zero; } - - if (Shell != IntPtr.Zero) + + if(Shell != IntPtr.Zero) { - d.GeomDestroy(Shell); - _parent_scene.geom_name_map.Remove(Shell); + try + { + d.GeomDestroy(Shell); + } + catch (System.AccessViolationException) + { + m_log.Error("[PHYSICS]: PrimGeom dead"); + } + // Remove any old entries +//string tShell; +//_parent_scene.geom_name_map.TryGetValue(Shell, out tShell); +//Console.WriteLine("**** Remove {0}", tShell); + + if(_parent_scene.geom_name_map.ContainsKey(Shell)) _parent_scene.geom_name_map.Remove(Shell); + if(_parent_scene.actor_name_map.ContainsKey(Shell)) _parent_scene.actor_name_map.Remove(Shell); Shell = IntPtr.Zero; } } @@ -1277,9 +1325,6 @@ namespace OpenSim.Region.Physics.OdePlugin + (Amotor!=IntPtr.Zero ? "Amotor ":"")); } AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z, m_tensor); - - _parent_scene.geom_name_map[Shell] = m_name; - _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; _parent_scene.AddCharacter(this); } else @@ -1299,17 +1344,28 @@ namespace OpenSim.Region.Physics.OdePlugin { //kill the body d.BodyDestroy(Body); - Body = IntPtr.Zero; } - if (Shell != IntPtr.Zero) + if(Shell != IntPtr.Zero) { - d.GeomDestroy(Shell); - _parent_scene.geom_name_map.Remove(Shell); + try + { + d.GeomDestroy(Shell); + } + catch (System.AccessViolationException) + { + m_log.Error("[PHYSICS]: PrimGeom dead"); + } + // Remove any old entries +//string tShell; +//_parent_scene.geom_name_map.TryGetValue(Shell, out tShell); +//Console.WriteLine("**** Remove {0}", tShell); + + if(_parent_scene.geom_name_map.ContainsKey(Shell)) _parent_scene.geom_name_map.Remove(Shell); + if(_parent_scene.actor_name_map.ContainsKey(Shell)) _parent_scene.actor_name_map.Remove(Shell); Shell = IntPtr.Zero; } - } m_isPhysical = m_tainted_isPhysical; @@ -1327,13 +1383,9 @@ namespace OpenSim.Region.Physics.OdePlugin CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH; //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); d.BodyDestroy(Body); - d.GeomDestroy(Shell); AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor); Velocity = Vector3.Zero; - - _parent_scene.geom_name_map[Shell] = m_name; - _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; } else { -- cgit v1.1 From 16814dd8f18b51f5dd8841ae341847e117bb83b3 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Thu, 2 Sep 2010 21:51:19 +0000 Subject: Fixes to JUMP system. --- OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs index 61c16b8..0c79aa6 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -90,6 +90,7 @@ namespace OpenSim.Region.Physics.OdePlugin public float walkDivisor = 1.3f; public float runDivisor = 0.8f; private bool flying = false; + private bool jumping = false; // add for jumping private bool m_iscolliding = false; private bool m_iscollidingGround = false; private bool m_wascolliding = false; @@ -229,7 +230,8 @@ namespace OpenSim.Region.Physics.OdePlugin public override bool Selected { - set { return; } +// set { return; } + set { jumping = value; } // add for jumping flag } public override float Buoyancy @@ -1018,7 +1020,8 @@ namespace OpenSim.Region.Physics.OdePlugin { // close, jump to lateral destination d.BodySetPosition(Body, _zeroPosition.X, _zeroPosition.Y, pos.Z); } - if (flying) +// if (flying) + if (flying || jumping) // add for jumping { vec.Z = (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P; } -- cgit v1.1 From c719e016ed9bfbb56fd8c571b9b7b9622bcef566 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Mon, 6 Sep 2010 21:45:07 +0000 Subject: Falling animation fix, comment out instrumentation. --- OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs index 0c79aa6..ae63cfa 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -269,7 +269,10 @@ namespace OpenSim.Region.Physics.OdePlugin /// public override bool IsColliding { - get { return m_iscolliding; } +//#@ get { return m_iscolliding; } + get { //## +//Console.WriteLine(">>>>>>>>>>>> IC get = {0}", m_iscolliding); //## + return m_iscolliding; } //## set { int i; @@ -307,6 +310,7 @@ namespace OpenSim.Region.Physics.OdePlugin { m_iscolliding = true; } +// ## Console.WriteLine("IC SET = {0} t{1} f{2} i {3}", value, truecount, falsecount, m_iscolliding); if (m_wascolliding != m_iscolliding) { //base.SendCollisionUpdate(new CollisionEventUpdate()); @@ -589,7 +593,7 @@ namespace OpenSim.Region.Physics.OdePlugin Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH); _parent_scene.geom_name_map[Shell] = m_name; _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; -//Console.WriteLine("**** Create {2} Dicts: actor={0} name={1}", _parent_scene.actor_name_map.Count, _parent_scene.geom_name_map.Count, m_name); +Console.WriteLine("**** Create {2} Dicts: actor={0} name={1} height={3} rad={4}", _parent_scene.actor_name_map.Count, _parent_scene.geom_name_map.Count, m_name, CAPSULE_LENGTH, CAPSULE_RADIUS); d.GeomSetCategoryBits(Shell, (int)m_collisionCategories); d.GeomSetCollideBits(Shell, (int)m_collisionFlags); @@ -857,7 +861,9 @@ namespace OpenSim.Region.Physics.OdePlugin { m_pidControllerActive = false; force *= 100f; - doForce(force); +//Console.WriteLine("DF 1"); // ## + if (!force.ApproxEquals(Vector3.Zero, 0.01f)) + doForce(force); // If uncommented, things get pushed off world // // m_log.Debug("Push!"); @@ -896,7 +902,8 @@ namespace OpenSim.Region.Physics.OdePlugin d.BodyAddForce(Body, force.X, force.Y, force.Z); //d.BodySetRotation(Body, ref m_StandUpRotation); //standupStraight(); - + d.Vector3 vel = d.BodyGetLinearVel(Body); //## +//Console.WriteLine("AvVel <{0},{1},{2}>", vel.X, vel.Y, vel.Z); //## } } @@ -1103,12 +1110,14 @@ namespace OpenSim.Region.Physics.OdePlugin } if (vec.IsFinite()) { - if (!vec.ApproxEquals(Vector3.Zero, 0.01f)) + if (!vec.ApproxEquals(Vector3.Zero, 0.02f)) // 0.01 allows 0.002 !! { +//Console.WriteLine("DF 2"); // ## + doForce(vec); if (!_zeroFlag) { - AlignAvatarTiltWithCurrentDirectionOfMovement(vec); +// AlignAvatarTiltWithCurrentDirectionOfMovement(vec); } } } -- cgit v1.1 From 83b16612ce13ee89f139df8fdc78ded14cb6a69e Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 25 Sep 2010 05:57:08 +0200 Subject: Experimental locking of taint processing --- OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 156 +++++++++++---------- 1 file changed, 80 insertions(+), 76 deletions(-) (limited to 'OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs index ae63cfa..505d455 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -143,6 +143,7 @@ namespace OpenSim.Region.Physics.OdePlugin // unique UUID of this character object public UUID m_uuid; public bool bad = false; + private Object m_syncRoot = new Object(); public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, CollisionLocker dode, Vector3 size, float pid_d, float pid_p, float capsule_radius, float tensor, float density, float height_fudge_factor, float walk_divisor, float rundivisor) { @@ -1323,103 +1324,106 @@ Console.WriteLine("**** Create {2} Dicts: actor={0} name={1} height={3} ra public void ProcessTaints(float timestep) { - - if (m_tainted_isPhysical != m_isPhysical) + lock (m_syncRoot) { - if (m_tainted_isPhysical) - { - // Create avatar capsule and related ODE data - if (!(Shell == IntPtr.Zero && Body == IntPtr.Zero && Amotor == IntPtr.Zero)) - { - m_log.Warn("[PHYSICS]: re-creating the following avatar ODE data, even though it already exists - " - + (Shell!=IntPtr.Zero ? "Shell ":"") - + (Body!=IntPtr.Zero ? "Body ":"") - + (Amotor!=IntPtr.Zero ? "Amotor ":"")); - } - AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z, m_tensor); - _parent_scene.AddCharacter(this); - } - else - { - _parent_scene.RemoveCharacter(this); - // destroy avatar capsule and related ODE data - if (Amotor != IntPtr.Zero) - { - // Kill the Amotor - d.JointDestroy(Amotor); - Amotor = IntPtr.Zero; - } - //kill the Geometry - _parent_scene.waitForSpaceUnlock(_parent_scene.space); - if (Body != IntPtr.Zero) + if (m_tainted_isPhysical != m_isPhysical) + { + if (m_tainted_isPhysical) { - //kill the body - d.BodyDestroy(Body); - Body = IntPtr.Zero; + // Create avatar capsule and related ODE data + if (!(Shell == IntPtr.Zero && Body == IntPtr.Zero && Amotor == IntPtr.Zero)) + { + m_log.Warn("[PHYSICS]: re-creating the following avatar ODE data, even though it already exists - " + + (Shell!=IntPtr.Zero ? "Shell ":"") + + (Body!=IntPtr.Zero ? "Body ":"") + + (Amotor!=IntPtr.Zero ? "Amotor ":"")); + } + AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z, m_tensor); + _parent_scene.AddCharacter(this); } - - if(Shell != IntPtr.Zero) + else { - try + _parent_scene.RemoveCharacter(this); + // destroy avatar capsule and related ODE data + if (Amotor != IntPtr.Zero) { - d.GeomDestroy(Shell); + // Kill the Amotor + d.JointDestroy(Amotor); + Amotor = IntPtr.Zero; } - catch (System.AccessViolationException) + //kill the Geometry + _parent_scene.waitForSpaceUnlock(_parent_scene.space); + + if (Body != IntPtr.Zero) { - m_log.Error("[PHYSICS]: PrimGeom dead"); + //kill the body + d.BodyDestroy(Body); + Body = IntPtr.Zero; } - // Remove any old entries -//string tShell; -//_parent_scene.geom_name_map.TryGetValue(Shell, out tShell); -//Console.WriteLine("**** Remove {0}", tShell); - if(_parent_scene.geom_name_map.ContainsKey(Shell)) _parent_scene.geom_name_map.Remove(Shell); - if(_parent_scene.actor_name_map.ContainsKey(Shell)) _parent_scene.actor_name_map.Remove(Shell); - Shell = IntPtr.Zero; + if(Shell != IntPtr.Zero) + { + try + { + d.GeomDestroy(Shell); + } + catch (System.AccessViolationException) + { + m_log.Error("[PHYSICS]: PrimGeom dead"); + } + // Remove any old entries + //string tShell; + //_parent_scene.geom_name_map.TryGetValue(Shell, out tShell); + //Console.WriteLine("**** Remove {0}", tShell); + + if(_parent_scene.geom_name_map.ContainsKey(Shell)) _parent_scene.geom_name_map.Remove(Shell); + if(_parent_scene.actor_name_map.ContainsKey(Shell)) _parent_scene.actor_name_map.Remove(Shell); + Shell = IntPtr.Zero; + } } - } - m_isPhysical = m_tainted_isPhysical; - } + m_isPhysical = m_tainted_isPhysical; + } - if (m_tainted_CAPSULE_LENGTH != CAPSULE_LENGTH) - { - if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero) + if (m_tainted_CAPSULE_LENGTH != CAPSULE_LENGTH) { + if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero) + { - m_pidControllerActive = true; - // no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate() - d.JointDestroy(Amotor); - float prevCapsule = CAPSULE_LENGTH; - CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH; - //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); - d.BodyDestroy(Body); - AvatarGeomAndBodyCreation(_position.X, _position.Y, - _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor); - Velocity = Vector3.Zero; - } - else - { - m_log.Warn("[PHYSICS]: trying to change capsule size, but the following ODE data is missing - " - + (Shell==IntPtr.Zero ? "Shell ":"") - + (Body==IntPtr.Zero ? "Body ":"") - + (Amotor==IntPtr.Zero ? "Amotor ":"")); + m_pidControllerActive = true; + // no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate() + d.JointDestroy(Amotor); + float prevCapsule = CAPSULE_LENGTH; + CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH; + //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); + d.BodyDestroy(Body); + AvatarGeomAndBodyCreation(_position.X, _position.Y, + _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor); + Velocity = Vector3.Zero; + } + else + { + m_log.Warn("[PHYSICS]: trying to change capsule size, but the following ODE data is missing - " + + (Shell==IntPtr.Zero ? "Shell ":"") + + (Body==IntPtr.Zero ? "Body ":"") + + (Amotor==IntPtr.Zero ? "Amotor ":"")); + } } - } - if (!m_taintPosition.ApproxEquals(_position, 0.05f)) - { - if (Body != IntPtr.Zero) + if (!m_taintPosition.ApproxEquals(_position, 0.05f)) { - d.BodySetPosition(Body, m_taintPosition.X, m_taintPosition.Y, m_taintPosition.Z); + if (Body != IntPtr.Zero) + { + d.BodySetPosition(Body, m_taintPosition.X, m_taintPosition.Y, m_taintPosition.Z); - _position.X = m_taintPosition.X; - _position.Y = m_taintPosition.Y; - _position.Z = m_taintPosition.Z; + _position.X = m_taintPosition.X; + _position.Y = m_taintPosition.Y; + _position.Z = m_taintPosition.Z; + } } - } + } } internal void AddCollisionFrameTime(int p) -- cgit v1.1 From bf695cccbabcc4c18ca26fac17922a1b79d25c33 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Fri, 3 Dec 2010 18:32:58 +0000 Subject: Fix spurious Av move when clothing item worn or removed. --- OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs index 505d455..93f9964 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -469,7 +469,7 @@ namespace OpenSim.Region.Physics.OdePlugin //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); Velocity = Vector3.Zero; - + m_taintPosition = _position; // update the stale taint position _parent_scene.AddPhysicsActorTaint(this); } else -- cgit v1.1 From 566eff17de31b4ffc1aef85c6047ce9e4e8bf5cd Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 28 Jan 2011 01:46:30 +0100 Subject: Comment a very spammy debug message that was being output directly to console. My last fox that makes bumping into sim borders/bans work makes this spam endlessly. --- OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs index 93f9964..1bce760 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -594,7 +594,7 @@ namespace OpenSim.Region.Physics.OdePlugin Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH); _parent_scene.geom_name_map[Shell] = m_name; _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; -Console.WriteLine("**** Create {2} Dicts: actor={0} name={1} height={3} rad={4}", _parent_scene.actor_name_map.Count, _parent_scene.geom_name_map.Count, m_name, CAPSULE_LENGTH, CAPSULE_RADIUS); +//Console.WriteLine("**** Create {2} Dicts: actor={0} name={1} height={3} rad={4}", _parent_scene.actor_name_map.Count, _parent_scene.geom_name_map.Count, m_name, CAPSULE_LENGTH, CAPSULE_RADIUS); d.GeomSetCategoryBits(Shell, (int)m_collisionCategories); d.GeomSetCollideBits(Shell, (int)m_collisionFlags); -- cgit v1.1 From f2855d36686a20f2a40f138c9eb7f92d2b56b6c6 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 24 Dec 2011 01:41:32 +0100 Subject: Add setter for Acceleration on physics objects. --- OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs index 58e2e4c..2945199 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -841,6 +841,7 @@ namespace OpenSim.Region.Physics.OdePlugin public override Vector3 Acceleration { get { return _acceleration; } + set { _acceleration = value; } } public void SetAcceleration(Vector3 accel) -- cgit v1.1 From 3999822e13d7ae2f6ab1c19a19a01e0cc7c7acd7 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 14 Apr 2012 05:07:52 +0100 Subject: Use chode character actor.SetMomentum() to force full restore Velocity in scenepresence TeleportWithMomentum(), since actor.Velocity was selected by original coders as the input of a desired velocity (even 'forces') that is modified by character conditions, like not changing velocity.Z if it is in free fall. --- OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs index 2945199..1f1ba95 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -140,6 +140,10 @@ namespace OpenSim.Region.Physics.OdePlugin public int m_eventsubscription = 0; private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate(); + private Vector3 m_taintMomentum = Vector3.Zero; + private bool m_haveTaintMomentum = false; + + // unique UUID of this character object public UUID m_uuid; public bool bad = false; @@ -800,8 +804,8 @@ namespace OpenSim.Region.Physics.OdePlugin { if (value.IsFinite()) { - m_pidControllerActive = true; _target_velocity = value; + m_pidControllerActive = true; } else { @@ -911,6 +915,12 @@ namespace OpenSim.Region.Physics.OdePlugin public override void SetMomentum(Vector3 momentum) { + if (momentum.IsFinite()) + { + m_taintMomentum = momentum; + m_haveTaintMomentum = true; + _parent_scene.AddPhysicsActorTaint(this); + } } @@ -1424,6 +1434,14 @@ namespace OpenSim.Region.Physics.OdePlugin } } + if (m_haveTaintMomentum) + { + m_haveTaintMomentum = false; + _velocity = m_taintMomentum; + _target_velocity = m_taintMomentum; + m_pidControllerActive = true; + d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z); + } } } -- cgit v1.1 From 04ed5519a5ad265794a0768a6a3c9e4e0fdf1a6c Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 16 Apr 2012 17:14:31 +0100 Subject: chODE bug fix --- OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs index 1f1ba95..c53ccec 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -921,6 +921,8 @@ namespace OpenSim.Region.Physics.OdePlugin m_haveTaintMomentum = true; _parent_scene.AddPhysicsActorTaint(this); } + else + m_log.Warn("[PHYSICS] !isFinite momentum"); } @@ -1337,7 +1339,6 @@ namespace OpenSim.Region.Physics.OdePlugin { lock (m_syncRoot) { - if (m_tainted_isPhysical != m_isPhysical) { if (m_tainted_isPhysical) @@ -1379,9 +1380,9 @@ namespace OpenSim.Region.Physics.OdePlugin { d.GeomDestroy(Shell); } - catch (System.AccessViolationException) + catch (Exception e) { - m_log.Error("[PHYSICS]: PrimGeom dead"); + m_log.ErrorFormat("[PHYSICS]: Failed to destroy character shell {0}",e.Message); } // Remove any old entries //string tShell; @@ -1428,10 +1429,10 @@ namespace OpenSim.Region.Physics.OdePlugin { d.BodySetPosition(Body, m_taintPosition.X, m_taintPosition.Y, m_taintPosition.Z); - _position.X = m_taintPosition.X; - _position.Y = m_taintPosition.Y; - _position.Z = m_taintPosition.Z; } + _position.X = m_taintPosition.X; + _position.Y = m_taintPosition.Y; + _position.Z = m_taintPosition.Z; } if (m_haveTaintMomentum) @@ -1440,7 +1441,8 @@ namespace OpenSim.Region.Physics.OdePlugin _velocity = m_taintMomentum; _target_velocity = m_taintMomentum; m_pidControllerActive = true; - d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z); + if (Body != IntPtr.Zero) + d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z); } } } -- cgit v1.1 From fff5c61ae83ad54eaff640d2868186d275f3dd62 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 16 Apr 2012 17:47:17 +0100 Subject: chODE: if character velocity > 50m/s apply breaks. In free fall this will give a terminal velocity +- 60m/s --- OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs index c53ccec..ec717d7 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -1122,9 +1122,18 @@ namespace OpenSim.Region.Physics.OdePlugin } // end add Kitto Flora } + + if (vel.X * vel.X + vel.Y * vel.Y + vel.Z * vel.Z > 2500.0f) // 50ms apply breaks + { + float breakfactor = 0.16f * m_mass; // will give aprox 60m/s terminal velocity at free fall + vec.X -= breakfactor * vel.X; + vec.Y -= breakfactor * vel.Y; + vec.Z -= breakfactor * vel.Z; + } + if (vec.IsFinite()) { - if (!vec.ApproxEquals(Vector3.Zero, 0.02f)) // 0.01 allows 0.002 !! + if (vec.LengthSquared() > 0.0004f) // 0.01 allows 0.002 !! { //Console.WriteLine("DF 2"); // ## -- cgit v1.1