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; } } }
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 ":"")); } } }