From fc1be7e41fc7dd23c5396665f7b464de45590368 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 4 Dec 2012 01:54:37 +0000 Subject: raise standing avatar a bit to reduce knees bending on some collisions. reduce head size a bit --- OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index 3d5be3e..f33fdb4 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs @@ -96,7 +96,7 @@ namespace OpenSim.Region.Physics.OdePlugin private float feetSZ = 0.5f; const float feetScale = 0.9f; const float invFeetScale = 1.0f / 0.9f; - const float sizeZAdjust = 0.15f; + const float sizeZAdjust = 0.18f; private float boneOff = 0; @@ -676,12 +676,12 @@ namespace OpenSim.Region.Physics.OdePlugin m_invElipSizeX = 1.0f / m_size.X; m_invElipSizeY = 1.0f / m_size.Y; - float topsx = m_size.X; + float topsx = m_size.X * 0.9f; float midsx = m_size.X; float feetsx = m_size.X * feetScale; float bonesx = feetsx * 0.2f; - float topsy = m_size.Y * 0.5f; + float topsy = m_size.Y * 0.4f; float midsy = m_size.Y; float feetsy = m_size.Y * feetScale; float bonesy = feetsy * 0.2f; @@ -1057,7 +1057,7 @@ namespace OpenSim.Region.Physics.OdePlugin // colide with land d.AABB aabb; d.GeomGetAABB(feetbox, out aabb); - float chrminZ = aabb.MinZ - 0.04f; // move up a bit + float chrminZ = aabb.MinZ - 0.02f; // move up a bit Vector3 posch = localpos; float ftmp; -- cgit v1.1 From b6d29aa124cf1ec1c1dbe6874720e6cc39faf06f Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 4 Dec 2012 02:46:40 +0000 Subject: move characters (avatars) to own collision space, also fixing a problem with previus code that was still assuming the avatar is g2 --- OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index f33fdb4..925900f 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs @@ -708,21 +708,21 @@ namespace OpenSim.Region.Physics.OdePlugin bot += midsz; float topz = bot + topsz * 0.5f; - _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); + _parent_scene.waitForSpaceUnlock(_parent_scene.CharsSpace); - feetbox = d.CreateBox(_parent_scene.ActiveSpace, feetsx, feetsy, feetsz); + feetbox = d.CreateBox(_parent_scene.CharsSpace, feetsx, feetsy, feetsz); d.GeomSetCategoryBits(feetbox, (uint)m_collisionCategories); d.GeomSetCollideBits(feetbox, (uint)m_collisionFlags); - midbox = d.CreateBox(_parent_scene.ActiveSpace, midsx, midsy, midsz); + midbox = d.CreateBox(_parent_scene.CharsSpace, midsx, midsy, midsz); d.GeomSetCategoryBits(midbox, (uint)m_collisionCategories); d.GeomSetCollideBits(midbox, (uint)m_collisionFlags); - topbox = d.CreateBox(_parent_scene.ActiveSpace, topsx, topsy, topsz); + topbox = d.CreateBox(_parent_scene.CharsSpace, topsx, topsy, topsz); d.GeomSetCategoryBits(topbox, (uint)m_collisionCategories); d.GeomSetCollideBits(topbox, (uint)m_collisionFlags); - bonebox = d.CreateBox(_parent_scene.ActiveSpace, bonesx, bonesy, bonesz); + bonebox = d.CreateBox(_parent_scene.CharsSpace, bonesx, bonesy, bonesz); d.GeomSetCategoryBits(bonebox, (uint)m_collisionCategories); d.GeomSetCollideBits(bonebox, (uint)m_collisionFlags); @@ -828,21 +828,21 @@ namespace OpenSim.Region.Physics.OdePlugin if (topbox != IntPtr.Zero) { _parent_scene.actor_name_map.Remove(topbox); - _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); + _parent_scene.waitForSpaceUnlock(_parent_scene.CharsSpace); d.GeomDestroy(topbox); topbox = IntPtr.Zero; } if (midbox != IntPtr.Zero) { _parent_scene.actor_name_map.Remove(midbox); - _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); + _parent_scene.waitForSpaceUnlock(_parent_scene.CharsSpace); d.GeomDestroy(midbox); midbox = IntPtr.Zero; } if (feetbox != IntPtr.Zero) { _parent_scene.actor_name_map.Remove(feetbox); - _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); + _parent_scene.waitForSpaceUnlock(_parent_scene.CharsSpace); d.GeomDestroy(feetbox); feetbox = IntPtr.Zero; } @@ -850,7 +850,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (bonebox != IntPtr.Zero) { _parent_scene.actor_name_map.Remove(bonebox); - _parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); + _parent_scene.waitForSpaceUnlock(_parent_scene.CharsSpace); d.GeomDestroy(bonebox); bonebox = IntPtr.Zero; } -- cgit v1.1 From de3180a63ecb89971321b7dce60dd86703f87e6d Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 5 Dec 2012 23:19:18 +0000 Subject: avatar collision plane send to viewer is only relative to feet. change avatar collider, just rounding the boxes, etc --- .../Region/Physics/UbitOdePlugin/ODECharacter.cs | 155 +++++++++------------ 1 file changed, 63 insertions(+), 92 deletions(-) (limited to 'OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index 925900f..fd6b8aa 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs @@ -84,18 +84,15 @@ namespace OpenSim.Region.Physics.OdePlugin 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; - - private float m_invElipSizeX; - private float m_invElipSizeY; + const float basePID_D = 0.55f; // scaled for unit mass unit time (2200 /(50*80)) + const float basePID_P = 0.225f; // scaled for unit mass unit time (900 /(50*80)) + public float PID_D; + public float PID_P; private float feetOff = 0; private float feetSZ = 0.5f; - const float feetScale = 0.9f; - const float invFeetScale = 1.0f / 0.9f; + const float feetScale = 0.8f; const float sizeZAdjust = 0.18f; private float boneOff = 0; @@ -160,7 +157,7 @@ namespace OpenSim.Region.Physics.OdePlugin - public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, Vector3 pSize, float pid_d, float pid_p, float density, float walk_divisor, float rundivisor) + public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, Vector3 pSize, float density, float walk_divisor, float rundivisor) { m_uuid = UUID.Random(); @@ -184,8 +181,6 @@ namespace OpenSim.Region.Physics.OdePlugin _parent_scene = parent_scene; - PID_D = pid_d; - PID_P = pid_p; m_size.X = pSize.X; m_size.Y = pSize.Y; @@ -204,6 +199,8 @@ namespace OpenSim.Region.Physics.OdePlugin // force lower density for testing m_density = 3.0f; + m_density *= 1.4f; // scale to have mass similar to capsule + mu = parent_scene.AvatarFriction; walkDivisor = walk_divisor; @@ -211,6 +208,9 @@ namespace OpenSim.Region.Physics.OdePlugin m_mass = m_density * m_size.X * m_size.Y * m_size.Z; ; // sure we have a default + PID_D = basePID_D * m_mass / parent_scene.ODE_STEPSIZE; + PID_P = basePID_P * m_mass / parent_scene.ODE_STEPSIZE; + m_isPhysical = false; // current status: no ODE information exists Name = avName; @@ -491,7 +491,7 @@ namespace OpenSim.Region.Physics.OdePlugin { get { - return m_density * m_size.X * m_size.Y * m_size.Z; + return m_mass; } } public override void link(PhysicsActor obj) @@ -671,23 +671,22 @@ namespace OpenSim.Region.Physics.OdePlugin private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ) { // sizes one day should came from visual parameters + float sx = m_size.X; + float sy = m_size.Y; float sz = m_size.Z + sizeZAdjust; - m_invElipSizeX = 1.0f / m_size.X; - m_invElipSizeY = 1.0f / m_size.Y; + float topsx = sx * 0.9f; + float midsx = sx; + float feetsx = sx * feetScale; + float bonesx = sx * 0.2f; - float topsx = m_size.X * 0.9f; - float midsx = m_size.X; - float feetsx = m_size.X * feetScale; - float bonesx = feetsx * 0.2f; - - float topsy = m_size.Y * 0.4f; - float midsy = m_size.Y; - float feetsy = m_size.Y * feetScale; + float topsy = sy * 0.4f; + float midsy = sy; + float feetsy = sy * feetScale * 0.8f; float bonesy = feetsy * 0.2f; float topsz = sz * 0.15f; - float feetsz = sz * 0.3f; + float feetsz = sz * 0.45f; if (feetsz > 0.6f) feetsz = 0.6f; @@ -726,22 +725,12 @@ namespace OpenSim.Region.Physics.OdePlugin d.GeomSetCategoryBits(bonebox, (uint)m_collisionCategories); d.GeomSetCollideBits(bonebox, (uint)m_collisionFlags); - d.MassSetBox(out ShellMass, m_density, m_size.X , m_size.Y, m_size.Z); - - m_mass = ShellMass.mass; // update mass - - // rescale PID parameters - PID_D = _parent_scene.avPIDD; - PID_P = _parent_scene.avPIDP; + m_mass = m_density * m_size.X * m_size.Y * m_size.Z; // update mass - // rescale PID parameters so that this aren't affected by mass - // and so don't get unstable for some masses - // also scale by ode time step so you don't need to refix them + d.MassSetBoxTotal(out ShellMass, m_mass, m_size.X, m_size.Y, m_size.Z); - PID_D /= 50 * 80; //scale to original mass of around 80 and 50 ODE fps - PID_D *= m_mass / _parent_scene.ODE_STEPSIZE; - PID_P /= 50 * 80; - PID_P *= m_mass / _parent_scene.ODE_STEPSIZE; + PID_D = basePID_D * m_mass / _parent_scene.ODE_STEPSIZE; + PID_P = basePID_P * m_mass / _parent_scene.ODE_STEPSIZE; Body = d.BodyCreate(_parent_scene.world); @@ -857,8 +846,9 @@ namespace OpenSim.Region.Physics.OdePlugin } - public bool Collide(IntPtr me, bool reverse, ref d.ContactGeom contact) + public bool Collide(IntPtr me, bool reverse, ref d.ContactGeom contact, ref bool feetcollision) { + feetcollision = false; if (me == bonebox) // inner bone { @@ -870,44 +860,13 @@ namespace OpenSim.Region.Physics.OdePlugin if (me == topbox) // keep a box head return true; - // rotate elipsoide assuming only rotation around Z - float ca = m_orientation.W * m_orientation.W - m_orientation.Z * m_orientation.Z; - float sa = 2 * m_orientation.W * m_orientation.Z; - - float isx; - float isy; - - if (me == feetbox) // feet have narrow bounds - { - - isx = m_invElipSizeX * invFeetScale; - isy = m_invElipSizeY * invFeetScale; - } - else - { - isx = m_invElipSizeX; - isy = m_invElipSizeY; - } - - float a = isx * ca - isy * sa; - float b = isx * sa + isy * ca; - + float t; float offx = contact.pos.X - _position.X; - float er = offx * a; - er *= er; - float offy = contact.pos.Y - _position.Y; - float ty = offy * b; - er += ty * ty; if (me == midbox) { - if (er > 4.0f) // no collision - return false; - if (er < 0.2f) - return true; - - float t = offx * offx + offy * offy; + t = offx * offx + offy * offy; t = (float)Math.Sqrt(t); t = 1 / t; offx *= t; @@ -930,40 +889,51 @@ namespace OpenSim.Region.Physics.OdePlugin else if (me == feetbox) { - float c = feetSZ * 2; float h = contact.pos.Z - _position.Z; - float offz = h - feetOff; // distance from top of feetbox - float tz = offz / c; - er += tz * tz; + if (Math.Abs(contact.normal.Z) > 0.95f) + { + feetcollision = true; + if (h < boneOff) + IsColliding = true; + return true; + } + + float offz = h - feetOff; // distance from top of feetbox - if (er > 4.0f) // no collision + if (offz > 0) return false; - if (er > 0.2f) + if (offz > -0.01) + { + offx = 0; + offy = 0; + offz = -1.0f; + } + else { - float t = offx * offx + offy * offy + offz * offz; + t = offx * offx + offy * offy + offz * offz; t = (float)Math.Sqrt(t); t = 1 / t; offx *= t; offy *= t; offz *= t; - - if (reverse) - { - contact.normal.X = offx; - contact.normal.Y = offy; - contact.normal.Z = offz; - } - else - { - contact.normal.X = -offx; - contact.normal.Y = -offy; - contact.normal.Z = -offz; - } } - if(h < boneOff) + if (reverse) + { + contact.normal.X = offx; + contact.normal.Y = offy; + contact.normal.Z = offz; + } + else + { + contact.normal.X = -offx; + contact.normal.Y = -offy; + contact.normal.Z = -offz; + } + feetcollision = true; + if (h < boneOff) IsColliding = true; } else @@ -1105,6 +1075,7 @@ namespace OpenSim.Region.Physics.OdePlugin contact.SurfaceNormal.Y = 0f; contact.SurfaceNormal.Z = -1f; contact.RelativeSpeed = -vel.Z; + contact.CharacterFeet = true; AddCollisionEvent(0, contact); vec.Z *= 0.5f; -- cgit v1.1 From d2499c4c314b290c42f454913305d97c6eec92d6 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 7 Dec 2012 15:54:46 +0000 Subject: *TEST* Use new avatar size in ubitODE. --- .../Region/Physics/UbitOdePlugin/ODECharacter.cs | 48 ++++++++++++++++++++-- 1 file changed, 44 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index fd6b8aa..9c245e6 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs @@ -90,13 +90,12 @@ namespace OpenSim.Region.Physics.OdePlugin public float PID_D; public float PID_P; + private float m_feetOffset = 0; private float feetOff = 0; private float feetSZ = 0.5f; const float feetScale = 0.8f; - const float sizeZAdjust = 0.18f; private float boneOff = 0; - public float walkDivisor = 1.3f; public float runDivisor = 0.8f; private bool flying = false; @@ -475,6 +474,28 @@ namespace OpenSim.Region.Physics.OdePlugin } } + public override void setAvatarSize(Vector3 size, float feetOffset) + { + if (size.IsFinite()) + { + if (size.X < 0.01f) + size.X = 0.01f; + if (size.Y < 0.01f) + size.Y = 0.01f; + if (size.Z < 0.01f) + size.Z = 0.01f; + + strAvatarSize st = new strAvatarSize(); + st.size = size; + st.offset = feetOffset; + AddChange(changes.AvatarSize, st); + } + else + { + m_log.Warn("[PHYSICS]: Got a NaN AvatarSize from Scene on a Character"); + } + + } /// /// This creates the Avatar's physical Surrogate at the position supplied /// @@ -673,7 +694,8 @@ namespace OpenSim.Region.Physics.OdePlugin // sizes one day should came from visual parameters float sx = m_size.X; float sy = m_size.Y; - float sz = m_size.Z + sizeZAdjust; + float sz = m_size.Z; + float topsx = sx * 0.9f; float midsx = sx; @@ -693,7 +715,7 @@ namespace OpenSim.Region.Physics.OdePlugin float midsz = sz - topsz - feetsz; float bonesz = sz; - float bot = -sz * 0.5f; + float bot = -sz * 0.5f + m_feetOffset; boneOff = bot + 0.3f; @@ -754,6 +776,7 @@ namespace OpenSim.Region.Physics.OdePlugin d.GeomSetOffsetPosition(feetbox, 0, 0, feetz); d.GeomSetOffsetPosition(midbox, 0, 0, midz); d.GeomSetOffsetPosition(topbox, 0, 0, topz); + d.GeomSetOffsetPosition(bonebox, 0, 0, m_feetOffset); // The purpose of the AMotor here is to keep the avatar's physical // surrogate from rotating while moving @@ -1402,6 +1425,12 @@ namespace OpenSim.Region.Physics.OdePlugin { } + private void changeAvatarSize(strAvatarSize st) + { + m_feetOffset = st.offset; + changeSize(st.size); + } + private void changeSize(Vector3 pSize) { if (pSize.IsFinite()) @@ -1609,6 +1638,10 @@ namespace OpenSim.Region.Physics.OdePlugin changeSize((Vector3)arg); break; + case changes.AvatarSize: + changeAvatarSize((strAvatarSize)arg); + break; + case changes.Momentum: changeMomentum((Vector3)arg); break; @@ -1656,5 +1689,12 @@ namespace OpenSim.Region.Physics.OdePlugin { _parent_scene.AddChange((PhysicsActor)this, what, arg); } + + private struct strAvatarSize + { + public Vector3 size; + public float offset; + } + } } -- cgit v1.1 From 2ea0dc55d7ea6da6e91ab614856cdeece7eae5d2 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 7 Dec 2012 20:06:35 +0000 Subject: create a new ode character also with the new information --- OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index 9c245e6..15bdc57 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs @@ -156,7 +156,7 @@ namespace OpenSim.Region.Physics.OdePlugin - public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, Vector3 pSize, float density, float walk_divisor, float rundivisor) + public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, Vector3 pSize, float pfeetOffset, float density, float walk_divisor, float rundivisor) { m_uuid = UUID.Random(); @@ -192,6 +192,7 @@ namespace OpenSim.Region.Physics.OdePlugin if(m_size.Z <0.01f) m_size.Z = 0.01f; + m_feetOffset = pfeetOffset; m_orientation = Quaternion.Identity; m_density = density; -- cgit v1.1 From 80639ace95089414423b16f90c8994f50e010373 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 11 Dec 2012 04:36:27 +0000 Subject: a few more changes on avatar collider --- .../Region/Physics/UbitOdePlugin/ODECharacter.cs | 347 ++++++++++++++++----- 1 file changed, 274 insertions(+), 73 deletions(-) (limited to 'OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index 15bdc57..1b25faf 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs @@ -74,7 +74,6 @@ namespace OpenSim.Region.Physics.OdePlugin private Vector3 _position; private Vector3 _zeroPosition; - private bool _zeroFlag = false; private Vector3 _velocity; private Vector3 _target_velocity; private Vector3 _acceleration; @@ -90,11 +89,15 @@ namespace OpenSim.Region.Physics.OdePlugin public float PID_D; public float PID_P; + private float timeStep; + private float invtimeStep; + private float m_feetOffset = 0; private float feetOff = 0; private float feetSZ = 0.5f; const float feetScale = 0.8f; private float boneOff = 0; + private float m_lastVelocitySqr = 0; public float walkDivisor = 1.3f; public float runDivisor = 0.8f; @@ -103,6 +106,9 @@ namespace OpenSim.Region.Physics.OdePlugin private bool m_iscollidingGround = false; private bool m_iscollidingObj = false; private bool m_alwaysRun = false; + + private bool _zeroFlag = false; + private int m_requestedUpdateFrequency = 0; private uint m_localID = 0; public bool m_returnCollisions = false; @@ -120,6 +126,7 @@ namespace OpenSim.Region.Physics.OdePlugin int m_colliderfilter = 0; int m_colliderGroundfilter = 0; int m_colliderObjectfilter = 0; + bool m_collisionException = false; // Default we're a Character private CollisionCategories m_collisionCategories = (CollisionCategories.Character); @@ -132,10 +139,11 @@ namespace OpenSim.Region.Physics.OdePlugin // we do land collisions not ode | CollisionCategories.Land); public IntPtr Body = IntPtr.Zero; private OdeScene _parent_scene; - public IntPtr topbox = IntPtr.Zero; - public IntPtr midbox = IntPtr.Zero; - public IntPtr feetbox = IntPtr.Zero; - public IntPtr bonebox = IntPtr.Zero; + private IntPtr topbox = IntPtr.Zero; + private IntPtr midbox = IntPtr.Zero; + private IntPtr feetbox = IntPtr.Zero; + private IntPtr bbox = IntPtr.Zero; + public IntPtr collider = IntPtr.Zero; public IntPtr Amotor = IntPtr.Zero; @@ -143,6 +151,7 @@ namespace OpenSim.Region.Physics.OdePlugin + public int m_eventsubscription = 0; private int m_cureventsubscription = 0; private CollisionEventUpdate CollisionEventsThisFrame = null; @@ -160,6 +169,9 @@ namespace OpenSim.Region.Physics.OdePlugin { m_uuid = UUID.Random(); + timeStep = parent_scene.ODE_STEPSIZE; + invtimeStep = 1 / timeStep; + if (pos.IsFinite()) { if (pos.Z > 99999f) @@ -208,8 +220,8 @@ namespace OpenSim.Region.Physics.OdePlugin m_mass = m_density * m_size.X * m_size.Y * m_size.Z; ; // sure we have a default - PID_D = basePID_D * m_mass / parent_scene.ODE_STEPSIZE; - PID_P = basePID_P * m_mass / parent_scene.ODE_STEPSIZE; + PID_D = basePID_D * m_mass * invtimeStep; + PID_P = basePID_P * m_mass * invtimeStep; m_isPhysical = false; // current status: no ODE information exists @@ -292,7 +304,7 @@ namespace OpenSim.Region.Physics.OdePlugin set { flying = value; - // m_log.DebugFormat("[PHYSICS]: Set OdeCharacter Flying to {0}", flying); +// m_log.DebugFormat("[PHYSICS]: Set OdeCharacter Flying to {0}", flying); } } @@ -336,25 +348,25 @@ namespace OpenSim.Region.Physics.OdePlugin get { return m_iscollidingGround; } set { - /* we now control this - if (value) - { - m_colliderGroundfilter += 2; - if (m_colliderGroundfilter > 2) - m_colliderGroundfilter = 2; - } - else - { - m_colliderGroundfilter--; - if (m_colliderGroundfilter < 0) - m_colliderGroundfilter = 0; - } - - if (m_colliderGroundfilter == 0) - m_iscollidingGround = false; - else - m_iscollidingGround = true; - */ +/* we now control this + if (value) + { + m_colliderGroundfilter += 2; + if (m_colliderGroundfilter > 2) + m_colliderGroundfilter = 2; + } + else + { + m_colliderGroundfilter--; + if (m_colliderGroundfilter < 0) + m_colliderGroundfilter = 0; + } + + if (m_colliderGroundfilter == 0) + m_iscollidingGround = false; + else + m_iscollidingGround = true; + */ } } @@ -386,7 +398,7 @@ namespace OpenSim.Region.Physics.OdePlugin else m_iscollidingObj = true; - // m_iscollidingObj = value; +// m_iscollidingObj = value; if (m_iscollidingObj) m_pidControllerActive = false; @@ -634,8 +646,8 @@ namespace OpenSim.Region.Physics.OdePlugin get { return m_orientation; } set { - // fakeori = value; - // givefakeori++; +// fakeori = value; +// givefakeori++; value.Normalize(); AddChange(changes.Orientation, value); @@ -690,6 +702,46 @@ namespace OpenSim.Region.Physics.OdePlugin AddChange(changes.Momentum, momentum); } + private void ajustCollider() + { + float vq = _velocity.LengthSquared(); + if (m_lastVelocitySqr != vq) + { + m_lastVelocitySqr = vq; + if (vq > 100.0f) + { + Vector3 off = _velocity; + float t = 0.5f * timeStep; + off = off * t; + d.GeomSetOffsetPosition(bbox, off.X, off.Y, off.Z); + off.X = 2.0f * (m_size.X + Math.Abs(off.X)); + off.Y = 2.0f * (m_size.Y + Math.Abs(off.Y)); + off.Z = m_size.Z + 2.0f * Math.Abs(off.Z); + d.GeomBoxSetLengths(bbox, off.X, off.Y, off.Z); + + d.GeomSetCategoryBits(bbox, (uint)m_collisionCategories); + d.GeomSetCollideBits(bbox, (uint)m_collisionFlags); + d.GeomSetCategoryBits(topbox, 0); + d.GeomSetCollideBits(topbox, 0); + d.GeomSetCategoryBits(midbox, 0); + d.GeomSetCollideBits(midbox, 0); + d.GeomSetCategoryBits(feetbox, 0); + d.GeomSetCollideBits(feetbox, 0); + } + else + { + d.GeomSetCategoryBits(bbox, 0); + d.GeomSetCollideBits(bbox, 0); + d.GeomSetCategoryBits(topbox, (uint)m_collisionCategories); + d.GeomSetCollideBits(topbox, (uint)m_collisionFlags); + d.GeomSetCategoryBits(midbox, (uint)m_collisionCategories); + d.GeomSetCollideBits(midbox, (uint)m_collisionFlags); + d.GeomSetCategoryBits(feetbox, (uint)m_collisionCategories); + d.GeomSetCollideBits(feetbox, (uint)m_collisionFlags); + } + } + } + private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ) { // sizes one day should came from visual parameters @@ -697,7 +749,6 @@ namespace OpenSim.Region.Physics.OdePlugin float sy = m_size.Y; float sz = m_size.Z; - float topsx = sx * 0.9f; float midsx = sx; float feetsx = sx * feetScale; @@ -732,21 +783,17 @@ namespace OpenSim.Region.Physics.OdePlugin _parent_scene.waitForSpaceUnlock(_parent_scene.CharsSpace); - feetbox = d.CreateBox(_parent_scene.CharsSpace, feetsx, feetsy, feetsz); - d.GeomSetCategoryBits(feetbox, (uint)m_collisionCategories); - d.GeomSetCollideBits(feetbox, (uint)m_collisionFlags); - - midbox = d.CreateBox(_parent_scene.CharsSpace, midsx, midsy, midsz); - d.GeomSetCategoryBits(midbox, (uint)m_collisionCategories); - d.GeomSetCollideBits(midbox, (uint)m_collisionFlags); + collider = d.HashSpaceCreate(_parent_scene.CharsSpace); + d.HashSpaceSetLevels(collider, -4, 3); + d.SpaceSetSublevel(collider, 3); + d.SpaceSetCleanup(collider, false); + d.GeomSetCategoryBits(collider, (uint)m_collisionCategories); + d.GeomSetCollideBits(collider, (uint)m_collisionFlags); - topbox = d.CreateBox(_parent_scene.CharsSpace, topsx, topsy, topsz); - d.GeomSetCategoryBits(topbox, (uint)m_collisionCategories); - d.GeomSetCollideBits(topbox, (uint)m_collisionFlags); - - bonebox = d.CreateBox(_parent_scene.CharsSpace, bonesx, bonesy, bonesz); - d.GeomSetCategoryBits(bonebox, (uint)m_collisionCategories); - d.GeomSetCollideBits(bonebox, (uint)m_collisionFlags); + feetbox = d.CreateBox(collider, feetsx, feetsy, feetsz); + midbox = d.CreateBox(collider, midsx, midsy, midsz); + topbox = d.CreateBox(collider, topsx, topsy, topsz); + bbox = d.CreateBox(collider, m_size.X, m_size.Y, m_size.Z); m_mass = m_density * m_size.X * m_size.Y * m_size.Z; // update mass @@ -758,9 +805,13 @@ namespace OpenSim.Region.Physics.OdePlugin Body = d.BodyCreate(_parent_scene.world); _zeroFlag = false; + m_collisionException = false; m_pidControllerActive = true; m_freemove = false; + _velocity = Vector3.Zero; + m_lastVelocitySqr = 0; + d.BodySetAutoDisableFlag(Body, false); d.BodySetPosition(Body, npositionX, npositionY, npositionZ); @@ -772,12 +823,14 @@ namespace OpenSim.Region.Physics.OdePlugin d.GeomSetBody(feetbox, Body); d.GeomSetBody(midbox, Body); d.GeomSetBody(topbox, Body); - d.GeomSetBody(bonebox, Body); + d.GeomSetBody(bbox, Body); d.GeomSetOffsetPosition(feetbox, 0, 0, feetz); d.GeomSetOffsetPosition(midbox, 0, 0, midz); d.GeomSetOffsetPosition(topbox, 0, 0, topz); - d.GeomSetOffsetPosition(bonebox, 0, 0, m_feetOffset); + + ajustCollider(); + // The purpose of the AMotor here is to keep the avatar's physical // surrogate from rotating while moving @@ -841,44 +894,109 @@ namespace OpenSim.Region.Physics.OdePlugin if (topbox != IntPtr.Zero) { _parent_scene.actor_name_map.Remove(topbox); - _parent_scene.waitForSpaceUnlock(_parent_scene.CharsSpace); + _parent_scene.waitForSpaceUnlock(collider); d.GeomDestroy(topbox); topbox = IntPtr.Zero; } if (midbox != IntPtr.Zero) { _parent_scene.actor_name_map.Remove(midbox); - _parent_scene.waitForSpaceUnlock(_parent_scene.CharsSpace); + _parent_scene.waitForSpaceUnlock(collider); d.GeomDestroy(midbox); midbox = IntPtr.Zero; } if (feetbox != IntPtr.Zero) { _parent_scene.actor_name_map.Remove(feetbox); - _parent_scene.waitForSpaceUnlock(_parent_scene.CharsSpace); + _parent_scene.waitForSpaceUnlock(collider); d.GeomDestroy(feetbox); feetbox = IntPtr.Zero; } - if (bonebox != IntPtr.Zero) + if (bbox != IntPtr.Zero) + { + _parent_scene.actor_name_map.Remove(bbox); + _parent_scene.waitForSpaceUnlock(collider); + d.GeomDestroy(bbox); + bbox = IntPtr.Zero; + } + + if (collider != IntPtr.Zero) { - _parent_scene.actor_name_map.Remove(bonebox); - _parent_scene.waitForSpaceUnlock(_parent_scene.CharsSpace); - d.GeomDestroy(bonebox); - bonebox = IntPtr.Zero; + d.SpaceDestroy(collider); + collider = IntPtr.Zero; } } + //in place 2D rotation around Z assuming rot is normalised and is a rotation around Z + public void RotateXYonZ(ref float x, ref float y, ref Quaternion rot) + { + float sin = 2.0f * rot.Z * rot.W; + float cos = rot.W * rot.W - rot.Z * rot.Z; + float tx = x; + + x = tx * cos - y * sin; + y = tx * sin + y * cos; + } + public void RotateXYonZ(ref float x, ref float y, ref float sin, ref float cos) + { + float tx = x; + x = tx * cos - y * sin; + y = tx * sin + y * cos; + } + public void invRotateXYonZ(ref float x, ref float y, ref float sin, ref float cos) + { + float tx = x; + x = tx * cos + y * sin; + y = -tx * sin + y * cos; + } + + public void invRotateXYonZ(ref float x, ref float y, ref Quaternion rot) + { + float sin = - 2.0f * rot.Z * rot.W; + float cos = rot.W * rot.W - rot.Z * rot.Z; + float tx = x; + + x = tx * cos - y * sin; + y = tx * sin + y * cos; + } + + public bool Collide(IntPtr me, bool reverse, ref d.ContactGeom contact, ref bool feetcollision) { feetcollision = false; + if (m_collisionException) + return false; - if (me == bonebox) // inner bone + if (me == bbox) // if moving fast { - if (contact.pos.Z - _position.Z < boneOff) - IsColliding = true; - return true; + // force a full inelastic collision + m_collisionException = true; + + Vector3 off = m_size * 0.5f; + off.X += contact.depth; + off.Y += contact.depth; + off.Z += contact.depth; + if (reverse) + { + off.X *= -contact.normal.X; + off.Y *= -contact.normal.Y; + off.Z *= -contact.normal.Z; + } + else + { + off.X *= contact.normal.X; + off.Y *= contact.normal.Y; + off.Z *= contact.normal.Z; + } + + off.X += contact.pos.X; + off.Y += contact.pos.Y; + off.Z += contact.pos.Z; + + _position = off; + return false; } if (me == topbox) // keep a box head @@ -890,6 +1008,21 @@ namespace OpenSim.Region.Physics.OdePlugin if (me == midbox) { + if (Math.Abs(contact.normal.Z) > 0.95f) + { + float nz = contact.normal.Z; + if (!reverse) + nz = -nz; + + if (nz > 0) + return true; // missed head TODO + + // missed feet collision? + + + return true; + } + t = offx * offx + offy * offy; t = (float)Math.Sqrt(t); t = 1 / t; @@ -917,12 +1050,19 @@ namespace OpenSim.Region.Physics.OdePlugin if (Math.Abs(contact.normal.Z) > 0.95f) { + if (contact.normal.Z > 0) + contact.normal.Z = 1.0f; + else + contact.normal.Z = -1.0f; + contact.normal.X = 0.0f; + contact.normal.Y = 0.0f; feetcollision = true; if (h < boneOff) IsColliding = true; return true; } + float offz = h - feetOff; // distance from top of feetbox if (offz > 0) @@ -971,11 +1111,28 @@ namespace OpenSim.Region.Physics.OdePlugin /// This is the avatar's movement control + PID Controller /// /// - public void Move(float timeStep, List defects) + public void Move(List defects) { if (Body == IntPtr.Zero) return; + if (m_collisionException) + { + d.BodySetPosition(Body,_position.X, _position.Y, _position.Z); + d.BodySetLinearVel(Body, 0, 0, 0); + + float v = _velocity.Length(); + if (v != 0) + { + v = 6.0f / v; + _velocity = _velocity * v; + d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z); + } + ajustCollider(); + m_collisionException = false; + return; + } + d.Vector3 dtmp = d.BodyGetPosition(Body); Vector3 localpos = new Vector3(dtmp.X, dtmp.Y, dtmp.Z); @@ -1049,6 +1206,7 @@ namespace OpenSim.Region.Physics.OdePlugin //****************************************** // colide with land + d.AABB aabb; d.GeomGetAABB(feetbox, out aabb); float chrminZ = aabb.MinZ - 0.02f; // move up a bit @@ -1095,8 +1253,8 @@ namespace OpenSim.Region.Physics.OdePlugin contact.Position.X = localpos.X; contact.Position.Y = localpos.Y; contact.Position.Z = chrminZ; - contact.SurfaceNormal.X = 0f; - contact.SurfaceNormal.Y = 0f; + contact.SurfaceNormal.X = 0.0f; + contact.SurfaceNormal.Y = 0.0f; contact.SurfaceNormal.Z = -1f; contact.RelativeSpeed = -vel.Z; contact.CharacterFeet = true; @@ -1118,6 +1276,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_iscollidingGround = false; } + //****************************************** bool tviszero = (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f); @@ -1253,21 +1412,58 @@ namespace OpenSim.Region.Physics.OdePlugin } // update our local ideia of position velocity and aceleration + // _position = localpos; _position = localpos; + if (_zeroFlag) { _velocity = Vector3.Zero; _acceleration = Vector3.Zero; + m_rotationalVelocity = Vector3.Zero; } else { - _acceleration = _velocity; // previus velocity - _velocity = vel; - _acceleration = (vel - _acceleration) / timeStep; + Vector3 a =_velocity; // previus velocity + SetSmooth(ref _velocity, ref vel, 2); + a = (_velocity - a) * invtimeStep; + SetSmooth(ref _acceleration, ref a, 2); + + dtmp = d.BodyGetAngularVel(Body); + m_rotationalVelocity.X = 0f; + m_rotationalVelocity.Y = 0f; + m_rotationalVelocity.Z = dtmp.Z; + Math.Round(m_rotationalVelocity.Z,3); } - + ajustCollider(); } + public void round(ref Vector3 v, int digits) + { + v.X = (float)Math.Round(v.X, digits); + v.Y = (float)Math.Round(v.Y, digits); + v.Z = (float)Math.Round(v.Z, digits); + } + + public void SetSmooth(ref Vector3 dst, ref Vector3 value) + { + dst.X = 0.1f * dst.X + 0.9f * value.X; + dst.Y = 0.1f * dst.Y + 0.9f * value.Y; + dst.Z = 0.1f * dst.Z + 0.9f * value.Z; + } + + public void SetSmooth(ref Vector3 dst, ref Vector3 value, int rounddigits) + { + dst.X = 0.4f * dst.X + 0.6f * value.X; + dst.X = (float)Math.Round(dst.X, rounddigits); + + dst.Y = 0.4f * dst.Y + 0.6f * value.Y; + dst.Y = (float)Math.Round(dst.Y, rounddigits); + + dst.Z = 0.4f * dst.Z + 0.6f * value.Z; + dst.Z = (float)Math.Round(dst.Z, rounddigits); + } + + /// /// Updates the reported position and velocity. /// Used to copy variables from unmanaged space at heartbeat rate and also trigger scene updates acording @@ -1394,10 +1590,11 @@ namespace OpenSim.Region.Physics.OdePlugin AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z); - _parent_scene.actor_name_map[topbox] = (PhysicsActor)this; - _parent_scene.actor_name_map[midbox] = (PhysicsActor)this; + _parent_scene.actor_name_map[collider] = (PhysicsActor)this; _parent_scene.actor_name_map[feetbox] = (PhysicsActor)this; - _parent_scene.actor_name_map[bonebox] = (PhysicsActor)this; + _parent_scene.actor_name_map[midbox] = (PhysicsActor)this; + _parent_scene.actor_name_map[topbox] = (PhysicsActor)this; + _parent_scene.actor_name_map[bbox] = (PhysicsActor)this; _parent_scene.AddCharacter(this); } else @@ -1450,13 +1647,16 @@ namespace OpenSim.Region.Physics.OdePlugin _position.Z + (m_size.Z - oldsz) * 0.5f); Velocity = Vector3.Zero; + - _parent_scene.actor_name_map[topbox] = (PhysicsActor)this; - _parent_scene.actor_name_map[midbox] = (PhysicsActor)this; + _parent_scene.actor_name_map[collider] = (PhysicsActor)this; _parent_scene.actor_name_map[feetbox] = (PhysicsActor)this; - _parent_scene.actor_name_map[bonebox] = (PhysicsActor)this; + _parent_scene.actor_name_map[midbox] = (PhysicsActor)this; + _parent_scene.actor_name_map[topbox] = (PhysicsActor)this; + _parent_scene.actor_name_map[bbox] = (PhysicsActor)this; } m_freemove = false; + m_collisionException = false; m_pidControllerActive = true; } else @@ -1565,6 +1765,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (Body != IntPtr.Zero) d.BodySetLinearVel(Body, newmomentum.X, newmomentum.Y, newmomentum.Z); + ajustCollider(); } private void donullchange() @@ -1573,7 +1774,7 @@ namespace OpenSim.Region.Physics.OdePlugin public bool DoAChange(changes what, object arg) { - if (topbox == IntPtr.Zero && what != changes.Add && what != changes.Remove) + if (collider == IntPtr.Zero && what != changes.Add && what != changes.Remove) { return false; } -- cgit v1.1 From 28ea08c3e234f8ca3c6590af4045349af7fed844 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 11 Dec 2012 17:14:32 +0000 Subject: fix let other phys plugins work.. broken when added feetOffset --- OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index 1b25faf..b769c88 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs @@ -165,9 +165,10 @@ namespace OpenSim.Region.Physics.OdePlugin - public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, Vector3 pSize, float pfeetOffset, float density, float walk_divisor, float rundivisor) + public OdeCharacter(uint localID, String avName, OdeScene parent_scene, Vector3 pos, Vector3 pSize, float pfeetOffset, float density, float walk_divisor, float rundivisor) { m_uuid = UUID.Random(); + m_localID = localID; timeStep = parent_scene.ODE_STEPSIZE; invtimeStep = 1 / timeStep; @@ -1209,7 +1210,7 @@ namespace OpenSim.Region.Physics.OdePlugin d.AABB aabb; d.GeomGetAABB(feetbox, out aabb); - float chrminZ = aabb.MinZ - 0.02f; // move up a bit + float chrminZ = aabb.MinZ; ; // move up a bit Vector3 posch = localpos; float ftmp; @@ -1252,7 +1253,7 @@ namespace OpenSim.Region.Physics.OdePlugin contact.PenetrationDepth = depth; contact.Position.X = localpos.X; contact.Position.Y = localpos.Y; - contact.Position.Z = chrminZ; + contact.Position.Z = terrainheight; contact.SurfaceNormal.X = 0.0f; contact.SurfaceNormal.Y = 0.0f; contact.SurfaceNormal.Z = -1f; -- cgit v1.1 From f35e3c6fe04327ad4bc9b9864663910ea2b5d717 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 11 Dec 2012 19:38:44 +0000 Subject: changes on the fast speed avatars collider, collisions from above, etc --- .../Region/Physics/UbitOdePlugin/ODECharacter.cs | 126 +++++++++++---------- 1 file changed, 64 insertions(+), 62 deletions(-) (limited to 'OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index b769c88..27a9f1c 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs @@ -970,78 +970,86 @@ namespace OpenSim.Region.Physics.OdePlugin if (m_collisionException) return false; + Vector3 offset; + if (me == bbox) // if moving fast { // force a full inelastic collision m_collisionException = true; - Vector3 off = m_size * 0.5f; - off.X += contact.depth; - off.Y += contact.depth; - off.Z += contact.depth; + offset = m_size * m_orientation; + + offset.X = (float)Math.Abs(offset.X) * 0.5f + contact.depth; + offset.Y = (float)Math.Abs(offset.Y) * 0.5f + contact.depth; + offset.Z = (float)Math.Abs(offset.Z) * 0.5f + contact.depth; + if (reverse) { - off.X *= -contact.normal.X; - off.Y *= -contact.normal.Y; - off.Z *= -contact.normal.Z; + offset.X *= -contact.normal.X; + offset.Y *= -contact.normal.Y; + offset.Z *= -contact.normal.Z; } else { - off.X *= contact.normal.X; - off.Y *= contact.normal.Y; - off.Z *= contact.normal.Z; + offset.X *= contact.normal.X; + offset.Y *= contact.normal.Y; + offset.Z *= contact.normal.Z; } - off.X += contact.pos.X; - off.Y += contact.pos.Y; - off.Z += contact.pos.Z; + offset.X += contact.pos.X; + offset.Y += contact.pos.Y; + offset.Z += contact.pos.Z; - _position = off; + _position = offset; return false; } - if (me == topbox) // keep a box head - return true; - - float t; - float offx = contact.pos.X - _position.X; - float offy = contact.pos.Y - _position.Y; + offset.X = contact.pos.X - _position.X; + offset.Y = contact.pos.Y - _position.Y; - if (me == midbox) + if (me == topbox) { - if (Math.Abs(contact.normal.Z) > 0.95f) - { - float nz = contact.normal.Z; - if (!reverse) - nz = -nz; - - if (nz > 0) - return true; // missed head TODO + offset.Z = contact.pos.Z - _position.Z; - // missed feet collision? + offset.Normalize(); - - return true; + if (reverse) + { + contact.normal.X = offset.X; + contact.normal.Y = offset.Y; + contact.normal.Z = offset.Z; + } + else + { + contact.normal.X = -offset.X; + contact.normal.Y = -offset.Y; + contact.normal.Z = -offset.Z; } + return true; + } - t = offx * offx + offy * offy; - t = (float)Math.Sqrt(t); - t = 1 / t; - offx *= t; - offy *= t; + if (me == midbox) + { + if (Math.Abs(contact.normal.Z) > 0.95f) + offset.Z = contact.pos.Z - _position.Z; + else + offset.Z = contact.normal.Z; + + offset.Normalize(); if (reverse) { - contact.normal.X = offx; - contact.normal.Y = offy; + contact.normal.X = offset.X; + contact.normal.Y = offset.Y; + contact.normal.Z = offset.Z; } else { - contact.normal.X = -offx; - contact.normal.Y = -offy; + contact.normal.X = -offset.X; + contact.normal.Y = -offset.Y; + contact.normal.Z = -offset.Z; } - contact.normal.Z = 0; return true; } @@ -1063,39 +1071,33 @@ namespace OpenSim.Region.Physics.OdePlugin return true; } + offset.Z = h - feetOff; // distance from top of feetbox - float offz = h - feetOff; // distance from top of feetbox - - if (offz > 0) + if (offset.Z > 0) return false; - if (offz > -0.01) + if (offset.Z > -0.01) { - offx = 0; - offy = 0; - offz = -1.0f; + offset.X = 0; + offset.Y = 0; + offset.Z = -1.0f; } else { - t = offx * offx + offy * offy + offz * offz; - t = (float)Math.Sqrt(t); - t = 1 / t; - offx *= t; - offy *= t; - offz *= t; + offset.Normalize(); } if (reverse) { - contact.normal.X = offx; - contact.normal.Y = offy; - contact.normal.Z = offz; + contact.normal.X = offset.X; + contact.normal.Y = offset.Y; + contact.normal.Z = offset.Z; } else { - contact.normal.X = -offx; - contact.normal.Y = -offy; - contact.normal.Z = -offz; + contact.normal.X = -offset.X; + contact.normal.Y = -offset.Y; + contact.normal.Z = -offset.Z; } feetcollision = true; if (h < boneOff) @@ -1125,7 +1127,7 @@ namespace OpenSim.Region.Physics.OdePlugin float v = _velocity.Length(); if (v != 0) { - v = 6.0f / v; + v = 5.0f / v; _velocity = _velocity * v; d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z); } -- cgit v1.1 From 71fc9f29f92edf2956ecb25dcbcdb97d262c8a14 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 11 Dec 2012 22:53:24 +0000 Subject: make ubitODE ignore X and Y rotation components on avatar rotations --- .../Region/Physics/UbitOdePlugin/ODECharacter.cs | 51 ++++++++++++++++------ 1 file changed, 37 insertions(+), 14 deletions(-) (limited to 'OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs') diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs index 27a9f1c..bb04ea7 100644 --- a/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/UbitOdePlugin/ODECharacter.cs @@ -80,6 +80,7 @@ namespace OpenSim.Region.Physics.OdePlugin private Vector3 m_rotationalVelocity; private Vector3 m_size; private Quaternion m_orientation; + private Quaternion m_orientation2D; private float m_mass = 80f; public float m_density = 60f; private bool m_pidControllerActive = true; @@ -207,6 +208,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_feetOffset = pfeetOffset; m_orientation = Quaternion.Identity; + m_orientation2D = Quaternion.Identity; m_density = density; // force lower density for testing @@ -649,7 +651,6 @@ namespace OpenSim.Region.Physics.OdePlugin { // fakeori = value; // givefakeori++; - value.Normalize(); AddChange(changes.Orientation, value); } @@ -977,7 +978,7 @@ namespace OpenSim.Region.Physics.OdePlugin // force a full inelastic collision m_collisionException = true; - offset = m_size * m_orientation; + offset = m_size * m_orientation2D; offset.X = (float)Math.Abs(offset.X) * 0.5f + contact.depth; offset.Y = (float)Math.Abs(offset.Y) * 0.5f + contact.depth; @@ -1143,10 +1144,10 @@ namespace OpenSim.Region.Physics.OdePlugin // so force it back to identity d.Quaternion qtmp; - qtmp.W = m_orientation.W; - qtmp.X = m_orientation.X; - qtmp.Y = m_orientation.Y; - qtmp.Z = m_orientation.Z; + qtmp.W = m_orientation2D.W; + qtmp.X = m_orientation2D.X; + qtmp.Y = m_orientation2D.Y; + qtmp.Z = m_orientation2D.Z; d.BodySetQuaternion(Body, ref qtmp); if (m_pidControllerActive == false) @@ -1679,14 +1680,36 @@ namespace OpenSim.Region.Physics.OdePlugin private void changeOrientation(Quaternion newOri) { - d.Quaternion myrot = new d.Quaternion(); - myrot.X = newOri.X; - myrot.Y = newOri.Y; - myrot.Z = newOri.Z; - myrot.W = newOri.W; - float t = d.JointGetAMotorAngle(Amotor, 2); - d.BodySetQuaternion(Body,ref myrot); - m_orientation = newOri; + if (m_orientation != newOri) + { + m_orientation = newOri; // keep a copy for core use + // but only use rotations around Z + + m_orientation2D.W = newOri.W; + m_orientation2D.Z = newOri.Z; + + float t = m_orientation2D.W * m_orientation2D.W + m_orientation2D.Z * m_orientation2D.Z; + if (t > 0) + { + t = 1.0f / (float)Math.Sqrt(t); + m_orientation2D.W *= t; + m_orientation2D.Z *= t; + } + else + { + m_orientation2D.W = 1.0f; + m_orientation2D.Z = 0f; + } + m_orientation2D.Y = 0f; + m_orientation2D.X = 0f; + + d.Quaternion myrot = new d.Quaternion(); + myrot.X = m_orientation2D.X; + myrot.Y = m_orientation2D.Y; + myrot.Z = m_orientation2D.Z; + myrot.W = m_orientation2D.W; + d.BodySetQuaternion(Body, ref myrot); + } } private void changeVelocity(Vector3 newVel) -- cgit v1.1