@Override
  public boolean onDown(MotionEvent event) {
    scrolling = false;

    synchronized (GlobalData.audioScene) {
      // determine transformed coordinate of touch point
      touchPoint[0] = event.getX();
      touchPoint[1] = event.getY();
      inverseViewportTransformation.mapPoints(touchPoint);
      GlobalData.audioScene.inverseMapPoint(touchPoint);

      // try to find nearest sound source
      lastTouchSoundSource = GlobalData.audioScene.getNearestSoundSource(touchPoint);
      if (lastTouchSoundSource != null) {
        // get distance (touch point to source) in pixels
        selectionOffset[0] = lastTouchSoundSource.getX();
        selectionOffset[1] = lastTouchSoundSource.getY();
        GlobalData.audioScene.mapPoint(selectionOffset);
        viewportTransformation.mapPoints(selectionOffset);
        selectionOffset[0] -= event.getX();
        selectionOffset[1] -= event.getY();
        float distance =
            FloatMath.sqrt(
                selectionOffset[0] * selectionOffset[0] + selectionOffset[1] * selectionOffset[1]);

        // select source?
        if (distance > SOURCE_SELECT_RADIUS) {
          lastTouchSoundSource = null;
        }
      }
    }

    return true;
  }
  public float[][] getSceneBounds(Matrix viewportTransformation) {
    float[] point = {0.0f, 0.0f};

    // map reference point to screen coordinate system
    viewportTransformation.mapPoints(point);

    // set min/max to reference position
    float[][] minMaxXY = {
      {point[0], point[1]}, {point[0], point[1]}
    }; // two points: minXY and maxXY

    synchronized (GlobalData.audioScene) {
      int numSources = GlobalData.audioScene.getNumSoundSources();
      SoundSource s = null;
      for (int i = 0; i < numSources; i++) {
        s = GlobalData.audioScene.getSoundSource(i);
        point[0] = s.getX();
        point[1] = s.getY();

        // map to reference coordinate system
        GlobalData.audioScene.mapPoint(point);
        viewportTransformation.mapPoints(point);

        // check if point lies outwards current bounds
        if (point[0] < minMaxXY[0][0]) minMaxXY[0][0] = point[0];
        if (point[0] > minMaxXY[1][0]) minMaxXY[1][0] = point[0];
        if (point[1] < minMaxXY[0][1]) minMaxXY[0][1] = point[1];
        if (point[1] > minMaxXY[1][1]) minMaxXY[1][1] = point[1];
      }
    }

    return minMaxXY;
  }
  @Override
  public boolean onSingleTapConfirmed(MotionEvent event) {
    synchronized (GlobalData.audioScene) {
      // (de)select one or all sound sources
      if (lastTouchSoundSource != null) {
        if (lastTouchSoundSource.isSelected()) {
          GlobalData.audioScene.deselectSoundSource(lastTouchSoundSource);
        } else {
          GlobalData.audioScene.selectSoundSource(lastTouchSoundSource);
        }
      } else {
        if (GlobalData.audioScene.getSelectedSoundSources().isEmpty()) {
          GlobalData.audioScene.selectAllSoundSources();
        } else {
          GlobalData.audioScene.deselectAllSoundSources();
        }
      }
    }

    return true;
  }
  @Override
  public boolean onDoubleTap(MotionEvent e) {
    synchronized (GlobalData.audioScene) {
      if (lastTouchSoundSource == null) { // fit scene
        transformToFitScene();
      } else { // (un)mute sound sources
        // generate server request string
        String strMsg = "<request>";
        if (!lastTouchSoundSource.isSelected()) {
          // (un)mute one source
          strMsg +=
              "<source id='"
                  + lastTouchSoundSource.getId()
                  + "' mute='"
                  + (lastTouchSoundSource.isMuted() ? "false" : "true")
                  + "'/>";
        } else {
          // (un)mute current selected group of sources
          ArrayList<SoundSource> selectedSources = GlobalData.audioScene.getSelectedSoundSources();
          int numSources = selectedSources.size();
          SoundSource soundSource;
          for (int i = 0; i < numSources; i++) { // loop through all currently selected sources
            soundSource = selectedSources.get(i);
            strMsg +=
                "<source id='"
                    + soundSource.getId()
                    + "' mute='"
                    + (soundSource.isMuted() ? "false" : "true")
                    + "'/>";
          }
        }
        strMsg += "</request>\0";
        sendToServer(strMsg);
      }
    }

    return true;
  }
Ejemplo n.º 5
0
  /**
   * Processes a Sound Node to let it play.
   *
   * @param sound the Sound Node to be processed
   */
  private void process(Sound sound, Point3f soundLoc, View view, Point3f listenerPosition) {
    if ((soundDriver == null) || !soundDriver.isOnline()) return;

    if (!sound.isEnabled() && !sound.isPlaying()) return;

    if (sound.isDisabled()) return;

    final boolean isBackgroundSound = (sound instanceof BackgroundSound);

    // first determine if the sound should be active

    boolean setSoundLoc = false;
    boolean activate;
    if (!sound.isEnabled()) {
      activate = false;
    } else if (isBackgroundSound) {
      activate = true;
    } else {
      setSoundLoc = true;
      sound.getWorldTransform().get(soundLoc);

      float squaredDist = soundLoc.distanceSquared(listenerPosition);
      activate =
          (squaredDist < (view.getSoundActivationRadius() * view.getSoundActivationRadius()));
    }

    try {
      SoundSource ss = sound.getSource();

      // if the sound is not active then make sure it is deactivated
      if (!activate) {
        if (ss == null) return;

        if (ss.isPlaying()) {
          ss.pause();
          sound.setDeactivated(true);
        }

        return;
      }

      // if the sound should be active then make sure it is
      if (ss == null) {
        SoundContainer sc = sound.getSoundContainer();

        // set up the sound source
        try {
          ss = soundDriver.allocateSoundSource();
          ss.setContainer(sc);
          ss.setLoop(sound.isContinuousEnabled());

          if (isBackgroundSound) {
            ss.setRolloffFactor(0);
            ss.setRelative(true);
            ss.setPosition(0f, 0f, 0f);
          } else {
            PointSound ps = (PointSound) sound;

            float max = ps.getMaxDistance();

            if (max == -1) max = view.getSoundActivationRadius();

            float ref = ps.getReferenceDistance();

            if (ref == -1) ref = 0.17f * max;

            ss.setMaxDistance(max * 0.9f);
            ss.setReferenceDistance(ref);
            ss.setMaxVolume(ps.getMaxVolume());
            ss.setMinVolume(ps.getMinVolume());
            ss.setRolloffFactor(ps.getRolloffFactor());
            ss.setRelative(false);

            X3DLog.debug(
                "max distance = ",
                (max * 0.9f),
                ", ",
                "ref = ",
                ref,
                ", ",
                "max vol = ",
                ps.getMaxVolume(),
                ", ",
                "min vol = ",
                ps.getMinVolume(),
                ", ",
                "vol = ",
                sound.getInitialGain());
          }

          ss.setVolume(sound.getInitialGain());

          sound.setSource(ss);
        } catch (Throwable t) {
          X3DLog.print(t);
          t.printStackTrace();

          sound.setDisabled(true);

          return;
        }
      }

      // if the sound node is not a background node then set the source position
      if (setSoundLoc) ss.setPosition(soundLoc);

      // ok now we have a legitimate sound source.  We need to make sure it is
      // configured with the current state of the node

      if (sound.isPaused()) {
        if (sound.isPlaying()) ss.pause();
      } else if (sound.isEnabled() && !sound.isPlaying()) {
        if (sound.wasRestarted() || sound.wasDeactivated()) {
          ss.rewind();
          ss.play();
          sound.setRestarted(false);
          sound.setDeactivated(false);
        }
      } else if (!sound.isEnabled() && sound.isPlaying()) {
        ss.pause();
      }
    } catch (Throwable t) {
      X3DLog.print(t);
      t.printStackTrace();

      soundDriver = null;
    }
  }
  @Override
  public boolean onScroll(
      MotionEvent firstEvent, MotionEvent thisEvent, float distanceX, float distanceY) {

    // transform sound source or surface?
    if (lastTouchSoundSource != null) { // transform sound source
      synchronized (GlobalData.audioScene) {
        // is lastTouchSoundSource selected?
        if (!lastTouchSoundSource.isSelected()) {
          // select only this source
          GlobalData.audioScene.deselectAllSoundSources();
          GlobalData.audioScene.selectSoundSource(lastTouchSoundSource);
        }

        // save positions of sources if this is first scroll event
        if (!scrolling) {
          scrolling = true;
          firstScrollPoint[0] = firstEvent.getX();
          firstScrollPoint[1] = firstEvent.getY();
          ArrayList<SoundSource> selectedSources = GlobalData.audioScene.getSelectedSoundSources();
          int numSources = selectedSources.size();
          for (int i = 0; i < numSources; i++) { // loop through all currently selected sources
            selectedSources.get(i).getXY(point);
            GlobalData.audioScene.mapPoint(point);
            viewportTransformation.mapPoints(point);
            selectedSources.get(i).savePosition(point);
          }
        }

        // enough time elapsed to do next position update?
        long currentTime = SystemClock.uptimeMillis();
        if (currentTime - lastSendTime < MAX_POSITION_UPDATE_FREQ) return true;
        lastSendTime = currentTime;

        // translate or rotate?
        if (transformationMode == TransformationMode.TRANSLATE) { // translate
          // generate server request string
          String strMsg = "<request>";
          ArrayList<SoundSource> selectedSources = GlobalData.audioScene.getSelectedSoundSources();
          int numSources = selectedSources.size();
          SoundSource soundSource;
          for (int i = 0; i < numSources; i++) { // loop through all currently selected sources
            soundSource = selectedSources.get(i);

            // if source is fixed, skip it
            if (soundSource.isPositionFixed()) continue;

            strMsg += "<source id='" + soundSource.getId() + "'>";
            // transform screen coords into object coords, consider offset
            point[0] = soundSource.getSavedX() + thisEvent.getX() - firstScrollPoint[0];
            point[1] = soundSource.getSavedY() + thisEvent.getY() - firstScrollPoint[1];
            inverseViewportTransformation.mapPoints(point);

            if (soundSource.getSourceModel()
                == SoundSource.SourceModel.PLANE) { // recalculate orientation for plane waves
              float norm =
                  FloatMath.sqrt(
                      point[0] * point[0]
                          + point[1] * point[1]); // for plane waves, if source is movable
              if (norm != 0.0f) {
                float newAzimuth;
                if (point[1] >= 0.0f)
                  newAzimuth =
                      (float) (Math.acos(point[0] / norm) / Math.PI * 180.0f)
                          - 180.0f
                          + GlobalData.audioScene.getReference().getAzimuth();
                else
                  newAzimuth =
                      (float) -(Math.acos(point[0] / norm) / Math.PI * 180.0f)
                          - 180.0f
                          + GlobalData.audioScene.getReference().getAzimuth();
                strMsg += "<orientation azimuth='" + String.valueOf(newAzimuth) + "'/>";
              }
            }

            GlobalData.audioScene.inverseMapPoint(point);
            strMsg +=
                "<position x='"
                    + String.valueOf(point[0])
                    + "' y='"
                    + String.valueOf(point[1])
                    + "'/>";
            strMsg += "</source>";
          }
          strMsg += "</request>\0";

          // send changes to server
          sendToServer(strMsg);
        } else { // rotate
          // not implemented
        }
      }
    } else { // transform surface
      if (!scrolling) {
        scrolling = true;
        firstScrollPoint[0] = thisEvent.getX();
        firstScrollPoint[1] = thisEvent.getY();
        currentSavedTranslation[0] = currentTranslation[0];
        currentSavedTranslation[1] = currentTranslation[1];
      }

      // translate or rotate?
      if (transformationMode == TransformationMode.TRANSLATE) { // translate
        if (currentOrientation == Configuration.ORIENTATION_PORTRAIT) {
          point[0] = thisEvent.getX() - firstScrollPoint[0];
          point[1] = thisEvent.getY() - firstScrollPoint[1];
        } else if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
          point[0] = thisEvent.getY() - firstScrollPoint[1];
          point[1] = -(thisEvent.getX() - firstScrollPoint[0]);
        }
        setCurrentTranslation(
            currentSavedTranslation[0] + point[0], currentSavedTranslation[1] + point[1]);
      } else { // rotate
        // not implemented
      }
    }

    return true;
  }