Пример #1
0
        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 = new PhysicsVector(0f, 0f, 0f);

                    _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.IsIdentical(_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;
                }
            }
        }
Пример #2
0
        internal void ProcessTaints()
        {
            if (m_taintPosition != _position)
            {
                if (Body != IntPtr.Zero)
                {
                    d.BodySetPosition(Body, m_taintPosition.X, m_taintPosition.Y, m_taintPosition.Z);
                    _position = m_taintPosition;
                }
            }

            if (m_taintForce != Vector3.Zero)
            {
                if (Body != IntPtr.Zero)
                {
                    // FIXME: This is not a good solution since it's subject to a race condition if a force is another
                    // thread sets a new force while we're in this loop (since it could be obliterated by
                    // m_taintForce = Vector3.Zero.  Need to lock ProcessTaints() when we set a new tainted force.
                    d.BodyAddForce(Body, m_taintForce.X, m_taintForce.Y, m_taintForce.Z);
                }

                m_taintForce = Vector3.Zero;
            }

            if (m_taintTargetVelocity != _target_velocity)
            {
                _target_velocity = m_taintTargetVelocity;
            }

            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("[ODE CHARACTER]: re-creating the following avatar ODE data for " + Name + ", even though it already exists - "
                                   + (Shell != IntPtr.Zero ? "Shell ":"")
                                   + (Body != IntPtr.Zero ? "Body ":"")
                                   + (Amotor != IntPtr.Zero ? "Amotor ":""));
                    }

                    CreateOdeStructures(_position.X, _position.Y, _position.Z, m_tensor);
                    _parent_scene.AddCharacter(this);
                }
                else
                {
                    _parent_scene.RemoveCharacter(this);
                    DestroyOdeStructures();
                }

                m_isPhysical = m_tainted_isPhysical;
            }

            if (m_tainted_CAPSULE_LENGTH != CAPSULE_LENGTH)
            {
                if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero)
                {
//                    m_log.DebugFormat(
//                        "[ODE CHARACTER]: Changing capsule size from {0} to {1} for {2}",
//                        CAPSULE_LENGTH, m_tainted_CAPSULE_LENGTH, Name);

                    m_pidControllerActive = true;

                    // no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate()
                    DestroyOdeStructures();

                    float prevCapsule = CAPSULE_LENGTH;
                    CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH;

                    CreateOdeStructures(
                        _position.X,
                        _position.Y,
                        _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor);

                    // As with Size, we reset velocity.  However, this isn't strictly necessary since it doesn't
                    // appear to stall initial region crossings when done here.  Being done for consistency.
//                    Velocity = Vector3.Zero;
                }
                else
                {
                    m_log.Warn("[ODE CHARACTER]: trying to change capsule size for " + Name + ", but the following ODE data is missing - "
                               + (Shell == IntPtr.Zero ? "Shell ":"")
                               + (Body == IntPtr.Zero ? "Body ":"")
                               + (Amotor == IntPtr.Zero ? "Amotor ":""));
                }
            }
        }