public void handleUpdateWorldNode(long oid, WorldManagerClient.UpdateWorldNodeMessage wnodeMsg) {
   PerceiverData perceiverData = perceiverDataMap.get(oid);
   if (perceiverData == null) {
     if (Log.loggingDebug)
       Log.debug(
           "ProximityTracker.handleMessage: ignoring updateWNMsg for oid "
               + oid
               + " because PerceptionData for oid not found");
     return;
   }
   BasicWorldNode bwnode = wnodeMsg.getWorldNode();
   if (Log.loggingDebug)
     Log.debug(
         "ProximityTracker.handleMessage: UpdateWnode for "
             + oid
             + ", loc "
             + bwnode.getLoc()
             + ", dir "
             + bwnode.getDir());
   if (perceiverData.wnode != null) {
     perceiverData.previousLoc = perceiverData.lastLoc;
     perceiverData.wnode.setDirLocOrient(bwnode);
     perceiverData.wnode.setInstanceOid(bwnode.getInstanceOid());
     perceiverData.lastLoc = perceiverData.wnode.getLoc();
   } else
     Log.error(
         "ProximityTracker.handleMessage: In UpdateWorldNodeMessage for oid "
             + oid
             + ", perceiverData.wnode is null!");
   updateEntity(perceiverData);
 }
    protected void update() {
      Log.debug("Updater.update: in update");

      List<Long> perceiverOids = null;
      lock.lock();
      try {
        perceiverOids = new ArrayList<Long>(perceiverDataMap.keySet());
      } finally {
        lock.unlock();
      }
      // We loop over the copied perceiverOids causing
      // interpolation to happen, and capturing the location in
      // the PerceiverData, so we can later do comparisons
      // cheaply.  Note that underlying map can change while
      // we're doing so, so we don't raise errors if it happens.
      for (long perceiverOid : perceiverOids) {
        PerceiverData perceiverData = perceiverDataMap.get(perceiverOid);
        if (perceiverData != null) {
          perceiverData.previousLoc = perceiverData.lastLoc;
          //                    long lastInterp = perceiverData.wnode.getLastInterp();
          perceiverData.lastLoc = perceiverData.wnode.getLoc();
          //                     if (Log.loggingDebug)
          //                         Log.debug("Updater.update: perceiverOid " + perceiverOid + ",
          // previousLoc " + perceiverData.previousLoc +
          //                             ", lastLoc " + perceiverData.lastLoc + ", time since interp
          // " + (System.currentTimeMillis() - lastInterp));
        }
      }
      // Now actually do the double loop to check if inRange has
      // changed
      for (long perceiverOid : perceiverOids) {
        PerceiverData perceiverData = perceiverDataMap.get(perceiverOid);
        if (perceiverData == null) continue;
        // If the perceiver hasn't moved much, no need to
        // iterate over it's perceived entities
        if (perceiverData.previousLoc != null
            && Point.distanceToSquared(perceiverData.previousLoc, perceiverData.lastLoc) < 100f)
          continue;
        ArrayList<Long> perceivedOids = new ArrayList<Long>(perceiverData.perceivedOids);
        for (long perceivedOid : perceivedOids) {
          PerceiverData perceivedData = perceiverDataMap.get(perceivedOid);
          if (perceivedData == null) continue;
          // Invoke the testProximity method but tell it not
          // to interpolate, but instead get its location
          // from the PerceptionData.lastLoc members
          testProximity(perceiverData, perceivedData, false, false);
        }
      }
    }