2012-01-23 2 views
3

며칠 전 Google Sky Map을 오픈 소스로 사용 했으므로 그걸 가지고 놀고 싶습니다. 불행히도 사용자의 클릭 동작을 객체 (행성 등 ...)에 매핑 할 수 없습니다.Google Sky Map 오픈 소스 - 클릭 동작을 객체에 매핑하는 방법?

진입 점은 GestureInterceptor.onDown(MotionEvent e)이라고 생각합니다.

하지만 MotionEvent을 개체에 매핑하는 방법은 무엇입니까? 나는 여기서 완전히 잃어 버렸어.

현재 소스 코드를 찾을 수 있습니다 http://code.google.com/p/stardroid/source/browse/#svn%2Ftrunk%2Fapp

지금까지 해낸 무엇 :

AstronomerModel model = StardroidApplication.getModel(); 
Pointing pointing = model.getPointing(); 

그래서 나는 모델을하고 난 시선을 얻을 수 있습니다. 그렇다면 클릭 좌표를 지구 중심 좌표 (how?)로 변환 한 다음 해당 좌표에있는 객체를 찾습니다 (how?).

답변

1

좋아, 여기에 내가 한 일이있다.

Geocentric Positions 라벨을 캡처하여 ApplicationConstants 클래스에 모두 저장했습니다. ProtobufAstronomicalSource.getLabels()에서 얻을 수 있습니다. 플래닛을 제외하고 PlanetSource.initialize()를 사용할 수 있습니다.

그런 다음 사용자가 클릭하면 onSingleTapConfirmed 메서드가 com.google.android.stardroid.touch.GestureInterpreter 클래스에서 호출됩니다. 이 코드에서 모든 라벨을 얻은 다음이 코드를 사용하여 Geocentric Postions을 화면 위치로 변환합니다.

@Override 
     public boolean onSingleTapConfirmed(MotionEvent e) { 
     Log.d(TAG, "Confirmed single tap"); 

     Point screen = ApplicationConstants.getSizeOfScreen(); 
     int screenHeight = screen.y; 
     int screenWidth = screen.x; 
     float yClicked = screenHeight - e.getRawY(); //e.y is inverted, this normalizes it 
     float xClicked = e.getRawX(); 
     ArrayList<Label> labelArray = ApplicationConstants.getLabels(); 
     Log.d("LabelClicked", "label count: " + labelArray.size()); 
     ArrayList<LabelScreen> labelsOnScreen = new ArrayList<LabelScreen>(); 
     for (Label label : labelArray) { 
      //calculets current screen position of all labels, most of this code comes from LabelObjectManager.drawLabel() 
      Vector3 lookDir = ApplicationConstants.getLookDir(); 
      if (lookDir.x * label.x + lookDir.y * label.y + lookDir.z * label.z < ApplicationConstants.getmDotProductThreshold()) { 
       //return; 
      } 

      Vector3 mLabelOffset = ApplicationConstants.getmLabelOffset(); 

      // Offset the label to be underneath the given position (so a label will 
      // always appear underneath a star no matter how the phone is rotated) 
      Vector3 v = new Vector3(
       label.x - mLabelOffset.x * label.offset, 
       label.y - mLabelOffset.y * label.offset, 
       label.z - mLabelOffset.z * label.offset); 

      Vector3 screenPos = Matrix4x4.transformVector(
       ApplicationConstants.setTransformToScreenMatrix(), 
       v); 

      // We want this to align consistently with the pixels on the screen, so we 
      // snap to the nearest x/y coordinate, and add a magic offset of less than 
      // half a pixel. Without this, rounding error can cause the bottom and 
      // top of a label to be one pixel off, which results in a noticeable 
      // distortion in the text. 
      final float MAGIC_OFFSET = 0.25f; 
      screenPos.x = (int)screenPos.x + MAGIC_OFFSET; 
      screenPos.y = (int)screenPos.y + MAGIC_OFFSET; 

      //by Marcio Granzotto Rodrigues 
      if ((screenPos.x < 0.0f) | (screenPos.y < 0.0f)) { 
       //not on screen 
      }else if ((screenPos.x > screenWidth) | (screenPos.y > screenHeight)) { 
       //not on screen 
      }else if (screenPos.z < 0) { 
       //not on screen 
      }else { 
       //on screen 
       Log.d("LabelClicked", "on screen: " + label.getText() + " - " + screenPos.x + " " + screenPos.y + " " + screenPos.z); 
       LabelScreen labelScreen = new LabelScreen(label, screenPos); 
       labelsOnScreen.add(labelScreen); 
      }//end else 
     }//end for 

     Log.i("LabelClicked", "Labels on Screen: " + labelsOnScreen.size()); 
     LabelScreen theLabel = null; 
     for (LabelScreen labelScreen : labelsOnScreen) { 
      if (true) { //TODO check if label is on the clickable list 
       if (theLabel == null) { 
        //defines first label 
        theLabel = labelScreen; 
        Log.i("LabelClicked", "theLabel null -> " + theLabel.getLabel().getText()); 
       }else { 
        //check if this label is closer to the click area than theLabel 
        float theLabelRelativeX = theLabel.getScreenPos().x - xClicked; 
        float theLabelRelativeY = theLabel.getScreenPos().y - yClicked; 
        float myLabelRealativeX = labelScreen.getScreenPos().x - xClicked; 
        float myLabelRealativeY = labelScreen.getScreenPos().y - yClicked; 

        if ((Math.abs(myLabelRealativeX) < Math.abs(theLabelRelativeX)) 
          && (Math.abs(myLabelRealativeY) < Math.abs(theLabelRelativeY))) { 
         Log.i("LabelClicked", "theLabel " + theLabel.getLabel().getText() + " -> " + labelScreen.getLabel().getText()); 
         theLabel = labelScreen; 
        } 
       } 
      } 
     } 

     float theLabelRelativeX = theLabel.getScreenPos().x - xClicked; 
     float theLabelRelativeY = theLabel.getScreenPos().y - yClicked; 
     if ((theLabelRelativeX < screenWidth*0.1f) && (theLabelRelativeY < screenHeight*0.1f)) { 
      //clicked 
      if (theLabel.getLabel().getText().equals(ApplicationConstants.myContext.getString(com.google.android.stardroid.R.string.moon))) { 
       //ìf the clicked label is the moon, checks phase (in portuguese) 
       String moonPhase = ""; 
       switch (ApplicationConstants.getMoonPhase()) { 
       case ApplicationConstants.MOON_FULL: 
        moonPhase = " cheia"; 
        break; 
       case ApplicationConstants.MOON_CRESCENT: 
        moonPhase = " crescente"; 
        break; 
       case ApplicationConstants.MOON_NEW: 
        moonPhase = " nova"; 
        break; 
       case ApplicationConstants.MOON_GIBBOUS: 
        moonPhase = " minguante"; 
        break; 
       default: 
        break; 
       } 
       Toast.makeText(ApplicationConstants.myContext, theLabel.getLabel().getText() + moonPhase, Toast.LENGTH_SHORT).show(); 
       Log.i("LabelClicked", "You clicked: " + theLabel.getLabel().getText() + moonPhase); 
      }else { 
       Toast.makeText(ApplicationConstants.myContext, theLabel.getLabel().getText(), Toast.LENGTH_SHORT).show(); 
       Log.i("LabelClicked", "You clicked: " + theLabel.getLabel().getText()); 
      } 
     } 
     return false; 
     } 

이 정보가 도움이되기를 바랍니다.

+0

주실 수 있나요? ApplicationContants 클래스를 공유하십시오. –

관련 문제