@Override
  public void draw() {
    g.clear();
    g.color(255);
    _myTouchInteractionManager.draw(g);
    g.clearDepthBuffer();

    g.pushMatrix();
    _myArcball.draw(g);
    g.scale(0.5);
    g.color(255, 0, 0);
    g.pointSize(3);
    g.beginShape(CCDrawMode.POINTS);
    for (CCSkeletonTouchLocation myLocation : _myTouchInteractionManager.locations()) {
      g.vertex(myLocation.position());
    }
    g.endShape();
    for (CCSkeletonTouchLocation myLocation : _myTouchInteractionManager.locations()) {
      g.ellipse(myLocation.position(), myLocation.sourceProximity() * 100);
    }
    g.color(255);
    for (CCSkeleton mySkeleton : _mySkeletonManager.skeletons()) {
      mySkeleton.draw(g);
      CCPlane3f myBodyPlane = mySkeleton.bodyPlane();
      myBodyPlane.drawScale(100);
      myBodyPlane.draw(g);
    }
    for (CCTouchSource mySource : _myTouchInteractionManager.sources()) {
      g.ellipse(mySource.position(), mySource.locationProximity() * 100);
    }
    g.popMatrix();
  }
  @Override
  public void update(final float theDeltaTime) {

    if (USE_SKELETON_SENDER) {
      _myReceiver.update(theDeltaTime);
    } else {
      _myOpenNI.transformationMatrix().reset();
      _myOpenNI.transformationMatrix().translate(_cOpenNIX, _cOpenNIY, _cOpenNIZ);
      _myOpenNI.transformationMatrix().rotateX(CCMath.radians(_cRotateX));
      _myOpenNI.transformationMatrix().scale(_cOpenNIScale);
    }

    _mySkeletonManager.update(theDeltaTime);
    g.pushMatrix();
    _myArcball.draw(g);
    g.scale(0.5);
    g.camera().updateProjectionInfos();
    _myTouchInteractionManager.updateLocations(theDeltaTime);
    g.popMatrix();
  }
  @Override
  public void setup() {
    addControls("app", "app", this);

    _myArcball = new CCArcball(this);

    CCColladaLoader myColladaLoader = new CCColladaLoader("humanoid.dae");

    CCColladaScene myScene = myColladaLoader.scenes().element(0);
    CCColladaSkinController mySkin = myColladaLoader.controllers().element(0).skin();

    CCColladaSkeleton mySkeleton = new CCColladaSkeleton(mySkin, myScene.node("bvh_import/Hips"));

    if (USE_SKELETON_SENDER) {
      _myReceiver = new CCSkeletonReceiver(new CCUDPIn<>(new CCNetXMLCodec(), "127.0.0.1", 9000));
      _mySkeletonManager = new CCSkeletonManager(this, mySkeleton, _myReceiver);
      _myReceiver.start();
    } else {
      _myOpenNI = new CCOpenNI(this);
      _myOpenNI.openFileRecording("SkeletonRec.oni");
      _myUserGenerator = _myOpenNI.createUserGenerator();
      _myOpenNI.start();
      _mySkeletonManager =
          new CCSkeletonManager(this, mySkeleton, new CCOpenNISkeletonProvider(_myUserGenerator));
    }

    _myTouchInteractionManager =
        new CCSkeletonTouchInteractionManager(
            this, CCSkeletonJointType.LEFT_HAND, CCSkeletonJointType.RIGHT_HAND);

    _mySkeletonManager.events().add(_myTouchInteractionManager);
    _myTouchInteractionManager.createMouseSource();

    CCSkeletonTouchLocationListener myListener =
        new CCSkeletonTouchLocationListener() {

          @Override
          public void onOver(CCSkeletonTouchLocation theLocation) {
            //				CCLog.info("ON OVER:" + theLocation.name());
          }

          @Override
          public void onOut(CCSkeletonTouchLocation theLocation) {
            //				CCLog.info("ON OUT:" + theLocation.name());
          }

          @Override
          public void onSelect(CCSkeletonTouchLocation theLocation) {
            //				CCLog.info("ON SELECT:" + theLocation.name());
          }

          @Override
          public void onDeselect(CCSkeletonTouchLocation theLocation) {
            //				CCLog.info("ON DESELECT:" + theLocation.name());
          }
        };

    for (int i = 0; i < 100; i++) {
      CCSkeletonTouchLocation myLocation =
          new CCSkeletonTouchLocation("loc:" + i, CCVecMath.random3f(300));
      myLocation.events().add(myListener);
      _myTouchInteractionManager.locations().add(myLocation);
    }
  }