@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; }
/** * 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; }