gt:             Runnable collisionAction = new Runnable() {
context: /*
   * Copyright (C) 2014 Pablo Campillo-Sanchez <pabcampi@ucm.es>
   *
   * This software has been developed as part of the 
   * SociAAL project directed by Jorge J. Gomez Sanz
   * (http://grasia.fdi.ucm.es/sociaal)
   *
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation, either version 3 of the License, or
   * (at your option) any later version.
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
  package phat.controls.animation;
  
  import com.jme3.asset.AssetManager;
  import com.jme3.bullet.collision.PhysicsCollisionEvent;
  import com.jme3.bullet.collision.PhysicsCollisionListener;
  import com.jme3.bullet.collision.shapes.CollisionShape;
  import com.jme3.bullet.control.RigidBodyControl;
  import com.jme3.bullet.util.CollisionShapeFactory;
  import com.jme3.material.Material;
  import com.jme3.math.ColorRGBA;
  import com.jme3.math.Vector3f;
  import com.jme3.scene.Geometry;
  import com.jme3.scene.Node;
  import com.jme3.scene.Spatial;
  import com.jme3.scene.control.CameraControl;
  import com.jme3.scene.shape.Box;
  import java.util.Vector;
  import java.util.concurrent.ConcurrentLinkedQueue;
  import phat.agents.actors.ActorFactory;
  import phat.agents.actors.BasicActor;
  import phat.agents.actors.parkinson.HandTremblingControl;
  import phat.agents.actors.parkinson.HeadTremblingControl;
  import phat.audio.listeners.PCSpeaker;
  import phat.audio.listeners.XYRMSAudioChart;
  import phat.audio.util.AudioSimpleScenario;
  import phat.sensors.microphone.MicrophoneControl;
  import phat.util.Debug;
  
  /**
   *
   * @author pablo
   */
  public class FootStepsControlTestApp extends AudioSimpleScenario implements PhysicsCollisionListener/*, RagdollCollisionListener */{
  
      private MicrophoneControl micControl;
      private BasicActor actor;
  
      public FootStepsControlTestApp() {
          super();
          
          setShowSettings(true);
      }
      public static void main(String[] args) {
          FootStepsControlTestApp app = new FootStepsControlTestApp();
          app.setDisplayFps(false);
          //app.setShowSettings(false);
          app.setPauseOnLostFocus(false);
          app.setDisplayStatView(false);
  
          //recordVideoAndAudio(app);
  
          /*
           try {
           File video = new File("video.avi");
           File audio = new File("audio.wav");
          
           Capture.captureVideo(app, video);
           Capture.captureAudio(app, audio);
           } catch (IOException ex) {
           Logger.getLogger(FootStepsControlTestApp.class.getName()).log(Level.SEVERE, null, ex);
           }*/
  
          app.start();
      }
  
      @Override
      public void createTerrain() {
          Debug.enableDebugGrid(10f, assetManager, rootNode);
  
          bulletAppState.getPhysicsSpace().addCollisionListener(this);
  
          Box b = new Box(20f, 0.1f, 20f); // create cube shape at the origin
          Geometry base = new Geometry("Terrain", b);  // create cube geometry from the shape
          Material terrainMat = new Material(assetManager,
                  "Common/MatDefs/Misc/Unshaded.j3md");  // create a simple material
          terrainMat.setColor("Color", ColorRGBA.Gray);   // set color of material to blue
          base.setMaterial(terrainMat);
          base.move(new Vector3f(-1f, -0.1f, -1f).mult(ActorFactory.getScale()));
          base.setLocalScale(ActorFactory.getScale());
          // the collision mesh needs to be dynamic, otherwise, collision with dynamic objects
          // do not work well. They tend to go through others.
          CollisionShape sceneShape = CollisionShapeFactory.createDynamicMeshShape(base);
          RigidBodyControl landscape = new RigidBodyControl(sceneShape, 0f);
          base.addControl(landscape);
  
          bulletAppState.getPhysicsSpace().add(base); // tells the physicis engine it is a rigid-solid box-shaped object
          rootNode.attachChild(base);
      }
  
      @Override
      public void createOtherObjects() {
          ActorFactory.init(rootNode, assetManager, bulletAppState);
          actor = ActorFactory.createBasicActor("Actor", "Models/People/Elder/Elder.j3o", new Vector3f(0f, 2f, 0f), 0.3f, 0.5f, 0.5f, PatientAnimControl.class);
          rootNode.attachChild(actor.getNode());
  
          /*
          KinematicRagdollControl krc = ActorFactory.findControl(actor.getNode(), KinematicRagdollControl.class);
          krc.addCollisionListener(this);*/
  
          initGestures(actor.getNode());
  
          createObstacle(rootNode, assetManager);
      }
  
      private void initGestures(Node model) {
          HandTremblingControl htc = new HandTremblingControl(HandTremblingControl.Hand.LEFT_HAND);
          model.addControl(htc);
  
          htc = new HandTremblingControl(HandTremblingControl.Hand.RIGHT_HAND);
          model.addControl(htc);
  
          HeadTremblingControl headtc = new HeadTremblingControl();
          model.addControl(headtc);
      }
      /*private void initGestures(Node model) {
       HandTremblingControl htc = new HandTremblingControl(HandTremblingControl.Hand.LEFT_HAND);
       model.addControl(htc);  
          
       HeadTremblingControl headtc = new HeadTremblingControl();
       model.addControl(headtc);
       }*/
      float acumulative = 0f;
      float seconds = 0f;
      int numSeconds = 0;
      boolean moving = false;
  
      @Override
      public void simpleUpdate(float tpf) {
          super.simpleUpdate(tpf);
  
          Vector<Runnable> currentActions = new Vector<Runnable>(collisionActions);
          collisionActions.removeAll(currentActions);
          for (Runnable run : currentActions) {
              run.run();
          };
  
          acumulative += tpf;
          seconds += tpf;
  
          if (seconds > 1f) {
              System.out.println(numSeconds++);
              seconds = 0f;
          }
  
          if (acumulative > 2f && !moving) {
              actor.moveTo(new Vector3f(10f, 10f, 10f));
              moving = true;
          }
  
      }
      /*
      AudioSource noiseSource1;
      AudioSource noiseSource2;
      AudioSource noiseSource3;
      
      String noise1 = "Sound/HumanEffects/FallingDown/fallingDown1.ogg";
      String noise2 = "Sound/HumanEffects/FallingDown/fallingDown2.ogg";
      String noise3 = "Sound/HumanEffects/FallingDown/fallingDown3.ogg";
  
      private AudioSource createAudio(String resource) {
          AudioSource as = AudioFactory.getInstance().makeAudioSource("FootSteps", resource, Vector3f.ZERO);
          as.setLooping(false);
          as.setPositional(true);
          as.setDirectional(false);
          as.setVolume(0.5f);
          as.setRefDistance(1f);
          as.setTimeOffset(0f);
  
          //as.setShowRange(true);
  
          return as;
      }*/
  
      
      @Override
      protected void createAudio() {
          Node camFollower = new Node();
          // means that the Camera's transform is "copied" to the Transform of the Spatial.
          CameraControl cc = new CameraControl(cam, CameraControl.ControlDirection.CameraToSpatial);
          camFollower.addControl(cc);
          rootNode.attachChild(camFollower);
  
          micControl = new MicrophoneControl("Micro1", 10000, audioRenderer);
          camFollower.addControl(micControl);
  
          PCSpeaker pcSpeaker = new PCSpeaker();
          micControl.add(pcSpeaker);
          
          XYRMSAudioChart chart = new XYRMSAudioChart("RMS");
          micControl.add(chart);
          chart.showWindow();
  
          /*
          noiseSource1 = createAudio(noise1);
          noiseSource2 = createAudio(noise2);
          noiseSource3 = createAudio(noise3);
  
          actor.getNode().attachChild(noiseSource1);
          actor.getNode().attachChild(noiseSource2);
          actor.getNode().attachChild(noiseSource3);
          */
      }
      
      private ConcurrentLinkedQueue<Runnable> collisionActions = new ConcurrentLinkedQueue<Runnable>();
  
      @Override
      public void collision(PhysicsCollisionEvent pce) {
          Spatial obj1 = pce.getNodeA();
          Spatial obj2 = pce.getNodeB();
          if (obj1 != null && obj2 != null) {
              final String obj1n = pce.getNodeA().getName();
              final String obj2n = pce.getNodeB().getName();
  